summaryrefslogtreecommitdiff
path: root/pimd/pim_nht.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_nht.c')
-rw-r--r--pimd/pim_nht.c96
1 files changed, 53 insertions, 43 deletions
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 5f0f2a5933..32cdf4bf82 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -31,6 +31,8 @@
#include "pim_zlookup.h"
#include "pim_rp.h"
#include "pim_addr.h"
+#include "pim_register.h"
+#include "pim_vxlan.h"
/**
* pim_sendmsg_zebra_rnh -- Format and send a nexthop register/Unregister
@@ -336,7 +338,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
- /* fallthru */
+ fallthrough;
case NEXTHOP_TYPE_IPV4_IFINDEX:
nhaddr = nh->gate.ipv4;
break;
@@ -348,7 +350,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
- /* fallthru */
+ fallthrough;
case NEXTHOP_TYPE_IPV6_IFINDEX:
nhaddr = nh->gate.ipv6;
break;
@@ -399,17 +401,28 @@ static void pim_update_rp_nh(struct pim_instance *pim,
{
struct listnode *node = NULL;
struct rp_info *rp_info = NULL;
+ struct interface *ifp;
/*Traverse RP list and update each RP Nexthop info */
for (ALL_LIST_ELEMENTS_RO(pnc->rp_list, node, rp_info)) {
if (pim_rpf_addr_is_inaddr_any(&rp_info->rp))
continue;
+ ifp = rp_info->rp.source_nexthop.interface;
// Compute PIM RPF using cached nexthop
if (!pim_ecmp_nexthop_lookup(pim, &rp_info->rp.source_nexthop,
rp_info->rp.rpf_addr,
&rp_info->group, 1))
pim_rp_nexthop_del(rp_info);
+
+ /*
+ * If we transition from no path to a path
+ * we need to search through all the vxlan's
+ * that use this rp and send NULL registers
+ * for all the vxlan S,G streams
+ */
+ if (!ifp && rp_info->rp.source_nexthop.interface)
+ pim_vxlan_rp_info_is_alive(pim, &rp_info->rp);
}
}
@@ -436,17 +449,27 @@ static int pim_update_upstream_nh_helper(struct hash_bucket *bucket, void *arg)
(rpf_result == PIM_RPF_FAILURE && old.source_nexthop.interface))
pim_zebra_upstream_rpf_changed(pim, up, &old);
+ /*
+ * If we are a VXLAN source and we are transitioning from not
+ * having an outgoing interface to having an outgoing interface
+ * let's immediately send the null pim register
+ */
+ if (!old.source_nexthop.interface && up->rpf.source_nexthop.interface &&
+ PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(up->flags) &&
+ (up->reg_state == PIM_REG_NOINFO || up->reg_state == PIM_REG_JOIN)) {
+ pim_null_register_send(up);
+ }
if (PIM_DEBUG_PIM_NHT) {
- zlog_debug(
- "%s: NHT upstream %s(%s) old ifp %s new ifp %s",
- __func__, up->sg_str, pim->vrf->name,
- old.source_nexthop.interface ? old.source_nexthop
- .interface->name
- : "Unknown",
- up->rpf.source_nexthop.interface ? up->rpf.source_nexthop
- .interface->name
- : "Unknown");
+ zlog_debug("%s: NHT upstream %s(%s) old ifp %s new ifp %s rpf_result: %d",
+ __func__, up->sg_str, pim->vrf->name,
+ old.source_nexthop.interface ? old.source_nexthop
+ .interface->name
+ : "Unknown",
+ up->rpf.source_nexthop.interface ? up->rpf.source_nexthop
+ .interface->name
+ : "Unknown",
+ rpf_result);
}
return HASHWALK_CONTINUE;
@@ -700,7 +723,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
/* This API is used to parse Registered address nexthop update coming from Zebra
*/
-int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
+void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
+ struct zapi_route *nhr)
{
struct nexthop *nexthop;
struct nexthop *nhlist_head = NULL;
@@ -709,38 +733,27 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
struct pim_rpf rpf;
struct pim_nexthop_cache *pnc = NULL;
struct interface *ifp = NULL;
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct pim_instance *pim;
- struct zapi_route nhr;
- struct prefix match;
- if (!vrf)
- return 0;
pim = vrf->info;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &nhr)) {
- zlog_err("%s: Decode of nexthop update from zebra failed",
- __func__);
- return 0;
- }
-
- rpf.rpf_addr = pim_addr_from_prefix(&match);
+ rpf.rpf_addr = pim_addr_from_prefix(match);
pnc = pim_nexthop_cache_find(pim, &rpf);
if (!pnc) {
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: Skipping NHT update, addr %pPA is not in local cached DB.",
__func__, &rpf.rpf_addr);
- return 0;
+ return;
}
pnc->last_update = pim_time_monotonic_usec();
- if (nhr.nexthop_num) {
+ if (nhr->nexthop_num) {
pnc->nexthop_num = 0;
- for (i = 0; i < nhr.nexthop_num; i++) {
- nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]);
+ for (i = 0; i < nhr->nexthop_num; i++) {
+ nexthop = nexthop_from_zapi_nexthop(&nhr->nexthops[i]);
switch (nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
/*
@@ -819,11 +832,11 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
#else
pim_addr nhaddr = nexthop->gate.ipv6;
#endif
- zlog_debug(
- "%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ",
- __func__, &match, pim->vrf->name, i + 1,
- &nhaddr, ifp->name, nexthop->type,
- nhr.distance, nhr.metric);
+ zlog_debug("%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ",
+ __func__, match, pim->vrf->name,
+ i + 1, &nhaddr, ifp->name,
+ nexthop->type, nhr->distance,
+ nhr->metric);
}
if (!ifp->info) {
@@ -864,23 +877,22 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pnc->nexthop = nhlist_head;
if (pnc->nexthop_num) {
pnc->flags |= PIM_NEXTHOP_VALID;
- pnc->distance = nhr.distance;
- pnc->metric = nhr.metric;
+ pnc->distance = nhr->distance;
+ pnc->metric = nhr->metric;
}
} else {
pnc->flags &= ~PIM_NEXTHOP_VALID;
- pnc->nexthop_num = nhr.nexthop_num;
+ pnc->nexthop_num = nhr->nexthop_num;
nexthops_free(pnc->nexthop);
pnc->nexthop = NULL;
}
SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED);
if (PIM_DEBUG_PIM_NHT)
- zlog_debug(
- "%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
- __func__, &match, pim->vrf->name, nhr.nexthop_num,
- pnc->nexthop_num, vrf_id, pnc->upstream_hash->count,
- listcount(pnc->rp_list));
+ zlog_debug("%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
+ __func__, match, pim->vrf->name, nhr->nexthop_num,
+ pnc->nexthop_num, vrf->vrf_id,
+ pnc->upstream_hash->count, listcount(pnc->rp_list));
pim_rpf_set_refresh_time(pim);
@@ -888,8 +900,6 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pim_update_rp_nh(pim, pnc);
if (pnc->upstream_hash->count)
pim_update_upstream_nh(pim, pnc);
-
- return 0;
}
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,