summaryrefslogtreecommitdiffstats
path: root/src/plugins/dhcp/dhcp4_proxy_node.c
diff options
context:
space:
mode:
authorStanislav Zaikin <zstaseg@gmail.com>2020-04-23 12:14:30 +0000
committerJohn Lo <loj@cisco.com>2020-04-26 13:18:54 +0000
commite65eea360c394429320a45d695ee4d770673b3d4 (patch)
tree2b42c9323c85c9e087756fafacfeddaf751874a5 /src/plugins/dhcp/dhcp4_proxy_node.c
parent681ea6dd287ed56b4ef32ba831cf9ae7d10c10de (diff)
dhcp: fix dhcp proxy behavior for qinq and dot1q subinterfaces
Previous behavior worked only when subinterface ID matches with dot1q tag and doesn't work at all in QinQ case. In this patch I'm checking how subinterface is configured. Type: fix Signed-off-by: Stanislav Zaikin <zstaseg@gmail.com> Change-Id: I7a662a0442fdc8e68aba5d6f469f3b1139a4bc2d
Diffstat (limited to 'src/plugins/dhcp/dhcp4_proxy_node.c')
-rw-r--r--src/plugins/dhcp/dhcp4_proxy_node.c36
1 files changed, 29 insertions, 7 deletions
diff --git a/src/plugins/dhcp/dhcp4_proxy_node.c b/src/plugins/dhcp/dhcp4_proxy_node.c
index 28c3e624aa1..78c4444a1e8 100644
--- a/src/plugins/dhcp/dhcp4_proxy_node.c
+++ b/src/plugins/dhcp/dhcp4_proxy_node.c
@@ -532,6 +532,8 @@ dhcp_proxy_to_client_input (vlib_main_t * vm,
vnet_hw_interface_t *hi0;
u32 sw_if_index = ~0;
vnet_sw_interface_t *si0;
+ u32 inner_vlan = (u32) ~ 0;
+ u32 outer_vlan = (u32) ~ 0;
u32 error0 = (u32) ~ 0;
vnet_sw_interface_t *swif;
u32 fib_index;
@@ -719,7 +721,19 @@ dhcp_proxy_to_client_input (vlib_main_t * vm,
vlib_buffer_advance (b0, -(sizeof (ethernet_header_t)));
si0 = vnet_get_sw_interface (vnm, original_sw_if_index);
if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
- vlib_buffer_advance (b0, -4 /* space for VLAN tag */ );
+ {
+ if (si0->sub.eth.flags.one_tag == 1)
+ {
+ vlib_buffer_advance (b0, -4 /* space for 1 VLAN tag */ );
+ outer_vlan = (si0->sub.eth.outer_vlan_id << 16) | 0x0800;
+ }
+ else if (si0->sub.eth.flags.two_tags == 1)
+ {
+ vlib_buffer_advance (b0, -8 /* space for 2 VLAN tag */ );
+ outer_vlan = (si0->sub.eth.outer_vlan_id << 16) | 0x8100;
+ inner_vlan = (si0->sub.eth.inner_vlan_id << 16) | 0x0800;
+ }
+ }
mac0 = vlib_buffer_get_current (b0);
@@ -728,15 +742,23 @@ dhcp_proxy_to_client_input (vlib_main_t * vm,
clib_memcpy (mac0->src_address, ei0->address,
sizeof (ei0->address));
clib_memset (mac0->dst_address, 0xff, sizeof (mac0->dst_address));
- mac0->type = (si0->type == VNET_SW_INTERFACE_TYPE_SUB) ?
- clib_net_to_host_u16 (0x8100) : clib_net_to_host_u16 (0x0800);
- if (si0->type == VNET_SW_INTERFACE_TYPE_SUB)
+ if (si0->type == VNET_SW_INTERFACE_TYPE_SUB
+ && outer_vlan != (u32) ~ 0)
{
+ mac0->type = (si0->sub.eth.flags.dot1ad == 1) ?
+ clib_net_to_host_u16 (0x88a8) : clib_net_to_host_u16 (0x8100);
u32 *vlan_tag = (u32 *) (mac0 + 1);
- u32 tmp;
- tmp = (si0->sub.id << 16) | 0x0800;
- *vlan_tag = clib_host_to_net_u32 (tmp);
+ *vlan_tag = clib_host_to_net_u32 (outer_vlan);
+ if (inner_vlan != (u32) ~ 0)
+ {
+ u32 *inner_vlan_tag = (u32 *) (vlan_tag + 1);
+ *inner_vlan_tag = clib_host_to_net_u32 (inner_vlan);
+ }
+ }
+ else
+ {
+ mac0->type = clib_net_to_host_u16 (0x0800);
}
do_trace: