diff options
author | Mikael Magnusson <mikma@users.sourceforge.net> | 2019-03-26 00:25:14 +0100 |
---|---|---|
committer | Mikael Magnusson <mikma@users.sourceforge.net> | 2020-05-08 18:52:55 +0200 |
commit | 0d19c1ba2e0bd23680c0c7fb3b734d9afe2df3b8 (patch) | |
tree | 632c566c37ed1a4d03fa9da5384ba9abdfde2111 | |
parent | f72a2873b0616cf232ec312da2629058bc3710ca (diff) |
Wireguard: Allow multiple channels
-rw-r--r-- | nest/protocol.h | 1 | ||||
-rw-r--r-- | proto/wireguard/config.Y | 14 | ||||
-rw-r--r-- | proto/wireguard/wireguard.c | 62 | ||||
-rw-r--r-- | proto/wireguard/wireguard.h | 12 |
4 files changed, 66 insertions, 23 deletions
diff --git a/nest/protocol.h b/nest/protocol.h index b46d37fe..0fca20af 100644 --- a/nest/protocol.h +++ b/nest/protocol.h @@ -477,6 +477,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 */ |