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