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 * @data: pointer to the data buffer to be parsed 59 * @len: data length 60 * 61 */ 62 void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data, 63 size_t len); 64 65 /** 66 * fetches packet analysis results 67 * 68 * @pkt: packet 69 * @hasip4: whether the packet has an IPv4 header 70 * @hasip6: whether the packet has an IPv6 header 71 * @l4hdr_proto: protocol of L4 header 72 * 73 */ 74 void net_rx_pkt_get_protocols(struct NetRxPkt *pkt, 75 bool *hasip4, bool *hasip6, 76 EthL4HdrProto *l4hdr_proto); 77 78 /** 79 * fetches L3 header offset 80 * 81 * @pkt: packet 82 * 83 */ 84 size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt); 85 86 /** 87 * fetches L4 header offset 88 * 89 * @pkt: packet 90 * 91 */ 92 size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt); 93 94 /** 95 * fetches L5 header offset 96 * 97 * @pkt: packet 98 * 99 */ 100 size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt); 101 102 /** 103 * fetches IP6 header analysis results 104 * 105 * Return: pointer to analysis results structure which is stored in internal 106 * packet area. 107 * 108 */ 109 eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt); 110 111 /** 112 * fetches IP4 header analysis results 113 * 114 * Return: pointer to analysis results structure which is stored in internal 115 * packet area. 116 * 117 */ 118 eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt); 119 120 /** 121 * fetches L4 header analysis results 122 * 123 * Return: pointer to analysis results structure which is stored in internal 124 * packet area. 125 * 126 */ 127 eth_l4_hdr_info *net_rx_pkt_get_l4_info(struct NetRxPkt *pkt); 128 129 typedef enum { 130 NetPktRssIpV4, 131 NetPktRssIpV4Tcp, 132 NetPktRssIpV6Tcp, 133 NetPktRssIpV6, 134 NetPktRssIpV6Ex, 135 NetPktRssIpV6TcpEx, 136 NetPktRssIpV4Udp, 137 NetPktRssIpV6Udp, 138 NetPktRssIpV6UdpEx, 139 } NetRxPktRssType; 140 141 /** 142 * calculates RSS hash for packet 143 * 144 * @pkt: packet 145 * @type: RSS hash type 146 * 147 * Return: Toeplitz RSS hash. 148 * 149 */ 150 uint32_t 151 net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt, 152 NetRxPktRssType type, 153 uint8_t *key); 154 155 /** 156 * fetches IP identification for the packet 157 * 158 * @pkt: packet 159 * 160 */ 161 uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt); 162 163 /** 164 * check if given packet is a TCP ACK packet 165 * 166 * @pkt: packet 167 * 168 */ 169 bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt); 170 171 /** 172 * check if given packet contains TCP data 173 * 174 * @pkt: packet 175 * 176 */ 177 bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt); 178 179 /** 180 * returns virtio header stored in rx context 181 * 182 * @pkt: packet 183 * @ret: virtio header 184 * 185 */ 186 struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt); 187 188 /** 189 * returns packet type 190 * 191 * @pkt: packet 192 * @ret: packet type 193 * 194 */ 195 eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt); 196 197 /** 198 * returns vlan tag 199 * 200 * @pkt: packet 201 * @ret: VLAN tag 202 * 203 */ 204 uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt); 205 206 /** 207 * tells whether vlan was stripped from the packet 208 * 209 * @pkt: packet 210 * @ret: VLAN stripped sign 211 * 212 */ 213 bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt); 214 215 /** 216 * attach scatter-gather data to rx packet 217 * 218 * @pkt: packet 219 * @iov: received data scatter-gather list 220 * @iovcnt number of elements in iov 221 * @iovoff data start offset in the iov 222 * @strip_vlan: should the module strip vlan from data 223 * 224 */ 225 void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt, 226 const struct iovec *iov, 227 int iovcnt, size_t iovoff, 228 bool strip_vlan); 229 230 /** 231 * attach scatter-gather data to rx packet 232 * 233 * @pkt: packet 234 * @iov: received data scatter-gather list 235 * @iovcnt number of elements in iov 236 * @iovoff data start offset in the iov 237 * @strip_vlan: should the module strip vlan from data 238 * @vet: VLAN tag Ethernet type 239 * 240 */ 241 void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt, 242 const struct iovec *iov, int iovcnt, 243 size_t iovoff, bool strip_vlan, 244 uint16_t vet); 245 246 /** 247 * attach data to rx packet 248 * 249 * @pkt: packet 250 * @data: pointer to the data buffer 251 * @len: data length 252 * @strip_vlan: should the module strip vlan from data 253 * 254 */ 255 static inline void 256 net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data, 257 size_t len, bool strip_vlan) 258 { 259 const struct iovec iov = { 260 .iov_base = (void *) data, 261 .iov_len = len 262 }; 263 264 net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan); 265 } 266 267 /** 268 * returns io vector that holds the attached data 269 * 270 * @pkt: packet 271 * @ret: pointer to IOVec 272 * 273 */ 274 struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt); 275 276 /** 277 * returns io vector length that holds the attached data 278 * 279 * @pkt: packet 280 * @ret: IOVec length 281 * 282 */ 283 uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt); 284 285 /** 286 * prints rx packet data if debug is enabled 287 * 288 * @pkt: packet 289 * 290 */ 291 void net_rx_pkt_dump(struct NetRxPkt *pkt); 292 293 /** 294 * copy passed vhdr data to packet context 295 * 296 * @pkt: packet 297 * @vhdr: VHDR buffer 298 * 299 */ 300 void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt, 301 struct virtio_net_hdr *vhdr); 302 303 /** 304 * copy passed vhdr data to packet context 305 * 306 * @pkt: packet 307 * @iov: VHDR iov 308 * @iovcnt: VHDR iov array size 309 * 310 */ 311 void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt, 312 const struct iovec *iov, int iovcnt); 313 314 /** 315 * unset vhdr data from packet context 316 * 317 * @pkt: packet 318 * 319 */ 320 void net_rx_pkt_unset_vhdr(struct NetRxPkt *pkt); 321 322 /** 323 * save packet type in packet context 324 * 325 * @pkt: packet 326 * @packet_type: the packet type 327 * 328 */ 329 void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt, 330 eth_pkt_types_e packet_type); 331 332 /** 333 * validate TCP/UDP checksum of the packet 334 * 335 * @pkt: packet 336 * @csum_valid: checksum validation result 337 * @ret: true if validation was performed, false in case packet is 338 * not TCP/UDP or checksum validation is not possible 339 * 340 */ 341 bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid); 342 343 /** 344 * validate IPv4 checksum of the packet 345 * 346 * @pkt: packet 347 * @csum_valid: checksum validation result 348 * @ret: true if validation was performed, false in case packet is 349 * not TCP/UDP or checksum validation is not possible 350 * 351 */ 352 bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid); 353 354 /** 355 * fix IPv4 checksum of the packet 356 * 357 * @pkt: packet 358 * @ret: true if checksum was fixed, false in case packet is 359 * not TCP/UDP or checksum correction is not possible 360 * 361 */ 362 bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt); 363 364 #endif 365