summaryrefslogtreecommitdiff
path: root/proto
diff options
context:
space:
mode:
Diffstat (limited to 'proto')
-rw-r--r--proto/wireguard/config.Y17
-rw-r--r--proto/wireguard/wireguard.c93
-rw-r--r--proto/wireguard/wireguard.h24
3 files changed, 76 insertions, 58 deletions
diff --git a/proto/wireguard/config.Y b/proto/wireguard/config.Y
index ff57c9bc..dceebb67 100644
--- a/proto/wireguard/config.Y
+++ b/proto/wireguard/config.Y
@@ -14,6 +14,8 @@ CF_DEFINES
#define WG_CFG ((struct wg_config *) this_proto)
+static struct peer_config *this_peer = NULL;
+
CF_DECLS
CF_KEYWORDS(WIREGUARD, PRIVATE_KEY, LISTEN_PORT, PUBLIC_KEY, ENDPOINT, ALLOWED_IP)
@@ -24,6 +26,7 @@ proto: wireguard_proto '}' ;
wireguard_proto_start: proto_start WIREGUARD {
this_proto = proto_config_new(&proto_wireguard, $1);
+ init_list(&WG_CFG->peers);
}
;
@@ -39,9 +42,11 @@ wireguard_proto:
wg_peer: wg_peer_start wg_peer_opt_list wg_peer_end;
-wg_peer_start: PEER
+wg_peer_start: PEER { this_peer = peer_new(WG_CFG); }
-wg_peer_end:
+wg_peer_end: {
+ this_peer = NULL;
+}
;
wg_peer_item:
@@ -65,14 +70,14 @@ private_key: text { WG_CFG->private_key = $1; }
listen_port: expr { WG_CFG->listen_port = $1; }
-public_key: text { WG_CFG->peer.public_key = $1; }
+public_key: text { this_peer->public_key = $1; }
-endpoint: ipa { WG_CFG->peer.endpoint = $1; }
+endpoint: ipa { this_peer->endpoint = $1; }
-port: expr { WG_CFG->peer.remote_port = $1; }
+port: expr { this_peer->remote_port = $1; }
allowedip:
- net_or_ipa { WG_CFG->peer.allowedip = $1; }
+ net_or_ipa { this_peer->allowedip = $1; }
;
wg_proto_channel: wg_channel_start channel_opt_list wg_channel_end;
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c
index 4b065751..56507e2b 100644
--- a/proto/wireguard/wireguard.c
+++ b/proto/wireguard/wireguard.c
@@ -25,39 +25,49 @@ int get_device(struct wg_proto *p, wg_device **pdev, const char *device_name)
dev->listen_port = c->listen_port;
debug("listen port %d\n", c->listen_port);
- wg_peer *peer = calloc(1, sizeof(wg_peer));
- dev->first_peer = peer;
- dev->last_peer = peer;
-
- peer->flags = WGPEER_HAS_PUBLIC_KEY;
- memcpy(peer->public_key, p->peer.public_key, sizeof(peer->public_key));
- peer->next_peer = NULL;
-
- sockaddr_fill((sockaddr*)&peer->endpoint.addr,
- ipa_is_ip4(c->peer.endpoint) ? AF_INET : AF_INET6,
- c->peer.endpoint, NULL, c->peer.remote_port);
-
- wg_allowedip *allowedip = calloc(1, sizeof(wg_allowedip));
- peer->first_allowedip = allowedip;
- peer->last_allowedip = allowedip;
-
- switch (c->peer.allowedip.type)
+ struct peer_config *pc = NULL;
+ WALK_LIST(pc,c->peers)
{
- case NET_IP4:
- allowedip->family = AF_INET;
- allowedip->ip4 = ipa_to_in4(net_prefix(&c->peer.allowedip));
- allowedip->cidr = net_pxlen(&c->peer.allowedip);
- break;
- case NET_IP6:
- allowedip->family = AF_INET6;
- allowedip->ip6 = ipa_to_in6(net_prefix(&c->peer.allowedip));
- allowedip->cidr = net_pxlen(&c->peer.allowedip);
- break;
- default:
- break;
- }
+ wg_peer *peer = calloc(1, sizeof(wg_peer));
+ if (!dev->first_peer)
+ dev->first_peer = peer;
+ if (dev->last_peer)
+ dev->last_peer->next_peer = peer;
+ dev->last_peer = peer;
+
+ if (pc->public_key)
+ {
+ peer->flags = WGPEER_HAS_PUBLIC_KEY;
+ wg_key_from_base64(peer->public_key, pc->public_key);
+ }
+ peer->next_peer = NULL;
+
+ sockaddr_fill((sockaddr*)&peer->endpoint.addr,
+ ipa_is_ip4(pc->endpoint) ? AF_INET : AF_INET6,
+ pc->endpoint, NULL, pc->remote_port);
+
+ wg_allowedip *allowedip = calloc(1, sizeof(wg_allowedip));
+ peer->first_allowedip = allowedip;
+ peer->last_allowedip = allowedip;
+
+ switch (pc->allowedip.type)
+ {
+ case NET_IP4:
+ allowedip->family = AF_INET;
+ allowedip->ip4 = ipa_to_in4(net_prefix(&pc->allowedip));
+ allowedip->cidr = net_pxlen(&pc->allowedip);
+ break;
+ case NET_IP6:
+ allowedip->family = AF_INET6;
+ allowedip->ip6 = ipa_to_in6(net_prefix(&pc->allowedip));
+ allowedip->cidr = net_pxlen(&pc->allowedip);
+ break;
+ default:
+ break;
+ }
- allowedip->next_allowedip = NULL;
+ allowedip->next_allowedip = NULL;
+ }
*pdev = dev;
return 0;
@@ -393,9 +403,9 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
if (t && t->u.ptr && decode_tunnel_encap(t, &pubkey, &remote_ep_as4, &remote_ep_addr, &color, &udp_dest_port, &flags) == 0) {
log(L_TRACE "WG: Attr %x %x %d %04x", t->flags, t->type, t->u.ptr->length, flags);
- struct wg_device *dev = NULL;
+ struct wg_device *dev = p->dev;
- if (get_device(p, &dev, ifname) == 0) {
+ if (dev != NULL) {
bool dirty = false;
bool found = false;
struct wg_peer *peer = NULL;
@@ -429,8 +439,6 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
int res = wg_set_device(dev);
log(L_TRACE "WG: wg_set_device %d", res);
}
- wg_free_device(dev);
- dev = NULL;
}
@@ -498,9 +506,9 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
return;
}
- struct wg_device *dev = NULL;
+ struct wg_device *dev = p->dev;
- if (get_device(p, &dev, c->ifname) == 0) {
+ if (dev != NULL) {
bool found = false;
struct wg_peer *peer = NULL;
wg_for_each_peer(dev, peer) {
@@ -575,9 +583,6 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
}
}
- wg_free_device(dev);
- dev = NULL;
-
/*
old_metric = en->metric;
@@ -679,6 +684,14 @@ wg_dump(struct proto *P)
}
}
+struct peer_config *peer_new(struct wg_config *c)
+{
+ struct peer_config *pc = cfg_allocz(sizeof(struct peer_config));
+ debug("peer_new %p\n", pc);
+ add_tail(&c->peers, (node*)pc);
+ return pc;
+}
+
struct channel_class channel_wg = {
.channel_size = sizeof(struct wg_channel),
.config_size = sizeof(struct wg_channel_config),
diff --git a/proto/wireguard/wireguard.h b/proto/wireguard/wireguard.h
index cc116e38..69345953 100644
--- a/proto/wireguard/wireguard.h
+++ b/proto/wireguard/wireguard.h
@@ -4,20 +4,22 @@
#include "nest/protocol.h"
#include "sysdep/linux/wireguard.h"
+struct peer_config {
+ node n;
+ const char *public_key;
+ u16 listen_port;
+ ip_addr endpoint;
+ u16 remote_port;
+ struct net_addr allowedip;
+};
+
struct wg_config {
struct proto_config c;
const char *ifname;
const char *socket_path;
const char *private_key;
u16 listen_port;
-
- struct peer_config {
- const char *public_key;
- u16 listen_port;
- ip_addr endpoint;
- u16 remote_port;
- struct net_addr allowedip;
- } peer;
+ list peers;
};
struct wg_proto {
@@ -25,10 +27,6 @@ struct wg_proto {
struct iface *iface;
wg_key private_key;
wg_device *dev;
-
- struct peer {
- wg_key public_key;
- } peer;
};
struct wg_channel_config {
@@ -47,4 +45,6 @@ struct wg_entry {
extern struct channel_class channel_wg;
+struct peer_config *peer_new(struct wg_config *c);
+
#endif /* _BIRD_WIREGUARD_H */