From 651d0f713ef79c693b3e28a0aa591a394365a4de Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Fri, 17 Jun 2016 15:37:49 -0400 Subject: [PATCH] pim: Fix NOCACHE to use incoming interface When the kernel sends a NOCACHE message to pim we were looking up the interface to use for the incoming multicast packet based upon the source. No need to do that trust that the kernel has properly identified it and use that. Signed-off-by: Donald Sharp --- pimd/pim_cmd.c | 4 +-- pimd/pim_ifchannel.c | 2 +- pimd/pim_mroute.c | 2 +- pimd/pim_rp.c | 2 +- pimd/pim_rpf.c | 81 +++++++++++++++++++++++++------------------- pimd/pim_rpf.h | 5 +-- pimd/pim_upstream.c | 10 +++--- pimd/pim_upstream.h | 3 +- pimd/pim_zebra.c | 2 +- 9 files changed, 63 insertions(+), 48 deletions(-) diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 2132b2742b..3b0a8b3d5f 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2404,7 +2404,7 @@ DEFUN (show_ip_rib, return CMD_WARNING; } - if (pim_nexthop_lookup(&nexthop, addr)) { + if (pim_nexthop_lookup(&nexthop, addr, NULL)) { vty_out(vty, "Failure querying RIB nexthop for unicast address %s%s", addr_str, VTY_NEWLINE); return CMD_WARNING; @@ -2496,7 +2496,7 @@ DEFUN (ip_pim_rp, return CMD_WARNING; } - if (pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr) != 0) { + if (pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr, NULL) != 0) { vty_out(vty, "%% No Path to RP address specified: %s", argv[0]); return CMD_WARNING; } diff --git a/pimd/pim_ifchannel.c b/pimd/pim_ifchannel.c index ad97879d6d..5271d412d1 100644 --- a/pimd/pim_ifchannel.c +++ b/pimd/pim_ifchannel.c @@ -192,7 +192,7 @@ static struct pim_ifchannel *pim_ifchannel_new(struct interface *ifp, pim_ifp = ifp->info; zassert(pim_ifp); - up = pim_upstream_add(source_addr, group_addr); + up = pim_upstream_add(source_addr, group_addr, NULL); if (!up) { char src_str[100]; char grp_str[100]; diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c index cdce64ca5a..6f5fe480f2 100644 --- a/pimd/pim_mroute.c +++ b/pimd/pim_mroute.c @@ -96,7 +96,7 @@ pim_mroute_msg_nocache (int fd, struct interface *ifp, const struct igmpmsg *msg __PRETTY_FUNCTION__, grp_str, src_str); } - up = pim_upstream_add(msg->im_src, msg->im_dst); + up = pim_upstream_add(msg->im_src, msg->im_dst, ifp); if (!up) { if (PIM_DEBUG_PIM_TRACE) { zlog_debug("%s: Failure to add upstream information for (%s,%s)", diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index 6ba8482d4c..747f3d48e4 100644 --- a/pimd/pim_rp.c +++ b/pimd/pim_rp.c @@ -86,7 +86,7 @@ pim_rp_g (struct in_addr group) /* * For staticly configured RP, it is always the qpim_rp */ - pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr); + pim_nexthop_lookup(&qpim_rp.source_nexthop, qpim_rp.rpf_addr, NULL); return(&qpim_rp); } diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c index 1838118168..354fd664c0 100644 --- a/pimd/pim_rpf.c +++ b/pimd/pim_rpf.c @@ -37,45 +37,55 @@ 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) + struct in_addr addr, struct interface *incoming) { struct pim_zlookup_nexthop nexthop_tab[PIM_NEXTHOP_IFINDEX_TAB_SIZE]; int num_ifindex; struct interface *ifp; int first_ifindex; - num_ifindex = zclient_lookup_nexthop(qpim_zclient_lookup, nexthop_tab, - PIM_NEXTHOP_IFINDEX_TAB_SIZE, - addr, PIM_NEXTHOP_LOOKUP_MAX); - if (num_ifindex < 1) { - char addr_str[100]; - pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); - zlog_warn("%s %s: could not find nexthop ifindex for address %s", - __FILE__, __PRETTY_FUNCTION__, - addr_str); - return -1; - } - - first_ifindex = nexthop_tab[0].ifindex; - - if (num_ifindex > 1) { - char addr_str[100]; - pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); - zlog_info("%s %s: FIXME 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; - } + memset (nexthop_tab, 0, sizeof (struct pim_zlookup_nexthop) * PIM_NEXTHOP_IFINDEX_TAB_SIZE); + + if (!incoming) + { + num_ifindex = zclient_lookup_nexthop(qpim_zclient_lookup, nexthop_tab, + PIM_NEXTHOP_IFINDEX_TAB_SIZE, + addr, PIM_NEXTHOP_LOOKUP_MAX); + if (num_ifindex < 1) { + char addr_str[100]; + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_warn("%s %s: could not find nexthop ifindex for address %s", + __FILE__, __PRETTY_FUNCTION__, + addr_str); + return -1; + } + + first_ifindex = nexthop_tab[0].ifindex; + + if (num_ifindex > 1) { + char addr_str[100]; + pim_inet4_dump("", addr, addr_str, sizeof(addr_str)); + zlog_info("%s %s: FIXME 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; + } + } + else + { + ifp = incoming; + first_ifindex = ifp->ifindex; + } if (!ifp->info) { char addr_str[100]; @@ -121,7 +131,8 @@ static int nexthop_mismatch(const struct pim_nexthop *nh1, } enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, - struct in_addr *old_rpf_addr) + struct in_addr *old_rpf_addr, + struct interface *incoming) { struct in_addr save_rpf_addr; struct pim_nexthop save_nexthop; @@ -131,7 +142,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, save_rpf_addr = rpf->rpf_addr; /* detect change in RPF'(S,G) */ if (pim_nexthop_lookup(&rpf->source_nexthop, - up->upstream_addr)) { + up->upstream_addr, incoming)) { return PIM_RPF_FAILURE; } diff --git a/pimd/pim_rpf.h b/pimd/pim_rpf.h index 078e89f3ea..72cc7ba215 100644 --- a/pimd/pim_rpf.h +++ b/pimd/pim_rpf.h @@ -29,8 +29,9 @@ #include "pim_neighbor.h" int pim_nexthop_lookup(struct pim_nexthop *nexthop, - struct in_addr addr); + struct in_addr addr, struct interface *incoming); enum pim_rpf_result pim_rpf_update(struct pim_upstream *up, - struct in_addr *old_rpf_addr); + struct in_addr *old_rpf_addr, + struct interface *incoming); #endif /* PIM_RPF_H */ diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c index ff69069951..cb2619abb7 100644 --- a/pimd/pim_upstream.c +++ b/pimd/pim_upstream.c @@ -350,7 +350,8 @@ static void pim_upstream_switch(struct pim_upstream *up, static struct pim_upstream *pim_upstream_new(struct in_addr source_addr, - struct in_addr group_addr) + struct in_addr group_addr, + struct interface *incoming) { struct pim_upstream *up; enum pim_rpf_result rpf_result; @@ -388,7 +389,7 @@ static struct pim_upstream *pim_upstream_new(struct in_addr source_addr, up->rpf.source_nexthop.mrib_route_metric = qpim_infinite_assert_metric.route_metric; up->rpf.rpf_addr.s_addr = PIM_NET_INADDR_ANY; - rpf_result = pim_rpf_update(up, 0); + rpf_result = pim_rpf_update(up, 0, incoming); if (rpf_result == PIM_RPF_FAILURE) { XFREE(MTYPE_PIM_UPSTREAM, up); return NULL; @@ -418,7 +419,8 @@ struct pim_upstream *pim_upstream_find(struct in_addr source_addr, } struct pim_upstream *pim_upstream_add(struct in_addr source_addr, - struct in_addr group_addr) + struct in_addr group_addr, + struct interface *incoming) { struct pim_upstream *up; @@ -427,7 +429,7 @@ struct pim_upstream *pim_upstream_add(struct in_addr source_addr, ++up->ref_count; } else { - up = pim_upstream_new(source_addr, group_addr); + up = pim_upstream_new(source_addr, group_addr, incoming); } return up; diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h index c296bc9a25..ea44707c54 100644 --- a/pimd/pim_upstream.h +++ b/pimd/pim_upstream.h @@ -115,7 +115,8 @@ void pim_upstream_delete(struct pim_upstream *up); struct pim_upstream *pim_upstream_find(struct in_addr source_addr, struct in_addr group_addr); struct pim_upstream *pim_upstream_add(struct in_addr source_addr, - struct in_addr group_addr); + struct in_addr group_addr, + struct interface *ifp); void pim_upstream_del(struct pim_upstream *up); int pim_upstream_evaluate_join_desired(struct pim_upstream *up); diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c index c48629f05a..f4f1b47263 100644 --- a/pimd/pim_zebra.c +++ b/pimd/pim_zebra.c @@ -333,7 +333,7 @@ static void scan_upstream_rpf_cache() struct in_addr old_rpf_addr; enum pim_rpf_result rpf_result; - rpf_result = pim_rpf_update(up, &old_rpf_addr); + rpf_result = pim_rpf_update(up, &old_rpf_addr, NULL); if (rpf_result == PIM_RPF_FAILURE) continue; -- 2.39.5