summaryrefslogtreecommitdiffstats
path: root/src/vnet/devices/af_packet
diff options
context:
space:
mode:
authorAkshaya N <akshaya@rtbrick.com>2017-09-15 17:37:53 +0530
committerDamjan Marion <dmarion.lists@gmail.com>2017-09-27 18:22:37 +0000
commit535f0bfe0274e86c5d2e00dfd66dd632c6ae20a9 (patch)
tree015c69e7cafa65395e41b0bd69908c0c0f88fdae /src/vnet/devices/af_packet
parentd51020cdfc1c023f1953a7b6970f12cf09985900 (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>
Diffstat (limited to 'src/vnet/devices/af_packet')
-rw-r--r--src/vnet/devices/af_packet/node.c29
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)
{