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: 26c747ed6c ("bgpd: extend make_prefix to form srv6-based prefix")

Signed-off-by: Philippe Guibert <philippe.guibert@6wind.com>
This commit is contained in:
Philippe Guibert 2024-03-11 11:51:55 +01:00
parent 855873aa77
commit 8b3b152a1a

View File

@ -1066,9 +1066,16 @@ 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 &&
BGP_PATH_INFO_NUM_LABELS(pi)) {
IPV6_ADDR_COPY(&p->u.prefix6, &pi->attr->srv6_l3vpn->sid);
transpose_sid(&p->u.prefix6,
decode_label(&pi->extra->labels->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;