1 /* 2 * QEMU RX packets abstraction 3 * 4 * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com) 5 * 6 * Developed by Daynix Computing LTD (http://www.daynix.com) 7 * 8 * Authors: 9 * Dmitry Fleytman <dmitry@daynix.com> 10 * Tamir Shomer <tamirs@daynix.com> 11 * Yan Vugenfirer <yan@daynix.com> 12 * 13 * This work is licensed under the terms of the GNU GPL, version 2 or later. 14 * See the COPYING file in the top-level directory. 15 * 16 */ 17 18 #ifndef NET_RX_PKT_H 19 #define NET_RX_PKT_H 20 21 #include "net/eth.h" 22 23 /* defines to enable packet dump functions */ 24 /*#define NET_RX_PKT_DEBUG*/ 25 26 struct NetRxPkt; 27 28 /** 29 * Clean all rx packet resources 30 * 31 * @pkt: packet 32 * 33 */ 34 void net_rx_pkt_uninit(struct NetRxPkt *pkt); 35 36 /** 37 * Init function for rx packet functionality 38 * 39 * @pkt: packet pointer 40 * 41 */ 42 void net_rx_pkt_init(struct NetRxPkt **pkt); 43 44 /** 45 * returns total length of data attached to rx context 46 * 47 * @pkt: packet 48 * 49 * Return: nothing 50 * 51 */ 52 size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt); 53 54 /** 55 * parse and set packet analysis results 56 * 57 * @pkt: packet 58 * @iov: received data scatter-gather list 59 * @iovcnt: number of elements in iov 60 * @iovoff: data start offset in the iov 61 * 62 */ 63 void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, 64 const struct iovec *iov, size_t iovcnt, 65 size_t iovoff); 66 67 /** 68 * fetches packet analysis results 69 * 70 * @pkt: packet 71 * @hasip4: whether the packet has an IPv4 header 72 * @hasip6: whether the packet has an IPv6 header 73 * @l4hdr_proto: protocol of L4 header 74 * 75 */ 76 void net_rx_pkt_get_protocols(struct NetRxPkt *pkt, 77 bool *hasip4, bool *hasip6, 78 EthL4HdrProto *l4hdr_proto); 79 80 /** 81 * fetches L3 header offset 82 * 83 * @pkt: packet 84 * 85 */ 86 size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt); 87 88 /** 89 * fetches L4 header offset 90 * 91 * @pkt: packet 92 * 93 */ 94 size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt); 95 96 /** 97 * fetches L5 header offset 98 * 99 * @pkt: packet 100 * 101 */ 102 size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt); 103 104 /** 105 * fetches IP6 header analysis results 106 * 107 * Return: pointer to analysis results structure which is stored in internal 108 * packet area. 109 * 110 */ 111 eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt); 112 113 /** 114 * fetches IP4 header analysis results 115 * 116 * Return: pointer to analysis results structure which is stored in internal 117 * packet area. 118 * 119 */ 120 eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt); 121 122 typedef enum { 123 NetPktRssIpV4, 124 NetPktRssIpV4Tcp, 125 NetPktRssIpV6Tcp, 126 NetPktRssIpV6, 127 NetPktRssIpV6Ex, 128 NetPktRssIpV6TcpEx, 129 NetPktRssIpV4Udp, 130 NetPktRssIpV6Udp, 131 NetPktRssIpV6UdpEx, 132 } NetRxPktRssType; 133 134 /** 135 * calculates RSS hash for packet 136 * 137 * @pkt: packet 138 * @type: RSS hash type 139 * 140 * Return: Toeplitz RSS hash. 141 * 142 */ 143 uint32_t 144 net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt, 145 NetRxPktRssType type, 146 uint8_t *key); 147 148 /** 149 * fetches IP identification for the packet 150 * 151 * @pkt: packet 152 * 153 */ 154 uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt); 155 156 /** 157 * check if given packet is a TCP ACK packet 158 * 159 * @pkt: packet 160 * 161 */ 162 bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt); 163 164 /** 165 * check if given packet contains TCP data 166 * 167 * @pkt: packet 168 * 169 */ 170 bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt); 171 172 /** 173 * returns virtio header stored in rx context 174 * 175 * @pkt: packet 176 * @ret: virtio header 177 * 178 */ 179 struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt); 180 181 /** 182 * returns packet type 183 * 184 * @pkt: packet 185 * @ret: packet type 186 * 187 */ 188 eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt); 189 190 /** 191 * returns vlan tag 192 * 193 * @pkt: packet 194 * @ret: VLAN tag 195 * 196 */ 197 uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt); 198 199 /** 200 * tells whether vlan was stripped from the packet 201 * 202 * @pkt: packet 203 * @ret: VLAN stripped sign 204 * 205 */ 206 bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt); 207 208 /** 209 * attach scatter-gather data to rx packet 210 * 211 * @pkt: packet 212 * @iov: received data scatter-gather list 213 * @iovcnt number of elements in iov 214 * @iovoff data start offset in the iov 215 * @strip_vlan: should the module strip vlan from data 216 * 217 */ 218 void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt, 219 const struct iovec *iov, 220 int iovcnt, size_t iovoff, 221 bool strip_vlan); 222 223 /** 224 * attach scatter-gather data to rx packet 225 * 226 * @pkt: packet 227 * @iov: received data scatter-gather list 228 * @iovcnt: number of elements in iov 229 * @iovoff: data start offset in the iov 230 * @strip_vlan_index: index of Q tag if it is to be stripped. negative otherwise. 231 * @vet: VLAN tag Ethernet type 232 * @vet_ext: outer VLAN tag Ethernet type 233 * 234 */ 235 void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt, 236 const struct iovec *iov, int iovcnt, 237 size_t iovoff, int strip_vlan_index, 238 uint16_t vet, uint16_t vet_ext); 239 240 /** 241 * attach data to rx packet 242 * 243 * @pkt: packet 244 * @data: pointer to the data buffer 245 * @len: data length 246 * @strip_vlan: should the module strip vlan from data 247 * 248 */ 249 static inline void 250 net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data, 251 size_t len, bool strip_vlan) 252 { 253 const struct iovec iov = { 254 .iov_base = (void *) data, 255 .iov_len = len 256 }; 257 258 net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan); 259 } 260 261 /** 262 * returns io vector that holds the attached data 263 * 264 * @pkt: packet 265 * @ret: pointer to IOVec 266 * 267 */ 268 struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt); 269 270 /** 271 * returns io vector length that holds the attached data 272 * 273 * @pkt: packet 274 * @ret: IOVec length 275 * 276 */ 277 uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt); 278 279 /** 280 * prints rx packet data if debug is enabled 281 * 282 * @pkt: packet 283 * 284 */ 285 void net_rx_pkt_dump(struct NetRxPkt *pkt); 286 287 /** 288 * copy passed vhdr data to packet context 289 * 290 * @pkt: packet 291 * @vhdr: VHDR buffer 292 * 293 */ 294 void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt, 295 struct virtio_net_hdr *vhdr); 296 297 /** 298 * copy passed vhdr data to packet context 299 * 300 * @pkt: packet 301 * @iov: VHDR iov 302 * @iovcnt: VHDR iov array size 303 * 304 */ 305 void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt, 306 const struct iovec *iov, int iovcnt); 307 308 /** 309 * unset vhdr data from packet context 310 * 311 * @pkt: packet 312 * 313 */ 314 void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt); 315 316 /** 317 * save packet type in packet context 318 * 319 * @pkt: packet 320 * @packet_type: the packet type 321 * 322 */ 323 void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt, 324 eth_pkt_types_e packet_type); 325 326 /** 327 * validate TCP/UDP checksum of the packet 328 * 329 * @pkt: packet 330 * @csum_valid: checksum validation result 331 * @ret: true if validation was performed, false in case packet is 332 * not TCP/UDP or checksum validation is not possible 333 * 334 */ 335 bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid); 336 337 /** 338 * validate IPv4 checksum of the packet 339 * 340 * @pkt: packet 341 * @csum_valid: checksum validation result 342 * @ret: true if validation was performed, false in case packet is 343 * not TCP/UDP or checksum validation is not possible 344 * 345 */ 346 bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid); 347 348 /** 349 * fix IPv4 checksum of the packet 350 * 351 * @pkt: packet 352 * @ret: true if checksum was fixed, false in case packet is 353 * not TCP/UDP or checksum correction is not possible 354 * 355 */ 356 bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt); 357 358 #endif 359