*/
#include <vlib/vlib.h>
-#include <vnet/pg/pg.h>
#include <dhcp/dhcp_proxy.h>
#include <dhcp/dhcp6_packet.h>
#include <vnet/mfib/mfib_table.h>
dhcp_proxy_main_t *dpm = &dhcp_proxy_main;
from = vlib_frame_vector_args (from_frame);
n_left_from = from_frame->n_vectors;
- u32 pkts_to_server = 0, pkts_to_client = 0, pkts_no_server = 0;
- u32 pkts_no_interface_address = 0, pkts_no_exceeding_max_hop = 0;
+ u32 pkts_to_server = 0, pkts_to_client = 0;
+ u32 pkts_no_interface_address = 0;
u32 pkts_no_src_address = 0;
u32 pkts_wrong_msg_type = 0;
u32 pkts_too_big = 0;
{
error0 = DHCPV6_PROXY_ERROR_NO_SERVER;
next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_server++;
goto do_trace;
}
{
error0 = DHCPV6_RELAY_PKT_DROP_MAX_HOPS;
next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
- pkts_no_exceeding_max_hop++;
goto do_trace;
}
link_address_set:
- if ((b0->current_length + sizeof (*id1) + sizeof (*vss1) +
- sizeof (*cmac)) > vlib_buffer_get_default_data_size (vm))
+ if ((b0->current_data + b0->current_length + sizeof (*id1) +
+ sizeof (*vss1) + sizeof (*cmac)) >
+ vlib_buffer_get_default_data_size (vm))
{
error0 = DHCPV6_PROXY_ERROR_PKT_TOO_BIG;
next0 = DHCPV6_PROXY_TO_SERVER_INPUT_NEXT_DROP;
u32 ci0;
c0 = vlib_buffer_copy (vm, b0);
- VLIB_BUFFER_TRACE_TRAJECTORY_INIT (c0);
+ if (c0 == NULL)
+ {
+ vlib_node_increment_counter
+ (vm, dhcpv6_proxy_to_server_node.index,
+ DHCPV6_PROXY_ERROR_ALLOC_FAIL, 1);
+ continue;
+ }
ci0 = vlib_get_buffer_index (vm, c0);
server = &proxy->dhcp_servers[ii];
udp_header_t *u0, *u1 = 0;
dhcpv6_relay_hdr_t *h0;
ip6_header_t *ip1 = 0, *ip0;
- ip6_address_t _ia0, *ia0 = &_ia0;
+ ip6_address_t *ia0 = 0;
ip6_address_t client_address;
ethernet_interface_t *ei0;
ethernet_header_t *mac0;
u32 sw_if_index = ~0;
u32 original_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;
dhcpv6_option_t *r0 = 0, *o;
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) | 0x86dd;
+ }
+ 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) | 0x86dd;
+ }
+ }
mac0 = vlib_buffer_get_current (b0);
hi0 = vnet_get_sup_hw_interface (vnm, original_sw_if_index);
ei0 = pool_elt_at_index (em->interfaces, hi0->hw_instance);
- clib_memcpy (mac0->src_address, ei0->address, sizeof (ei0->address));
+ clib_memcpy (mac0->src_address, &ei0->address,
+ sizeof (mac0->src_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 (0x86dd);
- 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 (0x86dd);
}
/* $$$ consider adding a dynamic next to the graph node, for performance */
if (dhcp_proxy_server_add (FIB_PROTOCOL_IP6, addr, src_addr,
rx_fib_index, server_table_id))
{
- mfib_table_entry_path_update (rx_fib_index,
- &all_dhcp_servers,
- MFIB_SOURCE_DHCP, &path_for_us);
+ mfib_table_entry_path_update (rx_fib_index, &all_dhcp_servers,
+ MFIB_SOURCE_DHCP, MFIB_ENTRY_FLAG_NONE,
+ &path_for_us);
/*
* Each interface that is enabled in this table, needs to be added
* as an accepting interface, but this is not easily doable in VPP.