summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2019-09-27 23:21:56 +0200
committerMikael Magnusson <mikma@users.sourceforge.net>2019-11-15 00:11:29 +0100
commit4a402d2cdbfead5eba9eec6e955c136ad96328e0 (patch)
tree0b5d00c8be1bbb37c32fb9b3f5a828cff87008e6
parentc714681773bb0b932d55b2028c46e3a7982bdd6a (diff)
Wireguard: Add struct tunnel_encapold/wireguard-bp
-rw-r--r--lib/tunnel_encaps.c65
-rw-r--r--lib/tunnel_encaps.h18
-rw-r--r--proto/wireguard/wireguard.c26
3 files changed, 58 insertions, 51 deletions
diff --git a/lib/tunnel_encaps.c b/lib/tunnel_encaps.c
index c2b0f60d..5b72cb61 100644
--- a/lib/tunnel_encaps.c
+++ b/lib/tunnel_encaps.c
@@ -1,21 +1,19 @@
+#include <stdlib.h>
#include "lib/tunnel_encaps.h"
static
-int decode_encap(const void *p, size_t sub_tlv_len, void *encap, size_t *encap_size, u16 *flags)
+int decode_encap(const void *p, size_t sub_tlv_len, struct tunnel_encap *encap, struct pool *pool)
{
- if (sub_tlv_len > *encap_size) {
- log(L_TRACE "WG: encapsulation len error %d > %d", sub_tlv_len, *encap_size);
- return -1;
- }
-
- memcpy(encap, p, sub_tlv_len);
- *encap_size = sub_tlv_len;
- *flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_ENCAP;
+ mb_free(encap->encap);
+ encap->encap = mb_alloc(pool, sub_tlv_len);
+ memcpy(encap->encap, p, sub_tlv_len);
+ encap->encap_len = sub_tlv_len;
+ encap->flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_ENCAP;
return 0;
}
static
-int decode_color(const void *p, size_t sub_tlv_len, u32 *color, u16 *flags)
+int decode_color(const void *p, size_t sub_tlv_len, struct tunnel_encap *encap)
{
if (sub_tlv_len != 8) {
log(L_TRACE "WG: color len error %d", sub_tlv_len);
@@ -27,33 +25,33 @@ int decode_color(const void *p, size_t sub_tlv_len, u32 *color, u16 *flags)
return -1;
}
- *color = get_u32(p+2);
- *flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_COLOR;
+ encap->color = get_u32(p+2);
+ encap->flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_COLOR;
return 0;
}
static
-int decode_udp_dest_port(const void *p, size_t sub_tlv_len, u16 *udp_dest_port, u16 *flags)
+int decode_udp_dest_port(const void *p, size_t sub_tlv_len, struct tunnel_encap *encap)
{
if (sub_tlv_len != 2) {
log(L_TRACE "WG: udp dest port len error %d", sub_tlv_len);
return -1;
}
- *udp_dest_port = get_u16(p);
- *flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_UDP_DEST_PORT;
+ encap->udp_dest_port = get_u16(p);
+ encap->flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_UDP_DEST_PORT;
return 0;
}
static
-int decode_tunnel_ep(const void *p, size_t sub_tlv_len, u32 *as4, ip_addr *tunnel_ep, u16 *flags)
+int decode_tunnel_ep(const void *p, size_t sub_tlv_len, struct tunnel_encap *encap)
{
if (sub_tlv_len < 6) {
log(L_TRACE "WG: tunnel ep len error");
return -1;
}
- *as4 = get_u32(p);
+ encap->ep.asn = get_u32(p);
u16 af = get_u16(p + 4);
switch (af) {
case NET_IP4:
@@ -61,16 +59,16 @@ int decode_tunnel_ep(const void *p, size_t sub_tlv_len, u32 *as4, ip_addr *tunne
log(L_TRACE "WG: IPv4 len error %d", sub_tlv_len);
return -1;
}
- *tunnel_ep = ipa_from_ip4(get_ip4(p + 6));
- *flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP;
+ encap->ep.ip = ipa_from_ip4(get_ip4(p + 6));
+ encap->flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP;
return 0;
case NET_IP6:
if (sub_tlv_len != 22) {
log(L_TRACE "WG: IPv6 len error %d", sub_tlv_len);
return -1;
}
- *tunnel_ep = ipa_from_ip6(get_ip6(p + 6));
- *flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP;
+ encap->ep.ip = ipa_from_ip6(get_ip6(p + 6));
+ encap->flags |= FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP;
return 0;
default:
log(L_TRACE "WG: Address family error %d", af);
@@ -79,9 +77,7 @@ int decode_tunnel_ep(const void *p, size_t sub_tlv_len, u32 *as4, ip_addr *tunne
}
static
-int decode_sub_tlv(const u8 *p, size_t len, void *encap, size_t *encap_size,
- u32 *tunnel_ep_as, ip_addr *tunnel_ep_addr,
- u32 *color, u16 *udp_dest_port, u16 *flags)
+int decode_sub_tlv(const u8 *p, size_t len, struct tunnel_encap *encap, struct pool *pool)
{
if (len < 3) {
log(L_TRACE "WG: sub_tlv len error %d", len);
@@ -115,16 +111,16 @@ int decode_sub_tlv(const u8 *p, size_t len, void *encap, size_t *encap_size,
switch (type) {
case BGP_TUNNEL_ENCAP_A_SUB_TLV_ENCAP:
- res = decode_encap(p, sub_tlv_len, encap, encap_size, flags);
+ res = decode_encap(p, sub_tlv_len, encap, pool);
break;
case BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP:
- res = decode_tunnel_ep(p, sub_tlv_len, tunnel_ep_as, tunnel_ep_addr, flags);
+ res = decode_tunnel_ep(p, sub_tlv_len, encap);
break;
case BGP_TUNNEL_ENCAP_A_SUB_TLV_COLOR:
- res = decode_color(p, sub_tlv_len, color, flags);
+ res = decode_color(p, sub_tlv_len, encap);
break;
case BGP_TUNNEL_ENCAP_A_SUB_TLV_UDP_DEST_PORT:
- res = decode_udp_dest_port(p, sub_tlv_len, udp_dest_port, flags);
+ res = decode_udp_dest_port(p, sub_tlv_len, encap);
break;
default:
/* Skip unsupported sub-TLV. */
@@ -138,7 +134,7 @@ int decode_sub_tlv(const u8 *p, size_t len, void *encap, size_t *encap_size,
return p - first + sub_tlv_len;
}
-int decode_tunnel_encap(const eattr *e, u16 wg_tunnel_type, void *encap, size_t *encap_size, u32 *as4, ip_addr *tunnel_ep, u32 *color, u16 *udp_port, u16 *flags)
+int decode_tunnel_encap(const eattr *e, struct tunnel_encap *encap, struct pool *pool)
{
const u8 *p = e->u.ptr->data;
int len = e->u.ptr->length;
@@ -148,14 +144,9 @@ int decode_tunnel_encap(const eattr *e, u16 wg_tunnel_type, void *encap, size_t
return -1;
}
- u16 tunnel_type = get_u16(p);
+ encap->type = get_u16(p);
- log(L_DEBUG "WG: tunnel type %d", tunnel_type);
-
- if (tunnel_type != wg_tunnel_type) {
- log(L_TRACE "WG: tunnel type error %d", tunnel_type);
- return -1;
- }
+ log(L_DEBUG "WG: tunnel type %d", encap->type);
u16 value_length = get_u16(p + 2);
@@ -167,7 +158,7 @@ int decode_tunnel_encap(const eattr *e, u16 wg_tunnel_type, void *encap, size_t
}
for (const u8 *cur = p + 4; cur < p + 4 + value_length;) {
- int res = decode_sub_tlv(cur, value_length, encap, encap_size, as4, tunnel_ep, color, udp_port, flags);
+ int res = decode_sub_tlv(cur, value_length, encap, pool);
if (res < 0) {
log(L_TRACE "WG: decode error %d", res);
diff --git a/lib/tunnel_encaps.h b/lib/tunnel_encaps.h
index 9d25e5c5..341dcf22 100644
--- a/lib/tunnel_encaps.h
+++ b/lib/tunnel_encaps.h
@@ -16,6 +16,22 @@
#define FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP (1<<BGP_TUNNEL_ENCAP_A_SUB_TLV_TUNNEL_EP)
#define FLAG_BGP_TUNNEL_ENCAP_A_SUB_TLV_UDP_DEST_PORT (1<<BGP_TUNNEL_ENCAP_A_SUB_TLV_UDP_DEST_PORT)
-int decode_tunnel_encap(const eattr *e, u16 wg_tunnel_type, void *encap, size_t *encap_size, u32 *as4, ip_addr *tunnel_ep, u32 *color, u16 *udp_port, u16 *flags);
+/* Tunnel Encapsulation */
+struct tunnel_endpoint {
+ u32 asn;
+ ip_addr ip;
+};
+
+struct tunnel_encap {
+ int type;
+ void *encap;
+ size_t encap_len;
+ struct tunnel_endpoint ep;
+ u32 color;
+ u16 udp_dest_port;
+ u16 flags;
+};
+
+int decode_tunnel_encap(const eattr *e, struct tunnel_encap *encap, struct pool *pool);
#endif /* _BIRD_TUNNEL_ENCAPS_ */
diff --git a/proto/wireguard/wireguard.c b/proto/wireguard/wireguard.c
index 2c2e6796..9896b53a 100644
--- a/proto/wireguard/wireguard.c
+++ b/proto/wireguard/wireguard.c
@@ -156,7 +156,7 @@ dump(void *ptr, size_t len)
}
static wg_peer *
-add_peer(wg_device *dev, wg_key pubkey)
+add_peer(wg_device *dev, const wg_key pubkey)
{
struct wg_peer *peer = malloc(sizeof(struct wg_peer));
memset(peer, 0, sizeof(struct wg_peer));
@@ -254,21 +254,18 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
debug("WG: notify new %d %N\n",
new->attrs->dest, n->n.addr);
- wg_key pubkey;
- size_t pubkey_size = sizeof(wg_key);
- memset(pubkey, 0, pubkey_size);
- u32 tunnel_ep_as4 = 0;
- ip_addr tunnel_ep_addr = IPA_NONE;
- u16 udp_dest_port = 0;
- u32 color = 0;
- u16 flags = 0;
+ struct tunnel_encap encap;
+ memset(&encap, 0, sizeof(encap));
+ encap.ep.ip = IPA_NONE;
t = ea_find(new->attrs->eattrs, EA_CODE(PROTOCOL_BGP, BA_TUNNEL_ENCAP));
if (!t && he && he->src) {
t = ea_find(he->src->eattrs, EA_CODE(PROTOCOL_BGP, BA_TUNNEL_ENCAP));
}
- if (t && t->u.ptr && decode_tunnel_encap(t, c->tunnel_type, &pubkey, &pubkey_size, &tunnel_ep_as4, &tunnel_ep_addr, &color, &udp_dest_port, &flags) == 0 && pubkey_size == sizeof(wg_key)) {
- log(L_TRACE "WG: Attr %x %x %d %04x", t->flags, t->type, t->u.ptr->length, flags);
+ if (t && t->u.ptr && decode_tunnel_encap(t, &encap, P->pool) == 0 && encap.type == c->tunnel_type && encap.encap_len == sizeof(wg_key)) {
+ const wg_key *pubkey = encap.encap;
+
+ log(L_TRACE "WG: Attr %x %x %d %04x", t->flags, t->type, t->u.ptr->length, encap.flags);
struct wg_device *dev = p->dev;
@@ -288,7 +285,7 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
log(L_TRACE "WG: Found");
found = true;
- set_peer_tunnel_ep(peer, tunnel_ep_addr, udp_dest_port);
+ set_peer_tunnel_ep(peer, encap.ep.ip, encap.udp_dest_port);
add_allowed_ips(ch->c.net_type, n, peer);
dirty = true;
@@ -297,7 +294,7 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
if (!found) {
wg_peer *peer = add_peer(dev, pubkey);
- set_peer_tunnel_ep(peer, tunnel_ep_addr, udp_dest_port);
+ set_peer_tunnel_ep(peer, encap.ep.ip, encap.udp_dest_port);
add_allowed_ips(ch->c.net_type, n, peer);
dirty = true;
}
@@ -351,6 +348,9 @@ wg_rt_notify(struct proto *P, struct channel *CH, struct network *n,
log(L_TRACE "WG: No Attr");
}
+ mb_free(encap.encap);
+ encap.encap = NULL;
+
// old_metric = en->valid ? en->metric : -1;
// en->valid = RIP_ENTRY_VALID;