Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
310 changes: 310 additions & 0 deletions pimd/pim6_cmd.c
Original file line number Diff line number Diff line change
Expand Up @@ -503,6 +503,206 @@ DEFPY (no_ipv6_pim_ucast_bsm,
return pim_process_no_unicast_bsm_cmd(vty);
}

DEFPY (ipv6_pim_candidate_bsr,
ipv6_pim_candidate_bsr_cmd,
"[no] ipv6 pim candidate-bsr [{priority (0-255)|source <address X:X::X:X|interface IFNAME|loopback$loopback|any$any>}]",
NO_STR
IPV6_STR
"pim multicast routing\n"
"Make this router a Candidate BSR\n"
"BSR Priority (higher wins)\n"
"BSR Priority (higher wins)\n"
"Specify IP address for BSR operation\n"
"Local address to use\n"
"Local address to use\n"
"Interface to pick address from\n"
"Interface to pick address from\n"
"Pick highest loopback address (default)\n"
"Pick highest address from any interface\n")
{
char cand_bsr_xpath[XPATH_MAXLEN];
const struct lyd_node *vrf_dnode;
const char *vrfname;

if (vty->xpath_index) {
vrf_dnode = yang_dnode_get(vty->candidate_config->dnode,
VTY_CURR_XPATH);

if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}

vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;

snprintf(cand_bsr_xpath, sizeof(cand_bsr_xpath), FRR_PIM_CAND_BSR_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv6");

if (no)
nb_cli_enqueue_change(vty, cand_bsr_xpath, NB_OP_DESTROY, NULL);
else {
char xpath2[XPATH_MAXLEN + 16];

nb_cli_enqueue_change(vty, cand_bsr_xpath, NB_OP_CREATE, NULL);

if (any) {
snprintf(xpath2, sizeof(xpath2), "%s/if-any",
cand_bsr_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, NULL);
} else if (ifname) {
snprintf(xpath2, sizeof(xpath2), "%s/interface",
cand_bsr_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, ifname);
} else if (address_str) {
snprintf(xpath2, sizeof(xpath2), "%s/address",
cand_bsr_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE,
address_str);
} else {
snprintf(xpath2, sizeof(xpath2), "%s/if-loopback",
cand_bsr_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, NULL);
}

if (priority_str) {
snprintf(xpath2, sizeof(xpath2), "%s/bsr-priority",
cand_bsr_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_MODIFY,
priority_str);
}
}

return nb_cli_apply_changes(vty, NULL);
}

DEFPY (ipv6_pim_candidate_rp,
ipv6_pim_candidate_rp_cmd,
"[no] ipv6 pim candidate-rp [{priority (0-255)|interval (1-4294967295)|source <address X:X::X:X|interface IFNAME|loopback$loopback|any$any>}]",
NO_STR
IPV6_STR
"pim multicast routing\n"
"Make this router a Candidate RP\n"
"RP Priority (lower wins)\n"
"RP Priority (lower wins)\n"
"Advertisement interval (seconds)\n"
"Advertisement interval (seconds)\n"
"Specify IP address for RP operation\n"
"Local address to use\n"
"Local address to use\n"
"Interface to pick address from\n"
"Interface to pick address from\n"
"Pick highest loopback address (default)\n"
"Pick highest address from any interface\n")
{
char cand_rp_xpath[XPATH_MAXLEN];
const struct lyd_node *vrf_dnode;
const char *vrfname;

if (vty->xpath_index) {
vrf_dnode = yang_dnode_get(vty->candidate_config->dnode,
VTY_CURR_XPATH);

if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}

vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;

snprintf(cand_rp_xpath, sizeof(cand_rp_xpath), FRR_PIM_CAND_RP_XPATH,
"frr-pim:pimd", "pim", vrfname, "frr-routing:ipv6");

if (no)
nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_DESTROY, NULL);
else {
char xpath2[XPATH_MAXLEN + 24];

nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_CREATE, NULL);

if (any) {
snprintf(xpath2, sizeof(xpath2), "%s/if-any",
cand_rp_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, NULL);
} else if (ifname) {
snprintf(xpath2, sizeof(xpath2), "%s/interface",
cand_rp_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, ifname);
} else if (address_str) {
snprintf(xpath2, sizeof(xpath2), "%s/address",
cand_rp_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE,
address_str);
} else {
snprintf(xpath2, sizeof(xpath2), "%s/if-loopback",
cand_rp_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_CREATE, NULL);
}

if (priority_str) {
snprintf(xpath2, sizeof(xpath2), "%s/rp-priority",
cand_rp_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_MODIFY,
priority_str);
}
if (interval_str) {
snprintf(xpath2, sizeof(xpath2),
"%s/advertisement-interval", cand_rp_xpath);
nb_cli_enqueue_change(vty, xpath2, NB_OP_MODIFY,
interval_str);
}
}

return nb_cli_apply_changes(vty, NULL);
}

DEFPY (ipv6_pim_candidate_rp_group,
ipv6_pim_candidate_rp_group_cmd,
"[no] ipv6 pim candidate-rp group X:X::X:X/M",
NO_STR
IPV6_STR
"pim multicast routing\n"
"Make this router a Candidate RP\n"
"Configure groups to become candidate RP for\n"
"Multicast group prefix\n")
{
char cand_rp_xpath[XPATH_MAXLEN];
const struct lyd_node *vrf_dnode;
const char *vrfname;

if (vty->xpath_index) {
vrf_dnode = yang_dnode_get(vty->candidate_config->dnode,
VTY_CURR_XPATH);

if (!vrf_dnode) {
vty_out(vty,
"%% Failed to get vrf dnode in candidate db\n");
return CMD_WARNING_CONFIG_FAILED;
}

vrfname = yang_dnode_get_string(vrf_dnode, "./name");
} else
vrfname = VRF_DEFAULT_NAME;

snprintf(cand_rp_xpath, sizeof(cand_rp_xpath),
FRR_PIM_CAND_RP_XPATH "/group-list", "frr-pim:pimd", "pim",
vrfname, "frr-routing:ipv6");

if (no)
nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_DESTROY,
group_str);
else
nb_cli_enqueue_change(vty, cand_rp_xpath, NB_OP_CREATE,
group_str);

return nb_cli_apply_changes(vty, NULL);
}

DEFPY (ipv6_ssmpingd,
ipv6_ssmpingd_cmd,
"ipv6 ssmpingd [X:X::X:X]$source",
Expand Down Expand Up @@ -874,6 +1074,106 @@ DEFPY (show_ipv6_pim_secondary,
return pim_show_secondary_helper(vrf, vty);
}

DEFPY (show_ipv6_pim_cand_rp,
show_ipv6_pim_cand_rp_cmd,
"show ipv6 pim candidate-rp [vrf VRF_NAME] [json$uj]",
SHOW_STR
IPV6_STR
PIM_STR
"PIM Candidate RP state\n"
VRF_CMD_HELP_STR
JSON_STR)
{
struct vrf *vrf = pim_cmd_lookup(vty, vrf_name);
struct pim_instance *pim;
struct bsm_scope *scope;
json_object *json = 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) {
json = json_object_new_object();
json_object_string_addf(json, "address", "%pPA",
&scope->cand_rp_addrsel.run_addr);
json_object_int_add(json, "priority", scope->cand_rp_prio);
json_object_int_add(json, "nextAdvertisementMsec",
event_timer_remain_msec(
scope->cand_rp_adv_timer));

vty_out(vty, "%s\n",
json_object_to_json_string_ext(json,
JSON_C_TO_STRING_PRETTY));
json_object_free(json);
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;
}

DEFPY (show_ipv6_pim_bsr_rpdb,
show_ipv6_pim_bsr_rpdb_cmd,
"show ipv6 pim bsr candidate-rps [vrf VRF_NAME] [json$uj]",
SHOW_STR
IPV6_STR
PIM_STR
"boot-strap router information\n"
"Candidate RPs\n"
VRF_CMD_HELP_STR
JSON_STR)
{
struct vrf *vrf = pim_cmd_lookup(vty, vrf_name);

if (!vrf || !vrf->info)
return CMD_WARNING;

struct pim_instance *pim = vrf->info;
struct bsm_scope *scope = &pim->global_scope;

return pim_crp_db_show(vty, scope);
}

DEFPY (show_ipv6_pim_bsr_groups,
show_ipv6_pim_bsr_groups_cmd,
"show ipv6 pim bsr groups [vrf VRF_NAME] [json$uj]",
SHOW_STR
IPV6_STR
PIM_STR
"boot-strap router information\n"
"Candidate RP groups\n"
VRF_CMD_HELP_STR
JSON_STR)
{
struct vrf *vrf = pim_cmd_lookup(vty, vrf_name);

if (!vrf || !vrf->info)
return CMD_WARNING;

struct pim_instance *pim = vrf->info;
struct bsm_scope *scope = &pim->global_scope;

return pim_crp_groups_show(vty, scope);
}


DEFPY (show_ipv6_pim_statistics,
show_ipv6_pim_statistics_cmd,
"show ipv6 pim [vrf NAME] statistics [interface WORD$word] [json$json]",
Expand Down Expand Up @@ -1813,11 +2113,21 @@ void pim_cmd_init(void)
install_element(INTERFACE_NODE,
&interface_no_ipv6_mld_last_member_query_interval_cmd);

install_element(CONFIG_NODE, &ipv6_pim_candidate_bsr_cmd);
install_element(VRF_NODE, &ipv6_pim_candidate_bsr_cmd);
install_element(CONFIG_NODE, &ipv6_pim_candidate_rp_cmd);
install_element(VRF_NODE, &ipv6_pim_candidate_rp_cmd);
install_element(CONFIG_NODE, &ipv6_pim_candidate_rp_group_cmd);
install_element(VRF_NODE, &ipv6_pim_candidate_rp_group_cmd);

install_element(VIEW_NODE, &show_ipv6_pim_rp_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_rp_vrf_all_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_rpf_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_rpf_vrf_all_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_secondary_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_cand_rp_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_bsr_rpdb_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_bsr_groups_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_statistics_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_upstream_cmd);
install_element(VIEW_NODE, &show_ipv6_pim_upstream_vrf_all_cmd);
Expand Down
3 changes: 2 additions & 1 deletion pimd/pim6_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ struct frr_signal_t pim6d_signals[] = {
},
};

/* clang-format off */
static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
&frr_filter_info,
&frr_interface_info,
Expand All @@ -102,10 +103,10 @@ static const struct frr_yang_module_info *const pim6d_yang_modules[] = {
&frr_routing_info,
&frr_pim_info,
&frr_pim_rp_info,
&frr_pim_candidate_info,
&frr_gmp_info,
};

/* clang-format off */
FRR_DAEMON_INFO(pim6d, PIM6,
.vty_port = PIM6D_VTY_PORT,
.proghelp = "Protocol Independent Multicast (RFC7761) for IPv6",
Expand Down
4 changes: 4 additions & 0 deletions pimd/pim_addr.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,13 @@

#if PIM_IPV == 4
typedef struct in_addr pim_addr;
typedef struct prefix_ipv4 prefix_pim;

#define PIM_ADDRSTRLEN INET_ADDRSTRLEN
#define PIM_AF AF_INET
#define PIM_AFI AFI_IP
#define PIM_PROTO_REG IPPROTO_RAW
#define PIM_IANA_AFI IANA_AFI_IPV4
#define PIM_IPADDR IPADDR_V4
#define ipaddr_pim ipaddr_v4
#define PIM_MAX_BITLEN IPV4_MAX_BITLEN
Expand All @@ -44,11 +46,13 @@ union pimprefixconstptr {

#else
typedef struct in6_addr pim_addr;
typedef struct prefix_ipv6 prefix_pim;

#define PIM_ADDRSTRLEN INET6_ADDRSTRLEN
#define PIM_AF AF_INET6
#define PIM_AFI AFI_IP6
#define PIM_PROTO_REG IPPROTO_PIM
#define PIM_IANA_AFI IANA_AFI_IPV6
#define PIM_IPADDR IPADDR_V6
#define ipaddr_pim ipaddr_v6
#define PIM_MAX_BITLEN IPV6_MAX_BITLEN
Expand Down
Loading