+// SPDX-License-Identifier: GPL-2.0-or-later
/*
* PIM for Quagga
* Copyright (C) 2008 Everton da Silva Marques
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; see the file COPYING; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#include <zebra.h>
#include "jhash.h"
#include "pimd.h"
+#include "pim_instance.h"
#include "pim_rpf.h"
#include "pim_pim.h"
#include "pim_str.h"
bool pim_nexthop_lookup(struct pim_instance *pim, struct pim_nexthop *nexthop,
pim_addr addr, int neighbor_needed)
{
- struct pim_zlookup_nexthop nexthop_tab[MULTIPATH_NUM];
+ struct pim_zlookup_nexthop nexthop_tab[router->multipath];
struct pim_neighbor *nbr = NULL;
int num_ifindex;
struct interface *ifp = NULL;
ifindex_t first_ifindex = 0;
int found = 0;
int i = 0;
+ struct pim_interface *pim_ifp;
#if PIM_IPV == 4
/*
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: Using last lookup for %pPAs at %lld, %" PRId64
- " addr %pFX",
+ " addr %pPAs",
__func__, &addr, nexthop->last_lookup_time,
pim->last_route_change_time,
&nexthop->mrib_nexthop_addr);
}
memset(nexthop_tab, 0,
- sizeof(struct pim_zlookup_nexthop) * MULTIPATH_NUM);
- num_ifindex = zclient_lookup_nexthop(pim, nexthop_tab, MULTIPATH_NUM,
- addr, PIM_NEXTHOP_LOOKUP_MAX);
+ sizeof(struct pim_zlookup_nexthop) * router->multipath);
+ num_ifindex =
+ zclient_lookup_nexthop(pim, nexthop_tab, router->multipath,
+ addr, PIM_NEXTHOP_LOOKUP_MAX);
if (num_ifindex < 1) {
- zlog_warn(
- "%s %s: could not find nexthop ifindex for address %pPAs",
- __FILE__, __func__, &addr);
+ if (PIM_DEBUG_PIM_NHT)
+ zlog_debug(
+ "%s %s: could not find nexthop ifindex for address %pPAs",
+ __FILE__, __func__, &addr);
return false;
}
continue;
}
- if (!ifp->info) {
+ pim_ifp = ifp->info;
+ if (!pim_ifp || !pim_ifp->pim_enable) {
if (PIM_DEBUG_ZEBRA)
zlog_debug(
- "%s: multicast not enabled on input interface %s (ifindex=%d, RPF for source %pPAs)",
+ "%s: pim not enabled on input interface %s (ifindex=%d, RPF for source %pPAs)",
__func__, ifp->name, first_ifindex,
&addr);
i++;
- } else if (neighbor_needed
- && !pim_if_connected_to_source(ifp, addr)) {
- nbr = pim_neighbor_find_prefix(
- ifp, &nexthop_tab[i].nexthop_addr);
+ } else if (neighbor_needed &&
+ !pim_if_connected_to_source(ifp, addr)) {
+ nbr = pim_neighbor_find(ifp,
+ nexthop_tab[i].nexthop_addr);
if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug("ifp name: %s, pim nbr: %p",
ifp->name, nbr);
if (found) {
if (PIM_DEBUG_ZEBRA)
zlog_debug(
- "%s %s: found nexthop %pFX for address %pPAs: interface %s ifindex=%d metric=%d pref=%d",
+ "%s %s: found nexthop %pPAs for address %pPAs: interface %s ifindex=%d metric=%d pref=%d",
__FILE__, __func__,
&nexthop_tab[i].nexthop_addr, &addr, ifp->name,
first_ifindex, nexthop_tab[i].route_metric,
nexthop_tab[i].protocol_distance);
+
/* update nexthop data */
nexthop->interface = ifp;
nexthop->mrib_nexthop_addr = nexthop_tab[i].nexthop_addr;
static int nexthop_mismatch(const struct pim_nexthop *nh1,
const struct pim_nexthop *nh2)
{
- pim_addr nh_addr1 = pim_addr_from_prefix(&nh1->mrib_nexthop_addr);
- pim_addr nh_addr2 = pim_addr_from_prefix(&nh2->mrib_nexthop_addr);
-
return (nh1->interface != nh2->interface) ||
- (pim_addr_cmp(nh_addr1, nh_addr2)) ||
+ (pim_addr_cmp(nh1->mrib_nexthop_addr, nh2->mrib_nexthop_addr)) ||
(nh1->mrib_metric_preference != nh2->mrib_metric_preference) ||
(nh1->mrib_route_metric != nh2->mrib_route_metric);
}
{
struct pim_rpf *rpf = &up->rpf;
struct pim_rpf saved;
- struct prefix nht_p;
- struct prefix src, grp;
+ pim_addr src;
+ struct prefix grp;
bool neigh_needed = true;
uint32_t saved_mrib_route_metric;
- pim_addr rpf_addr;
if (PIM_UPSTREAM_FLAG_TEST_STATIC_IIF(up->flags))
return PIM_RPF_OK;
old->rpf_addr = saved.rpf_addr;
}
- pim_addr_to_prefix(&nht_p, up->upstream_addr);
-
- pim_addr_to_prefix(&src, up->upstream_addr); // RP or Src address
+ src = up->upstream_addr; // RP or Src address
pim_addr_to_prefix(&grp, up->sg.grp);
if ((pim_addr_is_any(up->sg.src) && I_am_RP(pim, up->sg.grp)) ||
PIM_UPSTREAM_FLAG_TEST_FHR(up->flags))
neigh_needed = false;
- pim_find_or_track_nexthop(pim, &nht_p, up, NULL, NULL);
- if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, &src, &grp,
- neigh_needed)) {
+ pim_find_or_track_nexthop(pim, up->upstream_addr, up, NULL, NULL);
+ if (!pim_ecmp_nexthop_lookup(pim, &rpf->source_nexthop, src, &grp,
+ neigh_needed)) {
/* Route is Deleted in Zebra, reset the stored NH data */
pim_upstream_rpf_clear(pim, up);
pim_rpf_cost_change(pim, up, saved_mrib_route_metric);
return PIM_RPF_FAILURE;
}
- rpf_addr = pim_rpf_find_rpf_addr(up);
- pim_addr_to_prefix(&rpf->rpf_addr, rpf_addr);
+ rpf->rpf_addr = pim_rpf_find_rpf_addr(up);
if (pim_rpf_addr_is_inaddr_any(rpf) && PIM_DEBUG_ZEBRA) {
/* RPF'(S,G) not found */
if (nexthop_mismatch(&rpf->source_nexthop, &saved.source_nexthop)) {
if (PIM_DEBUG_ZEBRA)
- zlog_debug("%s(%s): (S,G)=%s source nexthop now is: interface=%s address=%pFX pref=%d metric=%d",
+ zlog_debug("%s(%s): (S,G)=%s source nexthop now is: interface=%s address=%pPAs pref=%d metric=%d",
__func__, caller,
up->sg_str,
rpf->source_nexthop.interface ? rpf->source_nexthop.interface->name : "<ifname?>",
}
/* detect change in RPF'(S,G) */
- if (!prefix_same(&saved.rpf_addr, &rpf->rpf_addr) ||
+ if (pim_addr_cmp(saved.rpf_addr, rpf->rpf_addr) ||
saved.source_nexthop.interface != rpf->source_nexthop.interface) {
pim_rpf_cost_change(pim, up, saved_mrib_route_metric);
return PIM_RPF_CHANGED;
if (up->rpf.source_nexthop.interface) {
pim_upstream_switch(pim, up, PIM_UPSTREAM_NOTJOINED);
up->rpf.source_nexthop.interface = NULL;
- pim_addr_to_prefix(&up->rpf.source_nexthop.mrib_nexthop_addr,
- PIMADDR_ANY);
+ up->rpf.source_nexthop.mrib_nexthop_addr = PIMADDR_ANY;
up->rpf.source_nexthop.mrib_metric_preference =
router->infinite_assert_metric.metric_preference;
up->rpf.source_nexthop.mrib_route_metric =
router->infinite_assert_metric.route_metric;
- pim_addr_to_prefix(&up->rpf.rpf_addr, PIMADDR_ANY);
+ up->rpf.rpf_addr = PIMADDR_ANY;
pim_upstream_mroute_iif_update(up->channel_oil, __func__);
}
}
/* return NBR( RPF_interface(S), MRIB.next_hop( S ) ) */
- pim_addr nhaddr;
-
- nhaddr =
- pim_addr_from_prefix(&up->rpf.source_nexthop.mrib_nexthop_addr);
- neigh = pim_if_find_neighbor(up->rpf.source_nexthop.interface, nhaddr);
+ neigh = pim_if_find_neighbor(up->rpf.source_nexthop.interface,
+ up->rpf.source_nexthop.mrib_nexthop_addr);
if (neigh)
rpf_addr = neigh->source_addr;
else
int pim_rpf_addr_is_inaddr_any(struct pim_rpf *rpf)
{
- pim_addr rpf_addr = pim_addr_from_prefix(&rpf->rpf_addr);
-
- switch (rpf->rpf_addr.family) {
- case AF_INET:
- case AF_INET6:
- return pim_addr_is_any(rpf_addr);
- default:
- return 0;
- }
+ return pim_addr_is_any(rpf->rpf_addr);
}
int pim_rpf_is_same(struct pim_rpf *rpf1, struct pim_rpf *rpf2)
const struct pim_nexthop_cache *r = arg;
#if PIM_IPV == 4
- return jhash_1word(r->rpf.rpf_addr.u.prefix4.s_addr, 0);
+ return jhash_1word(r->rpf.rpf_addr.s_addr, 0);
#else
- return jhash2(r->rpf.rpf_addr.u.prefix6.s6_addr32,
- array_size(r->rpf.rpf_addr.u.prefix6.s6_addr32), 0);
+ return jhash2(r->rpf.rpf_addr.s6_addr32,
+ array_size(r->rpf.rpf_addr.s6_addr32), 0);
#endif
}
const struct pim_nexthop_cache *r2 =
(const struct pim_nexthop_cache *)arg2;
- return prefix_same(&r1->rpf.rpf_addr, &r2->rpf.rpf_addr);
+ return (!pim_addr_cmp(r1->rpf.rpf_addr, r2->rpf.rpf_addr));
}