From 0050f82b8db8d0ea2775fd1fd0b9aadab6844453 Mon Sep 17 00:00:00 2001 From: Donatas Abraitis Date: Tue, 11 Feb 2025 10:19:20 +0200 Subject: [PATCH] bgpd: Send LL only if LL Next Hop capability is negotiated If we have LL Next Hop capability exchanged, we should send LL-only as 16-bytes NH instead of a GUA (global unicast). Fixes: db853cc97eafee8742cd391aaa2b5bc58a6751ae ("bgpd: Implement Link-Local Next Hop capability") Signed-off-by: Donatas Abraitis --- bgpd/bgp_attr.c | 7 +++++-- bgpd/bgp_updgrp_packet.c | 22 +++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/bgpd/bgp_attr.c b/bgpd/bgp_attr.c index c15dada9c1..1a7d0e7568 100644 --- a/bgpd/bgp_attr.c +++ b/bgpd/bgp_attr.c @@ -4215,8 +4215,11 @@ size_t bgp_packet_mpattr_start(struct stream *s, struct peer *peer, afi_t afi, IPV6_MAX_BYTELEN); } else { stream_putc(s, IPV6_MAX_BYTELEN); - stream_put(s, &attr->mp_nexthop_global, - IPV6_MAX_BYTELEN); + if (CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_ADV) && + CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_RCV)) + stream_put(s, &attr->mp_nexthop_local, IPV6_MAX_BYTELEN); + else + stream_put(s, &attr->mp_nexthop_global, IPV6_MAX_BYTELEN); } } break; case SAFI_MPLS_VPN: { diff --git a/bgpd/bgp_updgrp_packet.c b/bgpd/bgp_updgrp_packet.c index ec418f2b1d..4b25aeb727 100644 --- a/bgpd/bgp_updgrp_packet.c +++ b/bgpd/bgp_updgrp_packet.c @@ -447,6 +447,8 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, int gnh_modified, lnh_modified; size_t offset_nhglobal = vec->offset + 1; size_t offset_nhlocal = vec->offset + 1; + bool ll_nexthop_only = !!CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_ADV) && + !!CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_RCV); gnh_modified = lnh_modified = 0; mod_v6nhg = &v6nhglobal; @@ -535,8 +537,9 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, gnh_modified = 1; } - if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL - || nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) { + if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL || + nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL || + (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL && ll_nexthop_only)) { stream_get_from(&v6nhlocal, s, offset_nhlocal, IPV6_MAX_BYTELEN); if (IN6_IS_ADDR_UNSPECIFIED(&v6nhlocal)) { @@ -545,14 +548,19 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt, } } - if (gnh_modified) - stream_put_in6_addr_at(s, offset_nhglobal, mod_v6nhg); - if (lnh_modified) + if (lnh_modified && ll_nexthop_only) { stream_put_in6_addr_at(s, offset_nhlocal, mod_v6nhl); + } else { + if (gnh_modified) + stream_put_in6_addr_at(s, offset_nhglobal, mod_v6nhg); + if (lnh_modified) + stream_put_in6_addr_at(s, offset_nhlocal, mod_v6nhl); + } if (bgp_debug_update(peer, NULL, NULL, 0)) { - if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL - || nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL) + if (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL || + nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL || + (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL && ll_nexthop_only)) zlog_debug( "u%" PRIu64 ":s%" PRIu64 " %s send UPDATE w/ mp_nexthops %pI6, %pI6%s",