diff options
author | Matthew Smith <mgsmith@netgate.com> | 2019-03-27 12:30:29 -0500 |
---|---|---|
committer | Neale Ranns <nranns@cisco.com> | 2019-03-29 08:19:25 +0000 |
commit | d4bdd93f07b0acc15f84ec602532bc3dbab3c2bb (patch) | |
tree | b0f1f7a996f9f9ea07ebc124c708f434f2ea9975 /src | |
parent | f20fd1ac904a68ee8e9099db1287b843fd00ee79 (diff) |
dhcp: only register UDP ports that are needed
When configuring a DHCP client, both the UDP ports for DHCP client
and server are registered. Packets to the server port end up being
dropped unless you have also configured a DHCP proxy.
This breaks a common home/office gateway use case where the WAN
interface gets configured using a DHCP client and devices attached
to a LAN interface attempt to configure themselves using DHCP. If
you try to punt to an external DHCP daemon to handle the LAN client
requests, the packets never make it to the external daemon because
of the server port being registered.
Modify dhcp_maybe_register_udp_ports() to accept a parameter that
controls which ports get registered. For a DHCP client, only the
client port is registered. For a DHCP proxy, both client and server
ports are registered.
Change-Id: I2182d9827e4c7424b03ebb94952c3d2dc37abdb6
Signed-off-by: Matthew Smith <mgsmith@netgate.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/vnet/dhcp/client.c | 2 | ||||
-rw-r--r-- | src/vnet/dhcp/dhcp4_proxy_node.c | 19 | ||||
-rw-r--r-- | src/vnet/dhcp/dhcp_proxy.h | 12 |
3 files changed, 21 insertions, 12 deletions
diff --git a/src/vnet/dhcp/client.c b/src/vnet/dhcp/client.c index 1c52b0cbdbb..aac3ad3eab6 100644 --- a/src/vnet/dhcp/client.c +++ b/src/vnet/dhcp/client.c @@ -907,7 +907,7 @@ dhcp_client_add_del (dhcp_client_add_del_args_t * a) if (a->is_add) { - dhcp_maybe_register_udp_ports (); + dhcp_maybe_register_udp_ports (DHCP_PORT_REG_CLIENT); pool_get (dcm->clients, c); clib_memset (c, 0, sizeof (*c)); c->state = DHCP_DISCOVER; diff --git a/src/vnet/dhcp/dhcp4_proxy_node.c b/src/vnet/dhcp/dhcp4_proxy_node.c index d0def3f740d..8a517080eae 100644 --- a/src/vnet/dhcp/dhcp4_proxy_node.c +++ b/src/vnet/dhcp/dhcp4_proxy_node.c @@ -746,21 +746,24 @@ VLIB_REGISTER_NODE (dhcp_proxy_to_client_node, static) = { /* *INDENT-ON* */ void -dhcp_maybe_register_udp_ports (void) +dhcp_maybe_register_udp_ports (dhcp_port_reg_flags_t ports) { dhcp_proxy_main_t *dm = &dhcp_proxy_main; vlib_main_t *vm = dm->vlib_main; + int port_regs_diff = dm->udp_ports_registered ^ ports; - if (dm->udp_ports_registered) + if (!port_regs_diff) return; - udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_client, - dhcp_proxy_to_client_node.index, 1 /* is_ip4 */ ); + if ((port_regs_diff & DHCP_PORT_REG_CLIENT) & ports) + udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_client, + dhcp_proxy_to_client_node.index, 1 /* is_ip4 */ ); - udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_server, - dhcp_proxy_to_server_node.index, 1 /* is_ip4 */ ); + if ((port_regs_diff & DHCP_PORT_REG_SERVER) & ports) + udp_register_dst_port (vm, UDP_DST_PORT_dhcp_to_server, + dhcp_proxy_to_server_node.index, 1 /* is_ip4 */ ); - dm->udp_ports_registered = 1; + dm->udp_ports_registered |= ports; } static clib_error_t * @@ -799,7 +802,7 @@ dhcp4_proxy_set_server (ip46_address_t * addr, if (ip46_address_is_zero (src_addr)) return VNET_API_ERROR_INVALID_SRC_ADDRESS; - dhcp_maybe_register_udp_ports (); + dhcp_maybe_register_udp_ports (DHCP_PORT_REG_CLIENT | DHCP_PORT_REG_SERVER); rx_fib_index = fib_table_find_or_create_and_lock (FIB_PROTOCOL_IP4, rx_table_id, diff --git a/src/vnet/dhcp/dhcp_proxy.h b/src/vnet/dhcp/dhcp_proxy.h index f8fc2902684..261dd6e1ea0 100644 --- a/src/vnet/dhcp/dhcp_proxy.h +++ b/src/vnet/dhcp/dhcp_proxy.h @@ -44,6 +44,12 @@ typedef enum DHCPV6_PROXY_N_ERROR, } dhcpv6_proxy_error_t; +/* flags to indicate which DHCP ports should be or have been registered */ +typedef enum +{ + DHCP_PORT_REG_CLIENT = 0x1, + DHCP_PORT_REG_SERVER = 0x2, +} dhcp_port_reg_flags_t; /** * @brief The Virtual Sub-net Selection information for a given RX FIB @@ -147,7 +153,7 @@ typedef struct /* hash lookup specific vrf_id -> option 82 vss suboption */ u32 *vss_index_by_rx_fib_index[DHCP_N_PROTOS]; - /* udp ports have been registered */ + /* flags to indicate which udp ports have been registered */ int udp_ports_registered; /* convenience */ @@ -158,9 +164,9 @@ typedef struct extern dhcp_proxy_main_t dhcp_proxy_main; /** - * @brief Register the dhcp client and server ports, if not already done + * @brief Register the dhcp client and/or server ports, if not already done */ -void dhcp_maybe_register_udp_ports (void); +void dhcp_maybe_register_udp_ports (dhcp_port_reg_flags_t ports); /** * @brief Send the details of a proxy session to the API client during a dump |