diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/tunnel_encaps.c | 65 | ||||
-rw-r--r-- | lib/tunnel_encaps.h | 18 |
2 files changed, 45 insertions, 38 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_ */ |