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 * @has_virt_hdr: device uses virtio header 41 * 42 */ 43void net_rx_pkt_init(struct NetRxPkt **pkt, bool has_virt_hdr); 44 45/** 46 * returns total length of data attached to rx context 47 * 48 * @pkt: packet 49 * 50 * Return: nothing 51 * 52 */ 53size_t net_rx_pkt_get_total_len(struct NetRxPkt *pkt); 54 55/** 56 * parse and set packet analysis results 57 * 58 * @pkt: packet 59 * @data: pointer to the data buffer to be parsed 60 * @len: data length 61 * 62 */ 63void net_rx_pkt_set_protocols(struct NetRxPkt *pkt, const void *data, 64 size_t len); 65 66/** 67 * fetches packet analysis results 68 * 69 * @pkt: packet 70 * @isip4: whether the packet given is IPv4 71 * @isip6: whether the packet given is IPv6 72 * @isudp: whether the packet given is UDP 73 * @istcp: whether the packet given is TCP 74 * 75 */ 76void net_rx_pkt_get_protocols(struct NetRxPkt *pkt, 77 bool *isip4, bool *isip6, 78 bool *isudp, bool *istcp); 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} NetRxPktRssType; 138 139/** 140* calculates RSS hash for packet 141* 142* @pkt: packet 143* @type: RSS hash type 144* 145* Return: Toeplitz RSS hash. 146* 147*/ 148uint32_t 149net_rx_pkt_calc_rss_hash(struct NetRxPkt *pkt, 150 NetRxPktRssType type, 151 uint8_t *key); 152 153/** 154* fetches IP identification for the packet 155* 156* @pkt: packet 157* 158*/ 159uint16_t net_rx_pkt_get_ip_id(struct NetRxPkt *pkt); 160 161/** 162* check if given packet is a TCP ACK packet 163* 164* @pkt: packet 165* 166*/ 167bool net_rx_pkt_is_tcp_ack(struct NetRxPkt *pkt); 168 169/** 170* check if given packet contains TCP data 171* 172* @pkt: packet 173* 174*/ 175bool net_rx_pkt_has_tcp_data(struct NetRxPkt *pkt); 176 177/** 178 * returns virtio header stored in rx context 179 * 180 * @pkt: packet 181 * @ret: virtio header 182 * 183 */ 184struct virtio_net_hdr *net_rx_pkt_get_vhdr(struct NetRxPkt *pkt); 185 186/** 187 * returns packet type 188 * 189 * @pkt: packet 190 * @ret: packet type 191 * 192 */ 193eth_pkt_types_e net_rx_pkt_get_packet_type(struct NetRxPkt *pkt); 194 195/** 196 * returns vlan tag 197 * 198 * @pkt: packet 199 * @ret: VLAN tag 200 * 201 */ 202uint16_t net_rx_pkt_get_vlan_tag(struct NetRxPkt *pkt); 203 204/** 205 * tells whether vlan was stripped from the packet 206 * 207 * @pkt: packet 208 * @ret: VLAN stripped sign 209 * 210 */ 211bool net_rx_pkt_is_vlan_stripped(struct NetRxPkt *pkt); 212 213/** 214 * notifies caller if the packet has virtio header 215 * 216 * @pkt: packet 217 * @ret: true if packet has virtio header, false otherwize 218 * 219 */ 220bool net_rx_pkt_has_virt_hdr(struct NetRxPkt *pkt); 221 222/** 223* attach scatter-gather data to rx packet 224* 225* @pkt: packet 226* @iov: received data scatter-gather list 227* @iovcnt number of elements in iov 228* @iovoff data start offset in the iov 229* @strip_vlan: should the module strip vlan from data 230* 231*/ 232void net_rx_pkt_attach_iovec(struct NetRxPkt *pkt, 233 const struct iovec *iov, 234 int iovcnt, size_t iovoff, 235 bool strip_vlan); 236 237/** 238* attach scatter-gather data to rx packet 239* 240* @pkt: packet 241* @iov: received data scatter-gather list 242* @iovcnt number of elements in iov 243* @iovoff data start offset in the iov 244* @strip_vlan: should the module strip vlan from data 245* @vet: VLAN tag Ethernet type 246* 247*/ 248void net_rx_pkt_attach_iovec_ex(struct NetRxPkt *pkt, 249 const struct iovec *iov, int iovcnt, 250 size_t iovoff, bool strip_vlan, 251 uint16_t vet); 252 253/** 254 * attach data to rx packet 255 * 256 * @pkt: packet 257 * @data: pointer to the data buffer 258 * @len: data length 259 * @strip_vlan: should the module strip vlan from data 260 * 261 */ 262static inline void 263net_rx_pkt_attach_data(struct NetRxPkt *pkt, const void *data, 264 size_t len, bool strip_vlan) 265{ 266 const struct iovec iov = { 267 .iov_base = (void *) data, 268 .iov_len = len 269 }; 270 271 net_rx_pkt_attach_iovec(pkt, &iov, 1, 0, strip_vlan); 272} 273 274/** 275 * returns io vector that holds the attached data 276 * 277 * @pkt: packet 278 * @ret: pointer to IOVec 279 * 280 */ 281struct iovec *net_rx_pkt_get_iovec(struct NetRxPkt *pkt); 282 283/** 284* returns io vector length that holds the attached data 285* 286* @pkt: packet 287* @ret: IOVec length 288* 289*/ 290uint16_t net_rx_pkt_get_iovec_len(struct NetRxPkt *pkt); 291 292/** 293 * prints rx packet data if debug is enabled 294 * 295 * @pkt: packet 296 * 297 */ 298void net_rx_pkt_dump(struct NetRxPkt *pkt); 299 300/** 301 * copy passed vhdr data to packet context 302 * 303 * @pkt: packet 304 * @vhdr: VHDR buffer 305 * 306 */ 307void net_rx_pkt_set_vhdr(struct NetRxPkt *pkt, 308 struct virtio_net_hdr *vhdr); 309 310/** 311* copy passed vhdr data to packet context 312* 313* @pkt: packet 314* @iov: VHDR iov 315* @iovcnt: VHDR iov array size 316* 317*/ 318void net_rx_pkt_set_vhdr_iovec(struct NetRxPkt *pkt, 319 const struct iovec *iov, int iovcnt); 320 321/** 322 * save packet type in packet context 323 * 324 * @pkt: packet 325 * @packet_type: the packet type 326 * 327 */ 328void net_rx_pkt_set_packet_type(struct NetRxPkt *pkt, 329 eth_pkt_types_e packet_type); 330 331/** 332* validate TCP/UDP checksum of the packet 333* 334* @pkt: packet 335* @csum_valid: checksum validation result 336* @ret: true if validation was performed, false in case packet is 337* not TCP/UDP or checksum validation is not possible 338* 339*/ 340bool net_rx_pkt_validate_l4_csum(struct NetRxPkt *pkt, bool *csum_valid); 341 342/** 343* validate IPv4 checksum of the packet 344* 345* @pkt: packet 346* @csum_valid: checksum validation result 347* @ret: true if validation was performed, false in case packet is 348* not TCP/UDP or checksum validation is not possible 349* 350*/ 351bool net_rx_pkt_validate_l3_csum(struct NetRxPkt *pkt, bool *csum_valid); 352 353/** 354* fix IPv4 checksum of the packet 355* 356* @pkt: packet 357* @ret: true if checksum was fixed, false in case packet is 358* not TCP/UDP or checksum correction is not possible 359* 360*/ 361bool net_rx_pkt_fix_l4_csum(struct NetRxPkt *pkt); 362 363#endif 364