]> git.proxmox.com Git - mirror_frr.git/blobdiff - pimd/pim_rpf.c
zebra: Allow ns delete to happen after under/over flow checks
[mirror_frr.git] / pimd / pim_rpf.c
index 22741230d87e4e21f8aa3a3a854482a4ec9d59cb..814d2e076bb0f581d5d20770432aed962166b024 100644 (file)
 #include "pim_ifchannel.h"
 #include "pim_time.h"
 #include "pim_nht.h"
-
-static long long last_route_change_time = -1;
-long long nexthop_lookups_avoided = 0;
+#include "pim_oil.h"
 
 static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
 
-void pim_rpf_set_refresh_time(void)
+void pim_rpf_set_refresh_time(struct pim_instance *pim)
 {
-       last_route_change_time = pim_time_monotonic_usec();
+       pim->last_route_change_time = pim_time_monotonic_usec();
        if (PIM_DEBUG_TRACE)
-               zlog_debug("%s: New last route change time: %lld",
-                          __PRETTY_FUNCTION__, last_route_change_time);
+               zlog_debug("%s: vrf(%s) New last route change time: %" PRId64,
+                          __PRETTY_FUNCTION__, pim->vrf->name,
+                          pim->last_route_change_time);
 }
 
-int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
-                      int neighbor_needed)
+int pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
+                      struct in_addr addr, int neighbor_needed)
 {
        struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
        struct pim_neighbor *nbr = NULL;
@@ -60,8 +59,16 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
        int found = 0;
        int i = 0;
 
+       /*
+        * We should not attempt to lookup a
+        * 255.255.255.255 address, since
+        * it will never work
+        */
+       if (addr.s_addr == INADDR_NONE)
+               return -1;
+
        if ((nexthop->last_lookup.s_addr == addr.s_addr)
-           && (nexthop->last_lookup_time > last_route_change_time)) {
+           && (nexthop->last_lookup_time > pim->last_route_change_time)) {
                if (PIM_DEBUG_TRACE) {
                        char addr_str[INET_ADDRSTRLEN];
                        pim_inet4_dump("<addr?>", addr, addr_str,
@@ -70,12 +77,12 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
                        pim_addr_dump("<nexthop?>", &nexthop->mrib_nexthop_addr,
                                      nexthop_str, sizeof(nexthop_str));
                        zlog_debug(
-                               "%s: Using last lookup for %s at %lld, %lld addr%s",
+                               "%s: Using last lookup for %s at %lld, %" PRId64 " addr %s",
                                __PRETTY_FUNCTION__, addr_str,
                                nexthop->last_lookup_time,
-                               last_route_change_time, nexthop_str);
+                               pim->last_route_change_time, nexthop_str);
                }
-               nexthop_lookups_avoided++;
+               pim->nexthop_lookups_avoided++;
                return 0;
        } else {
                if (PIM_DEBUG_TRACE) {
@@ -83,17 +90,17 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
                        pim_inet4_dump("<addr?>", addr, addr_str,
                                       sizeof(addr_str));
                        zlog_debug(
-                               "%s: Looking up: %s, last lookup time: %lld, %lld",
+                               "%s: Looking up: %s, last lookup time: %lld, %" PRId64,
                                __PRETTY_FUNCTION__, addr_str,
                                nexthop->last_lookup_time,
-                               last_route_change_time);
+                               pim->last_route_change_time);
                }
        }
 
        memset(nexthop_tab, 0,
               sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
-       num_ifindex = zclient_lookup_nexthop(nexthop_tab, MULTIPATH_NUM, addr,
-                                            PIM_NEXTHOP_LOOKUP_MAX);
+       num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
+                                            addr, PIM_NEXTHOP_LOOKUP_MAX);
        if (num_ifindex < 1) {
                char addr_str[INET_ADDRSTRLEN];
                pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
@@ -106,7 +113,7 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
        while (!found && (i < num_ifindex)) {
                first_ifindex = nexthop_tab[i].ifindex;
 
-               ifp = if_lookup_by_index(first_ifindex, pimg->vrf_id);
+               ifp = if_lookup_by_index(first_ifindex, pim->vrf_id);
                if (!ifp) {
                        if (PIM_DEBUG_ZEBRA) {
                                char addr_str[INET_ADDRSTRLEN];
@@ -163,7 +170,7 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr,
                                nexthop_tab[i].route_metric,
                                nexthop_tab[i].protocol_distance);
                }
-               /* update nextop data */
+               /* update nexthop data */
                nexthop->interface = ifp;
                nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
                nexthop->mrib_metric_preference =
@@ -187,7 +194,8 @@ static int nexthop_mismatch(const struct pim_nexthop *nh1,
               || (nh1->mrib_route_metric != nh2->mrib_route_metric);
 }
 
-enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
+enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
+                                  struct pim_upstream *up, struct pim_rpf *old,
                                   uint8_t is_new)
 {
        struct pim_rpf *rpf = &up->rpf;
@@ -195,6 +203,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
        struct prefix nht_p;
        struct pim_nexthop_cache pnc;
        struct prefix src, grp;
+       bool neigh_needed = true;
 
        saved.source_nexthop = rpf->source_nexthop;
        saved.rpf_addr = rpf->rpf_addr;
@@ -218,22 +227,20 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
        grp.prefixlen = IPV4_MAX_BITLEN;
        grp.u.prefix4 = up->sg.grp;
        memset(&pnc, 0, sizeof(struct pim_nexthop_cache));
-       if (pim_find_or_track_nexthop(pimg, &nht_p, up, NULL, &pnc)) {
+
+       if ((up->sg.src.s_addr == INADDR_ANY && I_am_RP(pim, up->sg.grp)) ||
+           PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
+               neigh_needed = FALSE;
+       if (pim_find_or_track_nexthop(pim, &nht_p, up, NULL, &pnc)) {
                if (pnc.nexthop_num) {
-                       if (!pim_ecmp_nexthop_search(
-                                   pimg, &pnc, &up->rpf.source_nexthop, &src,
-                                   &grp,
-                                   !PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)
-                                           && !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(
-                                                      up->flags)))
+                       if (!pim_ecmp_nexthop_search(pim, &pnc,
+                                                    &up->rpf.source_nexthop,
+                                                    &src, &grp, neigh_needed))
                                return PIM_RPF_FAILURE;
                }
        } else {
-               if (!pim_ecmp_nexthop_lookup(
-                           pimg, &rpf->source_nexthop, up->upstream_addr, &src,
-                           &grp, !PIM_UPSTREAM_FLAG_TEST_FHR(up->flags)
-                                         && !PIM_UPSTREAM_FLAG_TEST_SRC_IGMP(
-                                                    up->flags)))
+               if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src,
+                                            &grp, neigh_needed))
                        return PIM_RPF_FAILURE;
        }
 
@@ -263,7 +270,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct pim_rpf *old,
                 rpf->source_nexthop.mrib_route_metric);
                }
 
-               pim_upstream_update_join_desired(up);
+               pim_upstream_update_join_desired(pim, up);
                pim_upstream_update_could_assert(up);
                pim_upstream_update_my_assert_metric(up);
        }
@@ -400,7 +407,7 @@ unsigned int pim_rpf_hash_key(void *arg)
        return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0);
 }
 
-int pim_rpf_equal(const void *arg1, const void *arg2)
+bool pim_rpf_equal(const void *arg1, const void *arg2)
 {
        const struct pim_nexthop_cache *r1 =
                (const struct pim_nexthop_cache *)arg1;