Even if we have unnumbered peering, let's respect `no neighbor X capability link-local`
and disable it per-neighbor on demand.
Fixes: db853cc97eafee8742cd391aaa2b5bc58a6751ae ("bgpd: Implement Link-Local Next Hop capability")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
if (!peer->nexthop.ifp) {
zlog_warn("%s sent a v6 global attribute but address is a V6 LL and there's no peer interface information. Hence, withdrawing",
peer->host);
- if (CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_ADV) &&
- CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_RCV))
+ if (PEER_HAS_LINK_LOCAL_CAPABILITY(peer))
bgp_notify_send(peer->connection, BGP_NOTIFY_UPDATE_ERR,
BGP_NOTIFY_UPDATE_UNREACH_NEXT_HOP);
return BGP_ATTR_PARSE_WITHDRAW;
IPV6_MAX_BYTELEN);
} else {
stream_putc(s, IPV6_MAX_BYTELEN);
- if (CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_ADV) &&
- CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_RCV))
+ if (PEER_HAS_LINK_LOCAL_CAPABILITY(peer))
stream_put(s, &attr->mp_nexthop_local, IPV6_MAX_BYTELEN);
else
stream_put(s, &attr->mp_nexthop_global, IPV6_MAX_BYTELEN);
/* If we receive MP_REACH with GUA as LL, we should
* check if we have Link-Local Next Hop capability also.
*/
- if (!(CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_ADV) &&
- CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_RCV))) {
+ if (!PEER_HAS_LINK_LOCAL_CAPABILITY(peer)) {
zlog_warn("%s: received IPv6 global next-hop as Link-Local, but no capability exchanged",
__func__);
p->u.prefix6 = attr->mp_nexthop_global;
* length of the Next Hop field to 16 and include only the IPv6 link-local
* address in the Next Hop field.
*/
- if (!(CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_ADV) &&
- CHECK_FLAG(peer->cap, PEER_CAP_LINK_LOCAL_RCV)))
+ if (!PEER_HAS_LINK_LOCAL_CAPABILITY(peer))
global_and_ll = true;
}
bgp_nexthop_hostname(path->peer, path->nexthop);
char esi_buf[ESI_STR_LEN];
bool ll_nexthop_only = attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL &&
- !!CHECK_FLAG(path->peer->cap, PEER_CAP_LINK_LOCAL_ADV) &&
- !!CHECK_FLAG(path->peer->cap, PEER_CAP_LINK_LOCAL_RCV);
+ PEER_HAS_LINK_LOCAL_CAPABILITY(path->peer);
if (json_paths)
json_path = json_object_new_object();
bgp_get_imported_bpi_ultimate(path);
struct bgp_route_evpn *bre = bgp_attr_get_evpn_overlay(attr);
bool ll_nexthop_only = attr->mp_nexthop_len == BGP_ATTR_NHLEN_IPV6_GLOBAL &&
- !!CHECK_FLAG(path->peer->cap, PEER_CAP_LINK_LOCAL_ADV) &&
- !!CHECK_FLAG(path->peer->cap, PEER_CAP_LINK_LOCAL_RCV);
+ PEER_HAS_LINK_LOCAL_CAPABILITY(path->peer);
if (json_paths) {
json_path = json_object_new_object();
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);
+ bool ll_nexthop_only = PEER_HAS_LINK_LOCAL_CAPABILITY(peer);
gnh_modified = lnh_modified = 0;
mod_v6nhg = &v6nhglobal;
}
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)) {
+ nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL || ll_nexthop_only) {
stream_get_from(&v6nhlocal, s, offset_nhlocal,
IPV6_MAX_BYTELEN);
if (IN6_IS_ADDR_UNSPECIFIED(&v6nhlocal)) {
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 ||
- (nhlen == BGP_ATTR_NHLEN_IPV6_GLOBAL && ll_nexthop_only))
+ nhlen == BGP_ATTR_NHLEN_VPNV6_GLOBAL_AND_LL || ll_nexthop_only)
zlog_debug(
"u%" PRIu64 ":s%" PRIu64
" %s send UPDATE w/ mp_nexthops %pI6, %pI6%s",
!(_afi == AFI_IP && _safi == SAFI_MPLS_VPN) && \
!(_afi == AFI_IP6 && _safi == SAFI_MPLS_VPN))
+#define PEER_HAS_LINK_LOCAL_CAPABILITY(_peer) \
+ (CHECK_FLAG(_peer->flags, PEER_FLAG_CAPABILITY_LINK_LOCAL) && \
+ CHECK_FLAG(_peer->cap, PEER_CAP_LINK_LOCAL_ADV) && \
+ CHECK_FLAG(_peer->cap, PEER_CAP_LINK_LOCAL_RCV))
+
#endif /* _QUAGGA_BGPD_H */