summaryrefslogtreecommitdiff
path: root/proto/wireguard
diff options
context:
space:
mode:
Diffstat (limited to 'proto/wireguard')
-rw-r--r--proto/wireguard/wireguard.c52
1 files changed, 51 insertions, 1 deletions
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c
index 1837dc9c..4e7abe88 100644
--- a/proto/wireguard/wireguard.c
+++ b/proto/wireguard/wireguard.c
@@ -1,5 +1,7 @@
// Based on proto/rip/rip.c
+#define LOCAL_DEBUG
+
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -9,6 +11,7 @@
#include "lib/lists.h"
#include "lib/ip.h"
#include "lib/tunnel_encaps.h"
+#include "nest/bfd.h"
#include "nest/protocol.h"
#include "nest/iface.h"
#include "sysdep/linux/wireguard.h"
@@ -16,6 +19,8 @@
#include "sysdep/unix/wg_user.h"
#include "wireguard.h"
+#define BA_NEXT_HOP 0x03
+
static ip_addr allowedip_to_ipa(struct wg_allowedip *allowedip);
static
@@ -380,6 +385,18 @@ remove_allowed_ip(wg_peer *peer, struct wg_allowedip *allowedip)
}
static void
+wg_bfd_notify(struct bfd_request *req UNUSED)
+{
+ log(L_WARN "wg_bfd_notify");
+}
+
+static bool
+ipa_subprefix(ip_addr addr, ip_addr net, ip_addr mask)
+{
+ return ipa_equal(ipa_and(addr, mask), net);
+}
+
+static void
wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
struct rte *new, struct rte *old UNUSED)
{
@@ -399,7 +416,7 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
if (iface && iface == p->iface) {
struct eattr *t;
- DBG("WG: found %p iface %I %p\n", new->attrs, nh->gw, nh->next);
+ DBG("WG: found %p iface %s %I %p\n", new->attrs, ifname, nh->gw, nh->next);
struct hostentry *he = new->attrs->hostentry;
@@ -426,6 +443,7 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
t = ea_find(he->src->eattrs, EA_CODE(PROTOCOL_BGP, BA_TUNNEL_ENCAP));
}
if (t && t->u.ptr && decode_tunnel_encap(t, &encap, P->pool) == 0 && encap.type == c->tunnel_type && encap.encap_len == sizeof(wg_key)) {
+ ip_addr *nh_ip = NULL;
const wg_key *pubkey = encap.encap;
bool add_ip = true;
struct wg_entry *en = fib_find(&ch->rtable, n->n.addr);
@@ -442,6 +460,31 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
WG_TRACE(D_EVENTS, "WG: Attr %x %x %d %04x", t->flags, t->type, t->u.ptr->length, encap.flags);
+ {
+ struct eattr *ea =
+ ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_NEXT_HOP));
+
+ nh_ip = (void *) ea->u.ptr->data;
+
+ struct neighbor *ne = neigh_find(P, *nh_ip, iface, NEF_STICKY);
+ if (!ne || (!ne->ifa)) {
+ log(L_WARN "Invalid next hop %I of wireguard", *nh_ip);
+ } else {
+ struct bfd_request *req;
+ void *data = NULL;
+ log(L_WARN "Add bfd request session %I %I", *nh_ip, ne->ifa->ip);
+ req = bfd_request_session(P->pool, *nh_ip, ne->ifa->ip,
+ NULL, //iface,
+ P->vrf,
+ wg_bfd_notify, data);
+ if (!req) {
+ log(L_WARN "bfd_request_session failed");
+ }
+ }
+ /* } else { */
+ /* log(L_WARN "Invalid hostentry"); */
+ }
+
struct wg_device *dev = p->dev;
if (dev != NULL) {
@@ -474,6 +517,13 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
struct wg_allowedip *allowed_n =
create_allowed_ip_network(ch->c.net_type, n);
add_allowed_ip(allowed_n, peer);
+#if 0
+ if (nh_ip) {
+ struct wg_allowedip *allowed_ip =
+ create_allowed_ip_addr(*nh_ip);
+ add_allowed_ip(allowed_ip, peer);
+ }
+#endif
}
dirty = true;