From 63b8f7a35e2a374081d563235cd617690339b425 Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Thu, 15 Sep 2016 14:18:28 +0000 Subject: [PATCH] pimd: Rework approach for needing nbrs Pim sometimes needs the upstream rpf lookup to only take into account if we have a nbr out the selected interface or not. Move the code for this to a better spot so we can make a more intelligent decision here. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 2 +- pimd/pim_mroute.c | 2 +- pimd/pim_register.c | 13 +++-- pimd/pim_rp.c | 4 +- pimd/pim_rpf.c | 121 +++++++++++++++++++++++++------------------- pimd/pim_rpf.h | 2 +- pimd/pim_zlookup.c | 22 -------- 7 files changed, 85 insertions(+), 81 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index a3ff7c25ed..76d42f3614 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2713,7 +2713,7 @@ DEFUN (show_ip_rib, return CMD_WARNING; } - if (pim_nexthop_lookup(&nexthop, addr)) { + if (pim_nexthop_lookup(&nexthop, addr, 0)) { vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s", addr_str, VTY_NEWLINE); return CMD_WARNING; diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index 1f64a6e299..dd3ae3117d 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -345,7 +345,7 @@ pim_mroute_msg_wrvifwhole (int fd, struct interface *ifp, const char *buf) pim_ifp = rpf->source_nexthop.interface->info; //No if channel, but upstream we are at the RP. - pim_nexthop_lookup (&source, up->upstream_register); + pim_nexthop_lookup (&source, up->upstream_register, 1); pim_register_stop_send(source.interface, &sg, pim_ifp->primary_address, up->upstream_register); if (!up->channel_oil) up->channel_oil = pim_channel_oil_add (&sg, pim_ifp->mroute_vif_index); diff --git a/pimd/pim_register.c b/pimd/pim_register.c index ebc46f60ea..f8144557c8 100644 --- a/pimd/pim_register.c +++ b/pimd/pim_register.c @@ -162,9 +162,16 @@ pim_register_send (const uint8_t *buf, int buf_size, struct in_addr src, struct } ifp = rpg->source_nexthop.interface; + if (!ifp) + { + if (PIM_DEBUG_PIM_REG) + zlog_debug ("%s: No interface to transmit register on", __PRETTY_FUNCTION__); + return; + } pinfo = (struct pim_interface *)ifp->info; if (!pinfo) { - zlog_debug("%s: No pinfo!\n", __PRETTY_FUNCTION__); + if (PIM_DEBUG_PIM_REG) + zlog_debug("%s: Interface: %s not configured for pim to trasmit on!\n", __PRETTY_FUNCTION__, ifp->name); return; } @@ -327,13 +334,13 @@ pim_register_recv (struct interface *ifp, upstream = pim_upstream_add (&sg, ifp); if (!upstream) { - zlog_warn ("Failure to crate upstream state"); + zlog_warn ("Failure to create upstream state"); return 1; } upstream->upstream_register = src_addr; pim_rp_set_upstream_addr (&upstream->upstream_addr, sg.src, sg.grp); pim_nexthop_lookup (&upstream->rpf.source_nexthop, - upstream->upstream_addr); + upstream->upstream_addr, 1); upstream->sg.src = sg.src; upstream->rpf.rpf_addr = upstream->rpf.source_nexthop.mrib_nexthop_addr; diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index ae2ce6e476..b5c5ad55b9 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -487,7 +487,7 @@ pim_rp_setup (void) for (ALL_LIST_ELEMENTS_RO (qpim_rp_list, node, rp_info)) { - if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4) != 0) + if (pim_nexthop_lookup (&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1) != 0) { zlog_err ("Unable to lookup nexthop for rp specified"); ret++; @@ -583,7 +583,7 @@ pim_rp_g (struct in_addr group) if (rp_info) { - pim_nexthop_lookup(&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4); + pim_nexthop_lookup(&rp_info->rp.source_nexthop, rp_info->rp.rpf_addr.u.prefix4, 1); return (&rp_info->rp); } diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 2e93162694..44acde0c9e 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -37,15 +37,16 @@ static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up); -int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr) +int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed) { struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM]; int num_ifindex; struct interface *ifp; int first_ifindex; + int found = 0; + int i = 0; 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); @@ -58,56 +59,73 @@ int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr) return -1; } - first_ifindex = nexthop_tab[0].ifindex; - - if (num_ifindex > 1 && PIM_DEBUG_ZEBRA) { - char addr_str[100]; - pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); - zlog_debug("%s %s: Ignoring multiple nexthop ifindex'es num_ifindex=%d for address %s (using only ifindex=%d)", - __FILE__, __PRETTY_FUNCTION__, - num_ifindex, addr_str, first_ifindex); - /* debug warning only, do not return */ - } - - ifp = if_lookup_by_index(first_ifindex); - if (!ifp) { - char addr_str[100]; - pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); - zlog_warn("%s %s: could not find interface for ifindex %d (address %s)", - __FILE__, __PRETTY_FUNCTION__, - first_ifindex, addr_str); - return -2; - } - - if (!ifp->info) { - char addr_str[100]; - pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); - zlog_warn("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)", - __PRETTY_FUNCTION__, - ifp->name, first_ifindex, addr_str); - /* debug warning only, do not return */ - } - - if (PIM_DEBUG_ZEBRA) { - char nexthop_str[100]; - char addr_str[100]; - pim_addr_dump("", &nexthop_tab[0].nexthop_addr, nexthop_str, sizeof(nexthop_str)); - pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); - zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d", - __FILE__, __PRETTY_FUNCTION__, - nexthop_str, addr_str, - ifp->name, first_ifindex, - nexthop_tab[0].route_metric, - nexthop_tab[0].protocol_distance); - } + while (!found) + { + first_ifindex = nexthop_tab[i].ifindex; + + ifp = if_lookup_by_index(first_ifindex); + if (!ifp) + { + if (PIM_DEBUG_ZEBRA) + { + char addr_str[100]; + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_debug("%s %s: could not find interface for ifindex %d (address %s)", + __FILE__, __PRETTY_FUNCTION__, + first_ifindex, addr_str); + } + return -2; + } + + if (!ifp->info && PIM_DEBUG_ZEBRA) + { + char addr_str[100]; + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_debug("%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)", + __PRETTY_FUNCTION__, + ifp->name, first_ifindex, addr_str); + } + + if (neighbor_needed) + { + struct pim_neighbor *nbr; + + nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4); + if (PIM_DEBUG_ZEBRA) + zlog_debug ("ifp name: %s, pim nbr: %p", ifp->name, nbr); + if (!nbr && !if_is_loopback (ifp)) + i++; + else + found = 1; + } + else + found = 1; + } - /* update nextop data */ - nexthop->interface = ifp; - nexthop->mrib_nexthop_addr = nexthop_tab[0].nexthop_addr; - nexthop->mrib_metric_preference = nexthop_tab[0].protocol_distance; - nexthop->mrib_route_metric = nexthop_tab[0].route_metric; + if (found) + { + if (PIM_DEBUG_ZEBRA) { + char nexthop_str[100]; + char addr_str[100]; + pim_addr_dump("", &nexthop_tab[0].nexthop_addr, nexthop_str, sizeof(nexthop_str)); + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_debug("%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d", + __FILE__, __PRETTY_FUNCTION__, + nexthop_str, addr_str, + ifp->name, first_ifindex, + nexthop_tab[0].route_metric, + nexthop_tab[0].protocol_distance); + } + /* update nextop data */ + nexthop->interface = ifp; + nexthop->mrib_nexthop_addr = nexthop_tab[0].nexthop_addr; + nexthop->mrib_metric_preference = nexthop_tab[0].protocol_distance; + nexthop->mrib_route_metric = nexthop_tab[0].route_metric; - return 0; + return 0; + } + else + return -1; } static int nexthop_mismatch(const struct pim_nexthop *nh1, @@ -128,7 +146,8 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_ save_nexthop = rpf->source_nexthop; /* detect change in pim_nexthop */ save_rpf_addr = rpf->rpf_addr; /* detect change in RPF'(S,G) */ - if (pim_nexthop_lookup(&rpf->source_nexthop, up->upstream_addr)) { + if (pim_nexthop_lookup(&rpf->source_nexthop, + up->upstream_addr, !PIM_UPSTREAM_FLAG_TEST_FHR (up->flags))) { return PIM_RPF_FAILURE; } diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h index fddc74a725..b93c934116 100644 --- a/pimd/pim_rpf.h +++ b/pimd/pim_rpf.h @@ -59,7 +59,7 @@ enum pim_rpf_result { struct pim_upstream; -int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr); +int pim_nexthop_lookup(struct pim_nexthop *nexthop, struct in_addr addr, int neighbor_needed); enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, struct in_addr *old_rpf_addr); int pim_rpf_addr_is_inaddr_none (struct pim_rpf *rpf); diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c index 636552abd7..bee9c63e96 100644 --- a/pimd/pim_zlookup.c +++ b/pimd/pim_zlookup.c @@ -332,7 +332,6 @@ zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[], int lookup; uint32_t route_metric = 0xFFFFFFFF; uint8_t protocol_distance = 0xFF; - int i; qpim_nexthop_lookups++; @@ -394,27 +393,6 @@ zclient_lookup_nexthop (struct pim_zlookup_nexthop nexthop_tab[], nexthop_tab[0].protocol_distance = protocol_distance; } - /* - * Let's see if any of the nexthops can actually be used. - * We need to check them against the neighbors that we - * have formed. As that we shouldn't be sending - * j/p messages upstream towards non-neighbors - */ - for (i = 0; i < num_ifindex ; i++) - { - struct interface *ifp; - struct pim_neighbor *nbr; - - ifp = if_lookup_by_index_vrf (nexthop_tab[i].ifindex, VRF_DEFAULT); - nbr = pim_neighbor_find (ifp, nexthop_tab[i].nexthop_addr.u.prefix4); - if (ifp->info && !nbr && !if_is_loopback (ifp)) - { - num_ifindex--; - if (i != num_ifindex) - memcpy (&nexthop_tab[i], &nexthop_tab[i+1], sizeof (nexthop_tab[i])); - i--; - } - } return num_ifindex; } -- 2.39.5