summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
Diffstat (limited to 'pimd')
-rw-r--r--pimd/pim6_cmd.c8
-rw-r--r--pimd/pim6_main.c10
-rw-r--r--pimd/pim6_mld.c1
-rw-r--r--pimd/pim_addr.h16
-rw-r--r--pimd/pim_cmd.c16
-rw-r--r--pimd/pim_cmd_common.c63
-rw-r--r--pimd/pim_hello.c2
-rw-r--r--pimd/pim_iface.c33
-rw-r--r--pimd/pim_igmp_mtrace.c3
-rw-r--r--pimd/pim_instance.h2
-rw-r--r--pimd/pim_join.c6
-rw-r--r--pimd/pim_main.c17
-rw-r--r--pimd/pim_mlag.c4
-rw-r--r--pimd/pim_mroute.c5
-rw-r--r--pimd/pim_mroute.h28
-rw-r--r--pimd/pim_msg.c138
-rw-r--r--pimd/pim_nb_config.c40
-rw-r--r--pimd/pim_nht.c55
-rw-r--r--pimd/pim_nht.h3
-rw-r--r--pimd/pim_pim.c15
-rw-r--r--pimd/pim_rp.c2
-rw-r--r--pimd/pim_rpf.c2
-rw-r--r--pimd/pim_sock.c1
-rw-r--r--pimd/pim_tlv.c10
-rw-r--r--pimd/pim_upstream.c39
-rw-r--r--pimd/pim_upstream.h2
-rw-r--r--pimd/pim_vxlan.c49
-rw-r--r--pimd/pim_vxlan.h3
-rw-r--r--pimd/pim_zebra.c15
-rw-r--r--pimd/pim_zlookup.c5
-rw-r--r--pimd/pimd.h3
31 files changed, 342 insertions, 254 deletions
diff --git a/pimd/pim6_cmd.c b/pimd/pim6_cmd.c
index 262ce86..4db1157 100644
--- a/pimd/pim6_cmd.c
+++ b/pimd/pim6_cmd.c
@@ -77,7 +77,7 @@ DEFPY (ipv6_pim_spt_switchover_infinity,
DEFPY (ipv6_pim_spt_switchover_infinity_plist,
ipv6_pim_spt_switchover_infinity_plist_cmd,
- "ipv6 pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
+ "ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME$plist",
IPV6_STR
PIM_STR
"SPT-Switchover\n"
@@ -102,7 +102,7 @@ DEFPY (no_ipv6_pim_spt_switchover_infinity,
DEFPY (no_ipv6_pim_spt_switchover_infinity_plist,
no_ipv6_pim_spt_switchover_infinity_plist_cmd,
- "no ipv6 pim spt-switchover infinity-and-beyond prefix-list WORD",
+ "no ipv6 pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST6_NAME",
NO_STR
IPV6_STR
PIM_STR
@@ -436,7 +436,7 @@ DEFPY (no_ipv6_pim_rp,
DEFPY (ipv6_pim_rp_prefix_list,
ipv6_pim_rp_prefix_list_cmd,
- "ipv6 pim rp X:X::X:X$rp prefix-list WORD$plist",
+ "ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
IPV6_STR
PIM_STR
"Rendezvous Point\n"
@@ -449,7 +449,7 @@ DEFPY (ipv6_pim_rp_prefix_list,
DEFPY (no_ipv6_pim_rp_prefix_list,
no_ipv6_pim_rp_prefix_list_cmd,
- "no ipv6 pim rp X:X::X:X$rp prefix-list WORD$plist",
+ "no ipv6 pim rp X:X::X:X$rp prefix-list PREFIXLIST6_NAME$plist",
NO_STR
IPV6_STR
PIM_STR
diff --git a/pimd/pim6_main.c b/pimd/pim6_main.c
index 1af4a17..5ce6985 100644
--- a/pimd/pim6_main.c
+++ b/pimd/pim6_main.c
@@ -26,6 +26,7 @@
#include "pim_nb.h"
#include "pim6_cmd.h"
#include "pim6_mld.h"
+#include "pim_zlookup.h"
zebra_capabilities_t _caps_p[] = {
ZCAP_SYS_ADMIN,
@@ -189,11 +190,20 @@ int main(int argc, char **argv, char **envp)
static void pim6_terminate(void)
{
+ struct zclient *zclient;
+
pim_vrf_terminate();
pim_router_terminate();
prefix_list_reset();
access_list_reset();
+ zclient = pim_zebra_zclient_get();
+ if (zclient) {
+ zclient_stop(zclient);
+ zclient_free(zclient);
+ }
+
+ zclient_lookup_free();
frr_fini();
}
diff --git a/pimd/pim6_mld.c b/pimd/pim6_mld.c
index 20ef921..a39d182 100644
--- a/pimd/pim6_mld.c
+++ b/pimd/pim6_mld.c
@@ -13,6 +13,7 @@
*/
#include <zebra.h>
+#include <netinet/icmp6.h>
#include <netinet/ip6.h>
#include "lib/memory.h"
diff --git a/pimd/pim_addr.h b/pimd/pim_addr.h
index 94c63bb..ecba739 100644
--- a/pimd/pim_addr.h
+++ b/pimd/pim_addr.h
@@ -33,13 +33,13 @@ typedef struct in_addr pim_addr;
#define PIM_ADDR_FUNCNAME(name) ipv4_##name
union pimprefixptr {
- prefixtype(pimprefixptr, struct prefix, p)
- prefixtype(pimprefixptr, struct prefix_ipv4, p4)
+ uniontype(pimprefixptr, struct prefix, p)
+ uniontype(pimprefixptr, struct prefix_ipv4, p4)
} TRANSPARENT_UNION;
union pimprefixconstptr {
- prefixtype(pimprefixconstptr, const struct prefix, p)
- prefixtype(pimprefixconstptr, const struct prefix_ipv4, p4)
+ uniontype(pimprefixconstptr, const struct prefix, p)
+ uniontype(pimprefixconstptr, const struct prefix_ipv4, p4)
} TRANSPARENT_UNION;
#else
@@ -63,13 +63,13 @@ typedef struct in6_addr pim_addr;
#define PIM_ADDR_FUNCNAME(name) ipv6_##name
union pimprefixptr {
- prefixtype(pimprefixptr, struct prefix, p)
- prefixtype(pimprefixptr, struct prefix_ipv6, p6)
+ uniontype(pimprefixptr, struct prefix, p)
+ uniontype(pimprefixptr, struct prefix_ipv6, p6)
} TRANSPARENT_UNION;
union pimprefixconstptr {
- prefixtype(pimprefixconstptr, const struct prefix, p)
- prefixtype(pimprefixconstptr, const struct prefix_ipv6, p6)
+ uniontype(pimprefixconstptr, const struct prefix, p)
+ uniontype(pimprefixconstptr, const struct prefix_ipv6, p6)
} TRANSPARENT_UNION;
#endif
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 2e90cf9..be36a07 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -78,7 +78,7 @@ static struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
if (!vrf) {
if (uj)
- vty_json_empty(vty);
+ vty_json_empty(vty, NULL);
else
vty_out(vty, "Specified VRF: %s does not exist\n",
argv[*idx]->arg);
@@ -2999,7 +2999,7 @@ DEFUN (ip_pim_spt_switchover_infinity,
DEFPY (ip_pim_spt_switchover_infinity_plist,
ip_pim_spt_switchover_infinity_plist_cmd,
- "ip pim spt-switchover infinity-and-beyond prefix-list WORD$plist",
+ "ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME$plist",
IP_STR
PIM_STR
"SPT-Switchover\n"
@@ -3024,7 +3024,7 @@ DEFUN (no_ip_pim_spt_switchover_infinity,
DEFUN (no_ip_pim_spt_switchover_infinity_plist,
no_ip_pim_spt_switchover_infinity_plist_cmd,
- "no ip pim spt-switchover infinity-and-beyond prefix-list WORD",
+ "no ip pim spt-switchover infinity-and-beyond prefix-list PREFIXLIST4_NAME",
NO_STR
IP_STR
PIM_STR
@@ -3038,7 +3038,7 @@ DEFUN (no_ip_pim_spt_switchover_infinity_plist,
DEFPY (pim_register_accept_list,
pim_register_accept_list_cmd,
- "[no] ip pim register-accept-list WORD$word",
+ "[no] ip pim register-accept-list PREFIXLIST4_NAME$word",
NO_STR
IP_STR
PIM_STR
@@ -3283,7 +3283,7 @@ DEFPY (ip_pim_rp,
DEFPY (ip_pim_rp_prefix_list,
ip_pim_rp_prefix_list_cmd,
- "ip pim rp A.B.C.D$rp prefix-list WORD$plist",
+ "ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
IP_STR
"pim multicast routing\n"
"Rendezvous Point\n"
@@ -3311,7 +3311,7 @@ DEFPY (no_ip_pim_rp,
DEFPY (no_ip_pim_rp_prefix_list,
no_ip_pim_rp_prefix_list_cmd,
- "no ip pim rp A.B.C.D$rp prefix-list WORD$plist",
+ "no ip pim rp A.B.C.D$rp prefix-list PREFIXLIST4_NAME$plist",
NO_STR
IP_STR
"pim multicast routing\n"
@@ -3325,7 +3325,7 @@ DEFPY (no_ip_pim_rp_prefix_list,
DEFUN (ip_pim_ssm_prefix_list,
ip_pim_ssm_prefix_list_cmd,
- "ip pim ssm prefix-list WORD",
+ "ip pim ssm prefix-list PREFIXLIST4_NAME",
IP_STR
"pim multicast routing\n"
"Source Specific Multicast\n"
@@ -3376,7 +3376,7 @@ DEFUN (no_ip_pim_ssm_prefix_list,
DEFUN (no_ip_pim_ssm_prefix_list_name,
no_ip_pim_ssm_prefix_list_name_cmd,
- "no ip pim ssm prefix-list WORD",
+ "no ip pim ssm prefix-list PREFIXLIST4_NAME",
NO_STR
IP_STR
"pim multicast routing\n"
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index c3eb49d..ee318d4 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -6,6 +6,7 @@
*/
#include <zebra.h>
+#include <sys/ioctl.h>
#include "lib/json.h"
#include "command.h"
@@ -68,7 +69,7 @@ const char *pim_cli_get_vrf_name(struct vty *vty)
return NULL;
}
- return yang_dnode_get_string(vrf_node, "./name");
+ return yang_dnode_get_string(vrf_node, "name");
}
int pim_process_join_prune_cmd(struct vty *vty, const char *jpi_str)
@@ -524,7 +525,9 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str)
{
const char *vrfname;
- char rp_group_xpath[XPATH_MAXLEN];
+ char group_xpath[XPATH_MAXLEN];
+ char rp_xpath[XPATH_MAXLEN];
+ int printed;
int result = 0;
struct prefix group;
pim_addr rp_addr;
@@ -569,12 +572,18 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
if (vrfname == NULL)
return CMD_WARNING_CONFIG_FAILED;
- snprintf(rp_group_xpath, sizeof(rp_group_xpath),
- FRR_PIM_STATIC_RP_XPATH, "frr-pim:pimd", "pim", vrfname,
- FRR_PIM_AF_XPATH_VAL, rp_str);
- strlcat(rp_group_xpath, "/group-list", sizeof(rp_group_xpath));
+ snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
+ "frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
+ printed = snprintf(group_xpath, sizeof(group_xpath),
+ "%s/group-list[.='%s']", rp_xpath, group_str);
+
+ if (printed >= (int)(sizeof(group_xpath))) {
+ vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
+ XPATH_MAXLEN);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- nb_cli_enqueue_change(vty, rp_group_xpath, NB_OP_CREATE, group_str);
+ nb_cli_enqueue_change(vty, group_xpath, NB_OP_CREATE, NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -582,7 +591,6 @@ int pim_process_rp_cmd(struct vty *vty, const char *rp_str,
int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
const char *group_str)
{
- char group_list_xpath[XPATH_MAXLEN];
char group_xpath[XPATH_MAXLEN];
char rp_xpath[XPATH_MAXLEN];
int printed;
@@ -595,18 +603,8 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
snprintf(rp_xpath, sizeof(rp_xpath), FRR_PIM_STATIC_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, FRR_PIM_AF_XPATH_VAL, rp_str);
-
- printed = snprintf(group_list_xpath, sizeof(group_list_xpath),
- "%s/group-list", rp_xpath);
-
- if (printed >= (int)(sizeof(group_list_xpath))) {
- vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
- XPATH_MAXLEN);
- return CMD_WARNING_CONFIG_FAILED;
- }
-
- printed = snprintf(group_xpath, sizeof(group_xpath), "%s[.='%s']",
- group_list_xpath, group_str);
+ printed = snprintf(group_xpath, sizeof(group_xpath),
+ "%s/group-list[.='%s']", rp_xpath, group_str);
if (printed >= (int)(sizeof(group_xpath))) {
vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
@@ -623,8 +621,7 @@ int pim_process_no_rp_cmd(struct vty *vty, const char *rp_str,
if (yang_is_last_list_dnode(group_dnode))
nb_cli_enqueue_change(vty, rp_xpath, NB_OP_DESTROY, NULL);
else
- nb_cli_enqueue_change(vty, group_list_xpath, NB_OP_DESTROY,
- group_str);
+ nb_cli_enqueue_change(vty, group_xpath, NB_OP_DESTROY, NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -1059,8 +1056,8 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
frr_each (rb_pim_oil, &pim->channel_oil_head, c_oil) {
char src_str[PIM_ADDRSTRLEN];
char grp_str[PIM_ADDRSTRLEN];
- char in_ifname[INTERFACE_NAMSIZ + 1];
- char out_ifname[INTERFACE_NAMSIZ + 1];
+ char in_ifname[IFNAMSIZ + 1];
+ char out_ifname[IFNAMSIZ + 1];
int oif_vif_index;
struct interface *ifp_in;
bool isRpt;
@@ -3406,6 +3403,8 @@ int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
{
const char *vrfname;
char ssmpingd_ip_xpath[XPATH_MAXLEN];
+ char ssmpingd_src_ip_xpath[XPATH_MAXLEN];
+ int printed;
vrfname = pim_cli_get_vrf_name(vty);
if (vrfname == NULL)
@@ -3414,10 +3413,16 @@ int pim_process_ssmpingd_cmd(struct vty *vty, enum nb_operation operation,
snprintf(ssmpingd_ip_xpath, sizeof(ssmpingd_ip_xpath),
FRR_PIM_VRF_XPATH, "frr-pim:pimd", "pim", vrfname,
FRR_PIM_AF_XPATH_VAL);
- strlcat(ssmpingd_ip_xpath, "/ssm-pingd-source-ip",
- sizeof(ssmpingd_ip_xpath));
+ printed = snprintf(ssmpingd_src_ip_xpath, sizeof(ssmpingd_src_ip_xpath),
+ "%s/ssm-pingd-source-ip[.='%s']", ssmpingd_ip_xpath,
+ src_str);
+ if (printed >= (int)sizeof(ssmpingd_src_ip_xpath)) {
+ vty_out(vty, "Xpath too long (%d > %u)", printed + 1,
+ XPATH_MAXLEN);
+ return CMD_WARNING_CONFIG_FAILED;
+ }
- nb_cli_enqueue_change(vty, ssmpingd_ip_xpath, operation, src_str);
+ nb_cli_enqueue_change(vty, ssmpingd_src_ip_xpath, operation, NULL);
return nb_cli_apply_changes(vty, NULL);
}
@@ -3662,8 +3667,8 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
int first;
char grp_str[PIM_ADDRSTRLEN];
char src_str[PIM_ADDRSTRLEN];
- char in_ifname[INTERFACE_NAMSIZ + 1];
- char out_ifname[INTERFACE_NAMSIZ + 1];
+ char in_ifname[IFNAMSIZ + 1];
+ char out_ifname[IFNAMSIZ + 1];
int oif_vif_index;
struct interface *ifp_in;
char proto[100];
diff --git a/pimd/pim_hello.c b/pimd/pim_hello.c
index 978607d..a0661ef 100644
--- a/pimd/pim_hello.c
+++ b/pimd/pim_hello.c
@@ -440,7 +440,7 @@ int pim_hello_build_tlv(struct interface *ifp, uint8_t *tlv_buf,
}
/* Secondary Address List */
- if (ifp->connected->count) {
+ if (if_connected_count(ifp->connected)) {
curr = pim_tlv_append_addrlist_ucast(curr, pastend, ifp,
PIM_AF);
if (!curr) {
diff --git a/pimd/pim_iface.c b/pimd/pim_iface.c
index 5fa4715..5d7132c 100644
--- a/pimd/pim_iface.c
+++ b/pimd/pim_iface.c
@@ -379,7 +379,7 @@ static int pim_sec_addr_update(struct interface *ifp)
sec_addr->flags |= PIM_SEC_ADDRF_STALE;
}
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
pim_addr addr = pim_addr_from_prefix(ifc->address);
if (pim_addr_is_any(addr))
@@ -723,13 +723,12 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
if (pim_ifp &&
(!IPV6_ADDR_CMP(&ifc->address->u.prefix6, &pim_ifp->ll_lowest) ||
!IPV6_ADDR_CMP(&ifc->address->u.prefix6, &pim_ifp->ll_highest))) {
- struct listnode *cnode;
struct connected *cc;
memset(&pim_ifp->ll_lowest, 0xff, sizeof(pim_ifp->ll_lowest));
memset(&pim_ifp->ll_highest, 0, sizeof(pim_ifp->ll_highest));
- for (ALL_LIST_ELEMENTS_RO(ifc->ifp->connected, cnode, cc)) {
+ frr_each (if_connected, ifc->ifp->connected, cc) {
if (!IN6_IS_ADDR_LINKLOCAL(&cc->address->u.prefix6) &&
!IN6_IS_ADDR_LOOPBACK(&cc->address->u.prefix6))
continue;
@@ -765,8 +764,6 @@ void pim_if_addr_del(struct connected *ifc, int force_prim_as_any)
void pim_if_addr_add_all(struct interface *ifp)
{
struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
int v4_addrs = 0;
int v6_addrs = 0;
struct pim_interface *pim_ifp = ifp->info;
@@ -777,7 +774,7 @@ void pim_if_addr_add_all(struct interface *ifp)
if (!pim_ifp)
return;
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
struct prefix *p = ifc->address;
if (p->family != AF_INET)
@@ -813,8 +810,6 @@ void pim_if_addr_add_all(struct interface *ifp)
void pim_if_addr_del_all(struct interface *ifp)
{
struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
struct pim_instance *pim;
pim = ifp->vrf->info;
@@ -825,7 +820,7 @@ void pim_if_addr_del_all(struct interface *ifp)
if (!ifp->info)
return;
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ frr_each_safe (if_connected, ifp->connected, ifc) {
struct prefix *p = ifc->address;
if (p->family != PIM_AF)
@@ -841,14 +836,12 @@ void pim_if_addr_del_all(struct interface *ifp)
void pim_if_addr_del_all_igmp(struct interface *ifp)
{
struct connected *ifc;
- struct listnode *node;
- struct listnode *nextnode;
/* PIM/IGMP enabled ? */
if (!ifp->info)
return;
- for (ALL_LIST_ELEMENTS(ifp->connected, node, nextnode, ifc)) {
+ frr_each_safe (if_connected, ifp->connected, ifc) {
struct prefix *p = ifc->address;
if (p->family != AF_INET)
@@ -861,7 +854,6 @@ void pim_if_addr_del_all_igmp(struct interface *ifp)
pim_addr pim_find_primary_addr(struct interface *ifp)
{
struct connected *ifc;
- struct listnode *node;
struct pim_interface *pim_ifp = ifp->info;
if (pim_ifp && !pim_addr_is_any(pim_ifp->update_source))
@@ -873,7 +865,7 @@ pim_addr pim_find_primary_addr(struct interface *ifp)
pim_addr best_addr = PIMADDR_ANY;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
pim_addr addr;
if (ifc->address->family != AF_INET6)
@@ -892,7 +884,7 @@ pim_addr pim_find_primary_addr(struct interface *ifp)
int v6_addrs = 0;
struct connected *promote_ifc = NULL;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
switch (ifc->address->family) {
case AF_INET:
v4_addrs++;
@@ -1487,7 +1479,7 @@ void pim_if_update_assert_tracking_desired(struct interface *ifp)
*/
void pim_if_create_pimreg(struct pim_instance *pim)
{
- char pimreg_name[INTERFACE_NAMSIZ];
+ char pimreg_name[IFNAMSIZ];
if (!pim->regiface) {
if (pim->vrf->vrf_id == VRF_DEFAULT)
@@ -1523,7 +1515,6 @@ void pim_if_create_pimreg(struct pim_instance *pim)
struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src)
{
- struct listnode *cnode;
struct connected *c;
struct prefix p;
@@ -1532,7 +1523,7 @@ struct prefix *pim_if_connected_to_source(struct interface *ifp, pim_addr src)
pim_addr_to_prefix(&p, src);
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, cnode, c)) {
+ frr_each (if_connected, ifp->connected, c) {
if (c->address->family != PIM_AF)
continue;
if (prefix_match(c->address, &p))
@@ -1771,8 +1762,10 @@ void pim_iface_init(void)
hook_register_prio(if_add, 0, pim_if_new_hook);
hook_register_prio(if_del, 0, pim_if_delete_hook);
- if_zapi_callbacks(pim_ifp_create, pim_ifp_up, pim_ifp_down,
- pim_ifp_destroy);
+ hook_register_prio(if_real, 0, pim_ifp_create);
+ hook_register_prio(if_up, 0, pim_ifp_up);
+ hook_register_prio(if_down, 0, pim_ifp_down);
+ hook_register_prio(if_unreal, 0, pim_ifp_destroy);
}
static void pim_if_membership_clear(struct interface *ifp)
diff --git a/pimd/pim_igmp_mtrace.c b/pimd/pim_igmp_mtrace.c
index 4d3f602..309da13 100644
--- a/pimd/pim_igmp_mtrace.c
+++ b/pimd/pim_igmp_mtrace.c
@@ -21,7 +21,6 @@
static struct in_addr mtrace_primary_address(struct interface *ifp)
{
struct connected *ifc;
- struct listnode *node;
struct in_addr any;
struct pim_interface *pim_ifp;
@@ -32,7 +31,7 @@ static struct in_addr mtrace_primary_address(struct interface *ifp)
any.s_addr = INADDR_ANY;
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
struct prefix *p = ifc->address;
if (p->family != AF_INET)
diff --git a/pimd/pim_instance.h b/pimd/pim_instance.h
index 11577ae..ec33133 100644
--- a/pimd/pim_instance.h
+++ b/pimd/pim_instance.h
@@ -97,7 +97,7 @@ struct pim_router {
struct in_addr local_vtep_ip;
struct pim_mlag_stats mlag_stats;
enum pim_mlag_flags mlag_flags;
- char peerlink_rif[INTERFACE_NAMSIZ];
+ char peerlink_rif[IFNAMSIZ];
struct interface *peerlink_rif_p;
};
diff --git a/pimd/pim_join.c b/pimd/pim_join.c
index 671f7a3..bfdb0f0 100644
--- a/pimd/pim_join.c
+++ b/pimd/pim_join.c
@@ -43,7 +43,7 @@ static void recv_join(struct interface *ifp, struct pim_neighbor *neigh,
{
struct pim_interface *pim_ifp = NULL;
- if (PIM_DEBUG_PIM_TRACE)
+ if (PIM_DEBUG_PIM_J_P)
zlog_debug(
"%s: join (S,G)=%pSG rpt=%d wc=%d upstream=%pPAs holdtime=%d from %pPA on %s",
__func__, sg, !!(source_flags & PIM_RPT_BIT_MASK),
@@ -115,7 +115,7 @@ static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
{
struct pim_interface *pim_ifp = NULL;
- if (PIM_DEBUG_PIM_TRACE)
+ if (PIM_DEBUG_PIM_J_P)
zlog_debug(
"%s: prune (S,G)=%pSG rpt=%d wc=%d upstream=%pPAs holdtime=%d from %pPA on %s",
__func__, sg, source_flags & PIM_RPT_BIT_MASK,
@@ -147,7 +147,7 @@ static void recv_prune(struct interface *ifp, struct pim_neighbor *neigh,
* Received Prune(*,G) messages are processed even if the
* RP in the message does not match RP(G).
*/
- if (PIM_DEBUG_PIM_TRACE)
+ if (PIM_DEBUG_PIM_J_P)
zlog_debug("%s: Prune received with RP(%pPAs) for %pSG",
__func__, &sg->src, sg);
diff --git a/pimd/pim_main.c b/pimd/pim_main.c
index 7db0a76..400db39 100644
--- a/pimd/pim_main.c
+++ b/pimd/pim_main.c
@@ -70,17 +70,20 @@ static const struct frr_yang_module_info *const pimd_yang_modules[] = {
&frr_gmp_info,
};
-FRR_DAEMON_INFO(pimd, PIM, .vty_port = PIMD_VTY_PORT,
+/* clang-format off */
+FRR_DAEMON_INFO(pimd, PIM,
+ .vty_port = PIMD_VTY_PORT,
+ .proghelp = "Implementation of the PIM routing protocol.",
- .proghelp = "Implementation of the PIM routing protocol.",
+ .signals = pimd_signals,
+ .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
- .signals = pimd_signals,
- .n_signals = 4 /* XXX array_size(pimd_signals) XXX*/,
+ .privs = &pimd_privs,
- .privs = &pimd_privs, .yang_modules = pimd_yang_modules,
- .n_yang_modules = array_size(pimd_yang_modules),
+ .yang_modules = pimd_yang_modules,
+ .n_yang_modules = array_size(pimd_yang_modules),
);
-
+/* clang-format on */
int main(int argc, char **argv, char **envp)
{
diff --git a/pimd/pim_mlag.c b/pimd/pim_mlag.c
index 5d72eb6..dcef2d0 100644
--- a/pimd/pim_mlag.c
+++ b/pimd/pim_mlag.c
@@ -434,7 +434,7 @@ static void pim_mlag_up_local_add_send(struct pim_instance *pim,
stream_putc(s, !(PIM_UPSTREAM_FLAG_TEST_MLAG_NON_DF(up->flags)));
stream_putl(s, vrf->vrf_id);
/* XXX - this field is a No-op for VXLAN*/
- stream_put(s, NULL, INTERFACE_NAMSIZ);
+ stream_put(s, NULL, IFNAMSIZ);
stream_fifo_push_safe(router->mlag_fifo, s);
pim_mlag_signal_zpthread();
@@ -467,7 +467,7 @@ static void pim_mlag_up_local_del_send(struct pim_instance *pim,
stream_putl(s, MLAG_OWNER_VXLAN);
stream_putl(s, vrf->vrf_id);
/* XXX - this field is a No-op for VXLAN */
- stream_put(s, NULL, INTERFACE_NAMSIZ);
+ stream_put(s, NULL, IFNAMSIZ);
/* XXX - is this the the most optimal way to do things */
stream_fifo_push_safe(router->mlag_fifo, s);
diff --git a/pimd/pim_mroute.c b/pimd/pim_mroute.c
index 7ea6ed9..c63e0f3 100644
--- a/pimd/pim_mroute.c
+++ b/pimd/pim_mroute.c
@@ -5,6 +5,9 @@
*/
#include <zebra.h>
+#include <netinet/icmp6.h>
+#include <sys/ioctl.h>
+
#include "log.h"
#include "privs.h"
#include "if.h"
@@ -1216,7 +1219,7 @@ int pim_upstream_mroute_add(struct channel_oil *c_oil, const char *name)
return pim_upstream_mroute_update(c_oil, name);
}
-/* Look for IIF changes and update the dateplane entry only if the IIF
+/* Look for IIF changes and update the dataplane entry only if the IIF
* has changed.
*/
int pim_upstream_mroute_iif_update(struct channel_oil *c_oil, const char *name)
diff --git a/pimd/pim_mroute.h b/pimd/pim_mroute.h
index 8706f42..fd4913c 100644
--- a/pimd/pim_mroute.h
+++ b/pimd/pim_mroute.h
@@ -25,8 +25,19 @@
#include <netinet/in.h>
#if defined(HAVE_LINUX_MROUTE_H)
#include <linux/mroute.h>
-#else
-#include "linux/mroute.h"
+#endif
+
+#if defined(HAVE_NETINET_IP_MROUTE_H)
+#include <netinet/ip_mroute.h>
+/*
+ * MRT_TABLE of 155 is needed because it is not defined
+ * on FreeBSD. MRT_TABLE is for vrf's. There is no
+ * equivalent on BSD at this point in time. Let's
+ * just get it compiling
+ */
+#ifndef MRT_TABLE
+#define MRT_TABLE 155
+#endif
#endif
typedef struct vifctl pim_vifctl;
@@ -70,8 +81,17 @@ typedef struct sioc_sg_req pim_sioc_sg_req;
#if defined(HAVE_LINUX_MROUTE6_H)
#include <linux/mroute6.h>
-#else
-#include "linux/mroute6.h"
+#endif
+#if defined(HAVE_NETINET_IP6_MROUTE_H)
+#include <sys/param.h>
+#include <netinet6/ip6_mroute.h>
+
+/*
+ * See the v4 discussion above
+ */
+#ifndef MRT_TABLE
+#define MRT_TABLE 155
+#endif
#endif
#ifndef MRT_INIT
diff --git a/pimd/pim_msg.c b/pimd/pim_msg.c
index 6814798..7a86e6b 100644
--- a/pimd/pim_msg.c
+++ b/pimd/pim_msg.c
@@ -185,84 +185,78 @@ size_t pim_msg_get_jp_group_size(struct list *sources)
size += sizeof(pim_encoded_source) * sources->count;
js = listgetdata(listhead(sources));
- if (js && pim_addr_is_any(js->up->sg.src) && js->is_join) {
- struct pim_upstream *child, *up;
- struct listnode *up_node;
-
- up = js->up;
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "%s: Considering (%s) children for (S,G,rpt) prune",
- __func__, up->sg_str);
-
- for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
- /*
- * PIM VXLAN is weird
- * It auto creates the S,G and populates a bunch
- * of flags that make it look like a SPT prune should
- * be sent. But this regularly scheduled join
- * for the *,G in the VXLAN setup can happen at
- * scheduled times *before* the null register
- * is received by the RP to cause it to initiate
- * the S,G joins toward the source. Let's just
- * assume that if this is a SRC VXLAN ORIG route
- * and no actual ifchannels( joins ) have been
- * created then do not send the embedded prune
- * Why you may ask? Well if the prune is S,G
- * RPT Prune is received *before* the join
- * from the RP( if it flows to this routers
- * upstream interface ) then we'll just wisely
- * create a mroute with an empty oil on
- * the upstream intermediate router preventing
- * packets from flowing to the RP
+ if (!js || !pim_addr_is_any(js->up->sg.src) || !js->is_join)
+ return size;
+
+ struct pim_upstream *child, *up;
+ struct listnode *up_node;
+
+ up = js->up;
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: Considering (%s) children for (S,G,rpt) prune",
+ __func__, up->sg_str);
+
+ for (ALL_LIST_ELEMENTS_RO(up->sources, up_node, child)) {
+ /*
+ * PIM VXLAN is weird
+ * It auto creates the S,G and populates a bunch
+ * of flags that make it look like a SPT prune should
+ * be sent. But this regularly scheduled join
+ * for the *,G in the VXLAN setup can happen at
+ * scheduled times *before* the null register
+ * is received by the RP to cause it to initiate
+ * the S,G joins toward the source. Let's just
+ * assume that if this is a SRC VXLAN ORIG route
+ * and no actual ifchannels( joins ) have been
+ * created then do not send the embedded prune
+ * Why you may ask? Well if the prune is S,G
+ * RPT Prune is received *before* the join
+ * from the RP( if it flows to this routers
+ * upstream interface ) then we'll just wisely
+ * create a mroute with an empty oil on
+ * the upstream intermediate router preventing
+ * packets from flowing to the RP
+ */
+ if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(child->flags) &&
+ listcount(child->ifchannels) == 0) {
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: %s Vxlan originated S,G route with no ifchannels, not adding prune to compound message",
+ __func__, child->sg_str);
+ } else if (!PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)) {
+ /* If we are using SPT and the SPT and RPT IIFs
+ * are different we can prune the source off
+ * of the RPT.
+ * If RPF_interface(S) is not resolved hold
+ * decision to prune as SPT may end up on the
+ * same IIF as RPF_interface(RP).
*/
- if (PIM_UPSTREAM_FLAG_TEST_SRC_VXLAN_ORIG(child->flags) &&
- listcount(child->ifchannels) == 0) {
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug("%s: %s Vxlan originated S,G route with no ifchannels, not adding prune to compound message",
- __func__, child->sg_str);
- } else if (!PIM_UPSTREAM_FLAG_TEST_USE_RPT(child->flags)) {
- /* If we are using SPT and the SPT and RPT IIFs
- * are different we can prune the source off
- * of the RPT.
- * If RPF_interface(S) is not resolved hold
- * decision to prune as SPT may end up on the
- * same IIF as RPF_interface(RP).
- */
- if (child->rpf.source_nexthop.interface &&
- !pim_rpf_is_same(&up->rpf,
- &child->rpf)) {
- size += sizeof(pim_encoded_source);
- PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
- child->flags);
- if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "%s: SPT Bit and RPF'(%s) != RPF'(S,G): Add Prune (%s,rpt) to compound message",
- __func__, up->sg_str,
- child->sg_str);
- } else if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "%s: SPT Bit and RPF'(%s) == RPF'(S,G): Not adding Prune for (%s,rpt)",
- __func__, up->sg_str,
- child->sg_str);
- } else if (pim_upstream_empty_inherited_olist(child)) {
- /* S is supposed to be forwarded along the RPT
- * but it's inherited OIL is empty. So just
- * prune it off.
- */
+ if (child->rpf.source_nexthop.interface &&
+ !pim_rpf_is_same(&up->rpf, &child->rpf)) {
size += sizeof(pim_encoded_source);
PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(
- child->flags);
+ child->flags);
if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "%s: inherited_olist(%s,rpt) is NULL, Add Prune to compound message",
- __func__, child->sg_str);
+ zlog_debug("%s: SPT Bit and RPF'(%s) != RPF'(S,G): Add Prune (%s,rpt) to compound message",
+ __func__, up->sg_str,
+ child->sg_str);
} else if (PIM_DEBUG_PIM_PACKETS)
- zlog_debug(
- "%s: Do not add Prune %s to compound message %s",
- __func__, child->sg_str, up->sg_str);
- }
+ zlog_debug("%s: SPT Bit and RPF'(%s) == RPF'(S,G): Not adding Prune for (%s,rpt)",
+ __func__, up->sg_str, child->sg_str);
+ } else if (pim_upstream_empty_inherited_olist(child)) {
+ /* S is supposed to be forwarded along the RPT
+ * but it's inherited OIL is empty. So just
+ * prune it off.
+ */
+ size += sizeof(pim_encoded_source);
+ PIM_UPSTREAM_FLAG_SET_SEND_SG_RPT_PRUNE(child->flags);
+ if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: inherited_olist(%s,rpt) is NULL, Add Prune to compound message",
+ __func__, child->sg_str);
+ } else if (PIM_DEBUG_PIM_PACKETS)
+ zlog_debug("%s: Do not add Prune %s to compound message %s",
+ __func__, child->sg_str, up->sg_str);
}
+
return size;
}
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index be05b69..4f1a4a1 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -485,7 +485,7 @@ int routing_control_plane_protocols_name_validate(
{
const char *name;
- name = yang_dnode_get_string(args->dnode, "./name");
+ name = yang_dnode_get_string(args->dnode, "name");
if (!strmatch(name, "pim")) {
snprintf(args->errmsg, args->errmsg_len,
"pim supports only one instance with name pimd");
@@ -779,7 +779,7 @@ void routing_control_plane_protocols_control_plane_protocol_pim_address_family_s
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
- spt_switch_action = yang_dnode_get_enum(args->dnode, "./spt-action");
+ spt_switch_action = yang_dnode_get_enum(args->dnode, "spt-action");
switch (spt_switch_action) {
case PIM_SPT_INFINITY:
@@ -922,8 +922,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
- yang_dnode_get_pimaddr(&source_addr, args->dnode,
- "./source-addr");
+ yang_dnode_get_pimaddr(&source_addr, args->dnode, NULL);
result = pim_ssmpingd_start(pim, source_addr);
if (result) {
snprintf(
@@ -953,8 +952,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ss
case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
- yang_dnode_get_pimaddr(&source_addr, args->dnode,
- "./source-addr");
+ yang_dnode_get_pimaddr(&source_addr, args->dnode, NULL);
result = pim_ssmpingd_stop(pim, source_addr);
if (result) {
snprintf(
@@ -1233,8 +1231,8 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_ms
case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
- yang_dnode_get_ip(&peer_ip, args->dnode, "./peer-ip");
- yang_dnode_get_ip(&source_ip, args->dnode, "./source-ip");
+ yang_dnode_get_ip(&peer_ip, args->dnode, "peer-ip");
+ yang_dnode_get_ip(&source_ip, args->dnode, "source-ip");
mp = pim_msdp_peer_add(pim, &peer_ip.ipaddr_v4,
&source_ip.ipaddr_v4, NULL);
nb_running_set_entry(args->dnode, mp);
@@ -1338,16 +1336,16 @@ void routing_control_plane_protocols_control_plane_protocol_pim_address_family_m
struct interface *ifp;
struct ipaddr reg_addr;
- ifname = yang_dnode_get_string(args->dnode, "./peerlink-rif");
+ ifname = yang_dnode_get_string(args->dnode, "peerlink-rif");
ifp = if_lookup_by_name(ifname, VRF_DEFAULT);
if (!ifp) {
snprintf(args->errmsg, args->errmsg_len,
"No such interface name %s", ifname);
return;
}
- role = yang_dnode_get_enum(args->dnode, "./my-role");
- peer_state = yang_dnode_get_bool(args->dnode, "./peer-state");
- yang_dnode_get_ip(&reg_addr, args->dnode, "./reg-address");
+ role = yang_dnode_get_enum(args->dnode, "my-role");
+ peer_state = yang_dnode_get_bool(args->dnode, "peer-state");
+ yang_dnode_get_ip(&reg_addr, args->dnode, "reg-address");
pim_vxlan_mlag_update(true, peer_state, role, ifp,
&reg_addr.ip._v4_addr);
@@ -1759,11 +1757,11 @@ void lib_interface_pim_address_family_bfd_apply_finish(
}
pim_ifp->bfd_config.detection_multiplier =
- yang_dnode_get_uint8(args->dnode, "./detect_mult");
+ yang_dnode_get_uint8(args->dnode, "detect_mult");
pim_ifp->bfd_config.min_rx =
- yang_dnode_get_uint16(args->dnode, "./min-rx-interval");
+ yang_dnode_get_uint16(args->dnode, "min-rx-interval");
pim_ifp->bfd_config.min_tx =
- yang_dnode_get_uint16(args->dnode, "./min-tx-interval");
+ yang_dnode_get_uint16(args->dnode, "min-tx-interval");
pim_bfd_reg_dereg_all_nbr(ifp);
}
@@ -2191,7 +2189,7 @@ int lib_interface_pim_address_family_mroute_destroy(
pim_iifp = iif->info;
pim = pim_iifp->pim;
- oifname = yang_dnode_get_string(args->dnode, "./oif");
+ oifname = yang_dnode_get_string(args->dnode, "oif");
oif = if_lookup_by_name(oifname, pim->vrf->vrf_id);
if (!oif) {
@@ -2201,8 +2199,8 @@ int lib_interface_pim_address_family_mroute_destroy(
return NB_ERR_INCONSISTENCY;
}
- yang_dnode_get_pimaddr(&source_addr, args->dnode, "./source-addr");
- yang_dnode_get_pimaddr(&group_addr, args->dnode, "./group-addr");
+ yang_dnode_get_pimaddr(&source_addr, args->dnode, "source-addr");
+ yang_dnode_get_pimaddr(&group_addr, args->dnode, "group-addr");
if (pim_static_del(pim, iif, oif, group_addr, source_addr)) {
snprintf(args->errmsg, args->errmsg_len,
@@ -2341,9 +2339,9 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
case NB_EV_APPLY:
vrf = nb_running_get_entry(args->dnode, NULL, true);
pim = vrf->info;
- yang_dnode_get_pimaddr(&rp_addr, args->dnode, "./rp-address");
+ yang_dnode_get_pimaddr(&rp_addr, args->dnode, "rp-address");
- if (yang_dnode_get(args->dnode, "./group-list")) {
+ if (yang_dnode_get(args->dnode, "group-list")) {
yang_dnode_get_prefix(&group, args->dnode,
"./group-list");
apply_mask(&group);
@@ -2352,7 +2350,7 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
args->errmsg_len);
}
- else if (yang_dnode_get(args->dnode, "./prefix-list")) {
+ else if (yang_dnode_get(args->dnode, "prefix-list")) {
plist = yang_dnode_get_string(args->dnode,
"./prefix-list");
if (!pim_get_all_mcast_group(&group)) {
diff --git a/pimd/pim_nht.c b/pimd/pim_nht.c
index 4e8e5f0..32cdf4b 100644
--- a/pimd/pim_nht.c
+++ b/pimd/pim_nht.c
@@ -338,7 +338,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
- /* fallthru */
+ fallthrough;
case NEXTHOP_TYPE_IPV4_IFINDEX:
nhaddr = nh->gate.ipv4;
break;
@@ -350,7 +350,7 @@ bool pim_nht_bsr_rpf_check(struct pim_instance *pim, pim_addr bsr_addr,
if (nh->ifindex == IFINDEX_INTERNAL)
continue;
- /* fallthru */
+ fallthrough;
case NEXTHOP_TYPE_IPV6_IFINDEX:
nhaddr = nh->gate.ipv6;
break;
@@ -723,7 +723,8 @@ static int pim_ecmp_nexthop_search(struct pim_instance *pim,
/* This API is used to parse Registered address nexthop update coming from Zebra
*/
-int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
+void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
+ struct zapi_route *nhr)
{
struct nexthop *nexthop;
struct nexthop *nhlist_head = NULL;
@@ -732,38 +733,27 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
struct pim_rpf rpf;
struct pim_nexthop_cache *pnc = NULL;
struct interface *ifp = NULL;
- struct vrf *vrf = vrf_lookup_by_id(vrf_id);
struct pim_instance *pim;
- struct zapi_route nhr;
- struct prefix match;
- if (!vrf)
- return 0;
pim = vrf->info;
- if (!zapi_nexthop_update_decode(zclient->ibuf, &match, &nhr)) {
- zlog_err("%s: Decode of nexthop update from zebra failed",
- __func__);
- return 0;
- }
-
- rpf.rpf_addr = pim_addr_from_prefix(&match);
+ rpf.rpf_addr = pim_addr_from_prefix(match);
pnc = pim_nexthop_cache_find(pim, &rpf);
if (!pnc) {
if (PIM_DEBUG_PIM_NHT)
zlog_debug(
"%s: Skipping NHT update, addr %pPA is not in local cached DB.",
__func__, &rpf.rpf_addr);
- return 0;
+ return;
}
pnc->last_update = pim_time_monotonic_usec();
- if (nhr.nexthop_num) {
+ if (nhr->nexthop_num) {
pnc->nexthop_num = 0;
- for (i = 0; i < nhr.nexthop_num; i++) {
- nexthop = nexthop_from_zapi_nexthop(&nhr.nexthops[i]);
+ for (i = 0; i < nhr->nexthop_num; i++) {
+ nexthop = nexthop_from_zapi_nexthop(&nhr->nexthops[i]);
switch (nexthop->type) {
case NEXTHOP_TYPE_IFINDEX:
/*
@@ -842,11 +832,11 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
#else
pim_addr nhaddr = nexthop->gate.ipv6;
#endif
- zlog_debug(
- "%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ",
- __func__, &match, pim->vrf->name, i + 1,
- &nhaddr, ifp->name, nexthop->type,
- nhr.distance, nhr.metric);
+ zlog_debug("%s: NHT addr %pFX(%s) %d-nhop via %pPA(%s) type %d distance:%u metric:%u ",
+ __func__, match, pim->vrf->name,
+ i + 1, &nhaddr, ifp->name,
+ nexthop->type, nhr->distance,
+ nhr->metric);
}
if (!ifp->info) {
@@ -887,23 +877,22 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pnc->nexthop = nhlist_head;
if (pnc->nexthop_num) {
pnc->flags |= PIM_NEXTHOP_VALID;
- pnc->distance = nhr.distance;
- pnc->metric = nhr.metric;
+ pnc->distance = nhr->distance;
+ pnc->metric = nhr->metric;
}
} else {
pnc->flags &= ~PIM_NEXTHOP_VALID;
- pnc->nexthop_num = nhr.nexthop_num;
+ pnc->nexthop_num = nhr->nexthop_num;
nexthops_free(pnc->nexthop);
pnc->nexthop = NULL;
}
SET_FLAG(pnc->flags, PIM_NEXTHOP_ANSWER_RECEIVED);
if (PIM_DEBUG_PIM_NHT)
- zlog_debug(
- "%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
- __func__, &match, pim->vrf->name, nhr.nexthop_num,
- pnc->nexthop_num, vrf_id, pnc->upstream_hash->count,
- listcount(pnc->rp_list));
+ zlog_debug("%s: NHT Update for %pFX(%s) num_nh %d num_pim_nh %d vrf:%u up %ld rp %d",
+ __func__, match, pim->vrf->name, nhr->nexthop_num,
+ pnc->nexthop_num, vrf->vrf_id,
+ pnc->upstream_hash->count, listcount(pnc->rp_list));
pim_rpf_set_refresh_time(pim);
@@ -911,8 +900,6 @@ int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS)
pim_update_rp_nh(pim, pnc);
if (pnc->upstream_hash->count)
pim_update_upstream_nh(pim, pnc);
-
- return 0;
}
int pim_ecmp_nexthop_lookup(struct pim_instance *pim,
diff --git a/pimd/pim_nht.h b/pimd/pim_nht.h
index 5a54e1c..a1feb76 100644
--- a/pimd/pim_nht.h
+++ b/pimd/pim_nht.h
@@ -45,7 +45,8 @@ struct pnc_hash_walk_data {
struct interface *ifp;
};
-int pim_parse_nexthop_update(ZAPI_CALLBACK_ARGS);
+void pim_nexthop_update(struct vrf *vrf, struct prefix *match,
+ struct zapi_route *nhr);
int pim_find_or_track_nexthop(struct pim_instance *pim, pim_addr addr,
struct pim_upstream *up, struct rp_info *rp,
struct pim_nexthop_cache *out_pnc);
diff --git a/pimd/pim_pim.c b/pimd/pim_pim.c
index a4c9178..1bc265b 100644
--- a/pimd/pim_pim.c
+++ b/pimd/pim_pim.c
@@ -743,14 +743,13 @@ static int hello_send(struct interface *ifp, uint16_t holdtime)
pim_ifp = ifp->info;
if (PIM_DEBUG_PIM_HELLO)
- zlog_debug(
- "%s: to %pPA on %s: holdt=%u prop_d=%u overr_i=%u dis_join_supp=%d dr_prio=%u gen_id=%08x addrs=%d",
- __func__, &qpim_all_pim_routers_addr, ifp->name,
- holdtime, pim_ifp->pim_propagation_delay_msec,
- pim_ifp->pim_override_interval_msec,
- pim_ifp->pim_can_disable_join_suppression,
- pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
- listcount(ifp->connected));
+ zlog_debug("%s: to %pPA on %s: holdt=%u prop_d=%u overr_i=%u dis_join_supp=%d dr_prio=%u gen_id=%08x addrs=%zu",
+ __func__, &qpim_all_pim_routers_addr, ifp->name,
+ holdtime, pim_ifp->pim_propagation_delay_msec,
+ pim_ifp->pim_override_interval_msec,
+ pim_ifp->pim_can_disable_join_suppression,
+ pim_ifp->pim_dr_priority, pim_ifp->pim_generation_id,
+ if_connected_count(ifp->connected));
pim_tlv_size = pim_hello_build_tlv(
ifp, pim_msg + PIM_PIM_MIN_LEN,
diff --git a/pimd/pim_rp.c b/pimd/pim_rp.c
index c751624..d8d2571 100644
--- a/pimd/pim_rp.c
+++ b/pimd/pim_rp.c
@@ -248,7 +248,7 @@ struct rp_info *pim_rp_find_match_group(struct pim_instance *pim,
}
rp_info = rn->info;
- if (PIM_DEBUG_PIM_TRACE) {
+ if (PIM_DEBUG_PIM_TRACE_DETAIL) {
if (best)
zlog_debug(
"Lookedup(%pFX): prefix_list match %s, rn %p found: %pFX",
diff --git a/pimd/pim_rpf.c b/pimd/pim_rpf.c
index b17ae31..d18ec49 100644
--- a/pimd/pim_rpf.c
+++ b/pimd/pim_rpf.c
@@ -32,7 +32,7 @@ static pim_addr pim_rpf_find_rpf_addr(struct pim_upstream *up);
void pim_rpf_set_refresh_time(struct pim_instance *pim)
{
pim->last_route_change_time = pim_time_monotonic_usec();
- if (PIM_DEBUG_PIM_TRACE)
+ if (PIM_DEBUG_PIM_TRACE_DETAIL)
zlog_debug("%s: vrf(%s) New last route change time: %" PRId64,
__func__, pim->vrf->name,
pim->last_route_change_time);
diff --git a/pimd/pim_sock.c b/pimd/pim_sock.c
index 6c65c5d..3476c17 100644
--- a/pimd/pim_sock.c
+++ b/pimd/pim_sock.c
@@ -5,6 +5,7 @@
*/
#include <zebra.h>
+#include <fcntl.h>
#include <sys/types.h>
#include <sys/socket.h>
diff --git a/pimd/pim_tlv.c b/pimd/pim_tlv.c
index 80d60b8..c463fa2 100644
--- a/pimd/pim_tlv.c
+++ b/pimd/pim_tlv.c
@@ -217,18 +217,17 @@ int pim_encode_addr_group(uint8_t *buf, afi_t afi, int bidir, int scope,
uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
struct interface *ifp, int family)
{
- struct listnode *node;
uint16_t option_len = 0;
uint8_t *curr;
size_t uel;
- struct list *ifconnected = ifp->connected;
+ struct connected *ifc;
struct pim_interface *pim_ifp = ifp->info;
pim_addr addr;
- node = listhead(ifconnected);
+ ifc = if_connected_first(ifp->connected);
/* Empty address list ? */
- if (!node) {
+ if (!ifc) {
return buf;
}
@@ -239,8 +238,7 @@ uint8_t *pim_tlv_append_addrlist_ucast(uint8_t *buf, const uint8_t *buf_pastend,
/* Scan secondary address list */
curr = buf + 4; /* skip T and L */
- for (; node; node = listnextnode(node)) {
- struct connected *ifc = listgetdata(node);
+ for (; ifc; ifc = if_connected_next(ifp->connected, ifc)) {
struct prefix *p = ifc->address;
int l_encode;
diff --git a/pimd/pim_upstream.c b/pimd/pim_upstream.c
index e36bd82..556d25b 100644
--- a/pimd/pim_upstream.c
+++ b/pimd/pim_upstream.c
@@ -17,6 +17,7 @@
#include "jhash.h"
#include "wheel.h"
#include "network.h"
+#include "frrdistance.h"
#include "pimd.h"
#include "pim_pim.h"
@@ -908,7 +909,7 @@ static struct pim_upstream *pim_upstream_new(struct pim_instance *pim,
* Set the right RPF so that future changes will
* be right
*/
- rpf_result = pim_rpf_update(pim, up, NULL, __func__);
+ (void)pim_rpf_update(pim, up, NULL, __func__);
pim_upstream_keep_alive_timer_start(
up, pim->keep_alive_time);
}
@@ -1943,6 +1944,40 @@ void pim_upstream_terminate(struct pim_instance *pim)
wheel_delete(pim->upstream_sg_wheel);
pim->upstream_sg_wheel = NULL;
}
+bool pim_sg_is_reevaluate_oil_req(struct pim_instance *pim,
+ struct pim_upstream *up)
+{
+ struct pim_interface *pim_ifp = NULL;
+
+ /*
+ * Attempt to retrieve the PIM interface information if the RPF
+ * interface is present
+ */
+ if (up->rpf.source_nexthop.interface) {
+ pim_ifp = up->rpf.source_nexthop.interface->info;
+ } else {
+ if (PIM_DEBUG_PIM_TRACE) {
+ zlog_debug("%s: up %s RPF is not present", __func__,
+ up->sg_str);
+ }
+ }
+
+ /*
+ * Determine if a reevaluation of the outgoing interface list (OIL) is
+ * required. This may be necessary in scenarios such as MSDP where the
+ * RP role for a group changes from secondary to primary. In such cases,
+ * SGRpt may receive a prune, resulting in an S,G entry with a NULL OIL.
+ * The S,G upstream should then inherit the OIL from *,G, which is
+ * particularly important for VXLAN setups.
+ */
+ if (up->channel_oil->oil_inherited_rescan ||
+ (pim_ifp && I_am_RP(pim_ifp->pim, up->sg.grp)) ||
+ pim_upstream_empty_inherited_olist(up)) {
+ return true;
+ }
+
+ return false;
+}
bool pim_upstream_equal(const void *arg1, const void *arg2)
{
@@ -2078,7 +2113,7 @@ static void pim_upstream_sg_running(void *arg)
* only doing this at this point in time
* to get us up and working for the moment
*/
- if (up->channel_oil->oil_inherited_rescan) {
+ if (pim_sg_is_reevaluate_oil_req(pim, up)) {
if (PIM_DEBUG_TRACE)
zlog_debug(
"%s: Handling unscanned inherited_olist for %s[%s]",
diff --git a/pimd/pim_upstream.h b/pimd/pim_upstream.h
index 4e0926e..62649cd 100644
--- a/pimd/pim_upstream.h
+++ b/pimd/pim_upstream.h
@@ -383,4 +383,6 @@ uint32_t pim_up_mlag_local_cost(struct pim_upstream *up);
uint32_t pim_up_mlag_peer_cost(struct pim_upstream *up);
void pim_upstream_reeval_use_rpt(struct pim_instance *pim);
int pim_upstream_could_register(struct pim_upstream *up);
+bool pim_sg_is_reevaluate_oil_req(struct pim_instance *pim,
+ struct pim_upstream *up);
#endif /* PIM_UPSTREAM_H */
diff --git a/pimd/pim_vxlan.c b/pimd/pim_vxlan.c
index 9650da8..f1f315c 100644
--- a/pimd/pim_vxlan.c
+++ b/pimd/pim_vxlan.c
@@ -32,6 +32,30 @@ static void pim_vxlan_work_timer_setup(bool start);
static void pim_vxlan_set_peerlink_rif(struct pim_instance *pim,
struct interface *ifp);
+#define PIM_VXLAN_STARTUP_NULL_REGISTERS 10
+
+static void pim_vxlan_rp_send_null_register_startup(struct event *e)
+{
+ struct pim_vxlan_sg *vxlan_sg = EVENT_ARG(e);
+
+ vxlan_sg->null_register_sent++;
+
+ if (vxlan_sg->null_register_sent > PIM_VXLAN_STARTUP_NULL_REGISTERS) {
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("Null registering stopping for %s",
+ vxlan_sg->sg_str);
+ return;
+ }
+
+ pim_null_register_send(vxlan_sg->up);
+
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("Sent null register for %s", vxlan_sg->sg_str);
+
+ event_add_timer(router->master, pim_vxlan_rp_send_null_register_startup,
+ vxlan_sg, PIM_VXLAN_WORK_TIME, &vxlan_sg->null_register);
+}
+
/*
* The rp info has gone from no path to having a
* path. Let's immediately send out the null pim register
@@ -61,8 +85,13 @@ void pim_vxlan_rp_info_is_alive(struct pim_instance *pim,
* If the rp is the same we should send
*/
if (rpg == rpg_changed) {
- zlog_debug("VXLAN RP INFO is alive sending");
- pim_null_register_send(vxlan_sg->up);
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("VXLAN RP info for %s alive sending",
+ vxlan_sg->sg_str);
+ vxlan_sg->null_register_sent = 0;
+ event_add_event(router->master,
+ pim_vxlan_rp_send_null_register_startup,
+ vxlan_sg, 0, &vxlan_sg->null_register);
}
}
}
@@ -201,8 +230,18 @@ void pim_vxlan_update_sg_reg_state(struct pim_instance *pim,
*/
if (reg_join)
pim_vxlan_add_work(vxlan_sg);
- else
+ else {
+ /*
+ * Stop the event that is sending NULL Registers on startup
+ * there is no need to keep spamming it
+ */
+ if (PIM_DEBUG_VXLAN)
+ zlog_debug("Received Register stop for %s",
+ vxlan_sg->sg_str);
+
+ EVENT_OFF(vxlan_sg->null_register);
pim_vxlan_del_work(vxlan_sg);
+ }
}
static void pim_vxlan_work_timer_cb(struct event *t)
@@ -804,6 +843,7 @@ static void pim_vxlan_sg_del_item(struct pim_vxlan_sg *vxlan_sg)
{
vxlan_sg->flags |= PIM_VXLAN_SGF_DEL_IN_PROG;
+ EVENT_OFF(vxlan_sg->null_register);
pim_vxlan_del_work(vxlan_sg);
if (pim_vxlan_is_orig_mroute(vxlan_sg))
@@ -1210,6 +1250,9 @@ void pim_vxlan_exit(struct pim_instance *pim)
{
hash_clean_and_free(&pim->vxlan.sg_hash,
(void (*)(void *))pim_vxlan_sg_del_item);
+
+ if (vxlan_info.work_list)
+ list_delete(&vxlan_info.work_list);
}
void pim_vxlan_terminate(void)
diff --git a/pimd/pim_vxlan.h b/pimd/pim_vxlan.h
index 5039bf6..fe3d625 100644
--- a/pimd/pim_vxlan.h
+++ b/pimd/pim_vxlan.h
@@ -49,6 +49,9 @@ struct pim_vxlan_sg {
struct interface *iif;
/* on a MLAG setup the peerlink is added as a static OIF */
struct interface *orig_oif;
+
+ struct event *null_register;
+ uint32_t null_register_sent;
};
enum pim_vxlan_mlag_flags {
diff --git a/pimd/pim_zebra.c b/pimd/pim_zebra.c
index 62f00db..04cd087 100644
--- a/pimd/pim_zebra.c
+++ b/pimd/pim_zebra.c
@@ -55,12 +55,11 @@ static int pim_router_id_update_zebra(ZAPI_CALLBACK_ARGS)
static void dump_if_address(struct interface *ifp)
{
struct connected *ifc;
- struct listnode *node;
zlog_debug("%s %s: interface %s addresses:", __FILE__, __func__,
ifp->name);
- for (ALL_LIST_ELEMENTS_RO(ifp->connected, node, ifc)) {
+ frr_each (if_connected, ifp->connected, ifc) {
struct prefix *p = ifc->address;
if (p->family != AF_INET)
@@ -97,8 +96,8 @@ static int pim_zebra_if_address_add(ZAPI_CALLBACK_ARGS)
p = c->address;
if (PIM_DEBUG_ZEBRA) {
- zlog_debug("%s: %s(%u) connected IP address %pFX flags %u %s",
- __func__, c->ifp->name, vrf_id, p, c->flags,
+ zlog_debug("%s: %s(%s) connected IP address %pFX flags %u %s",
+ __func__, c->ifp->name, VRF_LOGNAME(pim_ifp->pim->vrf), p, c->flags,
CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
? "secondary"
: "primary");
@@ -183,8 +182,8 @@ static int pim_zebra_if_address_del(ZAPI_CALLBACK_ARGS)
if (PIM_DEBUG_ZEBRA) {
zlog_debug(
- "%s: %s(%u) disconnected IP address %pFX flags %u %s",
- __func__, c->ifp->name, vrf_id, p, c->flags,
+ "%s: %s(%s) disconnected IP address %pFX flags %u %s",
+ __func__, c->ifp->name, VRF_LOGNAME(vrf), p, c->flags,
CHECK_FLAG(c->flags, ZEBRA_IFA_SECONDARY)
? "secondary"
: "primary");
@@ -326,7 +325,7 @@ static int pim_zebra_vxlan_sg_proc(ZAPI_CALLBACK_ARGS)
stream_get(&sg.grp, s, prefixlen);
if (PIM_DEBUG_ZEBRA)
- zlog_debug("%u:recv SG %s %pSG", vrf_id,
+ zlog_debug("%s:recv SG %s %pSG", VRF_LOGNAME(pim->vrf),
(cmd == ZEBRA_VXLAN_SG_ADD) ? "add" : "del", &sg);
if (cmd == ZEBRA_VXLAN_SG_ADD)
@@ -428,7 +427,6 @@ static zclient_handler *const pim_handlers[] = {
[ZEBRA_INTERFACE_ADDRESS_ADD] = pim_zebra_if_address_add,
[ZEBRA_INTERFACE_ADDRESS_DELETE] = pim_zebra_if_address_del,
- [ZEBRA_NEXTHOP_UPDATE] = pim_parse_nexthop_update,
[ZEBRA_ROUTER_ID_UPDATE] = pim_router_id_update_zebra,
#if PIM_IPV == 4
@@ -449,6 +447,7 @@ void pim_zebra_init(void)
zclient->zebra_capabilities = pim_zebra_capabilities;
zclient->zebra_connected = pim_zebra_connected;
+ zclient->nexthop_update = pim_nexthop_update;
zclient_init(zclient, ZEBRA_ROUTE_PIM, 0, &pimd_privs);
if (PIM_DEBUG_PIM_TRACE) {
diff --git a/pimd/pim_zlookup.c b/pimd/pim_zlookup.c
index 6a026f9..c19119f 100644
--- a/pimd/pim_zlookup.c
+++ b/pimd/pim_zlookup.c
@@ -122,10 +122,7 @@ void zclient_lookup_free(void)
void zclient_lookup_new(void)
{
- struct zclient_options options = zclient_options_default;
- options.synchronous = true;
-
- zlookup = zclient_new(router->master, &options, NULL, 0);
+ zlookup = zclient_new(router->master, &zclient_options_sync, NULL, 0);
if (!zlookup) {
flog_err(EC_LIB_ZAPI_SOCKET, "%s: zclient_new() failure",
__func__);
diff --git a/pimd/pimd.h b/pimd/pimd.h
index 9ec84fc..3d93189 100644
--- a/pimd/pimd.h
+++ b/pimd/pimd.h
@@ -19,9 +19,6 @@
#include "pim_memory.h"
#include "pim_assert.h"
-#define PIMD_VTY_PORT 2611
-#define PIM6D_VTY_PORT 2622
-
#define PIM_IP_PROTO_IGMP (2)
#define PIM_IP_PROTO_PIM (103)
#define PIM_IGMP_MIN_LEN (8)