@@ -5647,6 +5647,66 @@ DEFUN (show_ip_pim_bsrp,
56475647 return CMD_SUCCESS;
56485648}
56495649
5650+ DEFUN (show_ip_pim_cand_rp,
5651+ show_ip_pim_cand_rp_cmd,
5652+ "show ip pim candidate-rp [vrf NAME] [json]",
5653+ SHOW_STR
5654+ IP_STR
5655+ PIM_STR
5656+ "PIM Candidate RP state\n"
5657+ VRF_CMD_HELP_STR
5658+ JSON_STR)
5659+ {
5660+ int idx = 2;
5661+ struct vrf *vrf = pim_cmd_lookup_vrf(vty, argv, argc, &idx);
5662+ struct pim_instance *pim;
5663+ struct bsm_scope *scope;
5664+ bool uj = use_json(argc, argv);
5665+ json_object *json = NULL;
5666+
5667+ if (!vrf || !vrf->info)
5668+ return CMD_WARNING;
5669+
5670+ pim = (struct pim_instance *)vrf->info;
5671+ scope = &pim->global_scope;
5672+
5673+ if (!scope->cand_rp_addrsel.run) {
5674+ if (uj)
5675+ vty_out(vty, "{}\n");
5676+ else
5677+ vty_out(vty,
5678+ "This router is not currently operating as Candidate RP\n");
5679+ return CMD_SUCCESS;
5680+ }
5681+
5682+ if (uj) {
5683+ char buf[INET_ADDRSTRLEN];
5684+
5685+ json = json_object_new_object();
5686+ inet_ntop(AF_INET, &scope->cand_rp_addrsel.run_addr, buf,
5687+ sizeof(buf));
5688+ json_object_string_add(json, "address", buf);
5689+ json_object_int_add(json, "priority", scope->cand_rp_prio);
5690+ json_object_int_add(
5691+ json, "nextAdvertisementMsec",
5692+ pim_time_timer_remain_msec(scope->cand_rp_adv_timer));
5693+
5694+ vty_out(vty, "%s\n",
5695+ json_object_to_json_string_ext(
5696+ json, JSON_C_TO_STRING_PRETTY));
5697+ json_object_free(json);
5698+ return CMD_SUCCESS;
5699+ }
5700+
5701+ vty_out(vty, "Candidate-RP\nAddress: %pI4\nPriority: %u\n\n",
5702+ &scope->cand_rp_addrsel.run_addr, scope->cand_rp_prio);
5703+ vty_out(vty, "Next adv.: %lu msec\n",
5704+ pim_time_timer_remain_msec(scope->cand_rp_adv_timer));
5705+
5706+
5707+ return CMD_SUCCESS;
5708+ }
5709+
56505710DEFUN (show_ip_pim_statistics,
56515711 show_ip_pim_statistics_cmd,
56525712 "show ip pim [vrf NAME] statistics [interface WORD] [json]",
@@ -7441,6 +7501,124 @@ DEFUN (no_ip_pim_rp_prefix_list,
74417501 return nb_cli_apply_changes(vty, NULL);
74427502}
74437503
7504+ DEFPY (ip_pim_candidate_rp,
7505+ ip_pim_candidate_rp_cmd,
7506+ "[no] ip pim candidate-rp [{priority (0-255)|source <address A.B.C.D|interface IFNAME|loopback$loopback|any$any>}]",
7507+ NO_STR
7508+ IP_STR
7509+ "pim multicast routing\n"
7510+ "Make this router a Candidate RP\n"
7511+ "RP Priority (lower wins)\n"
7512+ "RP Priority (lower wins)\n"
7513+ "Specify IP address for RP operation\n"
7514+ "Local address to use\n"
7515+ "Local address to use\n"
7516+ "Interface to pick address from\n"
7517+ "Interface to pick address from\n"
7518+ "Pick highest loopback address (default)\n"
7519+ "Pick highest address from any interface\n")
7520+ {
7521+ char cand_rp_xpath[XPATH_MAXLEN];
7522+ const struct lyd_node *vrf_dnode;
7523+ const char *vrfname;
7524+
7525+ if (vty->xpath_index) {
7526+ vrf_dnode = yang_dnode_get(vty->candidate_config->dnode,
7527+ VTY_CURR_XPATH);
7528+
7529+ if (!vrf_dnode) {
7530+ vty_out(vty,
7531+ "%% Failed to get vrf dnode in candidate db\n");
7532+ return CMD_WARNING_CONFIG_FAILED;
7533+ }
7534+
7535+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7536+ } else
7537+ vrfname = VRF_DEFAULT_NAME;
7538+
7539+ snprintf(cand_rp_xpath, sizeof(cand_rp_xpath), FRR_PIM_CAND_RP_XPATH,
7540+ "frr-pim:pimd", "pim", vrfname, "frr-routing:ipv4");
7541+
7542+ if (no)
7543+ nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_DESTROY, NULL);
7544+ else {
7545+ char xpath2[XPATH_MAXLEN + 12];
7546+
7547+ nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_CREATE, NULL);
7548+
7549+ if (any) {
7550+ snprintf(xpath2, sizeof(xpath2), "%s/if-any",
7551+ cand_rp_xpath);
7552+ nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, NULL);
7553+ } else if (ifname) {
7554+ snprintf(xpath2, sizeof(xpath2), "%s/interface",
7555+ cand_rp_xpath);
7556+ nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE,
7557+ ifname);
7558+ } else if (address_str) {
7559+ snprintf(xpath2, sizeof(xpath2), "%s/address",
7560+ cand_rp_xpath);
7561+ nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE,
7562+ address_str);
7563+ } else {
7564+ snprintf(xpath2, sizeof(xpath2), "%s/if-loopback",
7565+ cand_rp_xpath);
7566+ nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, NULL);
7567+ }
7568+
7569+ if (priority_str) {
7570+ snprintf(xpath2, sizeof(xpath2), "%s/rp-priority",
7571+ cand_rp_xpath);
7572+ nb_cli_enqueue_change(vty, xpath2, NB_OP_MODIFY,
7573+ priority_str);
7574+ }
7575+ }
7576+
7577+ return nb_cli_apply_changes(vty, NULL);
7578+ }
7579+
7580+ DEFPY (ip_pim_candidate_rp_group,
7581+ ip_pim_candidate_rp_group_cmd,
7582+ "[no] ip pim candidate-rp group A.B.C.D/M",
7583+ NO_STR
7584+ IP_STR
7585+ "pim multicast routing\n"
7586+ "Make this router a Candidate RP\n"
7587+ "Configure groups to become candidate RP for\n"
7588+ "Multicast group prefix\n")
7589+ {
7590+ char cand_rp_xpath[XPATH_MAXLEN];
7591+ const struct lyd_node *vrf_dnode;
7592+ const char *vrfname;
7593+
7594+ if (vty->xpath_index) {
7595+ vrf_dnode = yang_dnode_get(vty->candidate_config->dnode,
7596+ VTY_CURR_XPATH);
7597+
7598+ if (!vrf_dnode) {
7599+ vty_out(vty,
7600+ "%% Failed to get vrf dnode in candidate db\n");
7601+ return CMD_WARNING_CONFIG_FAILED;
7602+ }
7603+
7604+ vrfname = yang_dnode_get_string(vrf_dnode, "./name");
7605+ } else
7606+ vrfname = VRF_DEFAULT_NAME;
7607+
7608+ snprintf(cand_rp_xpath, sizeof(cand_rp_xpath),
7609+ FRR_PIM_CAND_RP_XPATH "/group-list", "frr-pim:pimd", "pim",
7610+ vrfname, "frr-routing:ipv4");
7611+
7612+ if (no)
7613+ nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_DESTROY,
7614+ group_str);
7615+ else
7616+ nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_CREATE,
7617+ group_str);
7618+
7619+ return nb_cli_apply_changes(vty, NULL);
7620+ }
7621+
74447622DEFUN (ip_pim_ssm_prefix_list,
74457623 ip_pim_ssm_prefix_list_cmd,
74467624 "ip pim ssm prefix-list WORD",
@@ -10942,6 +11120,10 @@ void pim_cmd_init(void)
1094211120 install_element(VRF_NODE, &igmp_group_watermark_cmd);
1094311121 install_element(CONFIG_NODE, &no_igmp_group_watermark_cmd);
1094411122 install_element(VRF_NODE, &no_igmp_group_watermark_cmd);
11123+ install_element(CONFIG_NODE, &ip_pim_candidate_rp_cmd);
11124+ install_element(VRF_NODE, &ip_pim_candidate_rp_cmd);
11125+ install_element(CONFIG_NODE, &ip_pim_candidate_rp_group_cmd);
11126+ install_element(VRF_NODE, &ip_pim_candidate_rp_group_cmd);
1094511127
1094611128 install_element(INTERFACE_NODE, &interface_ip_igmp_cmd);
1094711129 install_element(INTERFACE_NODE, &interface_no_ip_igmp_cmd);
@@ -11042,6 +11224,7 @@ void pim_cmd_init(void)
1104211224 install_element(VIEW_NODE, &show_ip_pim_nexthop_lookup_cmd);
1104311225 install_element(VIEW_NODE, &show_ip_pim_bsrp_cmd);
1104411226 install_element(VIEW_NODE, &show_ip_pim_bsm_db_cmd);
11227+ install_element(VIEW_NODE, &show_ip_pim_cand_rp_cmd);
1104511228 install_element(VIEW_NODE, &show_ip_pim_statistics_cmd);
1104611229
1104711230 install_element(ENABLE_NODE, &clear_ip_mroute_count_cmd);
0 commit comments