diff options
Diffstat (limited to 'pimd/pim_cmd_common.c')
| -rw-r--r-- | pimd/pim_cmd_common.c | 337 |
1 files changed, 147 insertions, 190 deletions
diff --git a/pimd/pim_cmd_common.c b/pimd/pim_cmd_common.c index 02ddea8252..8aebce7d27 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) @@ -2876,31 +2825,39 @@ static int pim_print_vty_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg) struct vty *vty = cwd->vty; struct pim_instance *pim = cwd->pim; struct nexthop *nh_node = NULL; - ifindex_t first_ifindex; struct interface *ifp = NULL; struct ttable *tt = NULL; char *table = NULL; /* Prepare table. */ tt = ttable_new(&ttable_styles[TTSTYLE_BLANK]); - ttable_add_row(tt, "Address|Interface|Nexthop"); + ttable_add_row(tt, "Address|Interface|Nexthop|Table"); tt->style.cell.rpad = 2; tt->style.corner = '+'; ttable_restyle(tt); - for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) { - first_ifindex = nh_node->ifindex; - - ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id); + for (nh_node = pnc->mrib.nexthop; nh_node; nh_node = nh_node->next) { + ifp = if_lookup_by_index(nh_node->ifindex, pim->vrf->vrf_id); +#if PIM_IPV == 4 + ttable_add_row(tt, "%pPA|%s|%pI4|%s", &pnc->addr, ifp ? ifp->name : "NULL", + &nh_node->gate.ipv4, "MRIB"); +#else + ttable_add_row(tt, "%pPA|%s|%pI6|%s", &pnc->addr, ifp ? ifp->name : "NULL", + &nh_node->gate.ipv6, "MRIB"); +#endif + } + for (nh_node = pnc->urib.nexthop; nh_node; nh_node = nh_node->next) { + ifp = if_lookup_by_index(nh_node->ifindex, pim->vrf->vrf_id); #if PIM_IPV == 4 - ttable_add_row(tt, "%pPA|%s|%pI4", &pnc->rpf.rpf_addr, - ifp ? ifp->name : "NULL", &nh_node->gate.ipv4); + ttable_add_row(tt, "%pPA|%s|%pI4|%s", &pnc->addr, ifp ? ifp->name : "NULL", + &nh_node->gate.ipv4, "URIB"); #else - ttable_add_row(tt, "%pPA|%s|%pI6", &pnc->rpf.rpf_addr, - ifp ? ifp->name : "NULL", &nh_node->gate.ipv6); + ttable_add_row(tt, "%pPA|%s|%pI6|%s", &pnc->addr, ifp ? ifp->name : "NULL", + &nh_node->gate.ipv6, "URIB"); #endif } + /* Dump the generated table. */ table = ttable_dump(tt, "\n"); vty_out(vty, "%s\n", table); @@ -2910,56 +2867,58 @@ static int pim_print_vty_pnc_cache_walkcb(struct hash_bucket *bucket, void *arg) return CMD_SUCCESS; } -static int pim_print_json_pnc_cache_walkcb(struct hash_bucket *backet, - void *arg) +static void pim_print_json_nexthop(json_object *json_obj, struct nexthop *nh_node, + struct interface *ifp, char *addr_str, const char *type) { - struct pim_nexthop_cache *pnc = backet->data; - struct json_pnc_cache_walk_data *cwd = arg; - struct pim_instance *pim = cwd->pim; - struct nexthop *nh_node = NULL; - ifindex_t first_ifindex; - struct interface *ifp = NULL; - char addr_str[PIM_ADDRSTRLEN]; json_object *json_row = NULL; json_object *json_ifp = NULL; json_object *json_arr = NULL; struct pim_interface *pim_ifp = NULL; - bool pim_enable = false; - - for (nh_node = pnc->nexthop; nh_node; nh_node = nh_node->next) { - first_ifindex = nh_node->ifindex; - ifp = if_lookup_by_index(first_ifindex, pim->vrf->vrf_id); - snprintfrr(addr_str, sizeof(addr_str), "%pPA", - &pnc->rpf.rpf_addr); - json_object_object_get_ex(cwd->json_obj, addr_str, &json_row); - if (!json_row) { - json_row = json_object_new_object(); - json_object_string_addf(json_row, "address", "%pPA", - &pnc->rpf.rpf_addr); - json_object_object_addf(cwd->json_obj, json_row, "%pPA", - &pnc->rpf.rpf_addr); - json_arr = json_object_new_array(); - json_object_object_add(json_row, "nexthops", json_arr); - } - json_ifp = json_object_new_object(); - json_object_string_add(json_ifp, "interface", - ifp ? ifp->name : "NULL"); - if (ifp) - pim_ifp = ifp->info; + if (ifp) + pim_ifp = ifp->info; + + json_object_object_get_ex(json_obj, addr_str, &json_row); - if (pim_ifp && pim_ifp->pim_enable) - pim_enable = true; + if (!json_row) { + json_row = json_object_new_object(); + json_object_string_addf(json_row, "address", "%s", addr_str); + json_object_object_addf(json_obj, json_row, "%s", addr_str); + json_arr = json_object_new_array(); + json_object_object_add(json_row, "nexthops", json_arr); + } - json_object_boolean_add(json_ifp, "pimEnabled", pim_enable); + json_ifp = json_object_new_object(); + json_object_string_add(json_ifp, "interface", ifp ? ifp->name : "NULL"); + json_object_boolean_add(json_ifp, "pimEnabled", (pim_ifp && pim_ifp->pim_enable)); #if PIM_IPV == 4 - json_object_string_addf(json_ifp, "nexthop", "%pI4", - &nh_node->gate.ipv4); + json_object_string_addf(json_ifp, "nexthop", "%pI4", &nh_node->gate.ipv4); #else - json_object_string_addf(json_ifp, "nexthop", "%pI6", - &nh_node->gate.ipv6); + json_object_string_addf(json_ifp, "nexthop", "%pI6", &nh_node->gate.ipv6); #endif - json_object_array_add(json_arr, json_ifp); + json_object_string_add(json_ifp, "table", type); + json_object_array_add(json_arr, json_ifp); +} + +static int pim_print_json_pnc_cache_walkcb(struct hash_bucket *backet, void *arg) +{ + struct pim_nexthop_cache *pnc = backet->data; + struct json_pnc_cache_walk_data *cwd = arg; + json_object *json_obj = cwd->json_obj; + struct pim_instance *pim = cwd->pim; + char addr_str[PIM_ADDRSTRLEN]; + struct nexthop *nh_node = NULL; + struct interface *ifp = NULL; + + snprintfrr(addr_str, sizeof(addr_str), "%pPA", &pnc->addr); + for (nh_node = pnc->mrib.nexthop; nh_node; nh_node = nh_node->next) { + ifp = if_lookup_by_index(nh_node->ifindex, pim->vrf->vrf_id); + pim_print_json_nexthop(json_obj, nh_node, ifp, addr_str, "MRIB"); + } + + for (nh_node = pnc->urib.nexthop; nh_node; nh_node = nh_node->next) { + ifp = if_lookup_by_index(nh_node->ifindex, pim->vrf->vrf_id); + pim_print_json_nexthop(json_obj, nh_node, ifp, addr_str, "URIB"); } return CMD_SUCCESS; } @@ -2967,7 +2926,6 @@ static int pim_print_json_pnc_cache_walkcb(struct hash_bucket *backet, int pim_show_nexthop_lookup_cmd_helper(const char *vrf, struct vty *vty, pim_addr source, pim_addr group) { - int result = 0; pim_addr vif_source; struct prefix grp; struct pim_nexthop nexthop; @@ -2980,34 +2938,36 @@ int pim_show_nexthop_lookup_cmd_helper(const char *vrf, struct vty *vty, #if PIM_IPV == 4 if (pim_is_group_224_4(source)) { - vty_out(vty, - "Invalid argument. Expected Valid Source Address.\n"); + vty_out(vty, "Invalid argument. Expected Valid Source Address.\n"); return CMD_WARNING; } - - if (!pim_is_group_224_4(group)) { - vty_out(vty, - "Invalid argument. Expected Valid Multicast Group Address.\n"); + /* Only require group if source is not provided */ + if (pim_addr_is_any(source) && !pim_is_group_224_4(group)) { + vty_out(vty, "Invalid argument. Expected Valid Multicast Group Address.\n"); return CMD_WARNING; } #endif - if (!pim_rp_set_upstream_addr(v->info, &vif_source, source, group)) + /* This call will set vif_source=source, if source is not ANY. Otherwise vif_source + * will be set to the RP address according to the group address. If no RP is configured + * for the group, then return 0 and set vif_source to ANY + */ + if (!pim_rp_set_upstream_addr(v->info, &vif_source, source, group)) { + vty_out(vty, "(%pPAs, %pPA) --- Nexthop Lookup failed, no RP.\n", &source, &group); return CMD_SUCCESS; + } + pim_addr_to_prefix(&grp, group); memset(&nexthop, 0, sizeof(nexthop)); - result = - pim_ecmp_nexthop_lookup(v->info, &nexthop, vif_source, &grp, 0); - - if (!result) { - vty_out(vty, - "Nexthop Lookup failed, no usable routes returned.\n"); + if (!pim_nht_lookup_ecmp(v->info, &nexthop, vif_source, &grp, false)) { + vty_out(vty, "(%pPAs, %pPA) --- Nexthop Lookup failed, no usable routes returned.\n", + &source, &group); return CMD_SUCCESS; } - vty_out(vty, "Group %pFXh --- Nexthop %pPAs Interface %s\n", &grp, + vty_out(vty, "(%pPAs, %pPAs) --- Nexthop %pPAs Interface %s\n", &source, &group, &nexthop.mrib_nexthop_addr, nexthop.interface->name); return CMD_SUCCESS; @@ -3036,19 +2996,16 @@ void pim_show_nexthop(struct pim_instance *pim, struct vty *vty, bool uj) cwd.pim = pim; jcwd.pim = pim; - if (uj) { + if (uj) jcwd.json_obj = json_object_new_object(); - } else { - vty_out(vty, "Number of registered addresses: %lu\n", - pim->rpf_hash->count); - } + else + vty_out(vty, "Number of registered addresses: %lu\n", pim->nht_hash->count); if (uj) { - hash_walk(pim->rpf_hash, pim_print_json_pnc_cache_walkcb, - &jcwd); + hash_walk(pim->nht_hash, pim_print_json_pnc_cache_walkcb, &jcwd); vty_json(vty, jcwd.json_obj); } else - hash_walk(pim->rpf_hash, pim_print_vty_pnc_cache_walkcb, &cwd); + hash_walk(pim->nht_hash, pim_print_vty_pnc_cache_walkcb, &cwd); } int pim_show_neighbors_cmd_helper(const char *vrf, struct vty *vty, |
