Skip to content

Commit a0d2734

Browse files
committed
bgpd: Validate both nexthop information (NEXTHOP and NLRI)
If we receive an IPv6 prefix e.g.: 2001:db8:100::/64 with nextop: 0.0.0.0, and mp_nexthop: fc00::2, we should not treat this with an invalid nexthop because of 0.0.0.0. We MUST check for MP_REACH attribute also and decide later if we have at least one a valid nexthop. Signed-off-by: Donatas Abraitis <donatas@opensourcerouting.org>
1 parent 229466e commit a0d2734

File tree

1 file changed

+22
-28
lines changed

1 file changed

+22
-28
lines changed

bgpd/bgp_route.c

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -4459,7 +4459,7 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
44594459
uint8_t type, uint8_t stype, struct attr *attr,
44604460
struct bgp_dest *dest)
44614461
{
4462-
bool ret = false;
4462+
bool nh_invalid = false;
44634463
bool is_bgp_static_route =
44644464
(type == ZEBRA_ROUTE_BGP && stype == BGP_ROUTE_STATIC) ? true
44654465
: false;
@@ -4481,13 +4481,15 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
44814481
(safi != SAFI_UNICAST && safi != SAFI_MULTICAST && safi != SAFI_EVPN))
44824482
return false;
44834483

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

44924494
/* If MP_NEXTHOP is present, validate it. */
44934495
/* Note: For IPv6 nexthops, we only validate the global (1st) nexthop;
@@ -4502,39 +4504,31 @@ bool bgp_update_martian_nexthop(struct bgp *bgp, afi_t afi, safi_t safi,
45024504
switch (attr->mp_nexthop_len) {
45034505
case BGP_ATTR_NHLEN_IPV4:
45044506
case BGP_ATTR_NHLEN_VPNV4:
4505-
ret = (attr->mp_nexthop_global_in.s_addr ==
4506-
INADDR_ANY ||
4507-
!ipv4_unicast_valid(
4508-
&attr->mp_nexthop_global_in) ||
4509-
bgp_nexthop_self(bgp, afi, type, stype, attr,
4510-
dest));
4507+
nh_invalid = (attr->mp_nexthop_global_in.s_addr == INADDR_ANY ||
4508+
!ipv4_unicast_valid(&attr->mp_nexthop_global_in) ||
4509+
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));
45114510
break;
45124511

45134512
case BGP_ATTR_NHLEN_IPV6_GLOBAL:
45144513
case BGP_ATTR_NHLEN_VPNV6_GLOBAL:
4515-
ret = (IN6_IS_ADDR_UNSPECIFIED(
4516-
&attr->mp_nexthop_global)
4517-
|| IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
4518-
|| IN6_IS_ADDR_MULTICAST(
4519-
&attr->mp_nexthop_global)
4520-
|| bgp_nexthop_self(bgp, afi, type, stype, attr,
4521-
dest));
4514+
nh_invalid = (IN6_IS_ADDR_UNSPECIFIED(&attr->mp_nexthop_global) ||
4515+
IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global) ||
4516+
IN6_IS_ADDR_MULTICAST(&attr->mp_nexthop_global) ||
4517+
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));
45224518
break;
45234519
case BGP_ATTR_NHLEN_IPV6_GLOBAL_AND_LL:
4524-
ret = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global)
4525-
|| IN6_IS_ADDR_MULTICAST(
4526-
&attr->mp_nexthop_global)
4527-
|| bgp_nexthop_self(bgp, afi, type, stype, attr,
4528-
dest));
4520+
nh_invalid = (IN6_IS_ADDR_LOOPBACK(&attr->mp_nexthop_global) ||
4521+
IN6_IS_ADDR_MULTICAST(&attr->mp_nexthop_global) ||
4522+
bgp_nexthop_self(bgp, afi, type, stype, attr, dest));
45294523
break;
45304524

45314525
default:
4532-
ret = true;
4526+
nh_invalid = true;
45334527
break;
45344528
}
45354529
}
45364530

4537-
return ret;
4531+
return nh_invalid;
45384532
}
45394533

45404534
static void bgp_attr_add_no_export_community(struct attr *attr)

0 commit comments

Comments
 (0)