summaryrefslogtreecommitdiff
path: root/proto/bgp
diff options
context:
space:
mode:
authorOndrej Zajicek (work) <santiago@crfreenet.org>2021-01-12 15:37:01 +0100
committerOndrej Zajicek (work) <santiago@crfreenet.org>2021-01-12 15:37:01 +0100
commitd774f6d721b0e52ed800c4b9a3a482c8ce9dd074 (patch)
tree8aa6798a9e775098edda40f348a6ee4646b64ee4 /proto/bgp
parent910adaa08bbd416288797505399ab47f990817e6 (diff)
MRT: Fix IPv6 table dumps
Add fake MP_REACH_NLRI attribute with BGP next hop when encoding MRT table dumps for IPv6 routes. That is necessary to encode next hop as NEXT_HOP attribute is not used for MP-BGP. Thanks to Santiago Aggio for the bugreport.
Diffstat (limited to 'proto/bgp')
-rw-r--r--proto/bgp/attrs.c31
-rw-r--r--proto/bgp/bgp.h1
2 files changed, 32 insertions, 0 deletions
diff --git a/proto/bgp/attrs.c b/proto/bgp/attrs.c
index b2c37301..6752cb7f 100644
--- a/proto/bgp/attrs.c
+++ b/proto/bgp/attrs.c
@@ -683,6 +683,37 @@ bgp_format_cluster_list(const eattr *a, byte *buf, uint size)
}
+int
+bgp_encode_mp_reach_mrt(struct bgp_write_state *s UNUSED, eattr *a, byte *buf, uint size)
+{
+ /*
+ * Limited version of MP_REACH_NLRI used for MRT table dumps (IPv6 only):
+ *
+ * 3 B MP_REACH_NLRI header
+ * 1 B MP_REACH_NLRI data - Length of Next Hop Network Address
+ * var MP_REACH_NLRI data - Network Address of Next Hop
+ */
+
+ ip_addr *nh = (void *) a->u.ptr->data;
+ uint len = a->u.ptr->length;
+
+ ASSERT((len == 16) || (len == 32));
+
+ if (size < (3+1+len))
+ return -1;
+
+ bgp_put_attr_hdr3(buf, BA_MP_REACH_NLRI, BAF_OPTIONAL, 1+len);
+ buf[3] = len;
+ buf += 4;
+
+ put_ip6(buf, ipa_to_ip6(nh[0]));
+
+ if (len == 32)
+ put_ip6(buf+16, ipa_to_ip6(nh[1]));
+
+ return 3+1+len;
+}
+
static inline u32
get_af3(byte *buf)
{
diff --git a/proto/bgp/bgp.h b/proto/bgp/bgp.h
index 5cabd327..dd7dc28f 100644
--- a/proto/bgp/bgp.h
+++ b/proto/bgp/bgp.h
@@ -559,6 +559,7 @@ static inline void
bgp_unset_attr(ea_list **to, struct linpool *pool, uint code)
{ eattr *e = bgp_set_attr(to, pool, code, 0, 0); e->type = EAF_TYPE_UNDEF; }
+int bgp_encode_mp_reach_mrt(struct bgp_write_state *s, eattr *a, byte *buf, uint size);
int bgp_encode_attrs(struct bgp_write_state *s, ea_list *attrs, byte *buf, byte *end);
ea_list * bgp_decode_attrs(struct bgp_parse_state *s, byte *data, uint len);