mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-09 13:19:17 +00:00
Merge pull request #16259 from opensourcerouting/pim-20240620-cand-rp-bsr-prep
pimd: Candidate RP/BSR preparation
This commit is contained in:
commit
56afdee8e2
@ -94,6 +94,7 @@ struct frr_signal_t pim6d_signals[] = {
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
|
static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
|
||||||
&frr_filter_info,
|
&frr_filter_info,
|
||||||
&frr_interface_info,
|
&frr_interface_info,
|
||||||
@ -105,7 +106,6 @@ static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
|
|||||||
&frr_gmp_info,
|
&frr_gmp_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
FRR_DAEMON_INFO(pim6d, PIM6,
|
FRR_DAEMON_INFO(pim6d, PIM6,
|
||||||
.vty_port = PIM6D_VTY_PORT,
|
.vty_port = PIM6D_VTY_PORT,
|
||||||
.proghelp = "Protocol Independent Multicast (RFC7761) for IPv6",
|
.proghelp = "Protocol Independent Multicast (RFC7761) for IPv6",
|
||||||
|
@ -14,11 +14,13 @@
|
|||||||
|
|
||||||
#if PIM_IPV == 4
|
#if PIM_IPV == 4
|
||||||
typedef struct in_addr pim_addr;
|
typedef struct in_addr pim_addr;
|
||||||
|
typedef struct prefix_ipv4 prefix_pim;
|
||||||
|
|
||||||
#define PIM_ADDRSTRLEN INET_ADDRSTRLEN
|
#define PIM_ADDRSTRLEN INET_ADDRSTRLEN
|
||||||
#define PIM_AF AF_INET
|
#define PIM_AF AF_INET
|
||||||
#define PIM_AFI AFI_IP
|
#define PIM_AFI AFI_IP
|
||||||
#define PIM_PROTO_REG IPPROTO_RAW
|
#define PIM_PROTO_REG IPPROTO_RAW
|
||||||
|
#define PIM_IANA_AFI IANA_AFI_IPV4
|
||||||
#define PIM_IPADDR IPADDR_V4
|
#define PIM_IPADDR IPADDR_V4
|
||||||
#define ipaddr_pim ipaddr_v4
|
#define ipaddr_pim ipaddr_v4
|
||||||
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
|
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
|
||||||
@ -44,11 +46,13 @@ union pimprefixconstptr {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
typedef struct in6_addr pim_addr;
|
typedef struct in6_addr pim_addr;
|
||||||
|
typedef struct prefix_ipv6 prefix_pim;
|
||||||
|
|
||||||
#define PIM_ADDRSTRLEN INET6_ADDRSTRLEN
|
#define PIM_ADDRSTRLEN INET6_ADDRSTRLEN
|
||||||
#define PIM_AF AF_INET6
|
#define PIM_AF AF_INET6
|
||||||
#define PIM_AFI AFI_IP6
|
#define PIM_AFI AFI_IP6
|
||||||
#define PIM_PROTO_REG IPPROTO_PIM
|
#define PIM_PROTO_REG IPPROTO_PIM
|
||||||
|
#define PIM_IANA_AFI IANA_AFI_IPV6
|
||||||
#define PIM_IPADDR IPADDR_V6
|
#define PIM_IPADDR IPADDR_V6
|
||||||
#define ipaddr_pim ipaddr_v6
|
#define ipaddr_pim ipaddr_v6
|
||||||
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
|
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
|
||||||
|
@ -1451,3 +1451,8 @@ int pim_bsm_process(struct interface *ifp, pim_sgaddr *sg, uint8_t *buf,
|
|||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void pim_crp_nht_update(struct pim_instance *pim, struct pim_nexthop_cache *pnc)
|
||||||
|
{
|
||||||
|
/* stub for Candidate-RP */
|
||||||
|
}
|
||||||
|
@ -59,6 +59,7 @@ struct zebra_privs_t pimd_privs = {
|
|||||||
.cap_num_p = array_size(_caps_p),
|
.cap_num_p = array_size(_caps_p),
|
||||||
.cap_num_i = 0};
|
.cap_num_i = 0};
|
||||||
|
|
||||||
|
/* clang-format off */
|
||||||
static const struct frr_yang_module_info *const pimd_yang_modules[] = {
|
static const struct frr_yang_module_info *const pimd_yang_modules[] = {
|
||||||
&frr_filter_info,
|
&frr_filter_info,
|
||||||
&frr_interface_info,
|
&frr_interface_info,
|
||||||
@ -70,7 +71,6 @@ static const struct frr_yang_module_info *const pimd_yang_modules[] = {
|
|||||||
&frr_gmp_info,
|
&frr_gmp_info,
|
||||||
};
|
};
|
||||||
|
|
||||||
/* clang-format off */
|
|
||||||
FRR_DAEMON_INFO(pimd, PIM,
|
FRR_DAEMON_INFO(pimd, PIM,
|
||||||
.vty_port = PIMD_VTY_PORT,
|
.vty_port = PIMD_VTY_PORT,
|
||||||
.proghelp = "Implementation of the PIM routing protocol.",
|
.proghelp = "Implementation of the PIM routing protocol.",
|
||||||
|
@ -161,18 +161,27 @@ void pim_nht_bsr_add(struct pim_instance *pim, pim_addr addr)
|
|||||||
pnc->bsr_count++;
|
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,
|
static void pim_nht_drop_maybe(struct pim_instance *pim,
|
||||||
struct pim_nexthop_cache *pnc)
|
struct pim_nexthop_cache *pnc)
|
||||||
{
|
{
|
||||||
if (PIM_DEBUG_PIM_NHT)
|
if (PIM_DEBUG_PIM_NHT)
|
||||||
zlog_debug(
|
zlog_debug("%s: NHT %pPA(%s) rp_list count:%d upstream count:%ld BSR count:%u Cand-RP 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, pnc->candrp_count);
|
||||||
|
|
||||||
if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0
|
if (pnc->rp_list->count == 0 && pnc->upstream_hash->count == 0 &&
|
||||||
&& pnc->bsr_count == 0) {
|
pnc->bsr_count == 0 && pnc->candrp_count == 0) {
|
||||||
struct zclient *zclient = pim_zebra_zclient_get();
|
struct zclient *zclient = pim_zebra_zclient_get();
|
||||||
|
|
||||||
pim_sendmsg_zebra_rnh(pim, zclient, pnc,
|
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);
|
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,
|
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
|
||||||
struct interface *src_ifp, pim_addr src_ip)
|
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);
|
pim_update_rp_nh(pim, pnc);
|
||||||
if (pnc->upstream_hash->count)
|
if (pnc->upstream_hash->count)
|
||||||
pim_update_upstream_nh(pim, pnc);
|
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,
|
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
|
||||||
|
@ -38,6 +38,7 @@ struct pim_nexthop_cache {
|
|||||||
* same BSR
|
* same BSR
|
||||||
*/
|
*/
|
||||||
uint32_t bsr_count;
|
uint32_t bsr_count;
|
||||||
|
uint32_t candrp_count;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pnc_hash_walk_data {
|
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,
|
bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
|
||||||
struct interface *src_ifp, pim_addr src_ip);
|
struct interface *src_ifp, pim_addr src_ip);
|
||||||
void pim_upstream_nh_if_update(struct pim_instance *pim, struct interface *ifp);
|
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
|
#endif
|
||||||
|
@ -636,18 +636,16 @@ 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_send(int fd, pim_addr src, pim_addr dst, uint8_t *pim_msg,
|
||||||
int pim_msg_size, struct interface *ifp)
|
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_ifp->pim_passive_enable) {
|
||||||
if (PIM_DEBUG_PIM_PACKETS)
|
if (PIM_DEBUG_PIM_PACKETS)
|
||||||
zlog_debug(
|
zlog_debug("skip sending PIM message on passive interface %s",
|
||||||
"skip sending PIM message on passive interface %s",
|
|
||||||
ifp->name);
|
ifp->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#if PIM_IPV == 4
|
#if PIM_IPV == 4
|
||||||
uint8_t ttl;
|
uint8_t ttl;
|
||||||
@ -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)
|
if (PIM_DEBUG_PIM_PACKETS)
|
||||||
zlog_debug("%s: to %pPA on %s: msg_size=%d checksum=%x",
|
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);
|
header->checksum);
|
||||||
|
|
||||||
if (PIM_DEBUG_PIM_PACKETDUMP_SEND) {
|
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,
|
pim_msg_send_frame(fd, (char *)buffer, sendlen, (struct sockaddr *)&to,
|
||||||
tolen, ifp->name);
|
tolen, ifp ? ifp->name : "*");
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
#else
|
#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_base = pim_msg;
|
||||||
iovector[0].iov_len = pim_msg_size;
|
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;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
@ -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_zebra_update_all_interfaces(pim);
|
||||||
|
|
||||||
pim_rp_check_interfaces(pim, rp_all);
|
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_rp_refresh_group_to_rp_mapping(pim);
|
||||||
pim_find_or_track_nexthop(pim, nht_p, NULL, rp_all,
|
pim_find_or_track_nexthop(pim, nht_p, NULL, rp_all,
|
||||||
NULL);
|
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_zebra_update_all_interfaces(pim);
|
||||||
|
|
||||||
pim_rp_check_interfaces(pim, rp_info);
|
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);
|
pim_rp_refresh_group_to_rp_mapping(pim);
|
||||||
|
|
||||||
/* Register addr with Zebra NHT */
|
/* Register addr with Zebra NHT */
|
||||||
|
@ -4668,6 +4668,7 @@ sub process {
|
|||||||
# check for new typedefs, only function parameters and sparse annotations
|
# check for new typedefs, only function parameters and sparse annotations
|
||||||
# make sense.
|
# make sense.
|
||||||
if ($line =~ /\btypedef\s/ &&
|
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*\(\s*\*?$Ident\s*\)\s*\(/ &&
|
||||||
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
|
$line !~ /\btypedef\s+$Type\s+$Ident\s*\(/ &&
|
||||||
$line !~ /\b$typeTypedefs\b/ &&
|
$line !~ /\b$typeTypedefs\b/ &&
|
||||||
|
Loading…
Reference in New Issue
Block a user