summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pimd/pim_cmd.c147
-rw-r--r--pimd/pim_cmd.h1
-rw-r--r--pimd/pim_cmd_common.c159
-rw-r--r--pimd/pim_cmd_common.h11
-rw-r--r--pimd/pim_nb.c49
-rw-r--r--pimd/pim_nb.h29
-rw-r--r--pimd/pim_nb_config.c365
-rw-r--r--pimd/pim_vty.c8
-rw-r--r--yang/frr-pim-rp.yang71
9 files changed, 839 insertions, 1 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 0b503b8293..aa7fc0d81f 100644
--- a/pimd/pim_cmd.c
+++ b/pimd/pim_cmd.c
@@ -2820,6 +2820,75 @@ DEFPY (show_ip_pim_rp_vrf_all,
(struct prefix *)group, !!json);
}
+DEFPY (show_ip_pim_autorp,
+ show_ip_pim_autorp_cmd,
+ "show ip pim [vrf NAME] autorp [json$json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM AutoRP information\n"
+ JSON_STR)
+{
+ struct vrf *v;
+ json_object *json_parent = NULL;
+
+ v = vrf_lookup_by_name(vrf ? vrf : VRF_DEFAULT_NAME);
+ if (!v || !v->info) {
+ if (!json)
+ vty_out(vty, "%% Unable to find pim instance\n");
+ return CMD_WARNING;
+ }
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ pim_autorp_show_autorp(vty, v->info, json_parent);
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
+DEFPY (show_ip_pim_autorp_vrf_all,
+ show_ip_pim_autorp_vrf_all_cmd,
+ "show ip pim vrf all autorp [json$json]",
+ SHOW_STR
+ IP_STR
+ PIM_STR
+ VRF_CMD_HELP_STR
+ "PIM AutoRP information\n"
+ JSON_STR)
+{
+ struct vrf *vrf;
+ json_object *json_parent = NULL;
+ json_object *json_vrf = NULL;
+
+ if (json)
+ json_parent = json_object_new_object();
+
+ RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
+ if (vrf->info) {
+ if (!json)
+ vty_out(vty, "VRF: %s\n", vrf->name);
+ else
+ json_vrf = json_object_new_object();
+
+ pim_autorp_show_autorp(vty, vrf->info, json_vrf);
+
+ if (json)
+ json_object_object_add(json_parent, vrf->name,
+ json_vrf);
+ }
+ }
+
+ if (json)
+ vty_json(vty, json_parent);
+
+ return CMD_SUCCESS;
+}
+
DEFPY (show_ip_pim_rpf,
show_ip_pim_rpf_cmd,
"show ip pim [vrf NAME] rpf [json$json]",
@@ -4516,6 +4585,52 @@ DEFPY_ATTR(no_ip_pim_rp_prefix_list,
return ret;
}
+DEFPY (pim_autorp_discovery,
+ pim_autorp_discovery_cmd,
+ "[no] autorp discovery",
+ NO_STR
+ "AutoRP\n"
+ "Enable AutoRP discovery\n")
+{
+ if (no)
+ return pim_process_no_autorp_cmd(vty);
+ else
+ return pim_process_autorp_cmd(vty);
+}
+
+DEFPY (pim_autorp_announce_rp,
+ pim_autorp_announce_rp_cmd,
+ "[no] autorp announce A.B.C.D$rpaddr ![A.B.C.D/M$grp|group-list PREFIX_LIST$plist]",
+ NO_STR
+ "AutoRP\n"
+ "AutoRP Candidate RP announcement\n"
+ "AutoRP Candidate RP address\n"
+ "Group prefix\n"
+ "Prefix list\n"
+ "List name\n")
+{
+ return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, grp,
+ plist);
+}
+
+DEFPY (pim_autorp_announce_scope_int,
+ pim_autorp_announce_scope_int_cmd,
+ "[no] autorp announce ![{scope (1-255) | interval (1-65535) | holdtime (0-65535)}]",
+ NO_STR
+ "AutoRP\n"
+ "AutoRP Candidate RP announcement\n"
+ "Packet scope (TTL)\n"
+ "TTL value\n"
+ "Announcement interval\n"
+ "Time in seconds\n"
+ "Announcement holdtime\n"
+ "Time in seconds\n")
+{
+ return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str,
+ interval_str,
+ holdtime_str);
+}
+
DEFPY (pim_bsr_candidate_bsr,
pim_bsr_candidate_bsr_cmd,
"[no] bsr candidate-bsr [{priority (0-255)|source <address A.B.C.D|interface IFNAME|loopback$loopback|any$any>}]",
@@ -6377,6 +6492,29 @@ DEFUN (no_debug_bsm,
return CMD_SUCCESS;
}
+DEFUN (debug_autorp,
+ debug_autorp_cmd,
+ "debug pim autorp",
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_AUTORP_STR)
+{
+ PIM_DO_DEBUG_AUTORP;
+ return CMD_SUCCESS;
+}
+
+DEFUN (no_debug_autorp,
+ no_debug_autorp_cmd,
+ "no debug pim autorp",
+ NO_STR
+ DEBUG_STR
+ DEBUG_PIM_STR
+ DEBUG_PIM_AUTORP_STR)
+{
+ PIM_DONT_DEBUG_AUTORP;
+ return CMD_SUCCESS;
+}
+
DEFUN_NOSH (show_debugging_pim,
show_debugging_pim_cmd,
@@ -8714,6 +8852,9 @@ void pim_cmd_init(void)
install_element(PIM_NODE, &no_pim_rp_cmd);
install_element(PIM_NODE, &pim_rp_prefix_list_cmd);
install_element(PIM_NODE, &no_pim_rp_prefix_list_cmd);
+ install_element(PIM_NODE, &pim_autorp_discovery_cmd);
+ install_element(PIM_NODE, &pim_autorp_announce_rp_cmd);
+ install_element(PIM_NODE, &pim_autorp_announce_scope_int_cmd);
install_element(PIM_NODE, &no_pim_ssm_prefix_list_cmd);
install_element(PIM_NODE, &no_pim_ssm_prefix_list_name_cmd);
install_element(PIM_NODE, &pim_ssm_prefix_list_cmd);
@@ -8868,6 +9009,8 @@ void pim_cmd_init(void)
install_element(VIEW_NODE, &show_ip_pim_upstream_rpf_cmd);
install_element(VIEW_NODE, &show_ip_pim_rp_cmd);
install_element(VIEW_NODE, &show_ip_pim_rp_vrf_all_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_autorp_cmd);
+ install_element(VIEW_NODE, &show_ip_pim_autorp_vrf_all_cmd);
install_element(VIEW_NODE, &show_ip_pim_bsr_cmd);
install_element(VIEW_NODE, &show_ip_multicast_cmd);
install_element(VIEW_NODE, &show_ip_multicast_vrf_all_cmd);
@@ -8975,6 +9118,8 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE, &debug_pim_trace_detail_cmd);
install_element(ENABLE_NODE, &debug_ssmpingd_cmd);
install_element(CONFIG_NODE, &debug_ssmpingd_cmd);
+ install_element(ENABLE_NODE, &debug_autorp_cmd);
+ install_element(ENABLE_NODE, &no_debug_autorp_cmd);
install_element(ENABLE_NODE, &no_debug_ssmpingd_cmd);
install_element(CONFIG_NODE, &no_debug_ssmpingd_cmd);
install_element(ENABLE_NODE, &debug_pim_zebra_cmd);
@@ -9007,6 +9152,8 @@ void pim_cmd_init(void)
install_element(CONFIG_NODE, &debug_bsm_cmd);
install_element(ENABLE_NODE, &no_debug_bsm_cmd);
install_element(CONFIG_NODE, &no_debug_bsm_cmd);
+ install_element(CONFIG_NODE, &debug_autorp_cmd);
+ install_element(CONFIG_NODE, &no_debug_autorp_cmd);
install_element(CONFIG_NODE, &ip_igmp_group_watermark_cmd);
install_element(VRF_NODE, &ip_igmp_group_watermark_cmd);
diff --git a/pimd/pim_cmd.h b/pimd/pim_cmd.h
index d39d77cd2f..17cf4bb362 100644
--- a/pimd/pim_cmd.h
+++ b/pimd/pim_cmd.h
@@ -56,6 +56,7 @@
#define DEBUG_MSDP_PACKETS_STR "MSDP protocol packets\n"
#define DEBUG_MTRACE_STR "Mtrace protocol activity\n"
#define DEBUG_PIM_BSM_STR "BSR message processing activity\n"
+#define DEBUG_PIM_AUTORP_STR "AutoRP message processing activity\n"
void pim_cmd_init(void);
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index 7337bacc84..be7460d0fb 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -606,6 +606,165 @@ int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
return nb_cli_apply_changes(vty, NULL);
}
+int pim_process_autorp_cmd(struct vty *vty)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath), "%s/%s", FRR_PIM_AUTORP_XPATH,
+ "discovery-enabled");
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY, "true");
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+int pim_process_no_autorp_cmd(struct vty *vty)
+{
+ char xpath[XPATH_MAXLEN];
+
+ snprintf(xpath, sizeof(xpath), "%s/%s", FRR_PIM_AUTORP_XPATH,
+ "discovery-enabled");
+
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no,
+ const char *rpaddr_str,
+ const struct prefix_ipv4 *grp,
+ const char *plist)
+{
+ char xpath[XPATH_MAXLEN];
+ char grpstr[64];
+
+ if (no) {
+ if (!is_default_prefix((const struct prefix *)grp) || plist) {
+ /* If any single values are set, only destroy those */
+ if (!is_default_prefix((const struct prefix *)grp)) {
+ snprintfrr(xpath, sizeof(xpath),
+ "%s/candidate-rp-list[rp-address='%s']/group",
+ FRR_PIM_AUTORP_XPATH, rpaddr_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
+ NULL);
+ }
+ if (plist) {
+ snprintfrr(xpath, sizeof(xpath),
+ "%s/candidate-rp-list[rp-address='%s']/prefix-list",
+ FRR_PIM_AUTORP_XPATH, rpaddr_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
+ NULL);
+ }
+ } else {
+ /* No values set, remove the entire RP */
+ snprintfrr(xpath, sizeof(xpath),
+ "%s/candidate-rp-list[rp-address='%s']",
+ FRR_PIM_AUTORP_XPATH, rpaddr_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ }
+ } else {
+ if (!is_default_prefix((const struct prefix *)grp) || plist) {
+ snprintfrr(xpath, sizeof(xpath),
+ "%s/candidate-rp-list[rp-address='%s']",
+ FRR_PIM_AUTORP_XPATH, rpaddr_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL);
+ if (!is_default_prefix((const struct prefix *)grp)) {
+ snprintfrr(xpath, sizeof(xpath),
+ "%s/candidate-rp-list[rp-address='%s']/group",
+ FRR_PIM_AUTORP_XPATH, rpaddr_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ prefix2str(grp, grpstr,
+ sizeof(grpstr)));
+ }
+ if (plist) {
+ snprintfrr(xpath, sizeof(xpath),
+ "%s/candidate-rp-list[rp-address='%s']/prefix-list",
+ FRR_PIM_AUTORP_XPATH, rpaddr_str);
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ plist);
+ }
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
+int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no,
+ const char *scope,
+ const char *interval,
+ const char *holdtime)
+{
+ char xpath[XPATH_MAXLEN];
+
+ if (no) {
+ if (scope || interval || holdtime) {
+ /* If any single values are set, only destroy those */
+ if (scope) {
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH,
+ "announce-scope");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
+ NULL);
+ }
+ if (interval) {
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH,
+ "announce-interval");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
+ NULL);
+ }
+ if (holdtime) {
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH,
+ "announce-holdtime");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY,
+ NULL);
+ }
+ } else {
+ /* No values set, remove all */
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH, "announce-scope");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH, "announce-interval");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH, "announce-holdtime");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL);
+ }
+ } else {
+ if (scope || interval || holdtime) {
+ if (scope) {
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH,
+ "announce-scope");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ scope);
+ }
+ if (interval) {
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH,
+ "announce-interval");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ interval);
+ }
+ if (holdtime) {
+ snprintfrr(xpath, sizeof(xpath), "%s/%s",
+ FRR_PIM_AUTORP_XPATH,
+ "announce-holdtime");
+ nb_cli_enqueue_change(vty, xpath, NB_OP_MODIFY,
+ holdtime);
+ }
+ } else {
+ return CMD_WARNING_CONFIG_FAILED;
+ }
+ }
+
+ return nb_cli_apply_changes(vty, NULL);
+}
+
bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match)
{
return (pim_addr_is_any(match.grp) ||
diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h
index 7ded9b246a..d7c97e31d4 100644
--- a/pimd/pim_cmd_common.h
+++ b/pimd/pim_cmd_common.h
@@ -35,7 +35,16 @@ int pim_process_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list);
int pim_process_no_rp_plist_cmd(struct vty *vty, const char *rp_str,
const char *prefix_list);
-
+int pim_process_autorp_cmd(struct vty *vty);
+int pim_process_no_autorp_cmd(struct vty *vty);
+int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no,
+ const char *rpaddr_str,
+ const struct prefix_ipv4 *grp,
+ const char *plist);
+int pim_process_autorp_announce_scope_int_cmd(struct vty *vty, bool no,
+ const char *scope,
+ const char *interval,
+ const char *holdtime);
int pim_process_ip_pim_cmd(struct vty *vty);
int pim_process_no_ip_pim_cmd(struct vty *vty);
int pim_process_ip_pim_passive_cmd(struct vty *vty, bool enable);
diff --git a/pimd/pim_nb.c b/pimd/pim_nb.c
index 3c36512a3d..66001d1463 100644
--- a/pimd/pim_nb.c
+++ b/pimd/pim_nb.c
@@ -380,6 +380,55 @@ const struct frr_yang_module_info frr_pim_rp_info = {
}
},
{
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/discovery-enabled",
+ .cbs = {
+ .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/announce-scope",
+ .cbs = {
+ .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/announce-interval",
+ .cbs = {
+ .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/announce-holdtime",
+ .cbs = {
+ .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/candidate-rp-list",
+ .cbs = {
+ .create = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/candidate-rp-list/group",
+ .cbs = {
+ .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy,
+ }
+ },
+ {
+ .xpath = "/frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/candidate-rp-list/prefix-list",
+ .cbs = {
+ .modify = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify,
+ .destroy = routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy,
+ }
+ },
+ {
.xpath = NULL,
},
}
diff --git a/pimd/pim_nb.h b/pimd/pim_nb.h
index dfab582968..befad4efe4 100644
--- a/pimd/pim_nb.h
+++ b/pimd/pim_nb.h
@@ -159,6 +159,34 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
struct nb_cb_modify_args *args);
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_static_rp_rp_list_prefix_list_destroy(
struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify(
+ struct nb_cb_modify_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy(
+ struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify(
+ struct nb_cb_modify_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy(
+ struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify(
+ struct nb_cb_modify_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy(
+ struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify(
+ struct nb_cb_modify_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy(
+ struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create(
+ struct nb_cb_create_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy(
+ struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify(
+ struct nb_cb_modify_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy(
+ struct nb_cb_destroy_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify(
+ struct nb_cb_modify_args *args);
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy(
+ struct nb_cb_destroy_args *args);
/* frr-cand-bsr */
int routing_control_plane_protocols_control_plane_protocol_pim_address_family_candidate_bsr_create(
@@ -258,6 +286,7 @@ int routing_control_plane_protocols_name_validate(
"mroute[source-addr='%s'][group-addr='%s']"
#define FRR_PIM_STATIC_RP_XPATH \
"frr-pim-rp:rp/static-rp/rp-list[rp-address='%s']"
+#define FRR_PIM_AUTORP_XPATH "./frr-pim-rp:rp/auto-rp"
#define FRR_GMP_INTERFACE_XPATH \
"./frr-gmp:gmp/address-family[address-family='%s']"
#define FRR_GMP_ENABLE_XPATH \
diff --git a/pimd/pim_nb_config.c b/pimd/pim_nb_config.c
index 0366d8a857..2b78b8671f 100644
--- a/pimd/pim_nb_config.c
+++ b/pimd/pim_nb_config.c
@@ -26,6 +26,7 @@
#include "lib_errors.h"
#include "pim_util.h"
#include "pim6_mld.h"
+#include "pim_autorp.h"
#include "pim_igmp.h"
#if PIM_IPV == 6
@@ -147,6 +148,11 @@ static int pim_cmd_interface_add(struct interface *ifp)
pim_if_membership_refresh(ifp);
pim_if_create_pimreg(pim_ifp->pim);
+
+#if PIM_IPV == 4
+ pim_autorp_add_ifp(ifp);
+#endif
+
return 1;
}
@@ -2680,6 +2686,365 @@ int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp
return NB_OK;
}
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/discovery-enabled
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_modify(
+ struct nb_cb_modify_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ bool enabled;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ enabled = yang_dnode_get_bool(args->dnode, NULL);
+ if (enabled)
+ pim_autorp_start_discovery(pim);
+ else
+ pim_autorp_stop_discovery(pim);
+ break;
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_discovery_enabled_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ bool enabled;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ enabled = yang_dnode_get_bool(args->dnode, NULL);
+ /* Run AutoRP discovery by default */
+ if (!enabled)
+ pim_autorp_start_discovery(pim);
+ break;
+ }
+#endif
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/announce-scope
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_modify(
+ struct nb_cb_modify_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ uint8_t scope;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ scope = yang_dnode_get_uint8(args->dnode, NULL);
+ pim_autorp_announce_scope(pim, scope);
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_scope_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ pim_autorp_announce_scope(pim, 0);
+ }
+#endif
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/announce-interval
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_modify(
+ struct nb_cb_modify_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ uint16_t interval;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ interval = yang_dnode_get_uint16(args->dnode, NULL);
+ pim_autorp_announce_interval(pim, interval);
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_interval_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ pim_autorp_announce_interval(pim, 0);
+ }
+#endif
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/announce-holdtime
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_modify(
+ struct nb_cb_modify_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ uint16_t holdtime;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ holdtime = yang_dnode_get_uint16(args->dnode, NULL);
+ pim_autorp_announce_holdtime(pim, holdtime);
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_announce_holdtime_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ /* 0 is a valid value, so -1 indicates deleting (go back to default) */
+ pim_autorp_announce_holdtime(pim, -1);
+ }
+#endif
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/candidate-rp-list
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_create(
+ struct nb_cb_create_args *args)
+{
+#if PIM_IPV == 4
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ case NB_EV_APPLY:
+ break;
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ pim_addr rp_addr;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ 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");
+ if (!pim_autorp_rm_candidate_rp(pim, rp_addr))
+ return NB_ERR_INCONSISTENCY;
+ break;
+ }
+#endif
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/candidate-rp-list/group
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_modify(
+ struct nb_cb_modify_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ struct prefix group;
+ pim_addr rp_addr;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ 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_prefix(&group, args->dnode, NULL);
+ apply_mask(&group);
+ pim_autorp_add_candidate_rp_group(pim, rp_addr, group);
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_group_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ struct prefix group;
+ pim_addr rp_addr;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ 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_prefix(&group, args->dnode, NULL);
+ apply_mask(&group);
+ if (!pim_autorp_rm_candidate_rp_group(pim, rp_addr, group))
+ return NB_ERR_INCONSISTENCY;
+ }
+#endif
+
+ return NB_OK;
+}
+
+/*
+ * XPath: /frr-routing:routing/control-plane-protocols/control-plane-protocol/frr-pim:pim/address-family/frr-pim-rp:rp/auto-rp/candidate-rp-list/prefix-list
+ */
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_modify(
+ struct nb_cb_modify_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ pim_addr rp_addr;
+ const char *plist;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ case NB_EV_APPLY:
+ vrf = nb_running_get_entry(args->dnode, NULL, true);
+ pim = vrf->info;
+ plist = yang_dnode_get_string(args->dnode, NULL);
+ yang_dnode_get_pimaddr(&rp_addr, args->dnode, "../rp-address");
+ pim_autorp_add_candidate_rp_plist(pim, rp_addr, plist);
+ }
+#endif
+
+ return NB_OK;
+}
+int routing_control_plane_protocols_control_plane_protocol_pim_address_family_rp_auto_rp_candidate_rp_list_prefix_list_destroy(
+ struct nb_cb_destroy_args *args)
+{
+#if PIM_IPV == 4
+ struct vrf *vrf;
+ struct pim_instance *pim;
+ pim_addr rp_addr;
+ const char *plist;
+
+ switch (args->event) {
+ case NB_EV_VALIDATE:
+ case NB_EV_PREPARE:
+ case NB_EV_ABORT:
+ break;
+ 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");
+ plist = yang_dnode_get_string(args->dnode, NULL);
+ if (!pim_autorp_rm_candidate_rp_plist(pim, rp_addr, plist))
+ return NB_ERR_INCONSISTENCY;
+ break;
+ }
+#endif
+
+ return NB_OK;
+}
+
static void yang_addrsel(struct cand_addrsel *addrsel,
const struct lyd_node *node)
{
diff --git a/pimd/pim_vty.c b/pimd/pim_vty.c
index d5d6fb54d5..b633e81d55 100644
--- a/pimd/pim_vty.c
+++ b/pimd/pim_vty.c
@@ -165,6 +165,11 @@ int pim_debug_config_write(struct vty *vty)
++writes;
}
+ if (PIM_DEBUG_AUTORP) {
+ vty_out(vty, "debug pim autorp\n");
+ ++writes;
+ }
+
return writes;
}
@@ -182,6 +187,9 @@ int pim_global_config_write_worker(struct pim_instance *pim, struct vty *vty)
}
writes += pim_rp_config_write(pim, vty);
+#if PIM_IPV == 4
+ writes += pim_autorp_config_write(pim, vty);
+#endif
writes += pim_cand_config_write(pim, vty);
if (pim->vrf->vrf_id == VRF_DEFAULT) {
diff --git a/yang/frr-pim-rp.yang b/yang/frr-pim-rp.yang
index 4cc214135d..dbd5513ee5 100644
--- a/yang/frr-pim-rp.yang
+++ b/yang/frr-pim-rp.yang
@@ -111,6 +111,70 @@ module frr-pim-rp {
} // static-rp
} // static-rp-container
+ grouping auto-rp-container {
+ description
+ "Grouping of AutoRP container.";
+
+ container auto-rp {
+ description
+ "Containing AutoRP attributes.";
+
+ leaf discovery-enabled {
+ type boolean;
+ description
+ "Flag indicating if Auto RP discovery is enabled.";
+ }
+
+ leaf announce-scope {
+ type uint8;
+ description
+ "The TTL of the C-RP Announcement packet.";
+ }
+
+ leaf announce-interval {
+ type uint16;
+ description
+ "The time between sending C-RP announcement packets.";
+ }
+
+ leaf announce-holdtime {
+ type uint16;
+ description
+ "The hold time in seconds advertised in the announcement packet.";
+ }
+
+ list candidate-rp-list {
+ key "rp-address";
+ description
+ "A list of Candidate RP addresses.";
+
+ leaf rp-address {
+ type inet:ip-address;
+ description
+ "Specifies a candidate RP address.";
+ }
+
+ choice group-or-prefix-list {
+ description "Use group or prefix-list";
+ case group {
+ leaf group {
+ type frr-route-types:ip-multicast-group-prefix;
+ description
+ "Multicast group prefix.";
+ }
+ }
+ case prefix-list {
+ leaf prefix-list {
+ type plist-ref;
+ description
+ "Group prefix-list filter";
+ }
+ }
+ }
+ } // candidate-rp-list
+ } // auto-rp
+ } // auto-rp-container
+
/*
* Configuration data nodes
*/
@@ -123,6 +187,13 @@ module frr-pim-rp {
description
"PIM RP configuration data.";
uses static-rp-container;
+
+ uses auto-rp-container {
+ when "../frr-pim:address-family = 'frr-rt:ipv4'" {
+ description
+ "Only applicable to IPv4 address family.";
+ }
+ }
} // rp
} // augment
}