1 /*- 2 * BSD LICENSE 3 * 4 * Copyright 2016 6WIND S.A. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 11 * * Redistributions of source code must retain the above copyright 12 * notice, this list of conditions and the following disclaimer. 13 * * Redistributions in binary form must reproduce the above copyright 14 * notice, this list of conditions and the following disclaimer in 15 * the documentation and/or other materials provided with the 16 * distribution. 17 * * Neither the name of Intel Corporation nor the names of its 18 * contributors may be used to endorse or promote products derived 19 * from this software without specific prior written permission. 20 * 21 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 22 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 23 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 24 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 25 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 26 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 27 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 28 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 29 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 30 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 31 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 32 */ 33 34 #ifndef _RTE_NET_PTYPE_H_ 35 #define _RTE_NET_PTYPE_H_ 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 #include <rte_ip.h> 42 #include <rte_udp.h> 43 #include <rte_tcp.h> 44 #include <rte_sctp.h> 45 46 /** 47 * Structure containing header lengths associated to a packet, filled 48 * by rte_net_get_ptype(). 49 */ 50 struct rte_net_hdr_lens { 51 uint8_t l2_len; 52 uint8_t l3_len; 53 uint8_t l4_len; 54 uint8_t tunnel_len; 55 uint8_t inner_l2_len; 56 uint8_t inner_l3_len; 57 uint8_t inner_l4_len; 58 }; 59 60 /** 61 * Parse an Ethernet packet to get its packet type. 62 * 63 * This function parses the network headers in mbuf data and return its 64 * packet type. 65 * 66 * If it is provided by the user, it also fills a rte_net_hdr_lens 67 * structure that contains the lengths of the parsed network 68 * headers. Each length field is valid only if the associated packet 69 * type is set. For instance, hdr_lens->l2_len is valid only if 70 * (retval & RTE_PTYPE_L2_MASK) != RTE_PTYPE_UNKNOWN. 71 * 72 * Supported packet types are: 73 * L2: Ether, Vlan, QinQ 74 * L3: IPv4, IPv6 75 * L4: TCP, UDP, SCTP 76 * Tunnels: IPv4, IPv6, Gre, Nvgre 77 * 78 * @param m 79 * The packet mbuf to be parsed. 80 * @param hdr_lens 81 * A pointer to a structure where the header lengths will be returned, 82 * or NULL. 83 * @param layers 84 * List of layers to parse. The function will stop at the first 85 * empty layer. Examples: 86 * - To parse all known layers, use RTE_PTYPE_ALL_MASK. 87 * - To parse only L2 and L3, use RTE_PTYPE_L2_MASK | RTE_PTYPE_L3_MASK 88 * @return 89 * The packet type of the packet. 90 */ 91 uint32_t rte_net_get_ptype(const struct rte_mbuf *m, 92 struct rte_net_hdr_lens *hdr_lens, uint32_t layers); 93 94 /** 95 * Prepare pseudo header checksum 96 * 97 * This function prepares pseudo header checksum for TSO and non-TSO tcp/udp in 98 * provided mbufs packet data and based on the requested offload flags. 99 * 100 * - for non-TSO tcp/udp packets full pseudo-header checksum is counted and set 101 * in packet data, 102 * - for TSO the IP payload length is not included in pseudo header. 103 * 104 * This function expects that used headers are in the first data segment of 105 * mbuf, are not fragmented and can be safely modified. 106 * 107 * @param m 108 * The packet mbuf to be fixed. 109 * @param ol_flags 110 * TX offloads flags to use with this packet. 111 * @return 112 * 0 if checksum is initialized properly 113 */ 114 static inline int 115 rte_net_intel_cksum_flags_prepare(struct rte_mbuf *m, uint64_t ol_flags) 116 { 117 struct ipv4_hdr *ipv4_hdr; 118 struct ipv6_hdr *ipv6_hdr; 119 struct tcp_hdr *tcp_hdr; 120 struct udp_hdr *udp_hdr; 121 uint64_t inner_l3_offset = m->l2_len; 122 123 if ((ol_flags & PKT_TX_OUTER_IP_CKSUM) || 124 (ol_flags & PKT_TX_OUTER_IPV6)) 125 inner_l3_offset += m->outer_l2_len + m->outer_l3_len; 126 127 if ((ol_flags & PKT_TX_UDP_CKSUM) == PKT_TX_UDP_CKSUM) { 128 if (ol_flags & PKT_TX_IPV4) { 129 ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, 130 inner_l3_offset); 131 132 if (ol_flags & PKT_TX_IP_CKSUM) 133 ipv4_hdr->hdr_checksum = 0; 134 135 udp_hdr = (struct udp_hdr *)((char *)ipv4_hdr + 136 m->l3_len); 137 udp_hdr->dgram_cksum = rte_ipv4_phdr_cksum(ipv4_hdr, 138 ol_flags); 139 } else { 140 ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, 141 inner_l3_offset); 142 /* non-TSO udp */ 143 udp_hdr = rte_pktmbuf_mtod_offset(m, struct udp_hdr *, 144 inner_l3_offset + m->l3_len); 145 udp_hdr->dgram_cksum = rte_ipv6_phdr_cksum(ipv6_hdr, 146 ol_flags); 147 } 148 } else if ((ol_flags & PKT_TX_TCP_CKSUM) || 149 (ol_flags & PKT_TX_TCP_SEG)) { 150 if (ol_flags & PKT_TX_IPV4) { 151 ipv4_hdr = rte_pktmbuf_mtod_offset(m, struct ipv4_hdr *, 152 inner_l3_offset); 153 154 if (ol_flags & PKT_TX_IP_CKSUM) 155 ipv4_hdr->hdr_checksum = 0; 156 157 /* non-TSO tcp or TSO */ 158 tcp_hdr = (struct tcp_hdr *)((char *)ipv4_hdr + 159 m->l3_len); 160 tcp_hdr->cksum = rte_ipv4_phdr_cksum(ipv4_hdr, 161 ol_flags); 162 } else { 163 ipv6_hdr = rte_pktmbuf_mtod_offset(m, struct ipv6_hdr *, 164 inner_l3_offset); 165 /* non-TSO tcp or TSO */ 166 tcp_hdr = rte_pktmbuf_mtod_offset(m, struct tcp_hdr *, 167 inner_l3_offset + m->l3_len); 168 tcp_hdr->cksum = rte_ipv6_phdr_cksum(ipv6_hdr, 169 ol_flags); 170 } 171 } 172 173 return 0; 174 } 175 176 /** 177 * Prepare pseudo header checksum 178 * 179 * This function prepares pseudo header checksum for TSO and non-TSO tcp/udp in 180 * provided mbufs packet data. 181 * 182 * - for non-TSO tcp/udp packets full pseudo-header checksum is counted and set 183 * in packet data, 184 * - for TSO the IP payload length is not included in pseudo header. 185 * 186 * This function expects that used headers are in the first data segment of 187 * mbuf, are not fragmented and can be safely modified. 188 * 189 * @param m 190 * The packet mbuf to be fixed. 191 * @return 192 * 0 if checksum is initialized properly 193 */ 194 static inline int 195 rte_net_intel_cksum_prepare(struct rte_mbuf *m) 196 { 197 return rte_net_intel_cksum_flags_prepare(m, m->ol_flags); 198 } 199 200 #ifdef __cplusplus 201 } 202 #endif 203 204 205 #endif /* _RTE_NET_PTYPE_H_ */ 206