From f18cb4fb58cd443fad02ed991387b301885aaaea Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 8 May 2024 19:27:22 +0200 Subject: [PATCH 1/6] pimd: make clang-format slightly less annoying The YANG module list is really better as 1-item-per-line. Signed-off-by: David Lamparter --- pimd/pim6_main.c | 2 +- pimd/pim_main.c | 2 +- 2 files changed, 2 insertions(+), 2 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_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.", From 1f223ae1eed80f2552a279ee34464edf363bba6f Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Mon, 11 Jul 2022 21:58:27 +0200 Subject: [PATCH 2/6] pimd: add debugs for i-am-RP state This proved helpful in debugging the Candidate-RP code. Signed-off-by: David Lamparter --- pimd/pim_rp.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c index d8d25712a3..b0fb8a509a 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 */ From 18b82f64c9538b6fd3b9f61c86dfff8cbdc8c6b6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Wed, 8 May 2024 19:25:55 +0200 Subject: [PATCH 3/6] pimd: add prefix_* and IANA_AFI v4/v6 defines The Candidate-RP code is about to use these. Signed-off-by: David Lamparter --- pimd/pim_addr.h | 4 ++++ 1 file changed, 4 insertions(+) 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 From cca9bc193edfebbd93fbdd76bd4c3b8310f007d6 Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Sat, 9 Jul 2022 18:47:43 +0200 Subject: [PATCH 4/6] pimd: allow sending packets without pinned iface The upcoming Candidate-RP code needs to send PIM packets that go through normal unicast routing, without forcing a specific output interface. Allow passing in NULL ifp to do that. Signed-off-by: David Lamparter --- pimd/pim_pim.c | 24 +++++++++++------------- 1 file changed, 11 insertions(+), 13 deletions(-) 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 From b9a02da83b65fa7066ef17f71a32f5aa0648e28e Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 25 Jun 2021 11:42:38 +0200 Subject: [PATCH 5/6] pimd: prepare NHT for tracking BSM C-RPs For BSMs, we should track which of the RP candidates in the BSM message are actually available, before trying to use them (which also puts them in NHT for that). This applies for both BSRs as well as BSM receivers. Signed-off-by: David Lamparter --- pimd/pim_bsm.c | 5 +++++ pimd/pim_nht.c | 47 ++++++++++++++++++++++++++++++++++++++++------- pimd/pim_nht.h | 7 +++++++ 3 files changed, 52 insertions(+), 7 deletions(-) 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_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 From f9d4d1626d47944715eb522af38909cc90a1d53c Mon Sep 17 00:00:00 2001 From: David Lamparter Date: Fri, 21 Jun 2024 11:32:05 +0200 Subject: [PATCH 6/6] tools/checkpatch: accept pim_* typedefs pimd uses "v4/v6 dispatch" typedefs. Don't complain about those in checkpatch. Signed-off-by: David Lamparter --- tools/checkpatch.pl | 1 + 1 file changed, 1 insertion(+) diff --git a/tools/checkpatch.pl b/tools/checkpatch.pl index f52f1a1616..3e7abeda39 100755 --- a/tools/checkpatch.pl +++ b/tools/checkpatch.pl @@ -4668,6 +4668,7 @@ sub process { # check for new typedefs, only function parameters and sparse annotations # make sense. if ($line =~ /\btypedef\s/ && + $line !~ /\btypedef.*\s(pim_[^\s]+|[^\s]+_pim)\s*;/ && $line !~ /\btypedef\s+$Type\s*\(\s*\*?$Ident\s*\)\s*\(/ && $line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ && $line !~ /\b$typeTypedefs\b/ &&