summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2019-03-26 00:25:14 +0100
committerMikael Magnusson <mikma@users.sourceforge.net>2019-04-02 00:27:38 +0200
commit91b42ac1d49032d03a43e99e2ae80e9301dfdc45 (patch)
tree870bd1fcc0c66187df0d445c9a04a3be14e43b44
parent2c63759205307cfcb4a95dc7b1833be07d4feaa4 (diff)
Wireguard: Allow multiple channels
-rw-r--r--nest/protocol.h1
-rw-r--r--proto/wireguard/config.Y14
-rw-r--r--proto/wireguard/wireguard.c62
-rw-r--r--proto/wireguard/wireguard.h12
4 files changed, 66 insertions, 23 deletions
diff --git a/nest/protocol.h b/nest/protocol.h
index 1fdfb380..c9f02d2b 100644
--- a/nest/protocol.h
+++ b/nest/protocol.h
@@ -483,6 +483,7 @@ struct channel_class {
};
extern struct channel_class channel_bgp;
+extern struct channel_class channel_wg;
struct channel_config {
node n;
diff --git a/proto/wireguard/config.Y b/proto/wireguard/config.Y
index 7eee4a65..2eee7e72 100644
--- a/proto/wireguard/config.Y
+++ b/proto/wireguard/config.Y
@@ -29,11 +29,23 @@ wireguard_proto_start: proto_start WIREGUARD {
wireguard_proto:
wireguard_proto_start proto_name '{'
- | wireguard_proto proto_channel ';' { this_proto->net_type = $2->net_type; }
+ | wireguard_proto wg_proto_channel ';'
| wireguard_proto proto_item ';'
| wireguard_proto INTERFACE TEXT ';' { WG_CFG->ifname = $3; }
;
+wg_proto_channel: wg_channel_start channel_opt_list wg_channel_end;
+
+wg_channel_start: net_type
+{
+ this_channel = channel_config_get(&channel_wg, net_label[$1], $1, this_proto);
+}
+
+wg_channel_end:
+{
+ this_channel = NULL;
+}
+
CF_CODE
CF_END
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c
index c7345c46..2a020be2 100644
--- a/proto/wireguard/wireguard.c
+++ b/proto/wireguard/wireguard.c
@@ -275,16 +275,16 @@ set_peer_remote_ep(wg_peer *peer, ip_addr remote_ep_addr, u16 udp_dest_port)
}
static int
-add_allowed_ips(struct wg_proto *p, struct network *n, wg_peer *peer)
+add_allowed_ips(u8 net_type, struct network *n, wg_peer *peer)
{
// Add allowed ip
struct wg_allowedip *allowedip = malloc(sizeof(struct wg_allowedip));
memset(allowedip, 0, sizeof(struct wg_allowedip));
- if (p->p.cf->net_type == NET_IP4) {
+ if (net_type == NET_IP4) {
allowedip->family = AF_INET;
allowedip->ip4.s_addr = ip4_to_u32(ip4_hton(net4_prefix(n->n.addr)));
- } else if (p->p.cf->net_type == NET_IP6) {
+ } else if (net_type == NET_IP6) {
allowedip->family = AF_INET6;
ip6_addr addr = ip6_hton(net6_prefix(n->n.addr));
memcpy(allowedip->ip6.s6_addr, &addr, 16);
@@ -301,11 +301,12 @@ add_allowed_ips(struct wg_proto *p, struct network *n, wg_peer *peer)
}
static void
-wg_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *n,
+wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
struct rte *new, struct rte *old UNUSED)
{
struct wg_proto *p = (struct wg_proto *) P;
struct wg_config *c = (struct wg_config *) P->cf;
+ struct wg_channel *ch = (struct wg_channel *) CH;
struct wg_entry *en;
struct iface *iface = NULL;
const char *ifname = NULL;
@@ -320,7 +321,7 @@ wg_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *n,
struct eattr *t;
debug("WG: found iface\n");
- en = fib_get(&p->rtable, n->n.addr);
+ en = fib_get(&ch->rtable, n->n.addr);
debug("WG: notify new %d %N\n",
new->attrs->dest, n->n.addr);
@@ -356,7 +357,7 @@ wg_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *n,
found = true;
set_peer_remote_ep(peer, remote_ep_addr, udp_dest_port);
- add_allowed_ips(p, n, peer);
+ add_allowed_ips(ch->c.net_type, n, peer);
dirty = true;
break;
@@ -365,7 +366,7 @@ wg_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *n,
if (!found) {
wg_peer *peer = add_peer(dev, pubkey);
set_peer_remote_ep(peer, remote_ep_addr, udp_dest_port);
- add_allowed_ips(p, n, peer);
+ add_allowed_ips(ch->c.net_type, n, peer);
dirty = true;
}
@@ -435,7 +436,7 @@ wg_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *n,
n->n.addr);
/* Withdraw */
- en = fib_find(&p->rtable, n->n.addr);
+ en = fib_find(&ch->rtable, n->n.addr);
if (!en) { // || en->valid != RIP_ENTRY_VALID)
debug("WG: fib not found\n");
@@ -456,10 +457,10 @@ wg_rt_notify(struct proto *P, struct channel *ch UNUSED, struct network *n,
struct wg_allowedip *allowedip = malloc(sizeof(struct wg_allowedip));
memset(allowedip, 0, sizeof(struct wg_allowedip));
- if (p->p.cf->net_type == NET_IP4) {
+ if (ch->c.net_type == NET_IP4) {
allowedip->family = AF_INET;
allowedip->ip4.s_addr = ip4_to_u32(ip4_hton(net4_prefix(n->n.addr)));
- } else if (p->p.cf->net_type == NET_IP6) {
+ } else if (ch->c.net_type == NET_IP6) {
allowedip->family = AF_INET6;
ip6_addr addr = ip6_hton(net6_prefix(n->n.addr));
memcpy(allowedip->ip6.s6_addr, &addr, 16);
@@ -560,13 +561,16 @@ wg_init(struct proto_config *C)
debug("init\n");
- P->main_channel = proto_add_channel(P, proto_cf_main_channel(C));
-
P->if_notify = wg_if_notify;
P->rt_notify = wg_rt_notify;
P->reload_routes = wg_reload_routes;
// P->accept_ra_types = RA_ANY;
+ /* Add all channels */
+ struct wg_channel_config *cc;
+ WALK_LIST(cc, C->channels)
+ proto_add_channel(P, &cc->c);
+
return P;
}
@@ -578,8 +582,11 @@ wg_start(struct proto *P)
struct wg_proto *p = (struct wg_proto *) P;
debug("start\n");
- fib_init(&p->rtable, P->pool, P->net_type, sizeof(struct wg_entry),
- OFFSETOF(struct wg_entry, n), 0, wg_init_entry);
+ struct wg_channel *ch;
+ WALK_LIST(ch,p->p.channels) {
+ fib_init(&ch->rtable, P->pool, ch->c.net_type, sizeof(struct wg_entry),
+ OFFSETOF(struct wg_entry, n), 0, wg_init_entry);
+ }
return PS_UP;
}
@@ -590,21 +597,34 @@ wg_dump(struct proto *P)
int i;
i = 0;
- FIB_WALK(&p->rtable, struct wg_entry, en)
- {
-// struct wg_entry *en = (struct wg_entry *) e;
- debug("WG: entry #%d:\n",
- i++);
+
+ struct wg_channel *ch;
+ WALK_LIST(ch,p->p.channels) {
+ FIB_WALK(&ch->rtable, struct wg_entry, en)
+ {
+ // struct wg_entry *en = (struct wg_entry *) e;
+ debug("WG: entry #%d:\n",
+ i++);
+ }
+ FIB_WALK_END;
}
- FIB_WALK_END;
}
+struct channel_class channel_wg = {
+ .channel_size = sizeof(struct wg_channel),
+ .config_size = sizeof(struct wg_channel_config),
+ /* .init = wg_channel_init, */
+ /* .start = wg_channel_start, */
+ /* .shutdown = wg_channel_shutdown, */
+ /* .cleanup = wg_channel_cleanup, */
+ /* .reconfigure = wg_channel_reconfigure, */
+};
struct protocol proto_wireguard = {
.name = "Wireguard",
.template = "wg%d",
.class = PROTOCOL_WG,
- .channel_mask = NB_ANY,
+ .channel_mask = NB_IP,
.proto_size = sizeof(struct wg_proto),
.config_size = sizeof(struct wg_config),
.postconfig = wg_postconfig,
diff --git a/proto/wireguard/wireguard.h b/proto/wireguard/wireguard.h
index 992bb12b..3217df32 100644
--- a/proto/wireguard/wireguard.h
+++ b/proto/wireguard/wireguard.h
@@ -10,13 +10,23 @@ struct wg_config {
struct wg_proto {
struct proto p;
- struct fib rtable;
struct iface *iface;
};
+struct wg_channel_config {
+ struct channel_config c;
+};
+
+struct wg_channel {
+ struct channel c;
+
+ struct fib rtable;
+};
+
struct wg_entry {
struct fib_node n;
};
+extern struct channel_class channel_wg;
#endif /* _BIRD_WIREGUARD_H */