-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Packet abstraction for VMWARE network devices
Signed-off-by: Dmitry Fleytman <[email protected]> Signed-off-by: Yan Vugenfirer <[email protected]> Signed-off-by: Stefan Hajnoczi <[email protected]>
- Loading branch information
1 parent
75020a7
commit e263cd4
Showing
5 changed files
with
1,077 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,187 @@ | ||
/* | ||
* QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstractions | ||
* | ||
* Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com) | ||
* | ||
* Developed by Daynix Computing LTD (http://www.daynix.com) | ||
* | ||
* Authors: | ||
* Dmitry Fleytman <[email protected]> | ||
* Tamir Shomer <[email protected]> | ||
* Yan Vugenfirer <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
* | ||
*/ | ||
|
||
#include "vmxnet_rx_pkt.h" | ||
#include "net/eth.h" | ||
#include "qemu-common.h" | ||
#include "qemu/iov.h" | ||
#include "net/checksum.h" | ||
#include "net/tap.h" | ||
|
||
/* | ||
* RX packet may contain up to 2 fragments - rebuilt eth header | ||
* in case of VLAN tag stripping | ||
* and payload received from QEMU - in any case | ||
*/ | ||
#define VMXNET_MAX_RX_PACKET_FRAGMENTS (2) | ||
|
||
struct VmxnetRxPkt { | ||
struct virtio_net_hdr virt_hdr; | ||
uint8_t ehdr_buf[ETH_MAX_L2_HDR_LEN]; | ||
struct iovec vec[VMXNET_MAX_RX_PACKET_FRAGMENTS]; | ||
uint16_t vec_len; | ||
uint32_t tot_len; | ||
uint16_t tci; | ||
bool vlan_stripped; | ||
bool has_virt_hdr; | ||
eth_pkt_types_e packet_type; | ||
|
||
/* Analysis results */ | ||
bool isip4; | ||
bool isip6; | ||
bool isudp; | ||
bool istcp; | ||
}; | ||
|
||
void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr) | ||
{ | ||
struct VmxnetRxPkt *p = g_malloc0(sizeof *p); | ||
p->has_virt_hdr = has_virt_hdr; | ||
*pkt = p; | ||
} | ||
|
||
void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt) | ||
{ | ||
g_free(pkt); | ||
} | ||
|
||
struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
return &pkt->virt_hdr; | ||
} | ||
|
||
void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data, | ||
size_t len, bool strip_vlan) | ||
{ | ||
uint16_t tci = 0; | ||
uint16_t ploff; | ||
assert(pkt); | ||
pkt->vlan_stripped = false; | ||
|
||
if (strip_vlan) { | ||
pkt->vlan_stripped = eth_strip_vlan(data, pkt->ehdr_buf, &ploff, &tci); | ||
} | ||
|
||
if (pkt->vlan_stripped) { | ||
pkt->vec[0].iov_base = pkt->ehdr_buf; | ||
pkt->vec[0].iov_len = ploff - sizeof(struct vlan_header); | ||
pkt->vec[1].iov_base = (uint8_t *) data + ploff; | ||
pkt->vec[1].iov_len = len - ploff; | ||
pkt->vec_len = 2; | ||
pkt->tot_len = len - ploff + sizeof(struct eth_header); | ||
} else { | ||
pkt->vec[0].iov_base = (void *)data; | ||
pkt->vec[0].iov_len = len; | ||
pkt->vec_len = 1; | ||
pkt->tot_len = len; | ||
} | ||
|
||
pkt->tci = tci; | ||
|
||
eth_get_protocols(data, len, &pkt->isip4, &pkt->isip6, | ||
&pkt->isudp, &pkt->istcp); | ||
} | ||
|
||
void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt) | ||
{ | ||
#ifdef VMXNET_RX_PKT_DEBUG | ||
VmxnetRxPkt *pkt = (VmxnetRxPkt *)pkt; | ||
assert(pkt); | ||
|
||
printf("RX PKT: tot_len: %d, vlan_stripped: %d, vlan_tag: %d\n", | ||
pkt->tot_len, pkt->vlan_stripped, pkt->tci); | ||
#endif | ||
} | ||
|
||
void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt, | ||
eth_pkt_types_e packet_type) | ||
{ | ||
assert(pkt); | ||
|
||
pkt->packet_type = packet_type; | ||
|
||
} | ||
|
||
eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->packet_type; | ||
} | ||
|
||
size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->tot_len; | ||
} | ||
|
||
void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt, | ||
bool *isip4, bool *isip6, | ||
bool *isudp, bool *istcp) | ||
{ | ||
assert(pkt); | ||
|
||
*isip4 = pkt->isip4; | ||
*isip6 = pkt->isip6; | ||
*isudp = pkt->isudp; | ||
*istcp = pkt->istcp; | ||
} | ||
|
||
struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->vec; | ||
} | ||
|
||
void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt, | ||
struct virtio_net_hdr *vhdr) | ||
{ | ||
assert(pkt); | ||
|
||
memcpy(&pkt->virt_hdr, vhdr, sizeof pkt->virt_hdr); | ||
} | ||
|
||
bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->vlan_stripped; | ||
} | ||
|
||
bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->has_virt_hdr; | ||
} | ||
|
||
uint16_t vmxnet_rx_pkt_get_num_frags(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->vec_len; | ||
} | ||
|
||
uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt) | ||
{ | ||
assert(pkt); | ||
|
||
return pkt->tci; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,174 @@ | ||
/* | ||
* QEMU VMWARE VMXNET* paravirtual NICs - RX packets abstraction | ||
* | ||
* Copyright (c) 2012 Ravello Systems LTD (http://ravellosystems.com) | ||
* | ||
* Developed by Daynix Computing LTD (http://www.daynix.com) | ||
* | ||
* Authors: | ||
* Dmitry Fleytman <[email protected]> | ||
* Tamir Shomer <[email protected]> | ||
* Yan Vugenfirer <[email protected]> | ||
* | ||
* This work is licensed under the terms of the GNU GPL, version 2 or later. | ||
* See the COPYING file in the top-level directory. | ||
* | ||
*/ | ||
|
||
#ifndef VMXNET_RX_PKT_H | ||
#define VMXNET_RX_PKT_H | ||
|
||
#include "stdint.h" | ||
#include "stdbool.h" | ||
#include "net/eth.h" | ||
|
||
/* defines to enable packet dump functions */ | ||
/*#define VMXNET_RX_PKT_DEBUG*/ | ||
|
||
struct VmxnetRxPkt; | ||
|
||
/** | ||
* Clean all rx packet resources | ||
* | ||
* @pkt: packet | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_uninit(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* Init function for rx packet functionality | ||
* | ||
* @pkt: packet pointer | ||
* @has_virt_hdr: device uses virtio header | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_init(struct VmxnetRxPkt **pkt, bool has_virt_hdr); | ||
|
||
/** | ||
* returns total length of data attached to rx context | ||
* | ||
* @pkt: packet | ||
* | ||
* Return: nothing | ||
* | ||
*/ | ||
size_t vmxnet_rx_pkt_get_total_len(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* fetches packet analysis results | ||
* | ||
* @pkt: packet | ||
* @isip4: whether the packet given is IPv4 | ||
* @isip6: whether the packet given is IPv6 | ||
* @isudp: whether the packet given is UDP | ||
* @istcp: whether the packet given is TCP | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_get_protocols(struct VmxnetRxPkt *pkt, | ||
bool *isip4, bool *isip6, | ||
bool *isudp, bool *istcp); | ||
|
||
/** | ||
* returns virtio header stored in rx context | ||
* | ||
* @pkt: packet | ||
* @ret: virtio header | ||
* | ||
*/ | ||
struct virtio_net_hdr *vmxnet_rx_pkt_get_vhdr(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* returns packet type | ||
* | ||
* @pkt: packet | ||
* @ret: packet type | ||
* | ||
*/ | ||
eth_pkt_types_e vmxnet_rx_pkt_get_packet_type(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* returns vlan tag | ||
* | ||
* @pkt: packet | ||
* @ret: VLAN tag | ||
* | ||
*/ | ||
uint16_t vmxnet_rx_pkt_get_vlan_tag(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* tells whether vlan was stripped from the packet | ||
* | ||
* @pkt: packet | ||
* @ret: VLAN stripped sign | ||
* | ||
*/ | ||
bool vmxnet_rx_pkt_is_vlan_stripped(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* notifies caller if the packet has virtio header | ||
* | ||
* @pkt: packet | ||
* @ret: true if packet has virtio header, false otherwize | ||
* | ||
*/ | ||
bool vmxnet_rx_pkt_has_virt_hdr(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* returns number of frags attached to the packet | ||
* | ||
* @pkt: packet | ||
* @ret: number of frags | ||
* | ||
*/ | ||
uint16_t vmxnet_rx_pkt_get_num_frags(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* attach data to rx packet | ||
* | ||
* @pkt: packet | ||
* @data: pointer to the data buffer | ||
* @len: data length | ||
* @strip_vlan: should the module strip vlan from data | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_attach_data(struct VmxnetRxPkt *pkt, const void *data, | ||
size_t len, bool strip_vlan); | ||
|
||
/** | ||
* returns io vector that holds the attached data | ||
* | ||
* @pkt: packet | ||
* @ret: pointer to IOVec | ||
* | ||
*/ | ||
struct iovec *vmxnet_rx_pkt_get_iovec(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* prints rx packet data if debug is enabled | ||
* | ||
* @pkt: packet | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_dump(struct VmxnetRxPkt *pkt); | ||
|
||
/** | ||
* copy passed vhdr data to packet context | ||
* | ||
* @pkt: packet | ||
* @vhdr: VHDR buffer | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_set_vhdr(struct VmxnetRxPkt *pkt, | ||
struct virtio_net_hdr *vhdr); | ||
|
||
/** | ||
* save packet type in packet context | ||
* | ||
* @pkt: packet | ||
* @packet_type: the packet type | ||
* | ||
*/ | ||
void vmxnet_rx_pkt_set_packet_type(struct VmxnetRxPkt *pkt, | ||
eth_pkt_types_e packet_type); | ||
|
||
#endif |
Oops, something went wrong.