Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

bgpd: Validate both nexthop information (NEXTHOP and NLRI) (backport) #17446

Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 22 additions & 28 deletions bgpd/bgp_route.c
Original file line number Diff line number Diff line change
Expand Up @@ -4406,7 +4406,7 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
uint8_t type, uint8_t stype, struct attr *attr,
struct bgp_dest *dest)
{
bool ret = false;
bool nh_invalid = false;
bool is_bgp_static_route =
(type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
: false;
Expand All @@ -4428,13 +4428,15 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
(safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
return false;

/* If NEXT_HOP is present, validate it. */
if (attr->flag & ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)) {
if (attr->nexthop.s_addr == INADDR_ANY ||
!ipv4_unicast_valid(&attr->nexthop) ||
bgp_nexthop_self(bgp, afi, type, stype, attr, dest))
return true;
}
/* If NEXT_HOP is present, validate it:
* The route can have both nexthop + mp_nexthop encoded as multiple NLRIs,
* and we MUST check if at least one of them is valid.
* E.g.: IPv6 prefix can be with nexthop: 0.0.0.0, and mp_nexthop: fc00::1.
*/
if (CHECK_FLAG(attr->flag, ATTR_FLAG_BIT(BGP_ATTR_NEXT_HOP)))
nh_invalid = (attr->nexthop.s_addr == INADDR_ANY ||
!ipv4_unicast_valid(&attr->nexthop) ||
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));

/* If MP_NEXTHOP is present, validate it. */
/* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
Expand All @@ -4449,39 +4451,31 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
switch (attr->mp_nexthop_len) {
case BGP_ATTR_NHLEN_IPV4:
case BGP_ATTR_NHLEN_VPNV4:
ret = (attr->mp_nexthop_global_in.s_addr ==
INADDR_ANY ||
!ipv4_unicast_valid(
&attr->mp_nexthop_global_in) ||
bgp_nexthop_self(bgp, afi, type, stype, attr,
dest));
nh_invalid = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY ||
!ipv4_unicast_valid(&attr->mp_nexthop_global_in) ||
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));
break;

case BGP_ATTR_NHLEN_IPV6_GLOBAL:
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
ret = (IN6_IS_ADDR_UNSPECIFIED(
&attr->mp_nexthop_global)
|| IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
|| IN6_IS_ADDR_MULTICAST(
&attr->mp_nexthop_global)
|| bgp_nexthop_self(bgp, afi, type, stype, attr,
dest));
nh_invalid = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global) ||
IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global) ||
IN6_IS_ADDR_MULTICAST(&attr->mp_nexthop_global) ||
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));
break;
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
|| IN6_IS_ADDR_MULTICAST(
&attr->mp_nexthop_global)
|| bgp_nexthop_self(bgp, afi, type, stype, attr,
dest));
nh_invalid = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global) ||
IN6_IS_ADDR_MULTICAST(&attr->mp_nexthop_global) ||
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));
break;

default:
ret = true;
nh_invalid = true;
break;
}
}

return ret;
return nh_invalid;
}

static void bgp_attr_add_no_export_community(struct attr *attr)
Expand Down
Loading