diff options
author | Nathan Bahr <nbahr@atcorp.com> | 2024-11-01 20:11:14 +0100 |
---|---|---|
committer | Nathan Bahr <nbahr@atcorp.com> | 2024-11-19 23:33:11 +0100 |
commit | a060c72530b96181ca736e8c42257b558e1b8dd3 (patch) | |
tree | aa0866ae2c5b4e9cabade7cb6e1e8ddf4f60fd21 | |
parent | pimd,yang: Add PIMD northbound/yang for AutoRP mapping agent (diff) | |
download | frr-a060c72530b96181ca736e8c42257b558e1b8dd3.tar.xz frr-a060c72530b96181ca736e8c42257b558e1b8dd3.zip |
pimd: Implement autorp mapping agent CLI
Also exposes BSR cand_addrsel methods for use in AutoRP.
Signed-off-by: Nathan Bahr <nbahr@atcorp.com>
-rw-r--r-- | pimd/pim_bsm.c | 4 | ||||
-rw-r--r-- | pimd/pim_bsm.h | 5 | ||||
-rw-r--r-- | pimd/pim_cmd.c | 114 | ||||
-rw-r--r-- | pimd/pim_cmd_common.c | 185 | ||||
-rw-r--r-- | pimd/pim_cmd_common.h | 16 |
5 files changed, 149 insertions, 175 deletions
diff --git a/pimd/pim_bsm.c b/pimd/pim_bsm.c index a44e4e08f..75104141a 100644 --- a/pimd/pim_bsm.c +++ b/pimd/pim_bsm.c @@ -1769,14 +1769,14 @@ static inline pim_addr if_highest_addr(pim_addr cur, struct interface *ifp) return cur; } -static void cand_addrsel_clear(struct cand_addrsel *asel) +void cand_addrsel_clear(struct cand_addrsel *asel) { asel->run = false; asel->run_addr = PIMADDR_ANY; } /* returns whether address or active changed */ -static bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf) +bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf) { bool is_any = false, prev_run = asel->run; struct interface *ifp = NULL; diff --git a/pimd/pim_bsm.h b/pimd/pim_bsm.h index 1eacc1be5..b1582d0df 100644 --- a/pimd/pim_bsm.h +++ b/pimd/pim_bsm.h @@ -64,7 +64,7 @@ enum cand_addr { CAND_ADDR_EXPLICIT, }; -/* used separately for Cand-RP and Cand-BSR */ +/* used separately for Cand-RP, Cand-BSR, and AutoRP mapping agent */ struct cand_addrsel { bool cfg_enable; enum cand_addr cfg_mode : 8; @@ -369,6 +369,9 @@ void pim_cand_rp_trigger(struct bsm_scope *scope); void pim_cand_rp_grp_add(struct bsm_scope *scope, const prefix_pim *p); void pim_cand_rp_grp_del(struct bsm_scope *scope, const prefix_pim *p); +void cand_addrsel_clear(struct cand_addrsel *asel); +bool cand_addrsel_update(struct cand_addrsel *asel, struct vrf *vrf); + void pim_cand_addrs_changed(void); int pim_crp_process(struct interface *ifp, pim_sgaddr *src_dst, uint8_t *buf, diff --git a/pimd/pim_cmd.c b/pimd/pim_cmd.c index 934da2d53..732dd2971 100644 --- a/pimd/pim_cmd.c +++ b/pimd/pim_cmd.c @@ -2822,65 +2822,49 @@ DEFPY (show_ip_pim_rp_vrf_all, DEFPY (show_ip_pim_autorp, show_ip_pim_autorp_cmd, - "show ip pim [vrf NAME] autorp [json$json]", + "show ip pim [vrf <NAME|all>] autorp [discovery|candidate|mapping-agent]$component [json$json]", SHOW_STR IP_STR PIM_STR VRF_CMD_HELP_STR + "All VRF's\n" "PIM AutoRP information\n" + "RP Discovery details\n" + "Candidate RP details\n" + "Mapping Agent details\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; - } + struct vrf *v; 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 (vrf && strmatch(vrf, "all")) { + json_object *json_vrf = NULL; - if (json) - json_parent = json_object_new_object(); + RB_FOREACH (v, vrf_name_head, &vrfs_by_name) { + if (!v || !v->info) + continue; - RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) { - if (vrf->info) { - if (!json) - vty_out(vty, "VRF: %s\n", vrf->name); - else + if (json) json_vrf = json_object_new_object(); + else + vty_out(vty, "VRF: %s\n", v->name); - pim_autorp_show_autorp(vty, vrf->info, json_vrf); + pim_autorp_show_autorp(vty, v->info, component, json_vrf); if (json) - json_object_object_add(json_parent, vrf->name, - json_vrf); + json_object_object_add(json_parent, v->name, json_vrf); + } + } else { + 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; } + pim_autorp_show_autorp(vty, v->info, component, json_parent); } if (json) @@ -4609,13 +4593,17 @@ DEFPY (pim_autorp_announce_rp, "Prefix list\n" "List name\n") { - return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, (grp_str ? grp : NULL), - plist); + if (grp_str && (!pim_addr_is_multicast(grp->prefix) || grp->prefixlen < 4)) { + vty_out(vty, "%% group prefix %pFX is not a valid multicast range\n", grp); + return CMD_WARNING_CONFIG_FAILED; + } + + return pim_process_autorp_candidate_rp_cmd(vty, no, rpaddr_str, grp_str, 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] autorp announce {scope (1-255) | interval (1-65535) | holdtime (0-65535)}", NO_STR "AutoRP\n" "AutoRP Candidate RP announcement\n" @@ -4626,11 +4614,44 @@ DEFPY (pim_autorp_announce_scope_int, "Announcement holdtime\n" "Time in seconds\n") { - return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str, - interval_str, + return pim_process_autorp_announce_scope_int_cmd(vty, no, scope_str, interval_str, holdtime_str); } +DEFPY (pim_autorp_send_rp_discovery, + pim_autorp_send_rp_discovery_cmd, + "[no] autorp send-rp-discovery [source <address A.B.C.D | interface IFNAME | loopback$loopback | any$any>]", + NO_STR + "AutoRP\n" + "Enable AutoRP mapping agent\n" + "Specify AutoRP discovery source\n" + "Local address\n" + IP_ADDR_STR + "Local Interface (uses highest address)\n" + IFNAME_STR + "Highest loopback address (default)\n" + "Highest address of any interface\n") +{ + return pim_process_autorp_send_rp_discovery_cmd(vty, no, any, loopback, ifname, address_str); +} + +DEFPY (pim_autorp_send_rp_discovery_scope_int, + pim_autorp_send_rp_discovery_scope_int_cmd, + "[no] autorp send-rp-discovery {scope (0-255) | interval (1-65535) | holdtime (0-65535)}", + NO_STR + "AutoRP\n" + "Enable AutoRP mapping agent\n" + "Packet scope (TTL)\n" + "TTL value\n" + "Discovery TX interval\n" + "Time in seconds\n" + "Announcement holdtime\n" + "Time in seconds\n") +{ + return pim_process_autorp_send_rp_discovery_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>}]", @@ -8855,6 +8876,8 @@ void pim_cmd_init(void) 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, &pim_autorp_send_rp_discovery_cmd); + install_element(PIM_NODE, &pim_autorp_send_rp_discovery_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); @@ -9010,7 +9033,6 @@ void pim_cmd_init(void) 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); diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index 02ddea825..1476845a5 100644 --- a/pimd/pim_cmd_common.c +++ b/pimd/pim_cmd_common.c @@ -630,139 +630,88 @@ int pim_process_no_autorp_cmd(struct vty *vty) 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) +int pim_process_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str, + const char *grp, const char *plist) { - char xpath[XPATH_MAXLEN]; - char grpstr[64]; - if (no) { - if ((grp && !is_default_prefix((const struct prefix *)grp)) || plist) { + if (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 { + if (grp) + nb_cli_enqueue_change(vty, "./group", NB_OP_DESTROY, NULL); + if (plist) + nb_cli_enqueue_change(vty, "./prefix-list", 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); - } + nb_cli_enqueue_change(vty, ".", 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; - } + nb_cli_enqueue_change(vty, ".", NB_OP_CREATE, NULL); + if (grp) + nb_cli_enqueue_change(vty, "./group", NB_OP_MODIFY, grp); + if (plist) + nb_cli_enqueue_change(vty, "./prefix-list", NB_OP_MODIFY, plist); } - return nb_cli_apply_changes(vty, NULL); + return nb_cli_apply_changes(vty, "%s/candidate-rp-list[rp-address='%s']", + FRR_PIM_AUTORP_XPATH, rpaddr_str); } -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_autorp_announce_scope_int_cmd(struct vty *vty, bool no, const char *scope, + const char *interval, const char *holdtime) { - char xpath[XPATH_MAXLEN]; + /* At least one value is required, so set/delete anything defined */ + enum nb_operation op = (no ? NB_OP_DESTROY : NB_OP_MODIFY); + + if (scope) + nb_cli_enqueue_change(vty, "./announce-scope", op, scope); + if (interval) + nb_cli_enqueue_change(vty, "./announce-interval", op, interval); + if (holdtime) + nb_cli_enqueue_change(vty, "./announce-holdtime", op, holdtime); + return nb_cli_apply_changes(vty, "%s", FRR_PIM_AUTORP_XPATH); +} + +int pim_process_autorp_send_rp_discovery_cmd(struct vty *vty, bool no, bool any, bool loopback, + const char *ifname, const char *addr) +{ + /* Just take any "no" version of this command as disable the mapping agent */ + nb_cli_enqueue_change(vty, "./send-rp-discovery", NB_OP_MODIFY, (no ? "false" : "true")); 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); - } + nb_cli_enqueue_change(vty, "./if-any", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./interface", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./address", NB_OP_DESTROY, NULL); + nb_cli_enqueue_change(vty, "./if-loopback", 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; - } + /* Enabling mapping agent. Loopback is default, so any non-no for of the command will + * enable the mapping agent. + */ + if (any) + nb_cli_enqueue_change(vty, "./if-any", NB_OP_CREATE, NULL); + else if (ifname) + nb_cli_enqueue_change(vty, "./interface", NB_OP_MODIFY, ifname); + else if (addr) + nb_cli_enqueue_change(vty, "./address", NB_OP_MODIFY, addr); + else + nb_cli_enqueue_change(vty, "./if-loopback", NB_OP_CREATE, NULL); } - return nb_cli_apply_changes(vty, NULL); + return nb_cli_apply_changes(vty, "%s/%s", FRR_PIM_AUTORP_XPATH, "mapping-agent"); +} + +int pim_process_autorp_send_rp_discovery_scope_int_cmd(struct vty *vty, bool no, const char *scope, + const char *interval, const char *holdtime) +{ + /* At least one value is required, so only set/delete the values specified */ + enum nb_operation op = (no ? NB_OP_DESTROY : NB_OP_MODIFY); + + if (scope) + nb_cli_enqueue_change(vty, "./discovery-scope", op, scope); + if (interval) + nb_cli_enqueue_change(vty, "./discovery-interval", op, interval); + if (holdtime) + nb_cli_enqueue_change(vty, "./discovery-holdtime", op, holdtime); + + return nb_cli_apply_changes(vty, "%s/%s", FRR_PIM_AUTORP_XPATH, "mapping-agent"); } bool pim_sgaddr_match(pim_sgaddr item, pim_sgaddr match) diff --git a/pimd/pim_cmd_common.h b/pimd/pim_cmd_common.h index d7c97e31d..a06764711 100644 --- a/pimd/pim_cmd_common.h +++ b/pimd/pim_cmd_common.h @@ -37,14 +37,14 @@ 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_autorp_candidate_rp_cmd(struct vty *vty, bool no, const char *rpaddr_str, + const char *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_autorp_send_rp_discovery_cmd(struct vty *vty, bool no, bool any, bool loopback, + const char *ifname, const char *addr); +int pim_process_autorp_send_rp_discovery_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); |