diff options
Diffstat (limited to 'pbrd/pbr_vty.c')
| -rw-r--r-- | pbrd/pbr_vty.c | 312 |
1 files changed, 145 insertions, 167 deletions
diff --git a/pbrd/pbr_vty.c b/pbrd/pbr_vty.c index dfc8bec1bc..a52c2d1e30 100644 --- a/pbrd/pbr_vty.c +++ b/pbrd/pbr_vty.c @@ -142,18 +142,14 @@ DEFPY(pbr_map_match_src, pbr_map_match_src_cmd, if (pbrms->src) { if (prefix_same(pbrms->src, prefix)) return CMD_SUCCESS; + } else + pbrms->src = prefix_new(); - vty_out(vty, - "A `match src-ip XX` command already exists, please remove that first\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - pbrms->src = prefix_new(); prefix_copy(pbrms->src, prefix); } else prefix_free(&pbrms->src); - pbr_map_check(pbrms); + pbr_map_check(pbrms, true); return CMD_SUCCESS; } @@ -174,18 +170,14 @@ DEFPY(pbr_map_match_dst, pbr_map_match_dst_cmd, if (pbrms->dst) { if (prefix_same(pbrms->dst, prefix)) return CMD_SUCCESS; + } else + pbrms->dst = prefix_new(); - vty_out(vty, - "A `match dst-ip XX` command already exists, please remove that first\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - pbrms->dst = prefix_new(); prefix_copy(pbrms->dst, prefix); } else prefix_free(&pbrms->dst); - pbr_map_check(pbrms); + pbr_map_check(pbrms, true); return CMD_SUCCESS; } @@ -205,30 +197,52 @@ DEFPY(pbr_map_match_mark, pbr_map_match_mark_cmd, #endif if (!no) { - if (pbrms->mark) { + if (pbrms->mark) if (pbrms->mark == (uint32_t)mark) return CMD_SUCCESS; - vty_out(vty, - "A `match mark XX` command already exists, please remove that first\n"); - return CMD_WARNING_CONFIG_FAILED; - } - pbrms->mark = (uint32_t)mark; } else pbrms->mark = 0; - pbr_map_check(pbrms); + pbr_map_check(pbrms, true); return CMD_SUCCESS; } -#define SET_VRF_EXISTS_STR \ - "A `set vrf XX` command already exists, please remove that first\n" +static void pbrms_clear_set_vrf_config(struct pbr_map_sequence *pbrms) +{ + if (pbrms->vrf_lookup || pbrms->vrf_unchanged) { + pbr_map_delete_vrf(pbrms); + pbrms->vrf_name[0] = '\0'; + pbrms->vrf_lookup = false; + pbrms->vrf_unchanged = false; + } +} + +static void pbrms_clear_set_nhg_config(struct pbr_map_sequence *pbrms) +{ + if (pbrms->nhgrp_name) + pbr_map_delete_nexthops(pbrms); +} + +static void pbrms_clear_set_nexthop_config(struct pbr_map_sequence *pbrms) +{ + if (pbrms->nhg) + pbr_nht_delete_individual_nexthop(pbrms); +} + +static void pbrms_clear_set_config(struct pbr_map_sequence *pbrms) +{ + pbrms_clear_set_vrf_config(pbrms); + pbrms_clear_set_nhg_config(pbrms); + pbrms_clear_set_nexthop_config(pbrms); + + pbrms->nhs_installed = false; +} DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd, - "[no] set nexthop-group NHGNAME$name", - NO_STR + "set nexthop-group NHGNAME$name", "Set for the PBR-MAP\n" "nexthop-group to use\n" "The name of the nexthop-group\n") @@ -236,17 +250,6 @@ DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd, struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); struct nexthop_group_cmd *nhgc; - if (pbrms->nhg) { - vty_out(vty, - "A `set nexthop XX` command already exists, please remove that first\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (pbrms->vrf_lookup || pbrms->vrf_unchanged) { - vty_out(vty, SET_VRF_EXISTS_STR); - return CMD_WARNING_CONFIG_FAILED; - } - nhgc = nhgc_find(name); if (!nhgc) { vty_out(vty, "Specified nexthop-group %s does not exist\n", @@ -255,40 +258,39 @@ DEFPY(pbr_map_nexthop_group, pbr_map_nexthop_group_cmd, "PBR-MAP will not be applied until it is created\n"); } - if (no) { - if (pbrms->nhgrp_name && strcmp(name, pbrms->nhgrp_name) == 0) - pbr_map_delete_nexthops(pbrms); - else { - vty_out(vty, - "Nexthop Group specified: %s does not exist to remove\n", - name); - return CMD_WARNING_CONFIG_FAILED; - } - } else { - if (pbrms->nhgrp_name) { - if (strcmp(name, pbrms->nhgrp_name) != 0) { - vty_out(vty, - "Please delete current nexthop group before modifying current one\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (pbrms->nhgrp_name && strcmp(name, pbrms->nhgrp_name) == 0) + return CMD_SUCCESS; - return CMD_SUCCESS; - } - pbrms->nhgrp_name = XSTRDUP(MTYPE_TMP, name); - pbr_map_check(pbrms); - } + /* This is new/replacement config */ + pbrms_clear_set_config(pbrms); + + pbrms->nhgrp_name = XSTRDUP(MTYPE_TMP, name); + pbr_map_check(pbrms, true); + + return CMD_SUCCESS; +} + +DEFPY(no_pbr_map_nexthop_group, no_pbr_map_nexthop_group_cmd, + "no set nexthop-group [NHGNAME$name]", + NO_STR + "Set for the PBR-MAP\n" + "nexthop-group to use\n" + "The name of the nexthop-group\n") +{ + struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); + + pbrms_clear_set_config(pbrms); return CMD_SUCCESS; } DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, - "[no] set nexthop\ + "set nexthop\ <\ <A.B.C.D|X:X::X:X>$addr [INTERFACE$intf]\ |INTERFACE$intf\ >\ [nexthop-vrf NAME$vrf_name]", - NO_STR "Set for the PBR-MAP\n" "Specify one of the nexthops in this map\n" "v4 Address\n" @@ -301,18 +303,7 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); struct vrf *vrf; struct nexthop nhop; - struct nexthop *nh; - - if (pbrms->nhgrp_name) { - vty_out(vty, - "Please unconfigure the nexthop group before adding an individual nexthop\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - if (pbrms->vrf_lookup || pbrms->vrf_unchanged) { - vty_out(vty, SET_VRF_EXISTS_STR); - return CMD_WARNING_CONFIG_FAILED; - } + struct nexthop *nh = NULL; if (vrf_name) vrf = vrf_lookup_by_name(vrf_name); @@ -362,45 +353,18 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, if (pbrms->nhg) nh = nexthop_exists(pbrms->nhg, &nhop); - else { - char buf[PBR_NHC_NAMELEN]; - - if (no) { - vty_out(vty, "No nexthops to delete\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - pbrms->nhg = nexthop_group_new(); - pbrms->internal_nhg_name = - XSTRDUP(MTYPE_TMP, - pbr_nht_nexthop_make_name(pbrms->parent->name, - PBR_NHC_NAMELEN, - pbrms->seqno, - buf)); - nh = NULL; - } - - if (no) { - if (nh) - pbr_nht_delete_individual_nexthop(pbrms); - } else if (!nh) { - if (pbrms->nhg->nexthop) { - vty_out(vty, - "If you would like more than one nexthop please use nexthop-groups\n"); - return CMD_WARNING_CONFIG_FAILED; - } + if (nh) /* Same config re-entered */ + goto done; - /* must be adding new nexthop since !no and !nexthop_exists */ - nh = nexthop_new(); + /* This is new/replacement config */ + pbrms_clear_set_config(pbrms); - memcpy(nh, &nhop, sizeof(nhop)); - _nexthop_add(&pbrms->nhg->nexthop, nh); + pbr_nht_add_individual_nexthop(pbrms, &nhop); - pbr_nht_add_individual_nexthop(pbrms); - pbr_map_check(pbrms); - } + pbr_map_check(pbrms, true); +done: if (nhop.type == NEXTHOP_TYPE_IFINDEX || (nhop.type == NEXTHOP_TYPE_IPV6_IFINDEX && IN6_IS_ADDR_LINKLOCAL(&nhop.gate.ipv6))) { @@ -414,84 +378,80 @@ DEFPY(pbr_map_nexthop, pbr_map_nexthop_cmd, return CMD_SUCCESS; } -DEFPY(pbr_map_vrf, pbr_map_vrf_cmd, - "[no] set vrf <NAME$vrf_name|unchanged>", +DEFPY(no_pbr_map_nexthop, no_pbr_map_nexthop_cmd, + "no set nexthop\ + [<\ + <A.B.C.D|X:X::X:X>$addr [INTERFACE$intf]\ + |INTERFACE$intf\ + >\ + [nexthop-vrf NAME$vrf_name]]", NO_STR "Set for the PBR-MAP\n" - "Specify the VRF for this map\n" - "The VRF Name\n" - "Use the interface's VRF for lookup\n") + "Specify one of the nexthops in this map\n" + "v4 Address\n" + "v6 Address\n" + "Interface to use\n" + "Interface to use\n" + "If the nexthop is in a different vrf tell us\n" + "The nexthop-vrf Name\n") { struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); - if (no) { - pbr_map_delete_vrf(pbrms); + pbrms_clear_set_config(pbrms); - /* Reset all data */ - pbrms->nhs_installed = false; - pbrms->vrf_name[0] = '\0'; - pbrms->vrf_lookup = false; - pbrms->vrf_unchanged = false; - - return CMD_SUCCESS; - } + return CMD_SUCCESS; +} - if (pbrms->nhgrp_name || pbrms->nhg) { - vty_out(vty, - "A `set nexthop/nexthop-group XX` command already exits, please remove that first\n"); - return CMD_WARNING_CONFIG_FAILED; - } +DEFPY(pbr_map_vrf, pbr_map_vrf_cmd, + "set vrf <NAME$vrf_name|unchanged>", + "Set for the PBR-MAP\n" + "Specify the VRF for this map\n" + "The VRF Name\n" + "Use the interface's VRF for lookup\n") +{ + struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); /* - * Determine if a set vrf * command already exists. - * - * If its equivalent, just return success. - * - * Else, return failure, we don't allow atomic swaps yet. + * If an equivalent set vrf * exists, just return success. */ - if (vrf_name && pbrms->vrf_lookup) { - /* New vrf specified and one already exists */ - - /* Is this vrf different from one already configured? */ - if (strncmp(pbrms->vrf_name, vrf_name, sizeof(pbrms->vrf_name)) - != 0) - goto vrf_exists; - + if (vrf_name && pbrms->vrf_lookup + && strncmp(pbrms->vrf_name, vrf_name, sizeof(pbrms->vrf_name)) == 0) return CMD_SUCCESS; - - } else if (!vrf_name && pbrms->vrf_unchanged) { - /* Unchanged specified and unchanged already exists */ + else if (!vrf_name && pbrms->vrf_unchanged) /* Unchanged already set */ return CMD_SUCCESS; - } else if (vrf_name && pbrms->vrf_unchanged) { - /* New vrf specified and unchanged is already set */ - goto vrf_exists; - - } else if (!vrf_name && pbrms->vrf_lookup) { - /* Unchanged specified and vrf to lookup already exists */ - goto vrf_exists; + if (vrf_name && !pbr_vrf_lookup_by_name(vrf_name)) { + vty_out(vty, "Specified: %s is non-existent\n", vrf_name); + return CMD_WARNING_CONFIG_FAILED; } - /* Create new lookup VRF or Unchanged */ - if (vrf_name) { - if (!pbr_vrf_lookup_by_name(vrf_name)) { - vty_out(vty, "Specified: %s is non-existent\n", - vrf_name); - return CMD_WARNING_CONFIG_FAILED; - } + /* This is new/replacement config */ + pbrms_clear_set_config(pbrms); + if (vrf_name) { pbrms->vrf_lookup = true; strlcpy(pbrms->vrf_name, vrf_name, sizeof(pbrms->vrf_name)); } else pbrms->vrf_unchanged = true; - pbr_map_check(pbrms); + pbr_map_check(pbrms, true); return CMD_SUCCESS; +} -vrf_exists: - vty_out(vty, SET_VRF_EXISTS_STR); - return CMD_WARNING_CONFIG_FAILED; +DEFPY(no_pbr_map_vrf, no_pbr_map_vrf_cmd, + "no set vrf [<NAME$vrf_name|unchanged>]", + NO_STR + "Set for the PBR-MAP\n" + "Specify the VRF for this map\n" + "The VRF Name\n" + "Use the interface's VRF for lookup\n") +{ + struct pbr_map_sequence *pbrms = VTY_GET_CONTEXT(pbr_map_sequence); + + pbrms_clear_set_config(pbrms); + + return CMD_SUCCESS; } DEFPY (pbr_policy, @@ -717,7 +677,12 @@ DEFPY (show_pbr_interface, /* PBR debugging CLI ------------------------------------------------------- */ -static struct cmd_node debug_node = {DEBUG_NODE, "", 1}; +static struct cmd_node debug_node = { + .name = "debug", + .node = DEBUG_NODE, + .prompt = "", + .config_write = pbr_debug_config_write, +}; DEFPY(debug_pbr, debug_pbr_cmd, @@ -765,8 +730,13 @@ DEFUN_NOSH(show_debugging_pbr, /* ------------------------------------------------------------------------- */ +static int pbr_interface_config_write(struct vty *vty); static struct cmd_node interface_node = { - INTERFACE_NODE, "%s(config-if)# ", 1 /* vtysh ? yes */ + .name = "interface", + .node = INTERFACE_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-if)# ", + .config_write = pbr_interface_config_write, }; static int pbr_interface_config_write(struct vty *vty) @@ -794,8 +764,15 @@ static int pbr_interface_config_write(struct vty *vty) return 1; } +static int pbr_vty_map_config_write(struct vty *vty); /* PBR map node structure. */ -static struct cmd_node pbr_map_node = {PBRMAP_NODE, "%s(config-pbr-map)# ", 1}; +static struct cmd_node pbr_map_node = { + .name = "pbr-map", + .node = PBRMAP_NODE, + .parent_node = CONFIG_NODE, + .prompt = "%s(config-pbr-map)# ", + .config_write = pbr_vty_map_config_write, +}; static int pbr_vty_map_config_write_sequence(struct vty *vty, struct pbr_map *pbrm, @@ -873,15 +850,13 @@ void pbr_vty_init(void) { cmd_variable_handler_register(pbr_map_name); - install_node(&interface_node, - pbr_interface_config_write); + install_node(&interface_node); if_cmd_init(); - install_node(&pbr_map_node, - pbr_vty_map_config_write); + install_node(&pbr_map_node); /* debug */ - install_node(&debug_node, pbr_debug_config_write); + install_node(&debug_node); install_element(VIEW_NODE, &debug_pbr_cmd); install_element(CONFIG_NODE, &debug_pbr_cmd); install_element(VIEW_NODE, &show_debugging_pbr_cmd); @@ -897,8 +872,11 @@ void pbr_vty_init(void) install_element(PBRMAP_NODE, &pbr_map_match_dst_cmd); install_element(PBRMAP_NODE, &pbr_map_match_mark_cmd); install_element(PBRMAP_NODE, &pbr_map_nexthop_group_cmd); + install_element(PBRMAP_NODE, &no_pbr_map_nexthop_group_cmd); install_element(PBRMAP_NODE, &pbr_map_nexthop_cmd); + install_element(PBRMAP_NODE, &no_pbr_map_nexthop_cmd); install_element(PBRMAP_NODE, &pbr_map_vrf_cmd); + install_element(PBRMAP_NODE, &no_pbr_map_vrf_cmd); install_element(VIEW_NODE, &show_pbr_cmd); install_element(VIEW_NODE, &show_pbr_map_cmd); install_element(VIEW_NODE, &show_pbr_interface_cmd); |
