summaryrefslogtreecommitdiff
path: root/pimd
diff options
context:
space:
mode:
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim6_main.c2
-rw-r--r--pimd/pim_addr.h4
-rw-r--r--pimd/pim_bsm.c5
-rw-r--r--pimd/pim_main.c2
-rw-r--r--pimd/pim_nht.c47
-rw-r--r--pimd/pim_nht.h7
-rw-r--r--pimd/pim_pim.c24
-rw-r--r--pimd/pim_rp.c23
8 files changed, 82 insertions, 32 deletions
diff --git a/pimd/pim6_main.c b/pimd/pim6_main.c
index 5ce6985c45..24443404eb 100644
--- a/pimd/pim6_main.c
+++ b/pimd/pim6_main.c
@@ -94,6 +94,7 @@ struct frr_signal_t pim6d_signals[] = {
},
};
+/* clang-format off */
static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
&frr_filter_info,
&frr_interface_info,
@@ -105,7 +106,6 @@ static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
&frr_gmp_info,
};
-/* clang-format off */
FRR_DAEMON_INFO(pim6d, PIM6,
.vty_port = PIM6D_VTY_PORT,
.proghelp = "Protocol Independent Multicast (RFC7761) for IPv6",
diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h
index ecba739a5a..7b0c3f0350 100644
--- a/pimd/pim_addr.h
+++ b/pimd/pim_addr.h
@@ -14,11 +14,13 @@
#if PIM_IPV == 4
typedef struct in_addr pim_addr;
+typedef struct prefix_ipv4 prefix_pim;
#define PIM_ADDRSTRLEN INET_ADDRSTRLEN
#define PIM_AF AF_INET
#define PIM_AFI AFI_IP
#define PIM_PROTO_REG IPPROTO_RAW
+#define PIM_IANA_AFI IANA_AFI_IPV4
#define PIM_IPADDR IPADDR_V4
#define ipaddr_pim ipaddr_v4
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
@@ -44,11 +46,13 @@ union pimprefixconstptr {
#else
typedef struct in6_addr pim_addr;
+typedef struct prefix_ipv6 prefix_pim;
#define PIM_ADDRSTRLEN INET6_ADDRSTRLEN
#define PIM_AF AF_INET6
#define PIM_AFI AFI_IP6
#define PIM_PROTO_REG IPPROTO_PIM
+#define PIM_IANA_AFI IANA_AFI_IPV6
#define PIM_IPADDR IPADDR_V6
#define ipaddr_pim ipaddr_v6
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c
index df9161943d..2d451718a9 100644
--- a/pimd/pim_bsm.c
+++ b/pimd/pim_bsm.c
@@ -1451,3 +1451,8 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
return 0;
}
+
+void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc)
+{
+ /* stub for Candidate-RP */
+}
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 400db396c2..8f2ce0bed3 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -59,6 +59,7 @@ struct zebra_privs_t pimd_privs = {
.cap_num_p = array_size(_caps_p),
.cap_num_i = 0};
+/* clang-format off */
static const struct frr_yang_module_info *const pimd_yang_modules[] = {
&frr_filter_info,
&frr_interface_info,
@@ -70,7 +71,6 @@ static const struct frr_yang_module_info *const pimd_yang_modules[] = {
&frr_gmp_info,
};
-/* clang-format off */
FRR_DAEMON_INFO(pimd, PIM,
.vty_port = PIMD_VTY_PORT,
.proghelp = "Implementation of the PIM routing protocol.",
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 32cdf4bf82..57dcff3b47 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -161,18 +161,27 @@ void pim_nht_bsr_add(struct pim_instance *pim, pim_addr addr)
pnc->bsr_count++;
}
+bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr)
+{
+ struct pim_nexthop_cache *pnc;
+
+ pnc = pim_nht_get(pim, addr);
+
+ pnc->candrp_count++;
+ return CHECK_FLAG(pnc->flags, PIM_NEXTHOP_VALID);
+}
+
static void pim_nht_drop_maybe(struct pim_instance *pim,
struct pim_nexthop_cache *pnc)
{
if (PIM_DEBUG_PIM_NHT)
- zlog_debug(
- "%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u",
- __func__, &pnc->rpf.rpf_addr, pim->vrf->name,
- pnc->rp_list->count, pnc->upstream_hash->count,
- pnc->bsr_count);
+ zlog_debug("%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u Cand-RP count:%u",
+ __func__, &pnc->rpf.rpf_addr, pim->vrf->name,
+ pnc->rp_list->count, pnc->upstream_hash->count,
+ pnc->bsr_count, pnc->candrp_count);
- if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0
- && pnc->bsr_count == 0) {
+ if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0 &&
+ pnc->bsr_count == 0 && pnc->candrp_count == 0) {
struct zclient *zclient = pim_zebra_zclient_get();
pim_sendmsg_zebra_rnh(pim, zclient, pnc,
@@ -258,6 +267,27 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr addr)
pim_nht_drop_maybe(pim, pnc);
}
+void pim_nht_candrp_del(struct pim_instance *pim, pim_addr addr)
+{
+ struct pim_nexthop_cache *pnc = NULL;
+ struct pim_nexthop_cache lookup;
+
+ lookup.rpf.rpf_addr = addr;
+
+ pnc = hash_lookup(pim->rpf_hash, &lookup);
+
+ if (!pnc) {
+ zlog_warn("attempting to delete nonexistent NHT C-RP entry %pPA",
+ &addr);
+ return;
+ }
+
+ assertf(pnc->candrp_count > 0, "addr=%pPA", &addr);
+ pnc->candrp_count--;
+
+ pim_nht_drop_maybe(pim, pnc);
+}
+
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
struct interface *src_ifp, pim_addr src_ip)
{
@@ -900,6 +930,9 @@ void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
pim_update_rp_nh(pim, pnc);
if (pnc->upstream_hash->count)
pim_update_upstream_nh(pim, pnc);
+
+ if (pnc->candrp_count)
+ pim_crp_nht_update(pim, pnc);
}
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h
index a1feb76e3b..e74b375dc6 100644
--- a/pimd/pim_nht.h
+++ b/pimd/pim_nht.h
@@ -38,6 +38,7 @@ struct pim_nexthop_cache {
* same BSR
*/
uint32_t bsr_count;
+ uint32_t candrp_count;
};
struct pnc_hash_walk_data {
@@ -71,4 +72,10 @@ void pim_nht_bsr_del(struct pim_instance *pim, pim_addr bsr_addr);
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
struct interface *src_ifp, pim_addr src_ip);
void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
+
+/* wrappers for usage with Candidate RPs in BSMs */
+bool pim_nht_candrp_add(struct pim_instance *pim, pim_addr addr);
+void pim_nht_candrp_del(struct pim_instance *pim, pim_addr addr);
+void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc);
+
#endif
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index 1bc265b138..6a7e8924f2 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -636,17 +636,15 @@ static int pim_msg_send_frame(pim_addr src, pim_addr dst, ifindex_t ifindex,
int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
int pim_msg_size, struct interface *ifp)
{
- struct pim_interface *pim_ifp;
-
+ if (ifp) {
+ struct pim_interface *pim_ifp = ifp->info;
- pim_ifp = ifp->info;
-
- if (pim_ifp->pim_passive_enable) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "skip sending PIM message on passive interface %s",
- ifp->name);
- return 0;
+ if (pim_ifp->pim_passive_enable) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("skip sending PIM message on passive interface %s",
+ ifp->name);
+ return 0;
+ }
}
#if PIM_IPV == 4
@@ -710,7 +708,7 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
if (PIM_DEBUG_PIM_PACKETS)
zlog_debug("%s: to %pPA on %s: msg_size=%d checksum=%x",
- __func__, &dst, ifp->name, pim_msg_size,
+ __func__, &dst, ifp ? ifp->name : "*", pim_msg_size,
header->checksum);
if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
@@ -718,7 +716,7 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
}
pim_msg_send_frame(fd, (char *)buffer, sendlen, (struct sockaddr *)&to,
- tolen, ifp->name);
+ tolen, ifp ? ifp->name : "*");
return 0;
#else
@@ -727,7 +725,7 @@ int pim_msg_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
iovector[0].iov_base = pim_msg;
iovector[0].iov_len = pim_msg_size;
- pim_msg_send_frame(src, dst, ifp->ifindex, &iovector[0], fd);
+ pim_msg_send_frame(src, dst, ifp ? ifp->ifindex : 0, &iovector[0], fd);
return 0;
#endif
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index d8d25712a3..49be9c0a73 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -543,6 +543,9 @@ int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
pim_zebra_update_all_interfaces(pim);
pim_rp_check_interfaces(pim, rp_all);
+ if (rp_all->i_am_rp && PIM_DEBUG_PIM_NHT_RP)
+ zlog_debug("new RP %pPA for %pFX is ourselves",
+ &rp_all->rp.rpf_addr, &rp_all->group);
pim_rp_refresh_group_to_rp_mapping(pim);
pim_find_or_track_nexthop(pim, nht_p, NULL, rp_all,
NULL);
@@ -634,6 +637,9 @@ int pim_rp_new(struct pim_instance *pim, pim_addr rp_addr, struct prefix group,
pim_zebra_update_all_interfaces(pim);
pim_rp_check_interfaces(pim, rp_info);
+ if (rp_info->i_am_rp && PIM_DEBUG_PIM_NHT_RP)
+ zlog_debug("new RP %pPA for %pFX is ourselves",
+ &rp_info->rp.rpf_addr, &rp_info->group);
pim_rp_refresh_group_to_rp_mapping(pim);
/* Register addr with Zebra NHT */
@@ -1101,16 +1107,17 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
pim_addr source, pim_addr group)
{
struct rp_info *rp_info;
- struct prefix g;
+ struct prefix g = {};
- memset(&g, 0, sizeof(g));
+ if (!pim_addr_is_any(source)) {
+ *up = source;
+ return 1;
+ }
pim_addr_to_prefix(&g, group);
-
rp_info = pim_rp_find_match_group(pim, &g);
- if (!rp_info || ((pim_rpf_addr_is_inaddr_any(&rp_info->rp)) &&
- (pim_addr_is_any(source)))) {
+ if (!rp_info || pim_rpf_addr_is_inaddr_any(&rp_info->rp)) {
if (PIM_DEBUG_PIM_NHT_RP)
zlog_debug("%s: Received a (*,G) with no RP configured",
__func__);
@@ -1118,11 +1125,7 @@ int pim_rp_set_upstream_addr(struct pim_instance *pim, pim_addr *up,
return 0;
}
- if (pim_addr_is_any(source))
- *up = rp_info->rp.rpf_addr;
- else
- *up = source;
-
+ *up = rp_info->rp.rpf_addr;
return 1;
}