bgpd: prefer link-local to a ipv4-mapped ipv6 global

When a peer sends an IPv4-mapped IPv6 global and a IPv6 link-local
nexthop, prefer the link-local unless a route-map tells to use the
global.

Signed-off-by: Louis Scalbert <louis.scalbert@6wind.com>
This commit is contained in:
Louis Scalbert 2024-04-08 13:18:20 +02:00
parent fc5a738409
commit 5dd731af84

View File

@ -320,11 +320,6 @@ int bgp_find_or_add_nexthop(struct bgp *bgp_route, struct bgp *bgp_nexthop,
afi = BGP_ATTR_MP_NEXTHOP_LEN_IP6(pi->attr) ? AFI_IP6 afi = BGP_ATTR_MP_NEXTHOP_LEN_IP6(pi->attr) ? AFI_IP6
: AFI_IP; : AFI_IP;
/* Validation for the ipv4 mapped ipv6 nexthop. */
if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) {
afi = AFI_IP;
}
/* This will return true if the global IPv6 NH is a link local /* This will return true if the global IPv6 NH is a link local
* addr */ * addr */
if (make_prefix(afi, pi, &p) < 0) if (make_prefix(afi, pi, &p) < 0)
@ -1043,19 +1038,11 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
p->u.prefix4 = p_orig->u.prefix4; p->u.prefix4 = p_orig->u.prefix4;
p->prefixlen = p_orig->prefixlen; p->prefixlen = p_orig->prefixlen;
} else { } else {
if (IS_MAPPED_IPV6(&pi->attr->mp_nexthop_global)) { if (p_orig->family == AF_EVPN)
ipv4_mapped_ipv6_to_ipv4( p->u.prefix4 = pi->attr->mp_nexthop_global_in;
&pi->attr->mp_nexthop_global, &ipv4); else
p->u.prefix4 = ipv4; p->u.prefix4 = pi->attr->nexthop;
p->prefixlen = IPV4_MAX_BITLEN; p->prefixlen = IPV4_MAX_BITLEN;
} else {
if (p_orig->family == AF_EVPN)
p->u.prefix4 =
pi->attr->mp_nexthop_global_in;
else
p->u.prefix4 = pi->attr->nexthop;
p->prefixlen = IPV4_MAX_BITLEN;
}
} }
break; break;
case AFI_IP6: case AFI_IP6:
@ -1071,6 +1058,7 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
/* If we receive MP_REACH nexthop with ::(LL) /* If we receive MP_REACH nexthop with ::(LL)
* or LL(LL), use LL address as nexthop cache. * or LL(LL), use LL address as nexthop cache.
*/ */
p->prefixlen = IPV6_MAX_BITLEN;
if (pi->attr && if (pi->attr &&
pi->attr->mp_nexthop_len == pi->attr->mp_nexthop_len ==
BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL && BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL &&
@ -1085,15 +1073,22 @@ static int make_prefix(int afi, struct bgp_path_info *pi, struct prefix *p)
pi->attr->mp_nexthop_len == pi->attr->mp_nexthop_len ==
BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) { BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL) {
if (CHECK_FLAG(pi->attr->nh_flags, if (CHECK_FLAG(pi->attr->nh_flags,
BGP_ATTR_NH_MP_PREFER_GLOBAL)) BGP_ATTR_NH_MP_PREFER_GLOBAL)) {
p->u.prefix6 = if (IS_MAPPED_IPV6(
pi->attr->mp_nexthop_global; &pi->attr->mp_nexthop_global)) {
else ipv4_mapped_ipv6_to_ipv4(
&pi->attr->mp_nexthop_global,
&ipv4);
p->u.prefix4 = ipv4;
p->prefixlen = IPV4_MAX_BITLEN;
} else
p->u.prefix6 =
pi->attr->mp_nexthop_global;
} else
p->u.prefix6 = p->u.prefix6 =
pi->attr->mp_nexthop_local; pi->attr->mp_nexthop_local;
} else } else
p->u.prefix6 = pi->attr->mp_nexthop_global; p->u.prefix6 = pi->attr->mp_nexthop_global;
p->prefixlen = IPV6_MAX_BITLEN;
} }
break; break;
default: default: