1605d52e6SDmitry Fleytman /* 2605d52e6SDmitry Fleytman * QEMU RX packets abstraction 3605d52e6SDmitry Fleytman * 4605d52e6SDmitry Fleytman * Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com) 5605d52e6SDmitry Fleytman * 6605d52e6SDmitry Fleytman * Developed by Daynix Computing LTD (http://www.daynix.com) 7605d52e6SDmitry Fleytman * 8605d52e6SDmitry Fleytman * Authors: 9605d52e6SDmitry Fleytman * Dmitry Fleytman <dmitry@daynix.com> 10605d52e6SDmitry Fleytman * Tamir Shomer <tamirs@daynix.com> 11605d52e6SDmitry Fleytman * Yan Vugenfirer <yan@daynix.com> 12605d52e6SDmitry Fleytman * 13605d52e6SDmitry Fleytman * This work is licensed under the terms of the GNU GPL, version 2 or later. 14605d52e6SDmitry Fleytman * See the COPYING file in the top-level directory. 15605d52e6SDmitry Fleytman * 16605d52e6SDmitry Fleytman */ 17605d52e6SDmitry Fleytman 18605d52e6SDmitry Fleytman #ifndef NET_RX_PKT_H 19605d52e6SDmitry Fleytman #define NET_RX_PKT_H 20605d52e6SDmitry Fleytman 21605d52e6SDmitry Fleytman #include "net/eth.h" 22605d52e6SDmitry Fleytman 23605d52e6SDmitry Fleytman /* defines to enable packet dump functions */ 24605d52e6SDmitry Fleytman /*#define NET_RX_PKT_DEBUG*/ 25605d52e6SDmitry Fleytman 26605d52e6SDmitry Fleytman struct NetRxPkt; 27605d52e6SDmitry Fleytman 28605d52e6SDmitry Fleytman /** 29605d52e6SDmitry Fleytman * Clean all rx packet resources 30605d52e6SDmitry Fleytman * 31605d52e6SDmitry Fleytman * @pkt: packet 32605d52e6SDmitry Fleytman * 33605d52e6SDmitry Fleytman */ 34605d52e6SDmitry Fleytman void net_rx_pkt_uninit(struct NetRxPkt *pkt); 35605d52e6SDmitry Fleytman 36605d52e6SDmitry Fleytman /** 37605d52e6SDmitry Fleytman * Init function for rx packet functionality 38605d52e6SDmitry Fleytman * 39605d52e6SDmitry Fleytman * @pkt: packet pointer 40605d52e6SDmitry Fleytman * @has_virt_hdr: device uses virtio header 41605d52e6SDmitry Fleytman * 42605d52e6SDmitry Fleytman */ 43605d52e6SDmitry Fleytman void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr); 44605d52e6SDmitry Fleytman 45605d52e6SDmitry Fleytman /** 46605d52e6SDmitry Fleytman * returns total length of data attached to rx context 47605d52e6SDmitry Fleytman * 48605d52e6SDmitry Fleytman * @pkt: packet 49605d52e6SDmitry Fleytman * 50605d52e6SDmitry Fleytman * Return: nothing 51605d52e6SDmitry Fleytman * 52605d52e6SDmitry Fleytman */ 53605d52e6SDmitry Fleytman size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt); 54605d52e6SDmitry Fleytman 55605d52e6SDmitry Fleytman /** 56605d52e6SDmitry Fleytman * parse and set packet analysis results 57605d52e6SDmitry Fleytman * 58605d52e6SDmitry Fleytman * @pkt: packet 59605d52e6SDmitry Fleytman * @data: pointer to the data buffer to be parsed 60605d52e6SDmitry Fleytman * @len: data length 61605d52e6SDmitry Fleytman * 62605d52e6SDmitry Fleytman */ 63605d52e6SDmitry Fleytman void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data, 64605d52e6SDmitry Fleytman size_t len); 65605d52e6SDmitry Fleytman 66605d52e6SDmitry Fleytman /** 67605d52e6SDmitry Fleytman * fetches packet analysis results 68605d52e6SDmitry Fleytman * 69605d52e6SDmitry Fleytman * @pkt: packet 70605d52e6SDmitry Fleytman * @isip4: whether the packet given is IPv4 71605d52e6SDmitry Fleytman * @isip6: whether the packet given is IPv6 72605d52e6SDmitry Fleytman * @isudp: whether the packet given is UDP 73605d52e6SDmitry Fleytman * @istcp: whether the packet given is TCP 74605d52e6SDmitry Fleytman * 75605d52e6SDmitry Fleytman */ 76605d52e6SDmitry Fleytman void net_rx_pkt_get_protocols(struct NetRxPkt *pkt, 77605d52e6SDmitry Fleytman bool *isip4, bool *isip6, 78605d52e6SDmitry Fleytman bool *isudp, bool *istcp); 79605d52e6SDmitry Fleytman 80605d52e6SDmitry Fleytman /** 81eb700029SDmitry Fleytman * fetches L3 header offset 82eb700029SDmitry Fleytman * 83eb700029SDmitry Fleytman * @pkt: packet 84eb700029SDmitry Fleytman * 85eb700029SDmitry Fleytman */ 86eb700029SDmitry Fleytman size_t net_rx_pkt_get_l3_hdr_offset(struct NetRxPkt *pkt); 87eb700029SDmitry Fleytman 88eb700029SDmitry Fleytman /** 89eb700029SDmitry Fleytman * fetches L4 header offset 90eb700029SDmitry Fleytman * 91eb700029SDmitry Fleytman * @pkt: packet 92eb700029SDmitry Fleytman * 93eb700029SDmitry Fleytman */ 94eb700029SDmitry Fleytman size_t net_rx_pkt_get_l4_hdr_offset(struct NetRxPkt *pkt); 95eb700029SDmitry Fleytman 96eb700029SDmitry Fleytman /** 97eb700029SDmitry Fleytman * fetches L5 header offset 98eb700029SDmitry Fleytman * 99eb700029SDmitry Fleytman * @pkt: packet 100eb700029SDmitry Fleytman * 101eb700029SDmitry Fleytman */ 102eb700029SDmitry Fleytman size_t net_rx_pkt_get_l5_hdr_offset(struct NetRxPkt *pkt); 103eb700029SDmitry Fleytman 104eb700029SDmitry Fleytman /** 105eb700029SDmitry Fleytman * fetches IP6 header analysis results 106eb700029SDmitry Fleytman * 107eb700029SDmitry Fleytman * Return: pointer to analysis results structure which is stored in internal 108eb700029SDmitry Fleytman * packet area. 109eb700029SDmitry Fleytman * 110eb700029SDmitry Fleytman */ 111eb700029SDmitry Fleytman eth_ip6_hdr_info *net_rx_pkt_get_ip6_info(struct NetRxPkt *pkt); 112eb700029SDmitry Fleytman 113eb700029SDmitry Fleytman /** 114eb700029SDmitry Fleytman * fetches IP4 header analysis results 115eb700029SDmitry Fleytman * 116eb700029SDmitry Fleytman * Return: pointer to analysis results structure which is stored in internal 117eb700029SDmitry Fleytman * packet area. 118eb700029SDmitry Fleytman * 119eb700029SDmitry Fleytman */ 120eb700029SDmitry Fleytman eth_ip4_hdr_info *net_rx_pkt_get_ip4_info(struct NetRxPkt *pkt); 121eb700029SDmitry Fleytman 122eb700029SDmitry Fleytman /** 123eb700029SDmitry Fleytman * fetches L4 header analysis results 124eb700029SDmitry Fleytman * 125eb700029SDmitry Fleytman * Return: pointer to analysis results structure which is stored in internal 126eb700029SDmitry Fleytman * packet area. 127eb700029SDmitry Fleytman * 128eb700029SDmitry Fleytman */ 129eb700029SDmitry Fleytman eth_l4_hdr_info *net_rx_pkt_get_l4_info(struct NetRxPkt *pkt); 130eb700029SDmitry Fleytman 131eb700029SDmitry Fleytman typedef enum { 132eb700029SDmitry Fleytman NetPktRssIpV4, 133eb700029SDmitry Fleytman NetPktRssIpV4Tcp, 134eb700029SDmitry Fleytman NetPktRssIpV6Tcp, 135eb700029SDmitry Fleytman NetPktRssIpV6, 136*33bbc05eSYuri Benditovich NetPktRssIpV6Ex, 137*33bbc05eSYuri Benditovich NetPktRssIpV6TcpEx, 138*33bbc05eSYuri Benditovich NetPktRssIpV4Udp, 139*33bbc05eSYuri Benditovich NetPktRssIpV6Udp, 140*33bbc05eSYuri Benditovich NetPktRssIpV6UdpEx, 141eb700029SDmitry Fleytman } NetRxPktRssType; 142eb700029SDmitry Fleytman 143eb700029SDmitry Fleytman /** 144eb700029SDmitry Fleytman * calculates RSS hash for packet 145eb700029SDmitry Fleytman * 146eb700029SDmitry Fleytman * @pkt: packet 147eb700029SDmitry Fleytman * @type: RSS hash type 148eb700029SDmitry Fleytman * 149eb700029SDmitry Fleytman * Return: Toeplitz RSS hash. 150eb700029SDmitry Fleytman * 151eb700029SDmitry Fleytman */ 152eb700029SDmitry Fleytman uint32_t 153eb700029SDmitry Fleytman net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt, 154eb700029SDmitry Fleytman NetRxPktRssType type, 155eb700029SDmitry Fleytman uint8_t *key); 156eb700029SDmitry Fleytman 157eb700029SDmitry Fleytman /** 158eb700029SDmitry Fleytman * fetches IP identification for the packet 159eb700029SDmitry Fleytman * 160eb700029SDmitry Fleytman * @pkt: packet 161eb700029SDmitry Fleytman * 162eb700029SDmitry Fleytman */ 163eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt); 164eb700029SDmitry Fleytman 165eb700029SDmitry Fleytman /** 166eb700029SDmitry Fleytman * check if given packet is a TCP ACK packet 167eb700029SDmitry Fleytman * 168eb700029SDmitry Fleytman * @pkt: packet 169eb700029SDmitry Fleytman * 170eb700029SDmitry Fleytman */ 171eb700029SDmitry Fleytman bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt); 172eb700029SDmitry Fleytman 173eb700029SDmitry Fleytman /** 174eb700029SDmitry Fleytman * check if given packet contains TCP data 175eb700029SDmitry Fleytman * 176eb700029SDmitry Fleytman * @pkt: packet 177eb700029SDmitry Fleytman * 178eb700029SDmitry Fleytman */ 179eb700029SDmitry Fleytman bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt); 180eb700029SDmitry Fleytman 181eb700029SDmitry Fleytman /** 182605d52e6SDmitry Fleytman * returns virtio header stored in rx context 183605d52e6SDmitry Fleytman * 184605d52e6SDmitry Fleytman * @pkt: packet 185605d52e6SDmitry Fleytman * @ret: virtio header 186605d52e6SDmitry Fleytman * 187605d52e6SDmitry Fleytman */ 188605d52e6SDmitry Fleytman struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt); 189605d52e6SDmitry Fleytman 190605d52e6SDmitry Fleytman /** 191605d52e6SDmitry Fleytman * returns packet type 192605d52e6SDmitry Fleytman * 193605d52e6SDmitry Fleytman * @pkt: packet 194605d52e6SDmitry Fleytman * @ret: packet type 195605d52e6SDmitry Fleytman * 196605d52e6SDmitry Fleytman */ 197605d52e6SDmitry Fleytman eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt); 198605d52e6SDmitry Fleytman 199605d52e6SDmitry Fleytman /** 200605d52e6SDmitry Fleytman * returns vlan tag 201605d52e6SDmitry Fleytman * 202605d52e6SDmitry Fleytman * @pkt: packet 203605d52e6SDmitry Fleytman * @ret: VLAN tag 204605d52e6SDmitry Fleytman * 205605d52e6SDmitry Fleytman */ 206605d52e6SDmitry Fleytman uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt); 207605d52e6SDmitry Fleytman 208605d52e6SDmitry Fleytman /** 209605d52e6SDmitry Fleytman * tells whether vlan was stripped from the packet 210605d52e6SDmitry Fleytman * 211605d52e6SDmitry Fleytman * @pkt: packet 212605d52e6SDmitry Fleytman * @ret: VLAN stripped sign 213605d52e6SDmitry Fleytman * 214605d52e6SDmitry Fleytman */ 215605d52e6SDmitry Fleytman bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt); 216605d52e6SDmitry Fleytman 217605d52e6SDmitry Fleytman /** 218605d52e6SDmitry Fleytman * notifies caller if the packet has virtio header 219605d52e6SDmitry Fleytman * 220605d52e6SDmitry Fleytman * @pkt: packet 221605d52e6SDmitry Fleytman * @ret: true if packet has virtio header, false otherwize 222605d52e6SDmitry Fleytman * 223605d52e6SDmitry Fleytman */ 224605d52e6SDmitry Fleytman bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt); 225605d52e6SDmitry Fleytman 226605d52e6SDmitry Fleytman /** 227eb700029SDmitry Fleytman * attach scatter-gather data to rx packet 228eb700029SDmitry Fleytman * 229eb700029SDmitry Fleytman * @pkt: packet 230eb700029SDmitry Fleytman * @iov: received data scatter-gather list 231eb700029SDmitry Fleytman * @iovcnt number of elements in iov 232eb700029SDmitry Fleytman * @iovoff data start offset in the iov 233eb700029SDmitry Fleytman * @strip_vlan: should the module strip vlan from data 234eb700029SDmitry Fleytman * 235eb700029SDmitry Fleytman */ 236eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt, 237eb700029SDmitry Fleytman const struct iovec *iov, 238eb700029SDmitry Fleytman int iovcnt, size_t iovoff, 239eb700029SDmitry Fleytman bool strip_vlan); 240eb700029SDmitry Fleytman 241eb700029SDmitry Fleytman /** 242eb700029SDmitry Fleytman * attach scatter-gather data to rx packet 243eb700029SDmitry Fleytman * 244eb700029SDmitry Fleytman * @pkt: packet 245eb700029SDmitry Fleytman * @iov: received data scatter-gather list 246eb700029SDmitry Fleytman * @iovcnt number of elements in iov 247eb700029SDmitry Fleytman * @iovoff data start offset in the iov 248eb700029SDmitry Fleytman * @strip_vlan: should the module strip vlan from data 249eb700029SDmitry Fleytman * @vet: VLAN tag Ethernet type 250eb700029SDmitry Fleytman * 251eb700029SDmitry Fleytman */ 252eb700029SDmitry Fleytman void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt, 253eb700029SDmitry Fleytman const struct iovec *iov, int iovcnt, 254eb700029SDmitry Fleytman size_t iovoff, bool strip_vlan, 255eb700029SDmitry Fleytman uint16_t vet); 256eb700029SDmitry Fleytman 257eb700029SDmitry Fleytman /** 258605d52e6SDmitry Fleytman * attach data to rx packet 259605d52e6SDmitry Fleytman * 260605d52e6SDmitry Fleytman * @pkt: packet 261605d52e6SDmitry Fleytman * @data: pointer to the data buffer 262605d52e6SDmitry Fleytman * @len: data length 263605d52e6SDmitry Fleytman * @strip_vlan: should the module strip vlan from data 264605d52e6SDmitry Fleytman * 265605d52e6SDmitry Fleytman */ 266eb700029SDmitry Fleytman static inline void 267eb700029SDmitry Fleytman net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data, 268eb700029SDmitry Fleytman size_t len, bool strip_vlan) 269eb700029SDmitry Fleytman { 270eb700029SDmitry Fleytman const struct iovec iov = { 271eb700029SDmitry Fleytman .iov_base = (void *) data, 272eb700029SDmitry Fleytman .iov_len = len 273eb700029SDmitry Fleytman }; 274eb700029SDmitry Fleytman 275eb700029SDmitry Fleytman net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan); 276eb700029SDmitry Fleytman } 277605d52e6SDmitry Fleytman 278605d52e6SDmitry Fleytman /** 279605d52e6SDmitry Fleytman * returns io vector that holds the attached data 280605d52e6SDmitry Fleytman * 281605d52e6SDmitry Fleytman * @pkt: packet 282605d52e6SDmitry Fleytman * @ret: pointer to IOVec 283605d52e6SDmitry Fleytman * 284605d52e6SDmitry Fleytman */ 285605d52e6SDmitry Fleytman struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt); 286605d52e6SDmitry Fleytman 287605d52e6SDmitry Fleytman /** 288eb700029SDmitry Fleytman * returns io vector length that holds the attached data 289eb700029SDmitry Fleytman * 290eb700029SDmitry Fleytman * @pkt: packet 291eb700029SDmitry Fleytman * @ret: IOVec length 292eb700029SDmitry Fleytman * 293eb700029SDmitry Fleytman */ 294eb700029SDmitry Fleytman uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt); 295eb700029SDmitry Fleytman 296eb700029SDmitry Fleytman /** 297605d52e6SDmitry Fleytman * prints rx packet data if debug is enabled 298605d52e6SDmitry Fleytman * 299605d52e6SDmitry Fleytman * @pkt: packet 300605d52e6SDmitry Fleytman * 301605d52e6SDmitry Fleytman */ 302605d52e6SDmitry Fleytman void net_rx_pkt_dump(struct NetRxPkt *pkt); 303605d52e6SDmitry Fleytman 304605d52e6SDmitry Fleytman /** 305605d52e6SDmitry Fleytman * copy passed vhdr data to packet context 306605d52e6SDmitry Fleytman * 307605d52e6SDmitry Fleytman * @pkt: packet 308605d52e6SDmitry Fleytman * @vhdr: VHDR buffer 309605d52e6SDmitry Fleytman * 310605d52e6SDmitry Fleytman */ 311605d52e6SDmitry Fleytman void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt, 312605d52e6SDmitry Fleytman struct virtio_net_hdr *vhdr); 313605d52e6SDmitry Fleytman 314605d52e6SDmitry Fleytman /** 315eb700029SDmitry Fleytman * copy passed vhdr data to packet context 316eb700029SDmitry Fleytman * 317eb700029SDmitry Fleytman * @pkt: packet 318eb700029SDmitry Fleytman * @iov: VHDR iov 319eb700029SDmitry Fleytman * @iovcnt: VHDR iov array size 320eb700029SDmitry Fleytman * 321eb700029SDmitry Fleytman */ 322eb700029SDmitry Fleytman void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt, 323eb700029SDmitry Fleytman const struct iovec *iov, int iovcnt); 324eb700029SDmitry Fleytman 325eb700029SDmitry Fleytman /** 326605d52e6SDmitry Fleytman * save packet type in packet context 327605d52e6SDmitry Fleytman * 328605d52e6SDmitry Fleytman * @pkt: packet 329605d52e6SDmitry Fleytman * @packet_type: the packet type 330605d52e6SDmitry Fleytman * 331605d52e6SDmitry Fleytman */ 332605d52e6SDmitry Fleytman void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt, 333605d52e6SDmitry Fleytman eth_pkt_types_e packet_type); 334605d52e6SDmitry Fleytman 335eb700029SDmitry Fleytman /** 336eb700029SDmitry Fleytman * validate TCP/UDP checksum of the packet 337eb700029SDmitry Fleytman * 338eb700029SDmitry Fleytman * @pkt: packet 339eb700029SDmitry Fleytman * @csum_valid: checksum validation result 340eb700029SDmitry Fleytman * @ret: true if validation was performed, false in case packet is 341eb700029SDmitry Fleytman * not TCP/UDP or checksum validation is not possible 342eb700029SDmitry Fleytman * 343eb700029SDmitry Fleytman */ 344eb700029SDmitry Fleytman bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid); 345eb700029SDmitry Fleytman 346eb700029SDmitry Fleytman /** 347eb700029SDmitry Fleytman * validate IPv4 checksum of the packet 348eb700029SDmitry Fleytman * 349eb700029SDmitry Fleytman * @pkt: packet 350eb700029SDmitry Fleytman * @csum_valid: checksum validation result 351eb700029SDmitry Fleytman * @ret: true if validation was performed, false in case packet is 352eb700029SDmitry Fleytman * not TCP/UDP or checksum validation is not possible 353eb700029SDmitry Fleytman * 354eb700029SDmitry Fleytman */ 355eb700029SDmitry Fleytman bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid); 356eb700029SDmitry Fleytman 357eb700029SDmitry Fleytman /** 358eb700029SDmitry Fleytman * fix IPv4 checksum of the packet 359eb700029SDmitry Fleytman * 360eb700029SDmitry Fleytman * @pkt: packet 361eb700029SDmitry Fleytman * @ret: true if checksum was fixed, false in case packet is 362eb700029SDmitry Fleytman * not TCP/UDP or checksum correction is not possible 363eb700029SDmitry Fleytman * 364eb700029SDmitry Fleytman */ 365eb700029SDmitry Fleytman bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt); 366eb700029SDmitry Fleytman 367605d52e6SDmitry Fleytman #endif 368