diff options
author | Akshaya N <akshaya@rtbrick.com> | 2017-09-15 17:37:53 +0530 |
---|---|---|
committer | Dave Barach <openvpp@barachs.net> | 2017-09-28 19:49:20 +0000 |
commit | 7feb35f9fecdbc518945364d3b8ba259ce42d949 (patch) | |
tree | 89fc8e6cf83d1dfb7efc2fbbcf6d15d2b0844270 | |
parent | 839fa732c1a769d3aa9699192a0f06a969ddbda2 (diff) |
VLAN support on host(af-packet) interface.
On host interface if a VLAN tagged packet is received, linux kernel removes
the VLAN header from packet byte stream and adds metadata in tpacket2_hdr.
This patch explicitely checks for the presense of VLAN metadata and adds it
in VPP packet.
Change-Id: I0ba35c1e98dbc008ce18d032f22f2717d610c1aa
Signed-off-by: Akshaya N <akshaya@rtbrick.com>
(cherry picked from commit 535f0bfe0274e86c5d2e00dfd66dd632c6ae20a9)
-rw-r--r-- | src/vnet/devices/af_packet/node.c | 29 |
1 files changed, 26 insertions, 3 deletions
diff --git a/src/vnet/devices/af_packet/node.c b/src/vnet/devices/af_packet/node.c index d3af41b5d90..99c91f38805 100644 --- a/src/vnet/devices/af_packet/node.c +++ b/src/vnet/devices/af_packet/node.c @@ -173,12 +173,35 @@ af_packet_device_input_fn (vlib_main_t * vm, vlib_node_runtime_t * node, /* copy data */ u32 bytes_to_copy = data_len > n_buffer_bytes ? n_buffer_bytes : data_len; + u32 vlan_len = 0; + u32 bytes_copied = 0; b0->current_data = 0; - clib_memcpy (vlib_buffer_get_current (b0), - (u8 *) tph + tph->tp_mac + offset, bytes_to_copy); + /* Kernel removes VLAN headers, so reconstruct VLAN */ + if (PREDICT_FALSE (tph->tp_status & TP_STATUS_VLAN_VALID)) + { + if (PREDICT_TRUE (offset == 0)) + { + clib_memcpy (vlib_buffer_get_current (b0), + (u8 *) tph + tph->tp_mac, + sizeof (ethernet_header_t)); + ethernet_header_t *eth = vlib_buffer_get_current (b0); + ethernet_vlan_header_t *vlan = + (ethernet_vlan_header_t *) (eth + 1); + vlan->priority_cfi_and_id = + clib_host_to_net_u16 (tph->tp_vlan_tci); + vlan->type = eth->type; + eth->type = clib_host_to_net_u16 (ETHERNET_TYPE_VLAN); + vlan_len = sizeof (ethernet_vlan_header_t); + bytes_copied = sizeof (ethernet_header_t); + } + } + clib_memcpy (((u8 *) vlib_buffer_get_current (b0)) + + bytes_copied + vlan_len, + (u8 *) tph + tph->tp_mac + offset + bytes_copied, + (bytes_to_copy - bytes_copied)); /* fill buffer header */ - b0->current_length = bytes_to_copy; + b0->current_length = bytes_to_copy + vlan_len; if (offset == 0) { |