mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-07 09:22:03 +00:00
pimd: Handle rpf_addr in pim nht
Signed-off-by: sarita patra <saritap@vmware.com>
This commit is contained in:
parent
5d58abc161
commit
6288ebcf22
127
pimd/pim_nht.c
127
pimd/pim_nht.c
@ -52,11 +52,11 @@
|
|||||||
void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
|
void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
|
||||||
struct pim_nexthop_cache *pnc, int command)
|
struct pim_nexthop_cache *pnc, int command)
|
||||||
{
|
{
|
||||||
struct prefix *p;
|
struct prefix p;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
p = &(pnc->rpf.rpf_addr);
|
pim_addr_to_prefix(&p, pnc->rpf.rpf_addr);
|
||||||
ret = zclient_send_rnh(zclient, command, p, SAFI_UNICAST, false, false,
|
ret = zclient_send_rnh(zclient, command, &p, SAFI_UNICAST, false, false,
|
||||||
pim->vrf->vrf_id);
|
pim->vrf->vrf_id);
|
||||||
if (ret == ZCLIENT_SEND_FAILURE)
|
if (ret == ZCLIENT_SEND_FAILURE)
|
||||||
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
|
zlog_warn("sendmsg_nexthop: zclient_send_message() failed");
|
||||||
@ -65,7 +65,7 @@ void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: NHT %sregistered addr %pFX(%s) with Zebra ret:%d ",
|
"%s: NHT %sregistered addr %pFX(%s) with Zebra ret:%d ",
|
||||||
__func__,
|
__func__,
|
||||||
(command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", p,
|
(command == ZEBRA_NEXTHOP_REGISTER) ? " " : "de", &p,
|
||||||
pim->vrf->name, ret);
|
pim->vrf->name, ret);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -98,7 +98,7 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
|
|||||||
pnc->rp_list = list_new();
|
pnc->rp_list = list_new();
|
||||||
pnc->rp_list->cmp = pim_rp_list_cmp;
|
pnc->rp_list->cmp = pim_rp_list_cmp;
|
||||||
|
|
||||||
snprintfrr(hash_name, sizeof(hash_name), "PNC %pFX(%s) Upstream Hash",
|
snprintfrr(hash_name, sizeof(hash_name), "PNC %pPA(%s) Upstream Hash",
|
||||||
&pnc->rpf.rpf_addr, pim->vrf->name);
|
&pnc->rpf.rpf_addr, pim->vrf->name);
|
||||||
pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
|
pnc->upstream_hash = hash_create_size(8192, pim_upstream_hash_key,
|
||||||
pim_upstream_equal, hash_name);
|
pim_upstream_equal, hash_name);
|
||||||
@ -107,7 +107,7 @@ static struct pim_nexthop_cache *pim_nexthop_cache_add(struct pim_instance *pim,
|
|||||||
}
|
}
|
||||||
|
|
||||||
static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
|
static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
|
||||||
struct prefix *addr)
|
pim_addr *addr)
|
||||||
{
|
{
|
||||||
struct pim_nexthop_cache *pnc = NULL;
|
struct pim_nexthop_cache *pnc = NULL;
|
||||||
struct pim_rpf rpf;
|
struct pim_rpf rpf;
|
||||||
@ -124,7 +124,7 @@ static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
|
|||||||
ZEBRA_NEXTHOP_REGISTER);
|
ZEBRA_NEXTHOP_REGISTER);
|
||||||
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: NHT cache and zebra notification added for %pFX(%s)",
|
"%s: NHT cache and zebra notification added for %pPA(%s)",
|
||||||
__func__, addr, pim->vrf->name);
|
__func__, addr, pim->vrf->name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -134,7 +134,7 @@ static struct pim_nexthop_cache *pim_nht_get(struct pim_instance *pim,
|
|||||||
/* TBD: this does several distinct things and should probably be split up.
|
/* TBD: this does several distinct things and should probably be split up.
|
||||||
* (checking state vs. returning pnc vs. adding upstream vs. adding rp)
|
* (checking state vs. returning pnc vs. adding upstream vs. adding rp)
|
||||||
*/
|
*/
|
||||||
int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
|
int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr *addr,
|
||||||
struct pim_upstream *up, struct rp_info *rp,
|
struct pim_upstream *up, struct rp_info *rp,
|
||||||
struct pim_nexthop_cache *out_pnc)
|
struct pim_nexthop_cache *out_pnc)
|
||||||
{
|
{
|
||||||
@ -143,7 +143,7 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
|
|||||||
|
|
||||||
pnc = pim_nht_get(pim, addr);
|
pnc = pim_nht_get(pim, addr);
|
||||||
|
|
||||||
assertf(up || rp, "addr=%pFX", addr);
|
assertf(up || rp, "addr=%pPA", addr);
|
||||||
|
|
||||||
if (rp != NULL) {
|
if (rp != NULL) {
|
||||||
ch_node = listnode_lookup(pnc->rp_list, rp);
|
ch_node = listnode_lookup(pnc->rp_list, rp);
|
||||||
@ -167,13 +167,11 @@ int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
|
|||||||
void pim_nht_bsr_add(struct pim_instance *pim, struct in_addr addr)
|
void pim_nht_bsr_add(struct pim_instance *pim, struct in_addr addr)
|
||||||
{
|
{
|
||||||
struct pim_nexthop_cache *pnc;
|
struct pim_nexthop_cache *pnc;
|
||||||
struct prefix pfx;
|
pim_addr rpf_addr;
|
||||||
|
|
||||||
pfx.family = AF_INET;
|
rpf_addr = addr;
|
||||||
pfx.prefixlen = IPV4_MAX_BITLEN;
|
|
||||||
pfx.u.prefix4 = addr;
|
|
||||||
|
|
||||||
pnc = pim_nht_get(pim, &pfx);
|
pnc = pim_nht_get(pim, &rpf_addr);
|
||||||
|
|
||||||
pnc->bsr_count++;
|
pnc->bsr_count++;
|
||||||
}
|
}
|
||||||
@ -184,7 +182,7 @@ static void pim_nht_drop_maybe(struct pim_instance *pim,
|
|||||||
{
|
{
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: NHT %pFX(%s) rp_list count:%d upstream count:%ld BSR count:%u",
|
"%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u",
|
||||||
__func__, &pnc->rpf.rpf_addr, pim->vrf->name,
|
__func__, &pnc->rpf.rpf_addr, pim->vrf->name,
|
||||||
pnc->rp_list->count, pnc->upstream_hash->count,
|
pnc->rp_list->count, pnc->upstream_hash->count,
|
||||||
pnc->bsr_count);
|
pnc->bsr_count);
|
||||||
@ -206,7 +204,7 @@ static void pim_nht_drop_maybe(struct pim_instance *pim,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
|
void pim_delete_tracked_nexthop(struct pim_instance *pim, pim_addr *addr,
|
||||||
struct pim_upstream *up, struct rp_info *rp)
|
struct pim_upstream *up, struct rp_info *rp)
|
||||||
{
|
{
|
||||||
struct pim_nexthop_cache *pnc = NULL;
|
struct pim_nexthop_cache *pnc = NULL;
|
||||||
@ -217,7 +215,7 @@ void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
|
|||||||
lookup.rpf.rpf_addr = *addr;
|
lookup.rpf.rpf_addr = *addr;
|
||||||
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
||||||
if (!pnc) {
|
if (!pnc) {
|
||||||
zlog_warn("attempting to delete nonexistent NHT entry %pFX",
|
zlog_warn("attempting to delete nonexistent NHT entry %pPA",
|
||||||
addr);
|
addr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -261,9 +259,7 @@ void pim_nht_bsr_del(struct pim_instance *pim, struct in_addr addr)
|
|||||||
if (addr.s_addr == INADDR_ANY)
|
if (addr.s_addr == INADDR_ANY)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lookup.rpf.rpf_addr.family = AF_INET;
|
lookup.rpf.rpf_addr = addr;
|
||||||
lookup.rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
|
|
||||||
lookup.rpf.rpf_addr.u.prefix4 = addr;
|
|
||||||
|
|
||||||
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
||||||
|
|
||||||
@ -288,9 +284,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, struct in_addr bsr_addr,
|
|||||||
struct nexthop *nh;
|
struct nexthop *nh;
|
||||||
struct interface *ifp;
|
struct interface *ifp;
|
||||||
|
|
||||||
lookup.rpf.rpf_addr.family = AF_INET;
|
lookup.rpf.rpf_addr = bsr_addr;
|
||||||
lookup.rpf.rpf_addr.prefixlen = IPV4_MAX_BITLEN;
|
|
||||||
lookup.rpf.rpf_addr.u.prefix4 = bsr_addr;
|
|
||||||
|
|
||||||
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
pnc = hash_lookup(pim->rpf_hash, &lookup);
|
||||||
if (!pnc || !CHECK_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED)) {
|
if (!pnc || !CHECK_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED)) {
|
||||||
@ -497,9 +491,8 @@ uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp)
|
|||||||
|
|
||||||
static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
||||||
struct pim_nexthop_cache *pnc,
|
struct pim_nexthop_cache *pnc,
|
||||||
struct pim_nexthop *nexthop,
|
struct pim_nexthop *nexthop, pim_addr *src,
|
||||||
struct prefix *src, struct prefix *grp,
|
struct prefix *grp, int neighbor_needed)
|
||||||
int neighbor_needed)
|
|
||||||
{
|
{
|
||||||
struct pim_neighbor *nbrs[router->multipath], *nbr = NULL;
|
struct pim_neighbor *nbrs[router->multipath], *nbr = NULL;
|
||||||
struct interface *ifps[router->multipath];
|
struct interface *ifps[router->multipath];
|
||||||
@ -510,7 +503,6 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
uint8_t nh_iter = 0, found = 0;
|
uint8_t nh_iter = 0, found = 0;
|
||||||
uint32_t i, num_nbrs = 0;
|
uint32_t i, num_nbrs = 0;
|
||||||
pim_addr nh_addr = nexthop->mrib_nexthop_addr;
|
pim_addr nh_addr = nexthop->mrib_nexthop_addr;
|
||||||
pim_addr src_addr = pim_addr_from_prefix(src);
|
|
||||||
pim_addr grp_addr = pim_addr_from_prefix(grp);
|
pim_addr grp_addr = pim_addr_from_prefix(grp);
|
||||||
|
|
||||||
if (!pnc || !pnc->nexthop_num || !nexthop)
|
if (!pnc || !pnc->nexthop_num || !nexthop)
|
||||||
@ -544,7 +536,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
|
|
||||||
if (curr_route_valid &&
|
if (curr_route_valid &&
|
||||||
!pim_if_connected_to_source(nexthop->interface,
|
!pim_if_connected_to_source(nexthop->interface,
|
||||||
src_addr)) {
|
*src)) {
|
||||||
nbr = pim_neighbor_find(
|
nbr = pim_neighbor_find(
|
||||||
nexthop->interface,
|
nexthop->interface,
|
||||||
nexthop->mrib_nexthop_addr);
|
nexthop->mrib_nexthop_addr);
|
||||||
@ -565,7 +557,7 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: (%pPA,%pPA)(%s) current nexthop %s is valid, skipping new path selection",
|
"%s: (%pPA,%pPA)(%s) current nexthop %s is valid, skipping new path selection",
|
||||||
__func__, &src_addr,
|
__func__, src,
|
||||||
&grp_addr,
|
&grp_addr,
|
||||||
pim->vrf->name,
|
pim->vrf->name,
|
||||||
nexthop->interface->name);
|
nexthop->interface->name);
|
||||||
@ -591,11 +583,12 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
#endif
|
#endif
|
||||||
nbrs[i] = pim_neighbor_find(ifps[i], nhaddr);
|
nbrs[i] = pim_neighbor_find(ifps[i], nhaddr);
|
||||||
if (nbrs[i] ||
|
if (nbrs[i] ||
|
||||||
pim_if_connected_to_source(ifps[i], src_addr))
|
pim_if_connected_to_source(ifps[i], *src))
|
||||||
num_nbrs++;
|
num_nbrs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (pim->ecmp_enable) {
|
if (pim->ecmp_enable) {
|
||||||
|
struct prefix src_pfx;
|
||||||
uint32_t consider = pnc->nexthop_num;
|
uint32_t consider = pnc->nexthop_num;
|
||||||
|
|
||||||
if (neighbor_needed && num_nbrs < consider)
|
if (neighbor_needed && num_nbrs < consider)
|
||||||
@ -605,7 +598,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// PIM ECMP flag is enable then choose ECMP path.
|
// PIM ECMP flag is enable then choose ECMP path.
|
||||||
hash_val = pim_compute_ecmp_hash(src, grp);
|
pim_addr_to_prefix(&src_pfx, *src);
|
||||||
|
hash_val = pim_compute_ecmp_hash(&src_pfx, grp);
|
||||||
mod_val = hash_val % consider;
|
mod_val = hash_val % consider;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -617,8 +611,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s %s: could not find interface for ifindex %d (address %pPA(%s))",
|
"%s %s: could not find interface for ifindex %d (address %pPA(%s))",
|
||||||
__FILE__, __func__, first_ifindex,
|
__FILE__, __func__, first_ifindex, src,
|
||||||
&src_addr, pim->vrf->name);
|
pim->vrf->name);
|
||||||
if (nh_iter == mod_val)
|
if (nh_iter == mod_val)
|
||||||
mod_val++; // Select nexthpath
|
mod_val++; // Select nexthpath
|
||||||
nh_iter++;
|
nh_iter++;
|
||||||
@ -629,15 +623,14 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
|
"%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
|
||||||
__func__, ifp->name, pim->vrf->name,
|
__func__, ifp->name, pim->vrf->name,
|
||||||
first_ifindex, &src_addr);
|
first_ifindex, src);
|
||||||
if (nh_iter == mod_val)
|
if (nh_iter == mod_val)
|
||||||
mod_val++; // Select nexthpath
|
mod_val++; // Select nexthpath
|
||||||
nh_iter++;
|
nh_iter++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (neighbor_needed &&
|
if (neighbor_needed && !pim_if_connected_to_source(ifp, *src)) {
|
||||||
!pim_if_connected_to_source(ifp, src_addr)) {
|
|
||||||
nbr = nbrs[nh_iter];
|
nbr = nbrs[nh_iter];
|
||||||
if (!nbr && !if_is_loopback(ifp)) {
|
if (!nbr && !if_is_loopback(ifp)) {
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
@ -661,14 +654,14 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
|
|||||||
#endif
|
#endif
|
||||||
nexthop->mrib_metric_preference = pnc->distance;
|
nexthop->mrib_metric_preference = pnc->distance;
|
||||||
nexthop->mrib_route_metric = pnc->metric;
|
nexthop->mrib_route_metric = pnc->metric;
|
||||||
nexthop->last_lookup = src_addr;
|
nexthop->last_lookup = *src;
|
||||||
nexthop->last_lookup_time = pim_time_monotonic_usec();
|
nexthop->last_lookup_time = pim_time_monotonic_usec();
|
||||||
nexthop->nbr = nbr;
|
nexthop->nbr = nbr;
|
||||||
found = 1;
|
found = 1;
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: (%pPA,%pPA)(%s) selected nhop interface %s addr %pPAs mod_val %u iter %d ecmp %d",
|
"%s: (%pPA,%pPA)(%s) selected nhop interface %s addr %pPAs mod_val %u iter %d ecmp %d",
|
||||||
__func__, &src_addr, &grp_addr,
|
__func__, src, &grp_addr,
|
||||||
pim->vrf->name, ifp->name, &nh_addr,
|
pim->vrf->name, ifp->name, &nh_addr,
|
||||||
mod_val, nh_iter, pim->ecmp_enable);
|
mod_val, nh_iter, pim->ecmp_enable);
|
||||||
}
|
}
|
||||||
@ -708,12 +701,12 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (cmd == ZEBRA_NEXTHOP_UPDATE) {
|
if (cmd == ZEBRA_NEXTHOP_UPDATE) {
|
||||||
prefix_copy(&rpf.rpf_addr, &match);
|
rpf.rpf_addr = pim_addr_from_prefix(&match);
|
||||||
pnc = pim_nexthop_cache_find(pim, &rpf);
|
pnc = pim_nexthop_cache_find(pim, &rpf);
|
||||||
if (!pnc) {
|
if (!pnc) {
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: Skipping NHT update, addr %pFX is not in local cached DB.",
|
"%s: Skipping NHT update, addr %pPA is not in local cached DB.",
|
||||||
__func__, &rpf.rpf_addr);
|
__func__, &rpf.rpf_addr);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -740,12 +733,10 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
|
|||||||
*/
|
*/
|
||||||
#if PIM_IPV == 4
|
#if PIM_IPV == 4
|
||||||
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
|
nexthop->type = NEXTHOP_TYPE_IPV4_IFINDEX;
|
||||||
nexthop->gate.ipv4 =
|
nexthop->gate.ipv4 = pnc->rpf.rpf_addr;
|
||||||
pnc->rpf.rpf_addr.u.prefix4;
|
|
||||||
#else
|
#else
|
||||||
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
nexthop->type = NEXTHOP_TYPE_IPV6_IFINDEX;
|
||||||
nexthop->gate.ipv6 =
|
nexthop->gate.ipv6 = pnc->rpf.rpf_addr;
|
||||||
pnc->rpf.rpf_addr.u.prefix6;
|
|
||||||
#endif
|
#endif
|
||||||
break;
|
break;
|
||||||
#if PIM_IPV == 4
|
#if PIM_IPV == 4
|
||||||
@ -884,7 +875,7 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
|
|||||||
}
|
}
|
||||||
|
|
||||||
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
||||||
struct pim_nexthop *nexthop, struct prefix *src,
|
struct pim_nexthop *nexthop, pim_addr *src,
|
||||||
struct prefix *grp, int neighbor_needed)
|
struct prefix *grp, int neighbor_needed)
|
||||||
{
|
{
|
||||||
struct pim_nexthop_cache *pnc;
|
struct pim_nexthop_cache *pnc;
|
||||||
@ -898,11 +889,10 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
uint8_t i = 0;
|
uint8_t i = 0;
|
||||||
uint32_t hash_val = 0, mod_val = 0;
|
uint32_t hash_val = 0, mod_val = 0;
|
||||||
uint32_t num_nbrs = 0;
|
uint32_t num_nbrs = 0;
|
||||||
pim_addr src_addr = pim_addr_from_prefix(src);
|
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
||||||
zlog_debug("%s: Looking up: %pPA(%s), last lookup time: %lld",
|
zlog_debug("%s: Looking up: %pPA(%s), last lookup time: %lld",
|
||||||
__func__, &src_addr, pim->vrf->name,
|
__func__, src, pim->vrf->name,
|
||||||
nexthop->last_lookup_time);
|
nexthop->last_lookup_time);
|
||||||
|
|
||||||
rpf.rpf_addr = *src;
|
rpf.rpf_addr = *src;
|
||||||
@ -917,13 +907,13 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
memset(nexthop_tab, 0,
|
memset(nexthop_tab, 0,
|
||||||
sizeof(struct pim_zlookup_nexthop) * router->multipath);
|
sizeof(struct pim_zlookup_nexthop) * router->multipath);
|
||||||
num_ifindex =
|
num_ifindex =
|
||||||
zclient_lookup_nexthop(pim, nexthop_tab, router->multipath,
|
zclient_lookup_nexthop(pim, nexthop_tab, router->multipath, src,
|
||||||
src_addr, PIM_NEXTHOP_LOOKUP_MAX);
|
PIM_NEXTHOP_LOOKUP_MAX);
|
||||||
if (num_ifindex < 1) {
|
if (num_ifindex < 1) {
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_warn(
|
zlog_warn(
|
||||||
"%s: could not find nexthop ifindex for address %pPA(%s)",
|
"%s: could not find nexthop ifindex for address %pPA(%s)",
|
||||||
__func__, &src_addr, pim->vrf->name);
|
__func__, src, pim->vrf->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -941,13 +931,14 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
nbrs[i] = pim_neighbor_find(
|
nbrs[i] = pim_neighbor_find(
|
||||||
ifps[i], nexthop_tab[i].nexthop_addr);
|
ifps[i], nexthop_tab[i].nexthop_addr);
|
||||||
if (nbrs[i] ||
|
if (nbrs[i] ||
|
||||||
pim_if_connected_to_source(ifps[i], src_addr))
|
pim_if_connected_to_source(ifps[i], *src))
|
||||||
num_nbrs++;
|
num_nbrs++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If PIM ECMP enable then choose ECMP path.
|
// If PIM ECMP enable then choose ECMP path.
|
||||||
if (pim->ecmp_enable) {
|
if (pim->ecmp_enable) {
|
||||||
|
struct prefix src_pfx;
|
||||||
uint32_t consider = num_ifindex;
|
uint32_t consider = num_ifindex;
|
||||||
|
|
||||||
if (neighbor_needed && num_nbrs < consider)
|
if (neighbor_needed && num_nbrs < consider)
|
||||||
@ -956,7 +947,8 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
if (consider == 0)
|
if (consider == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
hash_val = pim_compute_ecmp_hash(src, grp);
|
pim_addr_to_prefix(&src_pfx, *src);
|
||||||
|
hash_val = pim_compute_ecmp_hash(&src_pfx, grp);
|
||||||
mod_val = hash_val % consider;
|
mod_val = hash_val % consider;
|
||||||
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
||||||
zlog_debug("%s: hash_val %u mod_val %u", __func__,
|
zlog_debug("%s: hash_val %u mod_val %u", __func__,
|
||||||
@ -972,8 +964,8 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s %s: could not find interface for ifindex %d (address %pPA(%s))",
|
"%s %s: could not find interface for ifindex %d (address %pPA(%s))",
|
||||||
__FILE__, __func__, first_ifindex,
|
__FILE__, __func__, first_ifindex, src,
|
||||||
&src_addr, pim->vrf->name);
|
pim->vrf->name);
|
||||||
if (i == mod_val)
|
if (i == mod_val)
|
||||||
mod_val++;
|
mod_val++;
|
||||||
i++;
|
i++;
|
||||||
@ -985,14 +977,13 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
|
"%s: multicast not enabled on input interface %s(%s) (ifindex=%d, RPF for source %pPA)",
|
||||||
__func__, ifp->name, pim->vrf->name,
|
__func__, ifp->name, pim->vrf->name,
|
||||||
first_ifindex, &src_addr);
|
first_ifindex, src);
|
||||||
if (i == mod_val)
|
if (i == mod_val)
|
||||||
mod_val++;
|
mod_val++;
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (neighbor_needed &&
|
if (neighbor_needed && !pim_if_connected_to_source(ifp, *src)) {
|
||||||
!pim_if_connected_to_source(ifp, src_addr)) {
|
|
||||||
nbr = nbrs[i];
|
nbr = nbrs[i];
|
||||||
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
if (PIM_DEBUG_PIM_NHT_DETAIL)
|
||||||
zlog_debug("ifp name: %s(%s), pim nbr: %p",
|
zlog_debug("ifp name: %s(%s), pim nbr: %p",
|
||||||
@ -1005,8 +996,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
"%s: NBR (%pPA) not found on input interface %s(%s) (RPF for source %pPA)",
|
"%s: NBR (%pPA) not found on input interface %s(%s) (RPF for source %pPA)",
|
||||||
__func__,
|
__func__,
|
||||||
&nexthop_tab[i].nexthop_addr,
|
&nexthop_tab[i].nexthop_addr,
|
||||||
ifp->name, pim->vrf->name,
|
ifp->name, pim->vrf->name, src);
|
||||||
&src_addr);
|
|
||||||
i++;
|
i++;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@ -1017,7 +1007,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: found nhop %pPA for addr %pPA interface %s(%s) metric %d dist %d",
|
"%s: found nhop %pPA for addr %pPA interface %s(%s) metric %d dist %d",
|
||||||
__func__, &nexthop_tab[i].nexthop_addr,
|
__func__, &nexthop_tab[i].nexthop_addr,
|
||||||
&src_addr, ifp->name, pim->vrf->name,
|
src, ifp->name, pim->vrf->name,
|
||||||
nexthop_tab[i].route_metric,
|
nexthop_tab[i].route_metric,
|
||||||
nexthop_tab[i].protocol_distance);
|
nexthop_tab[i].protocol_distance);
|
||||||
/* update nexthop data */
|
/* update nexthop data */
|
||||||
@ -1028,7 +1018,7 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
nexthop_tab[i].protocol_distance;
|
nexthop_tab[i].protocol_distance;
|
||||||
nexthop->mrib_route_metric =
|
nexthop->mrib_route_metric =
|
||||||
nexthop_tab[i].route_metric;
|
nexthop_tab[i].route_metric;
|
||||||
nexthop->last_lookup = src_addr;
|
nexthop->last_lookup = *src;
|
||||||
nexthop->last_lookup_time = pim_time_monotonic_usec();
|
nexthop->last_lookup_time = pim_time_monotonic_usec();
|
||||||
nexthop->nbr = nbr;
|
nexthop->nbr = nbr;
|
||||||
found = 1;
|
found = 1;
|
||||||
@ -1042,24 +1032,19 @@ int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
|
int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim, pim_addr *src,
|
||||||
struct prefix *src, struct prefix *grp)
|
struct prefix *grp)
|
||||||
{
|
{
|
||||||
struct pim_nexthop nhop;
|
struct pim_nexthop nhop;
|
||||||
int vif_index;
|
int vif_index;
|
||||||
ifindex_t ifindex;
|
ifindex_t ifindex;
|
||||||
pim_addr src_addr;
|
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_NHT_DETAIL) {
|
|
||||||
src_addr = pim_addr_from_prefix(src);
|
|
||||||
}
|
|
||||||
|
|
||||||
memset(&nhop, 0, sizeof(nhop));
|
memset(&nhop, 0, sizeof(nhop));
|
||||||
if (!pim_ecmp_nexthop_lookup(pim, &nhop, src, grp, 1)) {
|
if (!pim_ecmp_nexthop_lookup(pim, &nhop, src, grp, 1)) {
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: could not find nexthop ifindex for address %pPA(%s)",
|
"%s: could not find nexthop ifindex for address %pPA(%s)",
|
||||||
__func__, &src_addr, pim->vrf->name);
|
__func__, src, pim->vrf->name);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1069,7 +1054,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
|
|||||||
"%s: found nexthop ifindex=%d (interface %s(%s)) for address %pPA",
|
"%s: found nexthop ifindex=%d (interface %s(%s)) for address %pPA",
|
||||||
__func__, ifindex,
|
__func__, ifindex,
|
||||||
ifindex2ifname(ifindex, pim->vrf->vrf_id),
|
ifindex2ifname(ifindex, pim->vrf->vrf_id),
|
||||||
pim->vrf->name, &src_addr);
|
pim->vrf->name, src);
|
||||||
|
|
||||||
vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
|
vif_index = pim_if_find_vifindex_by_ifindex(pim, ifindex);
|
||||||
|
|
||||||
@ -1077,7 +1062,7 @@ int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
|
|||||||
if (PIM_DEBUG_PIM_NHT) {
|
if (PIM_DEBUG_PIM_NHT) {
|
||||||
zlog_debug(
|
zlog_debug(
|
||||||
"%s: low vif_index=%d(%s) < 1 nexthop for address %pPA",
|
"%s: low vif_index=%d(%s) < 1 nexthop for address %pPA",
|
||||||
__func__, vif_index, pim->vrf->name, &src_addr);
|
__func__, vif_index, pim->vrf->name, src);
|
||||||
}
|
}
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
@ -54,21 +54,21 @@ struct pim_nexthop_cache {
|
|||||||
};
|
};
|
||||||
|
|
||||||
int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
|
int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
|
||||||
int pim_find_or_track_nexthop(struct pim_instance *pim, struct prefix *addr,
|
int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr *addr,
|
||||||
struct pim_upstream *up, struct rp_info *rp,
|
struct pim_upstream *up, struct rp_info *rp,
|
||||||
struct pim_nexthop_cache *out_pnc);
|
struct pim_nexthop_cache *out_pnc);
|
||||||
void pim_delete_tracked_nexthop(struct pim_instance *pim, struct prefix *addr,
|
void pim_delete_tracked_nexthop(struct pim_instance *pim, pim_addr *addr,
|
||||||
struct pim_upstream *up, struct rp_info *rp);
|
struct pim_upstream *up, struct rp_info *rp);
|
||||||
struct pim_nexthop_cache *pim_nexthop_cache_find(struct pim_instance *pim,
|
struct pim_nexthop_cache *pim_nexthop_cache_find(struct pim_instance *pim,
|
||||||
struct pim_rpf *rpf);
|
struct pim_rpf *rpf);
|
||||||
uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp);
|
uint32_t pim_compute_ecmp_hash(struct prefix *src, struct prefix *grp);
|
||||||
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
||||||
struct pim_nexthop *nexthop, struct prefix *src,
|
struct pim_nexthop *nexthop, pim_addr *src,
|
||||||
struct prefix *grp, int neighbor_needed);
|
struct prefix *grp, int neighbor_needed);
|
||||||
void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
|
void pim_sendmsg_zebra_rnh(struct pim_instance *pim, struct zclient *zclient,
|
||||||
struct pim_nexthop_cache *pnc, int command);
|
struct pim_nexthop_cache *pnc, int command);
|
||||||
int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim,
|
int pim_ecmp_fib_lookup_if_vif_index(struct pim_instance *pim, pim_addr *src,
|
||||||
struct prefix *src, struct prefix *grp);
|
struct prefix *grp);
|
||||||
void pim_rp_nexthop_del(struct rp_info *rp_info);
|
void pim_rp_nexthop_del(struct rp_info *rp_info);
|
||||||
|
|
||||||
/* for RPF check on BSM message receipt */
|
/* for RPF check on BSM message receipt */
|
||||||
|
Loading…
Reference in New Issue
Block a user