]> git.puffer.fish Git - mirror/frr.git/commitdiff
pimd: Fix nexthop determination when sending towards RP 2347/head
authorMartin Buck <martin.buck@ruag.com>
Mon, 4 Jun 2018 13:52:14 +0000 (15:52 +0200)
committerMartin Buck <martin.buck@ruag.com>
Tue, 5 Jun 2018 07:58:33 +0000 (09:58 +0200)
When sending a PIM join upwards on the RP-based tree, it may get dropped on
the last hop before the RP if the RP is reachable via a connected route
(i.e. there's no associated nexthop). pimd needs to put the nexthop IP
address into the PIM join payload and fails to do that if that route has a
nexthop of 0.0.0.0. So whenever we look up a route to determine the nexthop
or we receive a nexthop tracking update from Zebra, use the destination
address as the nexthop address for connected routes.

Fixes #2326.

Signed-off-by: Martin Buck <mb-tmp-tvguho.pbz@gromit.dyndns.org>
pimd/pim_nht.c
pimd/pim_zlookup.c

index 94cb32bc23329fcc7d43931cf69406f94d2bcb73..e59428fa9e88180df71d7ba12504afac3f2b581c 100644 (file)
@@ -657,11 +657,20 @@ int pim_parse_nexthop_update(int command, struct zclient *zclient,
                        nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]);
                        switch (nexthop->type) {
                        case NEXTHOP_TYPE_IPV4:
-                       case NEXTHOP_TYPE_IFINDEX:
                        case NEXTHOP_TYPE_IPV4_IFINDEX:
                        case NEXTHOP_TYPE_IPV6:
                        case NEXTHOP_TYPE_BLACKHOLE:
                                break;
+                       case NEXTHOP_TYPE_IFINDEX:
+                               /*
+                                * Connected route (i.e. no nexthop), use
+                                * RPF address from nexthop cache (i.e.
+                                * destination) as PIM nexthop.
+                                */
+                               nexthop->type = NEXTHOP_TYPE_IPV4;
+                               nexthop->gate.ipv4 =
+                                       pnc->rpf.rpf_addr.u.prefix4;
+                               break;
                        case NEXTHOP_TYPE_IPV6_IFINDEX:
                                ifp1 = if_lookup_by_index(nexthop->ifindex,
                                                          pim->vrf_id);
index 37e2bfbbfd7d7eb5f39a39989791b13a8d29d08c..9295b231cb0236ac97cc7428f1d20c32b150d8d2 100644 (file)
@@ -217,22 +217,26 @@ static int zclient_read_nexthop(struct pim_instance *pim,
                }
                switch (nexthop_type) {
                case NEXTHOP_TYPE_IFINDEX:
+                       nexthop_tab[num_ifindex].ifindex = stream_getl(s);
+                       /*
+                        * Connected route (i.e. no nexthop), use
+                        * address passed in as PIM nexthop.  This will
+                        * allow us to work in cases where we are
+                        * trying to find a route for this box.
+                        */
+                       nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
+                       nexthop_tab[num_ifindex].nexthop_addr.prefixlen =
+                               IPV4_MAX_BITLEN;
+                       nexthop_tab[num_ifindex].nexthop_addr.u.prefix4 =
+                               addr;
+                       ++num_ifindex;
+                       break;
                case NEXTHOP_TYPE_IPV4_IFINDEX:
                case NEXTHOP_TYPE_IPV4:
                        nexthop_tab[num_ifindex].nexthop_addr.family = AF_INET;
-                       if (nexthop_type == NEXTHOP_TYPE_IPV4_IFINDEX
-                           || nexthop_type == NEXTHOP_TYPE_IPV4) {
-                               nexthop_tab[num_ifindex]
-                                       .nexthop_addr.u.prefix4.s_addr =
-                                       stream_get_ipv4(s);
-                       } else {
-                               nexthop_tab[num_ifindex]
-                                       .nexthop_addr.u.prefix4.s_addr =
-                                       PIM_NET_INADDR_ANY;
-                       }
+                       nexthop_tab[num_ifindex].nexthop_addr.u.prefix4.s_addr =
+                               stream_get_ipv4(s);
                        nexthop_tab[num_ifindex].ifindex = stream_getl(s);
-                       nexthop_tab[num_ifindex].protocol_distance = distance;
-                       nexthop_tab[num_ifindex].route_metric = metric;
                        ++num_ifindex;
                        break;
                case NEXTHOP_TYPE_IPV6_IFINDEX:
@@ -272,19 +276,13 @@ static int zclient_read_nexthop(struct pim_instance *pim,
                        }
                        ++num_ifindex;
                        break;
-               default:
-                       /* do nothing */
-                       {
-                               char addr_str[INET_ADDRSTRLEN];
-                               pim_inet4_dump("<addr?>", addr, addr_str,
-                                              sizeof(addr_str));
-                               zlog_warn(
-                                       "%s: found non-ifindex nexthop type=%d for address %s(%s)",
-                                       __PRETTY_FUNCTION__, nexthop_type,
-                                       addr_str, pim->vrf->name);
-                       }
-                       break;
+               case NEXTHOP_TYPE_IPV6:
+               case NEXTHOP_TYPE_BLACKHOLE:
+                       /* ignore */
+                       continue;
                }
+               nexthop_tab[num_ifindex].protocol_distance = distance;
+               nexthop_tab[num_ifindex].route_metric = metric;
        }
 
        return num_ifindex;