@@ -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
45404534static void bgp_attr_add_no_export_community (struct attr * attr )
0 commit comments