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, 53 #define VPP_DHCP_OPTION82_SUB1_SIZE 6 54 #define VPP_DHCP_OPTION82_SUB5_SIZE 6 55 #define VPP_DHCP_OPTION82_VSS_SIZE 12 56 #define VPP_DHCP_OPTION82_SIZE (VPP_DHCP_OPTION82_SUB1_SIZE + \ 57 VPP_DHCP_OPTION82_SUB5_SIZE + \ 58 VPP_DHCP_OPTION82_VSS_SIZE +3) 71 s =
format (s,
"DHCP proxy: sent to server %U\n",
74 s =
format (s,
"DHCP proxy: broadcast to client from %U\n",
80 s =
format (s,
" original_sw_if_index: %d, sw_if_index: %d\n",
90 u32 max_header_bytes = va_arg (*args,
u32);
93 header_bytes =
sizeof (h[0]);
94 if (max_header_bytes != 0 && header_bytes > max_header_bytes)
95 return format (s,
"dhcp header truncated");
97 s =
format (s,
"DHCP Proxy");
107 u32 n_left_from, next_index, *from, *to_next;
111 u32 pkts_to_server = 0, pkts_to_client = 0, pkts_no_server = 0;
112 u32 pkts_no_interface_address = 0;
113 u32 pkts_too_big = 0;
118 while (n_left_from > 0)
124 while (n_left_from > 0 && n_left_to_next > 0)
136 u32 original_sw_if_index = 0;
163 clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_server))
166 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_SEND_TO_CLIENT;
178 error0 = DHCP_PROXY_ERROR_NO_SERVER;
179 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
186 error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
187 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
194 if ((b0->
flags & VLIB_BUFFER_NEXT_PRESENT) != 0 ||
197 error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
198 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
257 original_sw_if_index = sw_if_index =
272 error0 = DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS;
273 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_DROP;
274 pkts_no_interface_address++;
284 *o_ifid = clib_host_to_net_u32 (original_sw_if_index);
298 id_len =
sizeof (vss->
vpn_id);
310 o->
data[13] = id_len + 1;
312 o->
data[15 + id_len] = 152;
313 o->
data[16 + id_len] = 0;
323 new_l0 = clib_net_to_host_u16 (old_l0);
325 new_l0 = clib_host_to_net_u16 (new_l0);
333 new_l0 = clib_net_to_host_u16 (u0->
length);
335 u0->
length = clib_host_to_net_u16 (new_l0);
341 DHCP_PROXY_ERROR_OPTION_82_ERROR, 1);
344 next0 = DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP;
381 to_next, n_left_to_next,
394 if (next0 == DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
404 to_next, n_left_to_next);
417 if (next0 == DHCP_PROXY_TO_SERVER_INPUT_NEXT_LOOKUP)
428 to_next, n_left_to_next,
435 DHCP_PROXY_ERROR_RELAY_TO_CLIENT,
438 DHCP_PROXY_ERROR_RELAY_TO_SERVER,
441 DHCP_PROXY_ERROR_NO_SERVER, pkts_no_server);
443 DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS,
444 pkts_no_interface_address);
446 DHCP_PROXY_ERROR_PKT_TOO_BIG, pkts_too_big);
453 .name =
"dhcp-proxy-to-server",
455 .vector_size =
sizeof (
u32),
462 #define _(s,n) [DHCP_PROXY_TO_SERVER_INPUT_NEXT_##s] = n, 470 .unformat_buffer = unformat_dhcp_proxy_header,
480 u32 n_left_from, *from;
489 while (n_left_from > 0)
511 u32 original_sw_if_index = (
u32) ~ 0;
541 if ((b0->
flags & VLIB_BUFFER_NEXT_PRESENT) != 0 || !rv)
543 error0 = DHCP_PROXY_ERROR_PKT_TOO_BIG;
571 sw_if_index = ((sub->
data[0] << 24) |
572 (sub->
data[1] << 16) |
573 (sub->
data[2] << 8) |
583 else if (sub->
option == 151 &&
590 if (vss_ctrl && vss_exist)
593 DHCP_PROXY_ERROR_OPTION_82_VSS_NOT_PROCESSED, 1);
600 if (sw_if_index == (
u32) ~ 0)
602 error0 = DHCP_PROXY_ERROR_NO_OPTION_82;
615 if (relay_addr.
as_u32 == 0)
617 error0 = DHCP_PROXY_ERROR_BAD_OPTION_82_ADDR;
623 error0 = DHCP_PROXY_ERROR_BAD_OPTION_82_ITF;
632 error0 = DHCP_PROXY_ERROR_NO_SERVER;
644 error0 = DHCP_PROXY_ERROR_BAD_SVR_FIB_OR_ADDRESS;
658 error0 = DHCP_PROXY_ERROR_NO_INTERFACE_ADDRESS;
664 error0 = DHCP_PROXY_ERROR_BAD_YIADDR;
669 u0->
dst_port = clib_net_to_host_u16 (UDP_DST_PORT_dhcp_to_client);
698 clib_net_to_host_u16 (0x8100) : clib_net_to_host_u16 (0x0800);
702 u32 *vlan_tag = (
u32 *) (mac0 + 1);
704 tmp = (si0->
sub.
id << 16) | 0x0800;
705 *vlan_tag = clib_host_to_net_u32 (tmp);
734 .name =
"dhcp-proxy-to-client",
736 .vector_size =
sizeof (
u32),
743 .unformat_buffer = unformat_dhcp_proxy_header,
787 ip46_address_t * src_addr,
788 u32 rx_table_id,
u32 server_table_id,
int is_del)
790 u32 rx_fib_index = 0;
795 .fp_addr.ip4.as_u32 = 0xffffffff,
800 return VNET_API_ERROR_INVALID_DST_ADDRESS;
803 return VNET_API_ERROR_INVALID_SRC_ADDRESS;
814 addr, server_table_id))
825 rx_fib_index, server_table_id))
843 ip46_address_t server_addr, src_addr;
844 u32 server_table_id = 0, rx_table_id = 0;
846 int set_src = 0, set_server = 0;
848 clib_memset (&server_addr, 0,
sizeof (server_addr));
856 else if (
unformat (input,
"server-fib-id %d", &server_table_id))
858 else if (
unformat (input,
"rx-fib-id %d", &rx_table_id))
860 else if (
unformat (input,
"src-address %U",
869 if (is_del || (set_server && set_src))
874 server_table_id, is_del);
880 case VNET_API_ERROR_INVALID_DST_ADDRESS:
883 case VNET_API_ERROR_INVALID_SRC_ADDRESS:
886 case VNET_API_ERROR_NO_SUCH_ENTRY:
888 (0,
"Fib id %d: no per-fib DHCP server configured", rx_table_id);
901 .path =
"set dhcp proxy",
902 .short_help =
"set dhcp proxy [del] server <ip-addr> src-address <ip-addr> [server-fib-id <n>] [rx-fib-id <n>]",
916 s =
format (s,
"%=14s%=16s%s",
"RX FIB",
"Src Address",
917 "Servers FIB,Address");
923 s =
format (s,
"%=14u%=16U",
962 .path =
"show dhcp proxy",
963 .short_help =
"Display dhcp proxy server info",
973 u32 oui = 0, fib_id = 0, tbl_id = ~0;
974 u8 *vpn_ascii_id = 0;
978 if (
unformat (input,
"table %d", &tbl_id))
980 else if (
unformat (input,
"oui %d", &oui))
982 else if (
unformat (input,
"vpn-id %d", &fib_id))
984 else if (
unformat (input,
"vpn-ascii-id %s", &vpn_ascii_id))
996 vpn_ascii_id, oui, fib_id, is_del);
1001 case VNET_API_ERROR_NO_SUCH_ENTRY:
1003 "option 82 vss for table %d not found in in pool.",
1013 .path =
"set dhcp option-82 vss",
1014 .short_help =
"set dhcp option-82 vss [del] table <table id> [oui <n> vpn-id <n> | vpn-ascii-id <text>]",
1030 .path =
"show dhcp vss",
1031 .short_help =
"show dhcp VSS",
1059 "source IP address");
1067 "No IPv4 address configured on",
1079 .path =
"show dhcp option-82-address interface",
1080 .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.
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)
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.
int dhcp_client_for_us(u32 bi, vlib_buffer_t *b, ip4_header_t *ip, udp_header_t *udp, dhcp_header_t *dhcp)
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
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)
#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)
Aggregrate type for a prefix.
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
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.
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.
dhcp_proxy_to_server_input_next_t
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
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)
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,...)
static void vlib_buffer_copy_trace_flag(vlib_main_t *vm, vlib_buffer_t *b, u32 bi_target)
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.
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
static u32 vlib_buffer_space_left_at_end(vlib_main_t *vm, vlib_buffer_t *b)
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 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)
#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.
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 represenation 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.
void udp_register_dst_port(vlib_main_t *vm, udp_dst_port_t dst_port, u32 node_index, u8 is_ip4)
ethernet_interface_t * interfaces
#define ip46_address_is_zero(ip46)
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
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)