From 3f04f9cf241071882cdb55fbda1888f2dfd7e3aa Mon Sep 17 00:00:00 2001 From: anlan_cs Date: Sun, 30 Jan 2022 19:44:35 -0500 Subject: [PATCH] zebra: let /32 host route with same IP cross VRF Contraints of host routes are too strict in current code: Host routes with same destination address and nexthop address are forbidden even when cross VRFs. Currently host routes with different destination and nexthop address can cross VRFs, it is ok. But host routes with same addresses are forbidden to cross VRFs, it is wrong. Since different VRFs can have the same addresses, leak specific host route with the same nexthop address ( it means destination address is same to nexthop address ) to other VRFs is a normal case. This commit relaxes that contraints. Host routes with same destination address and nexthop address are forbidden only when not cross VRFs. Signed-off-by: anlan_cs --- zebra/zebra_nhg.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/zebra/zebra_nhg.c b/zebra/zebra_nhg.c index e1d28e1534..469a94a65b 100644 --- a/zebra/zebra_nhg.c +++ b/zebra/zebra_nhg.c @@ -1966,7 +1966,7 @@ static int resolve_backup_nexthops(const struct nexthop *nexthop, */ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe, const struct prefix *top, int type, uint32_t flags, - uint32_t *pmtu) + uint32_t *pmtu, vrf_id_t vrf_id) { struct prefix p; struct route_table *table; @@ -2061,13 +2061,13 @@ static int nexthop_active(struct nexthop *nexthop, struct nhg_hash_entry *nhe, return 1; } - if (top - && ((top->family == AF_INET && top->prefixlen == IPV4_MAX_BITLEN - && nexthop->gate.ipv4.s_addr == top->u.prefix4.s_addr) - || (top->family == AF_INET6 && top->prefixlen == IPV6_MAX_BITLEN - && memcmp(&nexthop->gate.ipv6, &top->u.prefix6, - IPV6_MAX_BYTELEN) - == 0))) { + if (top && + ((top->family == AF_INET && top->prefixlen == IPV4_MAX_BITLEN && + nexthop->gate.ipv4.s_addr == top->u.prefix4.s_addr) || + (top->family == AF_INET6 && top->prefixlen == IPV6_MAX_BITLEN && + memcmp(&nexthop->gate.ipv6, &top->u.prefix6, IPV6_MAX_BYTELEN) == + 0)) && + nexthop->vrf_id == vrf_id) { if (IS_ZEBRA_DEBUG_RIB_DETAILED) zlog_debug( " :%s: Attempting to install a max prefixlength route through itself", @@ -2361,6 +2361,7 @@ static unsigned nexthop_active_check(struct route_node *rn, const struct prefix *p, *src_p; struct zebra_vrf *zvrf; uint32_t mtu = 0; + vrf_id_t vrf_id; srcdest_rnode_prefixes(rn, &p, &src_p); @@ -2389,10 +2390,12 @@ static unsigned nexthop_active_check(struct route_node *rn, goto skip_check; } + + vrf_id = zvrf_id(rib_dest_vrf(rib_dest_from_rnode(rn))); switch (nexthop->type) { case NEXTHOP_TYPE_IFINDEX: - if (nexthop_active(nexthop, nhe, &rn->p, re->type, - re->flags, &mtu)) + if (nexthop_active(nexthop, nhe, &rn->p, re->type, re->flags, + &mtu, vrf_id)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -2400,16 +2403,16 @@ static unsigned nexthop_active_check(struct route_node *rn, case NEXTHOP_TYPE_IPV4: case NEXTHOP_TYPE_IPV4_IFINDEX: family = AFI_IP; - if (nexthop_active(nexthop, nhe, &rn->p, re->type, - re->flags, &mtu)) + if (nexthop_active(nexthop, nhe, &rn->p, re->type, re->flags, + &mtu, vrf_id)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); break; case NEXTHOP_TYPE_IPV6: family = AFI_IP6; - if (nexthop_active(nexthop, nhe, &rn->p, re->type, - re->flags, &mtu)) + if (nexthop_active(nexthop, nhe, &rn->p, re->type, re->flags, + &mtu, vrf_id)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); @@ -2419,8 +2422,8 @@ static unsigned nexthop_active_check(struct route_node *rn, if (rn->p.family != AF_INET) family = AFI_IP6; - if (nexthop_active(nexthop, nhe, &rn->p, re->type, - re->flags, &mtu)) + if (nexthop_active(nexthop, nhe, &rn->p, re->type, re->flags, + &mtu, vrf_id)) SET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); else UNSET_FLAG(nexthop->flags, NEXTHOP_FLAG_ACTIVE); -- 2.39.5