From 2c738e64e47154df2ee15fa5f4817af95b8f6063 Mon Sep 17 00:00:00 2001 From: Philippe Guibert Date: Mon, 11 Mar 2024 11:51:55 +0100 Subject: [PATCH] bgpd: fix use real SID in BGP nexthop tracking When receiving an SRv6 BGP update, the nexthop tracking is used to find out the reachability of the BGP update. > # show bgp ipv6 vpn fd00:200::/64 > Paths: (1 available, best #1) > [..] > 4:4::4:4 from 4:4::4:4 (4.4.4.4) > Origin incomplete, metric 0, localpref 100, valid, internal, best (First path received) > Extended Community: RT:52:100 > Remote label: 16 > Remote SID: 2001:db8:f4:: > Last update: Mon Mar 11 11:50:04 2024 The IPv6 address used is the "Remote SID". Actually, this value is incomplete. Remote SID stands for the attribute value received in BGP, while the label value determines a complement of SRv6 SID value. The transposition technique authorises that in BGP, and in the above case, the incoming BGP update has used the transposition length. When there is a transposition in the SID attribute available, use the real SID address. The nexthop tracking will use that forged address. > # show bgp nexthop > Current BGP nexthop cache: > 4:4::4:4 valid [IGP metric 30], #paths 0, peer 4:4::4:4 > gate fe80::dced:1ff:fed6:878c, if ntfp3 > Last update: Mon Mar 11 11:50:02 2024 > 2001:db8:f4:1:: valid [IGP metric 0], #paths 2 > gate fe80::dced:1ff:fed6:878c, if ntfp3 Fixes: 26c747ed6c0b ("bgpd: extend make_prefix to form srv6-based prefix") Signed-off-by: Philippe Guibert --- bgpd/bgp_nht.c | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/bgpd/bgp_nht.c b/bgpd/bgp_nht.c index 786d07c5a946..243370a22023 100644 --- a/bgpd/bgp_nht.c +++ b/bgpd/bgp_nht.c @@ -1058,9 +1058,21 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p) case AFI_IP6: p->family = AF_INET6; if (pi->attr->srv6_l3vpn) { - IPV6_ADDR_COPY(&(p->u.prefix6), - &(pi->attr->srv6_l3vpn->sid)); p->prefixlen = IPV6_MAX_BITLEN; + if (pi->attr->srv6_l3vpn->transposition_len != 0 && + pi->extra && + bgp_is_valid_label(&pi->extra->label[0])) { + memcpy(&p->u.prefix6, &pi->attr->srv6_l3vpn->sid, + sizeof(struct in6_addr)); + transpose_sid(&p->u.prefix6, + decode_label(&pi->extra->label[0]), + pi->attr->srv6_l3vpn + ->transposition_offset, + pi->attr->srv6_l3vpn + ->transposition_len); + } else + IPV6_ADDR_COPY(&(p->u.prefix6), + &(pi->attr->srv6_l3vpn->sid)); } else if (is_bgp_static) { p->u.prefix6 = p_orig->u.prefix6; p->prefixlen = p_orig->prefixlen;