summaryrefslogtreecommitdiff
path: root/pimd/pim_cmd_common.c
diff options
context:
space:
mode:
Diffstat (limited to 'pimd/pim_cmd_common.c')
-rw-r--r--pimd/pim_cmd_common.c376
1 files changed, 357 insertions, 19 deletions
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c
index d1368ff1ff..02ddea8252 100644
--- a/pimd/pim_cmd_common.c
+++ b/pimd/pim_cmd_common.c
@@ -420,6 +420,17 @@ int pim_process_no_ip_pim_boundary_oil_cmd(struct vty *vty)
FRR_PIM_AF_XPATH_VAL);
}
+int pim_process_ip_gmp_proxy_cmd(struct vty *vty, bool enable)
+{
+ if (enable)
+ nb_cli_enqueue_change(vty, "./proxy", NB_OP_MODIFY, "true");
+ else
+ nb_cli_enqueue_change(vty, "./proxy", NB_OP_DESTROY, NULL);
+
+ return nb_cli_apply_changes(vty, FRR_GMP_INTERFACE_XPATH,
+ FRR_PIM_AF_XPATH_VAL);
+}
+
int pim_process_ip_mroute_cmd(struct vty *vty, const char *interface,
const char *group_str, const char *source_str)
{
@@ -595,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 ((grp && !is_default_prefix((const struct prefix *)grp)) || plist) {
+ /* If any single values are set, only destroy those */
+ if (grp && !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 ((grp && !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 (grp && !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) ||
@@ -874,7 +1044,7 @@ void pim_show_rpf(struct pim_instance *pim, struct vty *vty, json_object *json)
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -926,7 +1096,7 @@ void pim_show_neighbors_secondary(struct pim_instance *pim, struct vty *vty)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
@@ -1180,7 +1350,7 @@ void pim_show_state(struct pim_instance *pim, struct vty *vty,
#else
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
#endif
}
@@ -1413,7 +1583,7 @@ void pim_show_upstream(struct pim_instance *pim, struct vty *vty,
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -1490,7 +1660,7 @@ void pim_show_join_desired(struct pim_instance *pim, struct vty *vty, bool uj)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -1569,7 +1739,7 @@ void pim_show_upstream_rpf(struct pim_instance *pim, struct vty *vty, bool uj)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -1751,7 +1921,7 @@ void pim_show_join(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -1831,7 +2001,7 @@ void pim_show_jp_agg_list(struct pim_instance *pim, struct vty *vty)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
@@ -1974,7 +2144,7 @@ void pim_show_membership(struct pim_instance *pim, struct vty *vty, bool uj)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -2079,7 +2249,7 @@ void pim_show_channel(struct pim_instance *pim, struct vty *vty, bool uj)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -2262,7 +2432,7 @@ void pim_show_interfaces(struct pim_instance *pim, struct vty *vty, bool mlag,
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
@@ -2734,7 +2904,7 @@ static int pim_print_vty_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg)
/* Dump the generated table. */
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
return CMD_SUCCESS;
@@ -3214,7 +3384,7 @@ void pim_show_neighbors(struct pim_instance *pim, struct vty *vty,
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -3389,6 +3559,55 @@ int pim_process_no_unicast_bsm_cmd(struct vty *vty)
FRR_PIM_AF_XPATH_VAL);
}
+/* helper for bsr/rp candidate commands*/
+int pim_process_bsr_candidate_cmd(struct vty *vty, const char *cand_str,
+ bool no, bool is_rp, bool any,
+ const char *ifname, const char *addr,
+ const char *prio, const char *interval)
+{
+ if (no)
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, NULL);
+ else {
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL);
+
+ if (any)
+ nb_cli_enqueue_change(vty, "./if-any", NB_OP_CREATE,
+ NULL);
+ else if (ifname)
+ nb_cli_enqueue_change(vty, "./interface", NB_OP_CREATE,
+ ifname);
+ else if (addr)
+ nb_cli_enqueue_change(vty, "./address", NB_OP_CREATE,
+ addr);
+ else
+ nb_cli_enqueue_change(vty, "./if-loopback",
+ NB_OP_CREATE, NULL);
+
+ if (prio)
+ nb_cli_enqueue_change(vty,
+ (is_rp ? "./rp-priority"
+ : "./bsr-priority"),
+ NB_OP_MODIFY, prio);
+
+ /* only valid for rp candidate case*/
+ if (is_rp && interval)
+ nb_cli_enqueue_change(vty, "./advertisement-interval",
+ NB_OP_MODIFY, interval);
+ }
+
+ return nb_cli_apply_changes(vty, "%s", cand_str);
+}
+
+int pim_process_bsr_crp_grp_cmd(struct vty *vty, const char *grp, bool no)
+{
+ if (no)
+ nb_cli_enqueue_change(vty, ".", NB_OP_DESTROY, grp);
+ else
+ nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, grp);
+
+ return nb_cli_apply_changes(vty, "%s/group-list", FRR_PIM_CAND_RP_XPATH);
+}
+
static void show_scan_oil_stats(struct pim_instance *pim, struct vty *vty,
time_t now)
{
@@ -3500,7 +3719,7 @@ void show_multicast_interfaces(struct pim_instance *pim, struct vty *vty,
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -3939,7 +4158,7 @@ void show_mroute(struct pim_instance *pim, struct vty *vty, pim_sgaddr *sg,
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -4022,7 +4241,7 @@ void show_mroute_count(struct pim_instance *pim, struct vty *vty,
if (!json) {
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
}
@@ -4158,6 +4377,27 @@ struct vrf *pim_cmd_lookup(struct vty *vty, const char *name)
return vrf;
}
+struct vrf *pim_cmd_lookup_vrf(struct vty *vty, struct cmd_token *argv[],
+ const int argc, int *idx, bool uj)
+{
+ struct vrf *vrf;
+
+ if (argv_find(argv, argc, "NAME", idx))
+ vrf = vrf_lookup_by_name(argv[*idx]->arg);
+ else
+ vrf = vrf_lookup_by_id(VRF_DEFAULT);
+
+ if (!vrf) {
+ if (uj)
+ vty_json_empty(vty, NULL);
+ else
+ vty_out(vty, "Specified VRF: %s does not exist\n",
+ argv[*idx]->arg);
+ }
+
+ return vrf;
+}
+
void clear_mroute(struct pim_instance *pim)
{
struct pim_upstream *up;
@@ -5188,6 +5428,12 @@ void pim_show_bsr(struct pim_instance *pim, struct vty *vty, bool uj)
case ACCEPT_PREFERRED:
strlcpy(bsr_state, "ACCEPT_PREFERRED", sizeof(bsr_state));
break;
+ case BSR_PENDING:
+ strlcpy(bsr_state, "BSR_PENDING", sizeof(bsr_state));
+ break;
+ case BSR_ELECTED:
+ strlcpy(bsr_state, "BSR_ELECTED", sizeof(bsr_state));
+ break;
default:
strlcpy(bsr_state, "", sizeof(bsr_state));
}
@@ -5207,7 +5453,7 @@ void pim_show_bsr(struct pim_instance *pim, struct vty *vty, bool uj)
}
else {
- vty_out(vty, "PIMv2 Bootstrap information\n");
+ vty_out(vty, "PIMv2 Bootstrap Router information\n");
vty_out(vty, "Current preferred BSR address: %pPA\n",
&pim->global_scope.current_bsr);
vty_out(vty,
@@ -5325,7 +5571,7 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
tt = NULL;
}
@@ -5379,7 +5625,7 @@ static void pim_show_group_rp_mappings_info(struct pim_instance *pim,
table = ttable_dump(tt, "\n");
vty_out(vty, "%s\n", table);
- XFREE(MTYPE_TMP, table);
+ XFREE(MTYPE_TMP_TTABLE, table);
ttable_del(tt);
}
if (!bsm_rpinfos_count(bsgrp->partial_bsrp_list) && !uj)
@@ -5416,6 +5662,98 @@ int pim_show_group_rp_mappings_info_helper(const char *vrf, struct vty *vty,
return CMD_SUCCESS;
}
+int pim_show_bsr_cand_rp(const struct vrf *vrf, struct vty *vty, bool uj)
+{
+ struct pim_instance *pim;
+ struct bsm_scope *scope;
+ json_object *jsondata = NULL;
+
+ if (!vrf || !vrf->info)
+ return CMD_WARNING;
+
+ pim = (struct pim_instance *)vrf->info;
+ scope = &pim->global_scope;
+
+ if (!scope->cand_rp_addrsel.run) {
+ if (!!uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty,
+ "This router is not currently operating as Candidate RP\n");
+ return CMD_SUCCESS;
+ }
+
+ if (!!uj) {
+ jsondata = json_object_new_object();
+ json_object_string_addf(jsondata, "address", "%pPA",
+ &scope->cand_rp_addrsel.run_addr);
+ json_object_int_add(jsondata, "priority", scope->cand_rp_prio);
+ json_object_int_add(jsondata, "nextAdvertisementMsec",
+ event_timer_remain_msec(
+ scope->cand_rp_adv_timer));
+
+ vty_json(vty, jsondata);
+ return CMD_SUCCESS;
+ }
+
+ vty_out(vty, "Candidate-RP\nAddress: %pPA\nPriority: %u\n\n",
+ &scope->cand_rp_addrsel.run_addr, scope->cand_rp_prio);
+ vty_out(vty, "Next adv.: %lu msec\n",
+ event_timer_remain_msec(scope->cand_rp_adv_timer));
+
+
+ return CMD_SUCCESS;
+}
+
+int pim_show_bsr_cand_bsr(const struct vrf *vrf, struct vty *vty, bool uj)
+{
+ struct pim_instance *pim;
+ struct bsm_scope *scope;
+ json_object *jsondata = NULL;
+
+ if (!vrf || !vrf->info)
+ return CMD_WARNING;
+
+ pim = (struct pim_instance *)vrf->info;
+ scope = &pim->global_scope;
+
+ if (!scope->bsr_addrsel.cfg_enable) {
+ if (!!uj)
+ vty_out(vty, "{}\n");
+ else
+ vty_out(vty,
+ "This router is not currently operating as Candidate BSR\n");
+ return CMD_SUCCESS;
+ }
+
+ if (uj) {
+ char buf[INET_ADDRSTRLEN];
+
+ jsondata = json_object_new_object();
+ inet_ntop(AF_INET, &scope->bsr_addrsel.run_addr, buf,
+ sizeof(buf));
+ json_object_string_add(jsondata, "address", buf);
+ json_object_int_add(jsondata, "priority", scope->cand_bsr_prio);
+ json_object_boolean_add(jsondata, "elected",
+ pim->global_scope.state == BSR_ELECTED);
+
+ vty_json(vty, jsondata);
+ return CMD_SUCCESS;
+ }
+
+ vty_out(vty,
+ "Candidate-BSR\nAddress: %pPA\nPriority: %u\nElected: %s\n",
+ &scope->bsr_addrsel.run_addr, scope->cand_bsr_prio,
+ (pim->global_scope.state == BSR_ELECTED) ? " Yes" : " No");
+
+ if (!pim_addr_cmp(scope->bsr_addrsel.run_addr, PIMADDR_ANY))
+ vty_out(vty,
+ "\nThis router is not currently operating as Candidate BSR\n"
+ "Configure a BSR address to enable this feature\n\n");
+
+ return CMD_SUCCESS;
+}
+
/* Display the bsm database details */
static void pim_show_bsm_db(struct pim_instance *pim, struct vty *vty, bool uj)
{