diff options
Diffstat (limited to 'pimd/pim_nht.c')
| -rw-r--r-- | pimd/pim_nht.c | 96 |
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, |
