diff options
Diffstat (limited to 'proto')
-rw-r--r-- | proto/wireguard/wireguard.c | 52 |
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; |