25 #define dhcp_proxy_error(n,s) s, 27 #undef dhcp_proxy_error 30 #define foreach_dhcp_proxy_to_server_input_next \ 31 _ (DROP, "error-drop") \ 32 _ (LOOKUP, "ip4-lookup") \ 33 _ (SEND_TO_CLIENT, "dhcp-proxy-to-client") 37 #define _(s,n) DHCP_PROXY_TO_SERVER_INPUT_NEXT_##s, 57 #define VPP_DHCP_OPTION82_SUB1_SIZE 6 58 #define VPP_DHCP_OPTION82_SUB5_SIZE 6 59 #define VPP_DHCP_OPTION82_VSS_SIZE 12 60 #define VPP_DHCP_OPTION82_SIZE (VPP_DHCP_OPTION82_SUB1_SIZE + \ 61 VPP_DHCP_OPTION82_SUB5_SIZE + \ 62 VPP_DHCP_OPTION82_VSS_SIZE +3) 75 s =
format (s,
"DHCP proxy: sent to server %U\n",
78 s =
format (s,
"DHCP proxy: broadcast to client from %U\n",
84 s =
format (s,
" original_sw_if_index: %d, sw_if_index: %d\n",
96 u32 max_header_bytes = va_arg (*args,
u32);
99 header_bytes =
sizeof (h[0]);
100 if (max_header_bytes != 0 && header_bytes > max_header_bytes)
101 return format (s,
"dhcp header truncated");
103 s =
format (s,
"DHCP Proxy");
113 u32 n_left_from, next_index, *from, *to_next;
117 u32 pkts_to_server = 0, pkts_to_client = 0, pkts_no_server = 0;
118 u32 pkts_no_interface_address = 0;
119 u32 pkts_too_big = 0;
124 while (n_left_from > 0)
130 while (n_left_from > 0 && n_left_to_next > 0)
142 u32 original_sw_if_index = 0;
169 clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_server))
172 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_SEND_TO_CLIENT;
184 error0 = DHCP_PROXY_ERROR_NO_SERVER;
185 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
192 error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
193 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
200 if ((b0->
flags & VLIB_BUFFER_NEXT_PRESENT) != 0 ||
203 error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
204 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
263 original_sw_if_index = sw_if_index =
278 error0 = DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS;
279 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
280 pkts_no_interface_address++;
290 *o_ifid = clib_host_to_net_u32 (original_sw_if_index);
304 id_len =
sizeof (vss->
vpn_id);
316 o->
data[13] = id_len + 1;
318 o->
data[15 + id_len] = 152;
319 o->
data[16 + id_len] = 0;
329 new_l0 = clib_net_to_host_u16 (old_l0);
331 new_l0 = clib_host_to_net_u16 (new_l0);
339 new_l0 = clib_net_to_host_u16 (u0->
length);
341 u0->
length = clib_host_to_net_u16 (new_l0);
347 DHCP_PROXY_ERROR_OPTION_82_ERROR, 1);
350 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP;
371 DHCP_PROXY_ERROR_ALLOC_FAIL, 1);
394 to_next, n_left_to_next,
406 if (next0 == DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
420 to_next, n_left_to_next);
433 if (next0 == DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
446 to_next, n_left_to_next,
453 DHCP_PROXY_ERROR_RELAY_TO_CLIENT,
456 DHCP_PROXY_ERROR_RELAY_TO_SERVER,
459 DHCP_PROXY_ERROR_NO_SERVER, pkts_no_server);
461 DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS,
462 pkts_no_interface_address);
464 DHCP_PROXY_ERROR_PKT_TOO_BIG, pkts_too_big);
471 .name =
"dhcp-proxy-to-server",
473 .vector_size =
sizeof (
u32),
480 #define _(s,n) [DHCP_PROXY_TO_SERVER_INPUT_NEXT_##s] = n, 488 .unformat_buffer = unformat_dhcp_proxy_header,
505 u32 n_left_from, *from, *to_next, n_left_to_next;
516 while (n_left_from > 0)
520 while (n_left_from > 0 && n_left_to_next > 0)
535 u32 inner_vlan = (
u32) ~ 0;
536 u32 outer_vlan = (
u32) ~ 0;
542 u32 original_sw_if_index = (
u32) ~ 0;
548 bi0 = to_next[0] = from[0];
570 error0 = DHCP_PROXY_ERROR_FOR_US;
577 if ((b0->
flags & VLIB_BUFFER_NEXT_PRESENT) != 0 || !rv)
579 error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
607 sw_if_index = ((sub->
data[0] << 24) |
608 (sub->
data[1] << 16) |
609 (sub->
data[2] << 8) |
619 else if (sub->
option == 151 &&
626 if (vss_ctrl && vss_exist)
629 DHCP_PROXY_ERROR_OPTION_82_VSS_NOT_PROCESSED, 1);
635 if (sw_if_index == (
u32) ~ 0)
637 error0 = DHCP_PROXY_ERROR_NO_OPTION_82;
648 if (relay_addr.
as_u32 == 0)
650 error0 = DHCP_PROXY_ERROR_BAD_OPTION_82_ADDR;
656 error0 = DHCP_PROXY_ERROR_BAD_OPTION_82_ITF;
665 error0 = DHCP_PROXY_ERROR_NO_SERVER;
677 error0 = DHCP_PROXY_ERROR_BAD_SVR_FIB_OR_ADDRESS;
691 error0 = DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS;
697 error0 = DHCP_PROXY_ERROR_BAD_YIADDR;
702 u0->
dst_port = clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_client);
747 && outer_vlan != (
u32) ~ 0)
750 clib_net_to_host_u16 (0x88a8) : clib_net_to_host_u16 (0x8100);
751 u32 *vlan_tag = (
u32 *) (mac0 + 1);
752 *vlan_tag = clib_host_to_net_u32 (outer_vlan);
753 if (inner_vlan != (
u32) ~ 0)
755 u32 *inner_vlan_tag = (
u32 *) (vlan_tag + 1);
756 *inner_vlan_tag = clib_host_to_net_u32 (inner_vlan);
761 mac0->
type = clib_net_to_host_u16 (0x0800);
779 to_next, n_left_to_next,
791 .name =
"dhcp-proxy-to-client",
793 .vector_size =
sizeof (
u32),
800 .unformat_buffer = unformat_dhcp_proxy_header,
849 ip46_address_t * src_addr,
850 u32 rx_table_id,
u32 server_table_id,
int is_del)
852 u32 rx_fib_index = 0;
857 .fp_addr.ip4.as_u32 = 0xffffffff,
862 return VNET_API_ERROR_INVALID_DST_ADDRESS;
865 return VNET_API_ERROR_INVALID_SRC_ADDRESS;
876 addr, server_table_id))
887 rx_fib_index, server_table_id))
905 ip46_address_t server_addr, src_addr;
906 u32 server_table_id = 0, rx_table_id = 0;
908 int set_src = 0, set_server = 0;
910 clib_memset (&server_addr, 0,
sizeof (server_addr));
918 else if (
unformat (input,
"server-fib-id %d", &server_table_id))
920 else if (
unformat (input,
"rx-fib-id %d", &rx_table_id))
922 else if (
unformat (input,
"src-address %U",
931 if (is_del || (set_server && set_src))
936 server_table_id, is_del);
942 case VNET_API_ERROR_INVALID_DST_ADDRESS:
945 case VNET_API_ERROR_INVALID_SRC_ADDRESS:
948 case VNET_API_ERROR_NO_SUCH_ENTRY:
950 (0,
"Fib id %d: no per-fib DHCP server configured", rx_table_id);
963 .path =
"set dhcp proxy",
964 .short_help =
"set dhcp proxy [del] server <ip-addr> src-address <ip-addr> [server-fib-id <n>] [rx-fib-id <n>]",
978 s =
format (s,
"%=14s%=16s%s",
"RX FIB",
"Src Address",
979 "Servers FIB,Address");
985 s =
format (s,
"%=14u%=16U",
1024 .path =
"show dhcp proxy",
1025 .short_help =
"Display dhcp proxy server info",
1035 u32 oui = 0, fib_id = 0, tbl_id = ~0;
1036 u8 *vpn_ascii_id = 0;
1040 if (
unformat (input,
"table %d", &tbl_id))
1042 else if (
unformat (input,
"oui %d", &oui))
1044 else if (
unformat (input,
"vpn-id %d", &fib_id))
1046 else if (
unformat (input,
"vpn-ascii-id %s", &vpn_ascii_id))
1058 vpn_ascii_id, oui, fib_id, is_del);
1063 case VNET_API_ERROR_NO_SUCH_ENTRY:
1065 "option 82 vss for table %d not found in in pool.",
1075 .path =
"set dhcp option-82 vss",
1076 .short_help =
"set dhcp option-82 vss [del] table <table id> [oui <n> vpn-id <n> | vpn-ascii-id <text>]",
1092 .path =
"show dhcp vss",
1093 .short_help =
"show dhcp VSS",
1121 "source IP address");
1129 "No IPv4 address configured on",
1141 .path =
"show dhcp option-82-address interface",
1142 .short_help =
"show dhcp option-82-address interface <interface>",
static vlib_node_registration_t dhcp_proxy_to_client_node
(constructor) VLIB_REGISTER_NODE (dhcp_proxy_to_client_node)
u32 flags
buffer flags: VLIB_BUFFER_FREE_LIST_INDEX_MASK: bits used to store free list index, VLIB_BUFFER_IS_TRACED: trace this buffer.
static dhcp_vss_t * dhcp_get_vss_info(dhcp_proxy_main_t *dm, u32 rx_fib_index, fib_protocol_t proto)
Get the VSS data for the FIB index.
static u8 * vlib_buffer_get_tail(vlib_buffer_t *b)
Get pointer to the end of buffer's data.
vnet_main_t * vnet_get_main(void)
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
void dhcp_vss_walk(fib_protocol_t proto, dhcp_vss_walk_fn_t fn, void *ctx)
Walk/Visit each DHCP proxy VSS.
dhcp_server_t * dhcp_servers
The set of DHCP servers to which messages are relayed.
static uword dhcp_proxy_to_client_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
void dhcp_proxy_walk(fib_protocol_t proto, dhcp_proxy_walk_fn_t fn, void *ctx)
Walk/Visit each DHCP proxy server.
#define clib_memcpy_fast(a, b, c)
static clib_error_t * dhcp4_proxy_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define VPP_DHCP_OPTION82_SIZE
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
ip4_address_t * ip4_interface_first_address(ip4_main_t *im, u32 sw_if_index, ip_interface_address_t **result_ia)
ethernet_interface_t * interfaces
dhcp_proxy_main_t dhcp_proxy_main
Shard 4/6 instance of DHCP main.
int dhcp_vss_show_walk(dhcp_vss_t *vss, u32 rx_table_id, void *ctx)
Show (on CLI) a VSS config during a show walk.
static uword dhcp_proxy_to_server_input(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *from_frame)
u16 current_length
Nbytes between current data and the end of this buffer.
ip46_address_t dhcp_src_address
The source address to use in relayed messaes.
The Virtual Sub-net Selection information for a given RX FIB.
u32 rx_fib_index
The FIB index (not the external Table-ID) in which the client is resides.
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
unformat_function_t unformat_vnet_sw_interface
vlib_node_registration_t error_drop_node
(constructor) VLIB_REGISTER_NODE (error_drop_node)
u8 vss_type
VSS type as defined in RFC 6607: 0 for NVT ASCII VPN Identifier 1 for RFC 2685 VPN-ID of 7 octects - ...
u32 error_drop_node_index
vlib_error_t * errors
Vector of errors for this node.
format_function_t format_vnet_sw_if_index_name
static vlib_buffer_t * vlib_buffer_copy(vlib_main_t *vm, vlib_buffer_t *b)
#define clib_memcpy(d, s, n)
vl_api_interface_index_t sw_if_index
#define VLIB_INIT_FUNCTION(x)
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a 'special' entry from the FIB.
static vlib_node_registration_t dhcp_proxy_to_server_node
(constructor) VLIB_REGISTER_NODE (dhcp_proxy_to_server_node)
Aggregate type for a prefix.
static clib_error_t * dhcp4_proxy_set_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static dhcp_proxy_t * dhcp_get_proxy(dhcp_proxy_main_t *dm, u32 rx_fib_index, fib_protocol_t proto)
Get the DHCP proxy server data for the FIB index.
#define clib_error_return(e, args...)
int dhcp_proxy_server_add(fib_protocol_t proto, ip46_address_t *addr, ip46_address_t *src_address, u32 rx_fib_index, u32 server_table_id)
Add a new DHCP proxy server configuration.
u16 fp_len
The mask length.
static u32 vlib_get_buffer_index(vlib_main_t *vm, void *p)
Translate buffer pointer into buffer index.
vlib_error_t error
Error code for buffers to be enqueued to error handler.
u32 server_fib_index
The FIB index (not the external Table-ID) in which the server is reachable.
static u8 * format_dhcp4_proxy_server(u8 *s, va_list *args)
static u32 vlib_buffer_chain_linearize(vlib_main_t *vm, vlib_buffer_t *b)
Collection of global DHCP proxy data.
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
static u8 ip46_address_is_zero(const ip46_address_t *ip46)
u8 * format_dhcp_header(u8 *s, va_list *args)
dhcp_proxy_to_server_input_next_t
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
vnet_sw_interface_flags_t flags
vl_api_address_union_t src_address
static char * dhcp_proxy_error_strings[]
int dhcp_proxy_set_vss(fib_protocol_t proto, u32 tbl_id, u8 vss_type, u8 *vpn_ascii_id, u32 oui, u32 vpn_index, u8 is_del)
Configure/set a new VSS info.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
format_function_t format_ip46_address
static clib_error_t * dhcp4_proxy_init(vlib_main_t *vm)
fib_node_index_t fib_table_entry_special_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags)
Add a 'special' entry to the FIB.
#define VLIB_REGISTER_NODE(x,...)
u8 * vpn_ascii_id
Type 0 ASCII VPN Identifier.
static clib_error_t * dhcp_option_82_address_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
A representation of a single DHCP Server within a given VRF config.
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
static u32 vlib_buffer_space_left_at_end(vlib_main_t *vm, vlib_buffer_t *b)
vlib_main_t vlib_node_runtime_t * node
void fib_table_lock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Release a reference counting lock on the table.
u32 unnumbered_sw_if_index
#define VLIB_CLI_COMMAND(x,...)
int dhcp_client_for_us(u32 bi, vlib_buffer_t *b, ip4_header_t *ip, udp_header_t *udp, dhcp_header_t *dhcp)
int dhcp4_proxy_set_server(ip46_address_t *addr, ip46_address_t *src_addr, u32 rx_table_id, u32 server_table_id, int is_del)
u16 cached_next_index
Next frame index that vector arguments were last enqueued to last time this node ran.
ip46_address_t dhcp_server
The address of the DHCP server to which to relay the client's messages.
static u8 * format_dhcp_proxy_trace(u8 *s, va_list *args)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
#define foreach_dhcp_proxy_to_server_input_next
static clib_error_t * dhcp_option_82_vss_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
struct vnet_sub_interface_t::@327::@328::@330 flags
u8 packet_data[2 *sizeof(dhcp_header_t)]
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
static clib_error_t * dhcp_vss_show_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip4_address_t trace_ip4_address
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
struct _vlib_node_registration vlib_node_registration_t
A DHCP proxy representation fpr per-client VRF config.
int dhcp_proxy_server_del(fib_protocol_t proto, u32 rx_fib_index, ip46_address_t *addr, u32 server_table_id)
Delete a DHCP proxy config.
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
u8 vpn_id[7]
Type 1 VPN-ID.
#define VLIB_BUFFER_TRACE_TRAJECTORY_INIT(b)
VLIB buffer representation.
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define ip_csum_update(sum, old, new, type, field)
void dhcp_maybe_register_udp_ports(dhcp_port_reg_flags_t ports)
Register the dhcp client and/or server ports, if not already done.
static u8 * format_dhcp_proxy_header_with_length(u8 *s, va_list *args)
static ethernet_main_t * vnet_get_ethernet_main(void)
vnet_sw_interface_type_t type
ip4_main_t ip4_main
Global ip4 main structure.
#define vec_foreach(var, vec)
Vector iterator.
f64 end
end of the time range
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static int dhcp4_proxy_show_walk(dhcp_proxy_t *server, void *ctx)
static u16 ip_csum_fold(ip_csum_t c)
struct vnet_sub_interface_t::@327 eth