diff options
author | Artem Glazychev <artem.glazychev@xored.com> | 2021-05-25 12:06:42 +0700 |
---|---|---|
committer | Ed Warnicke <hagbard@gmail.com> | 2021-10-04 16:21:34 +0000 |
commit | 9e24f7eb911fc5ab7558109286fe8e1d2774ea93 (patch) | |
tree | f7aa375e88ee3d2325fb430bc4012b1ff012d734 /src/plugins/wireguard/wireguard_if.c | |
parent | 039f289e516b073f6db67f7b35aa3aa64fdc9c82 (diff) |
wireguard: use the same udp-port for multi-tunnel
now we can reuse udp-port for many wireguard interfaces
Type: improvement
Change-Id: I14b5a9dbe917d83300ccb4d6907743d88355e5c5
Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
Diffstat (limited to 'src/plugins/wireguard/wireguard_if.c')
-rw-r--r-- | src/plugins/wireguard/wireguard_if.c | 37 |
1 files changed, 23 insertions, 14 deletions
diff --git a/src/plugins/wireguard/wireguard_if.c b/src/plugins/wireguard/wireguard_if.c index b1c5cb20638..0866d24e775 100644 --- a/src/plugins/wireguard/wireguard_if.c +++ b/src/plugins/wireguard/wireguard_if.c @@ -32,7 +32,7 @@ static uword *wg_if_instances; static index_t *wg_if_index_by_sw_if_index; /* vector of interfaces key'd on their UDP port (in network order) */ -index_t *wg_if_index_by_port; +index_t **wg_if_indexes_by_port; static u8 * format_wg_if_name (u8 * s, va_list * args) @@ -254,13 +254,6 @@ wg_if_create (u32 user_instance, *sw_if_indexp = (u32) ~ 0; /* - * Check if the required port is already in use - */ - udp_dst_port_info_t *pi = udp_get_dst_port_info (&udp_main, port, UDP_IP4); - if (pi) - return VNET_API_ERROR_UDP_PORT_TAKEN; - - /* * Allocate a wg_if instance. Either select on dynamically * or try to use the desired user_instance number. */ @@ -295,10 +288,11 @@ wg_if_create (u32 user_instance, if (~0 == wg_if->user_instance) wg_if->user_instance = t_idx; - udp_register_dst_port (vlib_get_main (), port, wg_input_node.index, 1); + vec_validate_init_empty (wg_if_indexes_by_port, port, NULL); + if (vec_len (wg_if_indexes_by_port[port]) == 0) + udp_register_dst_port (vlib_get_main (), port, wg_input_node.index, 1); - vec_validate_init_empty (wg_if_index_by_port, port, INDEX_INVALID); - wg_if_index_by_port[port] = wg_if - wg_if_pool; + vec_add1 (wg_if_indexes_by_port[port], t_idx); wg_if->port = port; wg_if->local_idx = local - noise_local_pool; @@ -334,15 +328,30 @@ wg_if_delete (u32 sw_if_index) return VNET_API_ERROR_INVALID_VALUE; wg_if_t *wg_if; - wg_if = wg_if_get (wg_if_find_by_sw_if_index (sw_if_index)); + index_t wgii = wg_if_find_by_sw_if_index (sw_if_index); + wg_if = wg_if_get (wgii); if (NULL == wg_if) return VNET_API_ERROR_INVALID_SW_IF_INDEX_2; if (wg_if_instance_free (wg_if->user_instance) < 0) return VNET_API_ERROR_INVALID_VALUE_2; - udp_unregister_dst_port (vlib_get_main (), wg_if->port, 1); - wg_if_index_by_port[wg_if->port] = INDEX_INVALID; + // Remove peers before interface deletion + wg_if_peer_walk (wg_if, wg_peer_if_delete, NULL); + + index_t *ii; + index_t *ifs = wg_if_indexes_get_by_port (wg_if->port); + vec_foreach (ii, ifs) + { + if (*ii == wgii) + { + vec_del1 (ifs, ifs - ii); + break; + } + } + if (vec_len (ifs) == 0) + udp_unregister_dst_port (vlib_get_main (), wg_if->port, 1); + vnet_delete_hw_interface (vnm, hw->hw_if_index); pool_put_index (noise_local_pool, wg_if->local_idx); pool_put (wg_if_pool, wg_if); |