summaryrefslogtreecommitdiffstats
path: root/pimd
diff options
context:
space:
mode:
authorNathan Bahr <nbahr@atcorp.com>2024-09-17 04:10:03 +0200
committerNathan Bahr <nbahr@atcorp.com>2024-09-24 18:39:17 +0200
commit3b323fc441451e109e5f2b2d31b26a8002caf5c4 (patch)
tree2b0508da2a9e9b950086047e2deab7eb1af9d927 /pimd
parentpimd: Add AutoRP functionality to PIMD (diff)
downloadfrr-3b323fc441451e109e5f2b2d31b26a8002caf5c4.tar.xz
frr-3b323fc441451e109e5f2b2d31b26a8002caf5c4.zip
pimd,yang: Implement AutoRP CLI and NB config path
New CLI commands added: router pim [vrf NAME] autorp discovery autorp announce RP-ADDR [GROUP | group-list PREFIX-LIST] autorp announce {scope (1-255) | interval (1-65535) | holdtime (0-65535)} autorp discovery Enables Auto RP discovery for learning dynamic RP information using the AutoRP protocol. autorp announce RP-ADDR [GROUP | group-list PREFIX-LIST] Enable announcements of a candidate RP with the given group range, or prefix list of group ranges, to an AutoRP mapping agent. autorp announce {scope (1-255) | interval (1-65535) | holdtime (0-65535)} Configure the parameters of the AutoRP announcement messages. The scope sets the packet TTL. The interval sets the time between TX of announcements. The holdtime sets the hold time in the message, the time the mapping agent should wait before invalidating the candidate RP information. debug pim autorp Enable debug logging of the AutoRP protocol show ip pim [vrf NAME] autorp [json] Show details of the AutoRP protocol. To view learned RP info, use the existing command 'show ip pim rp-info' Extend pim yang for new configuration: augment /frr-rt:routing/frr-rt:control-plane-protocols/frr-rt:control-plane-protocol/frr-pim:pim/frr-pim:address-family: +--rw rp +--rw auto-rp +--rw discovery-enabled? boolean +--rw announce-scope? uint8 +--rw announce-interval? uint16 +--rw announce-holdtime? uint16 +--rw candidate-rp-list* [rp-address] +--rw rp-address inet:ip-address +--rw (group-or-prefix-list)? +--:(group) | +--rw group? frr-route-types:ip-multicast-group-prefix +--:(prefix-list) +--rw prefix-list? plist-ref Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
Diffstat (limited to 'pimd')
-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
8 files changed, 768 insertions, 1 deletions
diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c
index 0b503b829..aa7fc0d81 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 d39d77cd2..17cf4bb36 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 7337bacc8..be7460d0f 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 7ded9b246..d7c97e31d 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 3c36512a3..66001d146 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 dfab58296..befad4efe 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 0366d8a85..2b78b8671 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 d5d6fb54d..b633e81d5 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) {