wireguard: move adjacency processing from wireguard_peer to wireguard_interface

now we should add routes manually

Type: improvement
Change-Id: I877511a18854efdfad02939267d38a216b2ccec3
Signed-off-by: Artem Glazychev <artem.glazychev@xored.com>
This commit is contained in:
Artem Glazychev
2021-05-20 12:33:52 +07:00
committed by Ed Warnicke
parent da33105973
commit de3caf37c6
8 changed files with 158 additions and 246 deletions
+6 -1
View File
@@ -28,10 +28,15 @@ OpenSSL:
### Add a peer configuration:
```
> vpp# wireguard peer add <wg_interface> public-key <pub_key_other> endpoint <ip4_dst> allowed-ip <prefix> dst-port <port_dst> persistent-keepalive [keepalive_interval]
> vpp# wireguard peer add <wg_interface> public-key <pub_key_other> endpoint <ip4_dst> allowed-ip <prefix> port <port_dst> persistent-keepalive [keepalive_interval]
> vpp# *peer_idx*
```
### Add routes for allowed-ip:
```
> ip route add <prefix> via <wg_ip4> <wg_interface>
```
### Show config
```
> vpp# show wireguard interface
+1 -2
View File
@@ -249,8 +249,7 @@ send_wg_peers_details (index_t peeri, void *data)
int ii;
for (ii = 0; ii < n_allowed_ips; ii++)
ip_prefix_encode (&peer->allowed_ips[ii].prefix,
&rmp->peer.allowed_ips[ii]);
ip_prefix_encode (&peer->allowed_ips[ii], &rmp->peer.allowed_ips[ii]);
rmp->context = ctx->context;
+6 -72
View File
@@ -151,7 +151,10 @@ wg_if_admin_up_down (vnet_main_t * vnm, u32 hw_if_index, u32 flags)
void
wg_if_update_adj (vnet_main_t * vnm, u32 sw_if_index, adj_index_t ai)
{
/* The peers manage the adjacencies */
index_t wgii;
wgii = wg_if_find_by_sw_if_index (sw_if_index);
wg_if_peer_walk (wg_if_get (wgii), wg_peer_if_adj_change, &ai);
}
@@ -387,9 +390,8 @@ wg_if_peer_walk (wg_if_t * wgi, wg_if_peer_walk_cb_t fn, void *data)
index_t peeri, val;
/* *INDENT-OFF* */
hash_foreach (peeri, val, wgi->peers,
{
if (WALK_STOP == fn(wgi, peeri, data))
hash_foreach (peeri, val, wgi->peers, {
if (WALK_STOP == fn (peeri, data))
return peeri;
});
/* *INDENT-ON* */
@@ -397,74 +399,6 @@ wg_if_peer_walk (wg_if_t * wgi, wg_if_peer_walk_cb_t fn, void *data)
return INDEX_INVALID;
}
static void
wg_if_table_bind_v4 (ip4_main_t * im,
uword opaque,
u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
{
wg_if_t *wg_if;
wg_if = wg_if_get (wg_if_find_by_sw_if_index (sw_if_index));
if (NULL == wg_if)
return;
wg_peer_table_bind_ctx_t ctx = {
.af = AF_IP4,
.old_fib_index = old_fib_index,
.new_fib_index = new_fib_index,
};
wg_if_peer_walk (wg_if, wg_peer_if_table_change, &ctx);
}
static void
wg_if_table_bind_v6 (ip6_main_t * im,
uword opaque,
u32 sw_if_index, u32 new_fib_index, u32 old_fib_index)
{
wg_if_t *wg_if;
wg_if = wg_if_get (wg_if_find_by_sw_if_index (sw_if_index));
if (NULL == wg_if)
return;
wg_peer_table_bind_ctx_t ctx = {
.af = AF_IP6,
.old_fib_index = old_fib_index,
.new_fib_index = new_fib_index,
};
wg_if_peer_walk (wg_if, wg_peer_if_table_change, &ctx);
}
static clib_error_t *
wg_if_module_init (vlib_main_t * vm)
{
{
ip4_table_bind_callback_t cb = {
.function = wg_if_table_bind_v4,
};
vec_add1 (ip4_main.table_bind_callbacks, cb);
}
{
ip6_table_bind_callback_t cb = {
.function = wg_if_table_bind_v6,
};
vec_add1 (ip6_main.table_bind_callbacks, cb);
}
return (NULL);
}
/* *INDENT-OFF* */
VLIB_INIT_FUNCTION (wg_if_module_init) =
{
.runs_after = VLIB_INITS("ip_main_init"),
};
/* *INDENT-ON* */
/*
* fd.io coding-style-patch-verification: ON
*
+1 -2
View File
@@ -52,8 +52,7 @@ u8 *format_wg_if (u8 * s, va_list * va);
typedef walk_rc_t (*wg_if_walk_cb_t) (index_t wgi, void *data);
void wg_if_walk (wg_if_walk_cb_t fn, void *data);
typedef walk_rc_t (*wg_if_peer_walk_cb_t) (wg_if_t * wgi, index_t peeri,
void *data);
typedef walk_rc_t (*wg_if_peer_walk_cb_t) (index_t peeri, void *data);
index_t wg_if_peer_walk (wg_if_t * wgi, wg_if_peer_walk_cb_t fn, void *data);
void wg_if_peer_add (wg_if_t * wgi, index_t peeri);
+2 -21
View File
@@ -254,24 +254,6 @@ wg_handshake_process (vlib_main_t * vm, wg_main_t * wmp, vlib_buffer_t * b)
return WG_INPUT_ERROR_NONE;
}
static_always_inline bool
fib_prefix_is_cover_addr_4 (const fib_prefix_t * p1,
const ip4_address_t * ip4)
{
switch (p1->fp_proto)
{
case FIB_PROTOCOL_IP4:
return (ip4_destination_matches_route (&ip4_main,
&p1->fp_addr.ip4,
ip4, p1->fp_len) != 0);
case FIB_PROTOCOL_IP6:
return (false);
case FIB_PROTOCOL_MPLS:
break;
}
return (false);
}
VLIB_NODE_FN (wg_input_node) (vlib_main_t * vm,
vlib_node_runtime_t * node,
vlib_frame_t * frame)
@@ -386,7 +368,7 @@ VLIB_NODE_FN (wg_input_node) (vlib_main_t * vm,
ip4_header_t *iph = vlib_buffer_get_current (b[0]);
const wg_peer_allowed_ip_t *allowed_ip;
const fib_prefix_t *allowed_ip;
bool allowed = false;
/*
@@ -396,8 +378,7 @@ VLIB_NODE_FN (wg_input_node) (vlib_main_t * vm,
*/
vec_foreach (allowed_ip, peer->allowed_ips)
{
if (fib_prefix_is_cover_addr_4 (&allowed_ip->prefix,
&iph->src_address))
if (fib_prefix_is_cover_addr_4 (allowed_ip, &iph->src_address))
{
allowed = true;
break;
File diff suppressed because it is too large Load Diff
+21 -11
View File
@@ -33,12 +33,6 @@ typedef struct ip4_udp_header_t_
u8 *format_ip4_udp_header (u8 * s, va_list * va);
typedef struct wg_peer_allowed_ip_t_
{
fib_prefix_t prefix;
fib_node_index_t fib_entry_index;
} wg_peer_allowed_ip_t;
typedef struct wg_peer_endpoint_t_
{
ip46_address_t addr;
@@ -57,13 +51,13 @@ typedef struct wg_peer
wg_peer_endpoint_t dst;
wg_peer_endpoint_t src;
u32 table_id;
adj_index_t adj_index;
adj_index_t *adj_indices;
/* rewrite built from address information */
u8 *rewrite;
/* Vector of allowed-ips */
wg_peer_allowed_ip_t *allowed_ips;
fib_prefix_t *allowed_ips;
/* The WG interface this peer is attached to */
u32 wg_sw_if_index;
@@ -111,9 +105,9 @@ index_t wg_peer_walk (wg_peer_walk_cb_t fn, void *data);
u8 *format_wg_peer (u8 * s, va_list * va);
walk_rc_t wg_peer_if_admin_state_change (wg_if_t * wgi, index_t peeri,
void *data);
walk_rc_t wg_peer_if_table_change (wg_if_t * wgi, index_t peeri, void *data);
walk_rc_t wg_peer_if_admin_state_change (index_t peeri, void *data);
walk_rc_t wg_peer_if_adj_change (index_t peeri, void *data);
adj_walk_rc_t wg_peer_adj_walk (adj_index_t ai, void *data);
/*
* Expoed for the data-plane
@@ -145,6 +139,22 @@ wg_peer_assign_thread (u32 thread_id)
1) : thread_id));
}
static_always_inline bool
fib_prefix_is_cover_addr_4 (const fib_prefix_t *p1, const ip4_address_t *ip4)
{
switch (p1->fp_proto)
{
case FIB_PROTOCOL_IP4:
return (ip4_destination_matches_route (&ip4_main, &p1->fp_addr.ip4, ip4,
p1->fp_len) != 0);
case FIB_PROTOCOL_IP6:
return (false);
case FIB_PROTOCOL_MPLS:
break;
}
return (false);
}
#endif // __included_wg_peer_h__
/*
+36 -14
View File
@@ -22,6 +22,7 @@ from noise.connection import NoiseConnection, Keypair
from vpp_ipip_tun_interface import VppIpIpTunInterface
from vpp_interface import VppInterface
from vpp_ip_route import VppIpRoute, VppRoutePath
from vpp_object import VppObject
from framework import VppTestCase
from re import compile
@@ -133,14 +134,6 @@ class VppWgPeer(VppObject):
self.noise = NoiseConnection.from_name(NOISE_HANDSHAKE_NAME)
def validate_routing(self):
for a in self.allowed_ips:
self._test.assertTrue(find_route(self._test, a))
def validate_no_routing(self):
for a in self.allowed_ips:
self._test.assertFalse(find_route(self._test, a))
def add_vpp_config(self):
rv = self._test.vapi.wireguard_peer_add(
peer={
@@ -154,12 +147,10 @@ class VppWgPeer(VppObject):
self.index = rv.peer_index
self.receiver_index = self.index + 1
self._test.registry.register(self, self._test.logger)
self.validate_routing()
return self
def remove_vpp_config(self):
self._test.vapi.wireguard_peer_remove(peer_index=self.index)
self.validate_no_routing()
def object_id(self):
return ("wireguard-peer-%s" % self.index)
@@ -437,10 +428,13 @@ class TestWg(VppTestCase):
wg0,
self.pg1.remote_ip4,
port+1,
["10.11.2.0/24",
"10.11.3.0/24"]).add_vpp_config()
["10.11.3.0/24"]).add_vpp_config()
self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)
r1 = VppIpRoute(self, "10.11.3.0", 24,
[VppRoutePath("10.11.3.1",
wg0.sw_if_index)]).add_vpp_config()
# wait for the peer to send a handshake
rx = self.pg1.get_capture(1, timeout=2)
@@ -483,6 +477,10 @@ class TestWg(VppTestCase):
self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
self.assertEqual(rx[IP].ttl, 19)
r1.remove_vpp_config()
peer_1.remove_vpp_config()
wg0.remove_vpp_config()
def test_wg_peer_init(self):
""" Send handshake init """
wg_output_node_name = '/err/wg-output-tun/'
@@ -501,10 +499,13 @@ class TestWg(VppTestCase):
wg0,
self.pg1.remote_ip4,
port+1,
["10.11.2.0/24",
"10.11.3.0/24"]).add_vpp_config()
["10.11.3.0/24"]).add_vpp_config()
self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)
r1 = VppIpRoute(self, "10.11.3.0", 24,
[VppRoutePath("10.11.3.1",
wg0.sw_if_index)]).add_vpp_config()
# route a packet into the wg interface
# use the allowed-ip prefix
# this is dropped because the peer is not initiated
@@ -597,6 +598,7 @@ class TestWg(VppTestCase):
self.assertEqual(rx[IP].dst, self.pg0.remote_ip4)
self.assertEqual(rx[IP].ttl, 19)
r1.remove_vpp_config()
peer_1.remove_vpp_config()
wg0.remove_vpp_config()
@@ -629,17 +631,26 @@ class TestWg(VppTestCase):
peers_1 = []
peers_2 = []
routes_1 = []
routes_2 = []
for i in range(NUM_PEERS):
peers_1.append(VppWgPeer(self,
wg0,
self.pg1.remote_hosts[i].ip4,
port+1+i,
["10.0.%d.4/32" % i]).add_vpp_config())
routes_1.append(VppIpRoute(self, "10.0.%d.4" % i, 32,
[VppRoutePath(self.pg1.remote_hosts[i].ip4,
wg0.sw_if_index)]).add_vpp_config())
peers_2.append(VppWgPeer(self,
wg1,
self.pg2.remote_hosts[i].ip4,
port+100+i,
["10.100.%d.4/32" % i]).add_vpp_config())
routes_2.append(VppIpRoute(self, "10.100.%d.4" % i, 32,
[VppRoutePath(self.pg2.remote_hosts[i].ip4,
wg1.sw_if_index)]).add_vpp_config())
self.assertEqual(len(self.vapi.wireguard_peers_dump()), NUM_PEERS*2)
@@ -649,6 +660,12 @@ class TestWg(VppTestCase):
self.logger.info(self.vapi.cli("sh ip fib 172.16.3.17"))
self.logger.info(self.vapi.cli("sh ip fib 10.11.3.0"))
# remove routes
for r in routes_1:
r.remove_vpp_config()
for r in routes_2:
r.remove_vpp_config()
# remove peers
for p in peers_1:
self.assertTrue(p.query_vpp_config())
@@ -687,6 +704,10 @@ class WireguardHandoffTests(TestWg):
"10.11.3.0/24"]).add_vpp_config()
self.assertEqual(len(self.vapi.wireguard_peers_dump()), 1)
r1 = VppIpRoute(self, "10.11.3.0", 24,
[VppRoutePath("10.11.3.1",
wg0.sw_if_index)]).add_vpp_config()
# send a valid handsake init for which we expect a response
p = peer_1.mk_handshake(self.pg1)
@@ -744,5 +765,6 @@ class WireguardHandoffTests(TestWg):
peer_1.validate_encapped(rxs, pe)
r1.remove_vpp_config()
peer_1.remove_vpp_config()
wg0.remove_vpp_config()