]> git.puffer.fish Git - mirror/frr.git/commitdiff
zebra: let /32 host route with same IP cross VRF 10635/head
authoranlan_cs <vic.lan@pica8.com>
Mon, 31 Jan 2022 00:44:35 +0000 (19:44 -0500)
committeranlan_cs <vic.lan@pica8.com>
Tue, 8 Mar 2022 23:22:11 +0000 (07:22 +0800)
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 <vic.lan@pica8.com>
zebra/zebra_nhg.c

index e1d28e1534889a58264a69fa052e15c00f19bf78..469a94a65bc836bd36836a57689a4a46c3827e64 100644 (file)
@@ -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);