diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 04:24:32 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 04:24:32 +0000 |
commit | 35cadacd2bb9383686753731e31bd7e145fb2506 (patch) | |
tree | 4489adbde75a837989533837185b2b8369a0bf68 /pimd | |
parent | Adding debian version 9.1-0.1. (diff) | |
download | frr-35cadacd2bb9383686753731e31bd7e145fb2506.tar.xz frr-35cadacd2bb9383686753731e31bd7e145fb2506.zip |
Merging upstream version 10.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
-rw-r--r-- | pimd/pim6_cmd.c | 8 | ||||
-rw-r--r-- | pimd/pim6_main.c | 10 | ||||
-rw-r--r-- | pimd/pim6_mld.c | 1 | ||||
-rw-r--r-- | pimd/pim_addr.h | 16 | ||||
-rw-r--r-- | pimd/pim_cmd.c | 16 | ||||
-rw-r--r-- | pimd/pim_cmd_common.c | 63 | ||||
-rw-r--r-- | pimd/pim_hello.c | 2 | ||||
-rw-r--r-- | pimd/pim_iface.c | 33 | ||||
-rw-r--r-- | pimd/pim_igmp_mtrace.c | 3 | ||||
-rw-r--r-- | pimd/pim_instance.h | 2 | ||||
-rw-r--r-- | pimd/pim_join.c | 6 | ||||
-rw-r--r-- | pimd/pim_main.c | 17 | ||||
-rw-r--r-- | pimd/pim_mlag.c | 4 | ||||
-rw-r--r-- | pimd/pim_mroute.c | 5 | ||||
-rw-r--r-- | pimd/pim_mroute.h | 28 | ||||
-rw-r--r-- | pimd/pim_msg.c | 138 | ||||
-rw-r--r-- | pimd/pim_nb_config.c | 40 | ||||
-rw-r--r-- | pimd/pim_nht.c | 55 | ||||
-rw-r--r-- | pimd/pim_nht.h | 3 | ||||
-rw-r--r-- | pimd/pim_pim.c | 15 | ||||
-rw-r--r-- | pimd/pim_rp.c | 2 | ||||
-rw-r--r-- | pimd/pim_rpf.c | 2 | ||||
-rw-r--r-- | pimd/pim_sock.c | 1 | ||||
-rw-r--r-- | pimd/pim_tlv.c | 10 | ||||
-rw-r--r-- | pimd/pim_upstream.c | 39 | ||||
-rw-r--r-- | pimd/pim_upstream.h | 2 | ||||
-rw-r--r-- | pimd/pim_vxlan.c | 49 | ||||
-rw-r--r-- | pimd/pim_vxlan.h | 3 | ||||
-rw-r--r-- | pimd/pim_zebra.c | 15 | ||||
-rw-r--r-- | pimd/pim_zlookup.c | 5 | ||||
-rw-r--r-- | pimd/pimd.h | 3 |
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(®_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(®_addr, args->dnode, "reg-address"); pim_vxlan_mlag_update(true, peer_state, role, ifp, ®_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) |