forked from Mirror/frr
bgpd: Add an ability to disable link-local capability per peer
Even if we have unnumbered peering, let's respect `no neighbor X capability link-local`
and disable it per-neighbor on demand.
Fixes: db853cc97e
("bgpd: Implement Link-Local Next Hop capability")
Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
This commit is contained in:
parent
28c337de18
commit
ca24f56a5c
|
@ -2450,8 +2450,7 @@ int bgp_mp_reach_parse(struct bgp_attr_parser_args *args,
|
|||
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;
|
||||
|
@ -4215,8 +4214,7 @@ 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);
|
||||
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);
|
||||
|
|
|
@ -1102,8 +1102,7 @@ static bool make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
|
|||
/* 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;
|
||||
|
|
|
@ -2512,8 +2512,7 @@ bool subgroup_announce_check(struct bgp_dest *dest, struct bgp_path_info *pi,
|
|||
* 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;
|
||||
}
|
||||
|
||||
|
@ -9728,8 +9727,7 @@ void route_vty_out(struct vty *vty, const struct prefix *p,
|
|||
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();
|
||||
|
@ -10842,8 +10840,7 @@ void route_vty_out_detail(struct vty *vty, struct bgp *bgp, struct bgp_dest *bn,
|
|||
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();
|
||||
|
|
|
@ -447,8 +447,7 @@ 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);
|
||||
bool ll_nexthop_only = PEER_HAS_LINK_LOCAL_CAPABILITY(peer);
|
||||
|
||||
gnh_modified = lnh_modified = 0;
|
||||
mod_v6nhg = &v6nhglobal;
|
||||
|
@ -538,8 +537,7 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
|
|||
}
|
||||
|
||||
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)) {
|
||||
|
@ -559,8 +557,7 @@ struct stream *bpacket_reformat_for_peer(struct bpacket *pkt,
|
|||
|
||||
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",
|
||||
|
|
|
@ -2921,4 +2921,9 @@ extern void bgp_session_reset_safe(struct peer *peer, struct listnode **nnode);
|
|||
!(_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 */
|
||||
|
|
Loading…
Reference in a new issue