summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMikael Magnusson <mikma@users.sourceforge.net>2018-09-04 18:32:42 +0000
committerMikael Magnusson <mikma@users.sourceforge.net>2019-04-02 00:27:38 +0200
commitdd1a92bdb013b4ff38d9c2e7aebf132eeb4a47fc (patch)
treea6a141b87db23d5ce030c393467c55e263586676
parent5ac8017fb8c79fd044cb28d72f03fcdeb033f715 (diff)
BGP: Tunnel Encapsulation attribute
Refer to draft-ietf-idr-tunnel-encaps-11
-rw-r--r--proto/bgp/attrs.c52
-rw-r--r--proto/bgp/bgp.h1
-rw-r--r--proto/bgp/config.Y4
3 files changed, 56 insertions, 1 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index cbb22038..a27871bc 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -625,6 +625,48 @@ bgp_decode_large_community(struct bgp_parse_state *s, uint code UNUSED, uint fla
}
static void
+bgp_export_tunnel_encap(struct bgp_export_state *s, eattr *a)
+{
+ REPORT("bgp_export_tunnel_encap");
+ if (a->u.ptr->length == 0)
+ UNSET(a);
+
+ // a->u.ptr = lc_set_sort(s->pool, a->u.ptr);
+}
+
+static void
+bgp_decode_tunnel_encap(struct bgp_parse_state *s, uint code UNUSED, uint flags, byte *data, uint len, ea_list **to)
+{
+ REPORT("bgp_decode_tunnel_encap %d", len);
+ bgp_set_attr_data(to, s->pool, BA_TUNNEL_ENCAP, flags, data, len);
+}
+
+static int
+bgp_encode_tunnel_encap(struct bgp_write_state *s UNUSED, eattr *a, byte *buf, uint size)
+{
+ REPORT("bgp_encode_tunnel_encap %d", size);
+ return bgp_put_attr(buf, size, EA_ID(a->id), a->flags, a->u.ptr->data, a->u.ptr->length);
+}
+
+static void
+bgp_format_tunnel_encap(eattr *a, byte *buf, uint size)
+{
+ char *pos = buf;
+
+ for (uint i = 0; i < a->u.ptr->length; i++)
+ {
+ if (size < 4)
+ {
+ bsprintf(pos, "...");
+ return;
+ }
+
+ uint l = bsprintf(pos, "%02x ", a->u.ptr->data[i]);
+ ADVANCE(pos, size, l);
+ }
+}
+
+static void
bgp_export_mpls_label_stack(struct bgp_export_state *s, eattr *a)
{
net_addr *n = s->route->net->n.addr;
@@ -696,6 +738,7 @@ bgp_format_mpls_label_stack(eattr *a, byte *buf, uint size)
static inline void
bgp_decode_unknown(struct bgp_parse_state *s, uint code, uint flags, byte *data, uint len, ea_list **to)
{
+ REPORT("unknown %x %x", code, flags);
/* Cannot use bgp_set_attr_data() as it works on known attributes only */
ea_set_attr_data(to, s->pool, EA_CODE(PROTOCOL_BGP, code), flags, EAF_TYPE_OPAQUE, data, len);
}
@@ -828,6 +871,15 @@ static const struct bgp_attr_desc bgp_attr_table[] = {
.encode = bgp_encode_u32s,
.decode = bgp_decode_large_community,
},
+ [BA_TUNNEL_ENCAP] = {
+ .name = "tunnel_encap",
+ .type = EAF_TYPE_TUNNEL_ENCAP,
+ .flags = BAF_OPTIONAL | BAF_TRANSITIVE,
+ .export = bgp_export_tunnel_encap,
+ .encode = bgp_encode_tunnel_encap,
+ .decode = bgp_decode_tunnel_encap,
+ .format = bgp_format_tunnel_encap,
+ },
[BA_MPLS_LABEL_STACK] = {
.name = "mpls_label_stack",
.type = EAF_TYPE_INT_SET,
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index cfc88d8e..432084e4 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -593,6 +593,7 @@ void bgp_update_next_hop(struct bgp_export_state *s, eattr *a, ea_list **to);
#define BA_EXT_COMMUNITY 0x10 /* RFC 4360 */
#define BA_AS4_PATH 0x11 /* RFC 6793 */
#define BA_AS4_AGGREGATOR 0x12 /* RFC 6793 */
+#define BA_TUNNEL_ENCAP 0x17
#define BA_LARGE_COMMUNITY 0x20 /* RFC 8092 */
/* Bird's private internal BGP attributes */
diff --git a/proto/bgp/config.Y b/proto/bgp/config.Y
index ac8d024a..8ceff39e 100644
--- a/proto/bgp/config.Y
+++ b/proto/bgp/config.Y
@@ -29,7 +29,7 @@ CF_KEYWORDS(BGP, LOCAL, NEIGHBOR, AS, HOLD, TIME, CONNECT, RETRY, KEEPALIVE,
SECURITY, DETERMINISTIC, SECONDARY, ALLOW, BFD, ADD, PATHS, RX, TX,
GRACEFUL, RESTART, AWARE, CHECK, LINK, PORT, EXTENDED, MESSAGES, SETKEY,
STRICT, BIND, CONFEDERATION, MEMBER, MULTICAST, FLOW4, FLOW6, LONG,
- LIVED, STALE, IMPORT, IBGP, EBGP)
+ LIVED, STALE, IMPORT, IBGP, EBGP, BGP_TUNNEL_ENCAP)
%type <i> bgp_nh
%type <i32> bgp_afi
@@ -295,6 +295,8 @@ dynamic_attr: BGP_EXT_COMMUNITY
{ $$ = f_new_dynamic_attr(EAF_TYPE_EC_SET, T_ECLIST, EA_CODE(PROTOCOL_BGP, BA_EXT_COMMUNITY)); } ;
dynamic_attr: BGP_LARGE_COMMUNITY
{ $$ = f_new_dynamic_attr(EAF_TYPE_LC_SET, T_LCLIST, EA_CODE(PROTOCOL_BGP, BA_LARGE_COMMUNITY)); } ;
+dynamic_attr: BGP_TUNNEL_ENCAP
+ { $$ = f_new_dynamic_attr(EAF_TYPE_TUNNEL_ENCAP, T_TLV, EA_CODE(PROTOCOL_BGP, BA_TUNNEL_ENCAP)); } ;