pim6d: IPv6-adjust RPF lookups

Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
David Lamparter 2022-01-18 11:54:36 +01:00
parent 101b31041a
commit 00b1f412a1
6 changed files with 37 additions and 51 deletions

View file

@ -109,6 +109,7 @@ pim_jp_agg_get_interface_upstream_switch_list(struct pim_rpf *rpf)
struct pim_interface *pim_ifp; struct pim_interface *pim_ifp;
struct pim_iface_upstream_switch *pius; struct pim_iface_upstream_switch *pius;
struct listnode *node, *nnode; struct listnode *node, *nnode;
pim_addr rpf_addr;
if (!ifp) if (!ifp)
return NULL; return NULL;
@ -119,16 +120,18 @@ pim_jp_agg_get_interface_upstream_switch_list(struct pim_rpf *rpf)
if (!pim_ifp) if (!pim_ifp)
return NULL; return NULL;
rpf_addr = pim_addr_from_prefix(&rpf->rpf_addr);
for (ALL_LIST_ELEMENTS(pim_ifp->upstream_switch_list, node, nnode, for (ALL_LIST_ELEMENTS(pim_ifp->upstream_switch_list, node, nnode,
pius)) { pius)) {
if (pius->address.s_addr == rpf->rpf_addr.u.prefix4.s_addr) if (!pim_addr_cmp(pius->address, rpf_addr))
break; break;
} }
if (!pius) { if (!pius) {
pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP, pius = XCALLOC(MTYPE_PIM_JP_AGG_GROUP,
sizeof(struct pim_iface_upstream_switch)); sizeof(struct pim_iface_upstream_switch));
pius->address.s_addr = rpf->rpf_addr.u.prefix4.s_addr; pius->address = rpf_addr;
pius->us = list_new(); pius->us = list_new();
listnode_add_sort(pim_ifp->upstream_switch_list, pius); listnode_add_sort(pim_ifp->upstream_switch_list, pius);
} }

View file

@ -39,7 +39,7 @@
#include "pim_oil.h" #include "pim_oil.h"
#include "pim_mlag.h" #include "pim_mlag.h"
static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up); static pim_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
void pim_rpf_set_refresh_time(struct pim_instance *pim) void pim_rpf_set_refresh_time(struct pim_instance *pim)
{ {
@ -51,7 +51,7 @@ void pim_rpf_set_refresh_time(struct pim_instance *pim)
} }
bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop, bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
struct in_addr addr, int neighbor_needed) pim_addr addr, int neighbor_needed)
{ {
struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM]; struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
struct pim_neighbor *nbr = NULL; struct pim_neighbor *nbr = NULL;
@ -61,6 +61,7 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
int found = 0; int found = 0;
int i = 0; int i = 0;
#if PIM_IPV == 4
/* /*
* We should not attempt to lookup a * We should not attempt to lookup a
* 255.255.255.255 address, since * 255.255.255.255 address, since
@ -68,45 +69,37 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
*/ */
if (addr.s_addr == INADDR_NONE) if (addr.s_addr == INADDR_NONE)
return false; return false;
#endif
if ((nexthop->last_lookup.s_addr == addr.s_addr) if (!pim_addr_cmp(nexthop->last_lookup, addr)
&& (nexthop->last_lookup_time > pim->last_route_change_time)) { && (nexthop->last_lookup_time > pim->last_route_change_time)) {
if (PIM_DEBUG_PIM_NHT) { if (PIM_DEBUG_PIM_NHT) {
char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str,
sizeof(addr_str));
char nexthop_str[PREFIX_STRLEN]; char nexthop_str[PREFIX_STRLEN];
pim_addr_dump("<nexthop?>", &nexthop->mrib_nexthop_addr, pim_addr_dump("<nexthop?>", &nexthop->mrib_nexthop_addr,
nexthop_str, sizeof(nexthop_str)); nexthop_str, sizeof(nexthop_str));
zlog_debug( zlog_debug(
"%s: Using last lookup for %s at %lld, %" PRId64" addr %s", "%s: Using last lookup for %pPAs at %lld, %" PRId64" addr %s",
__func__, addr_str, nexthop->last_lookup_time, __func__, &addr, nexthop->last_lookup_time,
pim->last_route_change_time, nexthop_str); pim->last_route_change_time, nexthop_str);
} }
pim->nexthop_lookups_avoided++; pim->nexthop_lookups_avoided++;
return true; return true;
} else { } else {
if (PIM_DEBUG_PIM_NHT) { if (PIM_DEBUG_PIM_NHT)
char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str,
sizeof(addr_str));
zlog_debug( zlog_debug(
"%s: Looking up: %s, last lookup time: %lld, %" PRId64, "%s: Looking up: %pPAs, last lookup time: %lld, %" PRId64,
__func__, addr_str, nexthop->last_lookup_time, __func__, &addr, nexthop->last_lookup_time,
pim->last_route_change_time); pim->last_route_change_time);
} }
}
memset(nexthop_tab, 0, memset(nexthop_tab, 0,
sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM); sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM, num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
addr, PIM_NEXTHOP_LOOKUP_MAX); addr, PIM_NEXTHOP_LOOKUP_MAX);
if (num_ifindex < 1) { if (num_ifindex < 1) {
char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str, sizeof(addr_str));
zlog_warn( zlog_warn(
"%s %s: could not find nexthop ifindex for address %s", "%s %s: could not find nexthop ifindex for address %pPAs",
__FILE__, __func__, addr_str); __FILE__, __func__, &addr);
return false; return false;
} }
@ -115,29 +108,21 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id); ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id);
if (!ifp) { if (!ifp) {
if (PIM_DEBUG_ZEBRA) { if (PIM_DEBUG_ZEBRA)
char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str,
sizeof(addr_str));
zlog_debug( zlog_debug(
"%s %s: could not find interface for ifindex %d (address %s)", "%s %s: could not find interface for ifindex %d (address %pPAs)",
__FILE__, __func__, first_ifindex, __FILE__, __func__, first_ifindex,
addr_str); &addr);
}
i++; i++;
continue; continue;
} }
if (!ifp->info) { if (!ifp->info) {
if (PIM_DEBUG_ZEBRA) { if (PIM_DEBUG_ZEBRA)
char addr_str[INET_ADDRSTRLEN];
pim_inet4_dump("<addr?>", addr, addr_str,
sizeof(addr_str));
zlog_debug( zlog_debug(
"%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %s)", "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %pPAs)",
__func__, ifp->name, first_ifindex, __func__, ifp->name, first_ifindex,
addr_str); &addr);
}
i++; i++;
} else if (neighbor_needed } else if (neighbor_needed
&& !pim_if_connected_to_source(ifp, addr)) { && !pim_if_connected_to_source(ifp, addr)) {
@ -157,15 +142,12 @@ bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
if (found) { if (found) {
if (PIM_DEBUG_ZEBRA) { if (PIM_DEBUG_ZEBRA) {
char nexthop_str[PREFIX_STRLEN]; char nexthop_str[PREFIX_STRLEN];
char addr_str[INET_ADDRSTRLEN];
pim_addr_dump("<nexthop?>", pim_addr_dump("<nexthop?>",
&nexthop_tab[i].nexthop_addr, nexthop_str, &nexthop_tab[i].nexthop_addr, nexthop_str,
sizeof(nexthop_str)); sizeof(nexthop_str));
pim_inet4_dump("<addr?>", addr, addr_str,
sizeof(addr_str));
zlog_debug( zlog_debug(
"%s %s: found nexthop %s for address %s: interface %s ifindex=%d metric=%d pref=%d", "%s %s: found nexthop %s for address %pPAs: interface %s ifindex=%d metric=%d pref=%d",
__FILE__, __func__, nexthop_str, addr_str, __FILE__, __func__, nexthop_str, &addr,
ifp->name, first_ifindex, ifp->name, first_ifindex,
nexthop_tab[i].route_metric, nexthop_tab[i].route_metric,
nexthop_tab[i].protocol_distance); nexthop_tab[i].protocol_distance);
@ -230,6 +212,7 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
struct prefix src, grp; struct prefix src, grp;
bool neigh_needed = true; bool neigh_needed = true;
uint32_t saved_mrib_route_metric; uint32_t saved_mrib_route_metric;
pim_addr rpf_addr;
if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags)) if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags))
return PIM_RPF_OK; return PIM_RPF_OK;
@ -265,8 +248,9 @@ enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
return PIM_RPF_FAILURE; return PIM_RPF_FAILURE;
} }
rpf->rpf_addr.family = AF_INET; rpf_addr = pim_rpf_find_rpf_addr(up);
rpf->rpf_addr.u.prefix4 = pim_rpf_find_rpf_addr(up); pim_addr_to_prefix(&rpf->rpf_addr, rpf_addr);
if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA) { if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA) {
/* RPF'(S,G) not found */ /* RPF'(S,G) not found */
zlog_debug("%s(%s): RPF'%s not found: won't send join upstream", zlog_debug("%s(%s): RPF'%s not found: won't send join upstream",
@ -369,18 +353,17 @@ void pim_upstream_rpf_clear(struct pim_instance *pim,
packets should be coming and to which joins should be sent on the RP packets should be coming and to which joins should be sent on the RP
tree and SPT, respectively. tree and SPT, respectively.
*/ */
static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up) static pim_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
{ {
struct pim_ifchannel *rpf_ch; struct pim_ifchannel *rpf_ch;
struct pim_neighbor *neigh; struct pim_neighbor *neigh;
struct in_addr rpf_addr; pim_addr rpf_addr;
if (!up->rpf.source_nexthop.interface) { if (!up->rpf.source_nexthop.interface) {
zlog_warn("%s: missing RPF interface for upstream (S,G)=%s", zlog_warn("%s: missing RPF interface for upstream (S,G)=%s",
__func__, up->sg_str); __func__, up->sg_str);
rpf_addr.s_addr = PIM_NET_INADDR_ANY; return PIMADDR_ANY;
return rpf_addr;
} }
rpf_ch = pim_ifchannel_find(up->rpf.source_nexthop.interface, &up->sg); rpf_ch = pim_ifchannel_find(up->rpf.source_nexthop.interface, &up->sg);
@ -400,7 +383,7 @@ static struct in_addr pim_rpf_find_rpf_addr(struct pim_upstream *up)
if (neigh) if (neigh)
rpf_addr = neigh->source_addr; rpf_addr = neigh->source_addr;
else else
rpf_addr.s_addr = PIM_NET_INADDR_ANY; rpf_addr = PIMADDR_ANY;
return rpf_addr; return rpf_addr;
} }

View file

@ -58,7 +58,7 @@ unsigned int pim_rpf_hash_key(const void *arg);
bool pim_rpf_equal(const void *arg1, const void *arg2); bool pim_rpf_equal(const void *arg1, const void *arg2);
bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop, bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
struct in_addr addr, int neighbor_needed); pim_addr addr, int neighbor_needed);
enum pim_rpf_result pim_rpf_update(struct pim_instance *pim, enum pim_rpf_result pim_rpf_update(struct pim_instance *pim,
struct pim_upstream *up, struct pim_upstream *up,
struct pim_rpf *old, const char *caller); struct pim_rpf *old, const char *caller);

View file

@ -242,7 +242,7 @@ void pim_zebra_update_all_interfaces(struct pim_instance *pim)
struct pim_rpf rpf; struct pim_rpf rpf;
rpf.source_nexthop.interface = ifp; rpf.source_nexthop.interface = ifp;
rpf.rpf_addr.u.prefix4 = us->address; pim_addr_to_prefix(&rpf.rpf_addr, us->address);
pim_joinprune_send(&rpf, us->us); pim_joinprune_send(&rpf, us->us);
pim_jp_agg_clear_group(us->us); pim_jp_agg_clear_group(us->us);
} }

View file

@ -397,7 +397,7 @@ int zclient_lookup_read_pipe(struct thread *thread)
int zclient_lookup_nexthop(struct pim_instance *pim, int zclient_lookup_nexthop(struct pim_instance *pim,
struct pim_zlookup_nexthop nexthop_tab[], struct pim_zlookup_nexthop nexthop_tab[],
const int tab_size, struct in_addr addr, const int tab_size, pim_addr addr,
int max_lookup) int max_lookup)
{ {
int lookup; int lookup;

View file

@ -39,7 +39,7 @@ void zclient_lookup_free(void);
int zclient_lookup_nexthop(struct pim_instance *pim, int zclient_lookup_nexthop(struct pim_instance *pim,
struct pim_zlookup_nexthop nexthop_tab[], struct pim_zlookup_nexthop nexthop_tab[],
const int tab_size, struct in_addr addr, const int tab_size, pim_addr addr,
int max_lookup); int max_lookup);
void pim_zlookup_show_ip_multicast(struct vty *vty); void pim_zlookup_show_ip_multicast(struct vty *vty);