diff --git a/lib/filter_cli.c b/lib/filter_cli.c index 71fbc9080a..92230f176e 100644 --- a/lib/filter_cli.c +++ b/lib/filter_cli.c @@ -25,6 +25,8 @@ #include "lib/command.h" #include "lib/filter.h" #include "lib/northbound_cli.h" +#include "lib/plist.h" +#include "lib/plist_int.h" #ifndef VTYSH_EXTRACT_PL #include "lib/filter_cli_clippy.c" @@ -50,6 +52,8 @@ #define ACCESS_LIST_REMARK_STR "Access list entry comment\n" #define ACCESS_LIST_REMARK_LINE_STR "Comment up to 100 characters\n" +#define PREFIX_LIST_NAME_STR "Prefix list entry name\n" + /* * Helper function to locate filter data structures for Cisco-style ACLs. */ @@ -1049,6 +1053,426 @@ DEFPY( return nb_cli_apply_changes(vty, NULL); } +/* + * Prefix lists. + */ +static int plist_remove(struct vty *vty, const char *iptype, const char *name, + const char *seq, const char *action, struct prefix *p, + long ge, long le) +{ + struct prefix_list_entry *pentry; + enum prefix_list_type plt; + struct prefix_list *pl; + struct lyd_node *dnode; + char xpath[XPATH_MAXLEN]; + char xpath_entry[XPATH_MAXLEN + 32]; + + /* If the user provided sequence number, then just go for it. */ + if (seq != NULL) { + snprintf( + xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='%s'][name='%s']/entry[sequence='%s']", + iptype, name, seq); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + return nb_cli_apply_changes(vty, NULL); + } + + /* Otherwise, to keep compatibility, we need to figure it out. */ + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='%s'][name='%s']", iptype, + name); + + /* Access-list must exist before entries. */ + if (yang_dnode_exists(running_config->dnode, xpath) == false) + return CMD_WARNING; + + /* Use access-list data structure to fetch sequence. */ + if (strcmp(action, "permit") == 0) + plt = PREFIX_PERMIT; + else + plt = PREFIX_DENY; + + dnode = yang_dnode_get(running_config->dnode, xpath); + pl = nb_running_get_entry(dnode, NULL, true); + pentry = prefix_list_entry_lookup(pl, p, plt, -1, le, ge); + if (pentry == NULL) + return CMD_WARNING; + + snprintf(xpath_entry, sizeof(xpath_entry), + "%s/entry[sequence='%" PRId64 "']", xpath, pentry->seq); + nb_cli_enqueue_change(vty, xpath_entry, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY( + ip_prefix_list, ip_prefix_list_cmd, + "ip prefix-list WORD$name [seq (1-4294967295)$seq] $action ", + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_SEQ_STR + ACCESS_LIST_ACTION_STR + "Any prefix match. Same as \"0.0.0.0/0 le 32\"\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "Minimum prefix length to be matched\n" + "Minimum prefix length\n" + "Maximum prefix length to be matched\n" + "Maximum prefix length\n") +{ + struct prefix_list *pl; + struct lyd_node *dnode; + int rv; + int64_t sseq; + char xpath[XPATH_MAXLEN]; + char xpath_entry[XPATH_MAXLEN + 32]; + char xpath_value[XPATH_MAXLEN + 64]; + + /* + * Create the prefix-list first, so we can generate sequence if + * none given (backward compatibility). + */ + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv4'][name='%s']", name); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + rv = nb_cli_apply_changes(vty, NULL); + if (rv != CMD_SUCCESS) + return rv; + + /* Use prefix-list data structure to generate sequence. */ + dnode = yang_dnode_get(running_config->dnode, xpath); + pl = nb_running_get_entry(dnode, NULL, true); + if (seq_str == NULL) { + sseq = prefix_new_seq_get(pl); + snprintf(xpath_entry, sizeof(xpath_entry), + "%s/entry[sequence='%" PRId64 "']", xpath, sseq); + } else + snprintf(xpath_entry, sizeof(xpath_entry), + "%s/entry[sequence='%s']", xpath, seq_str); + + nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); + + snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action); + + if (prefix_str != NULL) { + snprintf(xpath_value, sizeof(xpath_value), "%s/ipv4-prefix", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + prefix_str); + + if (ge_str) { + snprintf(xpath_value, sizeof(xpath_value), + "%s/ipv4-prefix-length-greater-or-equal", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + ge_str); + } + if (le_str) { + snprintf(xpath_value, sizeof(xpath_value), + "%s/ipv4-prefix-length-lesser-or-equal", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + le_str); + } + } else { + snprintf(xpath_value, sizeof(xpath_value), "%s/any", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY( + no_ip_prefix_list, no_ip_prefix_list_cmd, + "no ip prefix-list WORD$name [seq (1-4294967295)$seq] $action ", + NO_STR + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_SEQ_STR + ACCESS_LIST_ACTION_STR + "Any prefix match. Same as \"0.0.0.0/0 le 32\"\n" + "IP prefix /, e.g., 35.0.0.0/8\n" + "Minimum prefix length to be matched\n" + "Minimum prefix length\n" + "Maximum prefix length to be matched\n" + "Maximum prefix length\n") +{ + return plist_remove(vty, "ipv4", name, seq_str, action, + (struct prefix *)prefix, ge, le); +} + +DEFPY( + no_ip_prefix_list_seq, no_ip_prefix_list_seq_cmd, + "no ip prefix-list WORD$name seq (1-4294967295)$seq", + NO_STR + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_SEQ_STR) +{ + return plist_remove(vty, "ipv4", name, seq_str, NULL, NULL, 0, 0); +} + +DEFPY( + no_ip_prefix_list_all, no_ip_prefix_list_all_cmd, + "no ip prefix-list WORD$name", + NO_STR + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR) +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv4'][name='%s']", name); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY( + ip_prefix_list_remark, ip_prefix_list_remark_cmd, + "ip prefix-list WORD$name remark LINE...", + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_REMARK_STR + ACCESS_LIST_REMARK_LINE_STR) +{ + int rv; + char *remark; + char xpath[XPATH_MAXLEN]; + char xpath_remark[XPATH_MAXLEN + 32]; + + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv4'][name='%s']", name); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + + snprintf(xpath_remark, sizeof(xpath_remark), "%s/remark", xpath); + remark = argv_concat(argv, argc, 4); + nb_cli_enqueue_change(vty, xpath_remark, NB_OP_CREATE, remark); + rv = nb_cli_apply_changes(vty, NULL); + XFREE(MTYPE_TMP, remark); + + return rv; +} + +DEFPY( + no_ip_prefix_list_remark, no_ip_prefix_list_remark_cmd, + "no ip prefix-list WORD$name remark", + NO_STR + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_REMARK_STR) +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv4'][name='%s']/remark", + name); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +ALIAS( + no_ip_prefix_list_remark, no_ip_prefix_list_remark_line_cmd, + "no ip prefix-list WORD remark LINE...", + NO_STR + IP_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_REMARK_STR + ACCESS_LIST_REMARK_LINE_STR) + +DEFPY( + ipv6_prefix_list, ipv6_prefix_list_cmd, + "ipv6 prefix-list WORD$name [seq (1-4294967295)] $action ", + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_SEQ_STR + ACCESS_LIST_ACTION_STR + "Any prefix match. Same as \"::0/0 le 128\"\n" + "IPv6 prefix /, e.g., 3ffe::/16\n" + "Maximum prefix length to be matched\n" + "Maximum prefix length\n" + "Minimum prefix length to be matched\n" + "Minimum prefix length\n") +{ + struct prefix_list *pl; + struct lyd_node *dnode; + int rv; + int64_t sseq; + char xpath[XPATH_MAXLEN]; + char xpath_entry[XPATH_MAXLEN + 32]; + char xpath_value[XPATH_MAXLEN + 64]; + + /* + * Create the prefix-list first, so we can generate sequence if + * none given (backward compatibility). + */ + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv6'][name='%s']", name); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + rv = nb_cli_apply_changes(vty, NULL); + if (rv != CMD_SUCCESS) + return rv; + + /* Use prefix-list data structure to generate sequence. */ + dnode = yang_dnode_get(running_config->dnode, xpath); + pl = nb_running_get_entry(dnode, NULL, true); + if (seq_str == NULL) { + sseq = prefix_new_seq_get(pl); + snprintf(xpath_entry, sizeof(xpath_entry), + "%s/entry[sequence='%" PRId64 "']", xpath, sseq); + } else + snprintf(xpath_entry, sizeof(xpath_entry), + "%s/entry[sequence='%s']", xpath, seq_str); + + nb_cli_enqueue_change(vty, xpath_entry, NB_OP_CREATE, NULL); + + snprintf(xpath_value, sizeof(xpath_value), "%s/action", xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, action); + + if (prefix_str != NULL) { + snprintf(xpath_value, sizeof(xpath_value), "%s/ipv6-prefix", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + prefix_str); + + if (ge_str) { + snprintf(xpath_value, sizeof(xpath_value), + "%s/ipv6-prefix-length-greater-or-equal", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + ge_str); + } + if (le_str) { + snprintf(xpath_value, sizeof(xpath_value), + "%s/ipv6-prefix-length-lesser-or-equal", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_MODIFY, + le_str); + } + } else { + snprintf(xpath_value, sizeof(xpath_value), "%s/any", + xpath_entry); + nb_cli_enqueue_change(vty, xpath_value, NB_OP_CREATE, NULL); + } + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY( + no_ipv6_prefix_list, no_ipv6_prefix_list_cmd, + "no ipv6 prefix-list WORD$name [seq (1-4294967295)$seq] $action ", + NO_STR + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_SEQ_STR + ACCESS_LIST_ACTION_STR + "Any prefix match. Same as \"::0/0 le 128\"\n" + "IPv6 prefix /, e.g., 3ffe::/16\n" + "Maximum prefix length to be matched\n" + "Maximum prefix length\n" + "Minimum prefix length to be matched\n" + "Minimum prefix length\n") +{ + return plist_remove(vty, "ipv6", name, seq_str, action, + (struct prefix *)prefix, ge, le); +} + +DEFPY( + no_ipv6_prefix_list_seq, no_ipv6_prefix_list_seq_cmd, + "no ipv6 prefix-list WORD$name seq (1-4294967295)$seq", + NO_STR + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_SEQ_STR) +{ + return plist_remove(vty, "ipv6", name, seq_str, NULL, NULL, 0, 0); +} + +DEFPY( + no_ipv6_prefix_list_all, no_ipv6_prefix_list_all_cmd, + "no ipv6 prefix-list WORD$name", + NO_STR + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR) +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv6'][name='%s']", name); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +DEFPY( + ipv6_prefix_list_remark, ipv6_prefix_list_remark_cmd, + "ipv6 prefix-list WORD$name remark LINE...", + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_REMARK_STR + ACCESS_LIST_REMARK_LINE_STR) +{ + int rv; + char *remark; + char xpath[XPATH_MAXLEN]; + char xpath_remark[XPATH_MAXLEN + 32]; + + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv6'][name='%s']", name); + nb_cli_enqueue_change(vty, xpath, NB_OP_CREATE, NULL); + + snprintf(xpath_remark, sizeof(xpath_remark), "%s/remark", xpath); + remark = argv_concat(argv, argc, 4); + nb_cli_enqueue_change(vty, xpath_remark, NB_OP_CREATE, remark); + rv = nb_cli_apply_changes(vty, NULL); + XFREE(MTYPE_TMP, remark); + + return rv; +} + +DEFPY( + no_ipv6_prefix_list_remark, no_ipv6_prefix_list_remark_cmd, + "no ipv6 prefix-list WORD$name remark", + NO_STR + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_REMARK_STR) +{ + char xpath[XPATH_MAXLEN]; + + snprintf(xpath, sizeof(xpath), + "/frr-filter:lib/prefix-list[type='ipv6'][name='%s']/remark", + name); + nb_cli_enqueue_change(vty, xpath, NB_OP_DESTROY, NULL); + + return nb_cli_apply_changes(vty, NULL); +} + +ALIAS( + no_ipv6_prefix_list_remark, no_ipv6_prefix_list_remark_line_cmd, + "no ipv6 prefix-list WORD remark LINE...", + NO_STR + IPV6_STR + PREFIX_LIST_STR + PREFIX_LIST_NAME_STR + ACCESS_LIST_REMARK_STR + ACCESS_LIST_REMARK_LINE_STR) + void filter_cli_init(void) { /* access-list cisco-style (legacy). */ @@ -1078,4 +1502,21 @@ void filter_cli_init(void) install_element(CONFIG_NODE, &no_mac_access_list_all_cmd); install_element(CONFIG_NODE, &mac_access_list_remark_cmd); install_element(CONFIG_NODE, &no_mac_access_list_remark_cmd); + + /* prefix lists. */ + install_element(CONFIG_NODE, &ip_prefix_list_cmd); + install_element(CONFIG_NODE, &no_ip_prefix_list_cmd); + install_element(CONFIG_NODE, &no_ip_prefix_list_seq_cmd); + install_element(CONFIG_NODE, &no_ip_prefix_list_all_cmd); + install_element(CONFIG_NODE, &ip_prefix_list_remark_cmd); + install_element(CONFIG_NODE, &no_ip_prefix_list_remark_cmd); + install_element(CONFIG_NODE, &no_ip_prefix_list_remark_line_cmd); + + install_element(CONFIG_NODE, &ipv6_prefix_list_cmd); + install_element(CONFIG_NODE, &no_ipv6_prefix_list_cmd); + install_element(CONFIG_NODE, &no_ipv6_prefix_list_seq_cmd); + install_element(CONFIG_NODE, &no_ipv6_prefix_list_all_cmd); + install_element(CONFIG_NODE, &ipv6_prefix_list_remark_cmd); + install_element(CONFIG_NODE, &no_ipv6_prefix_list_remark_cmd); + install_element(CONFIG_NODE, &no_ipv6_prefix_list_remark_line_cmd); } diff --git a/lib/plist.c b/lib/plist.c index 0addb6fde0..98e02a5f1a 100644 --- a/lib/plist.c +++ b/lib/plist.c @@ -832,280 +832,6 @@ prefix_entry_dup_check(struct prefix_list *plist, struct prefix_list_entry *new) return NULL; } -static int vty_invalid_prefix_range(struct vty *vty, const char *prefix) -{ - vty_out(vty, - "%% Invalid prefix range for %s, make sure: len < ge-value <= le-value\n", - prefix); - return CMD_WARNING_CONFIG_FAILED; -} - -static int vty_prefix_list_install(struct vty *vty, afi_t afi, const char *name, - const char *seq, const char *typestr, - const char *prefix, const char *ge, - const char *le) -{ - int ret; - enum prefix_list_type type; - struct prefix_list *plist; - struct prefix_list_entry *pentry; - struct prefix_list_entry *dup; - struct prefix p, p_tmp; - bool any = false; - int64_t seqnum = -1; - int lenum = 0; - int genum = 0; - - if (name == NULL || prefix == NULL || typestr == NULL) { - vty_out(vty, "%% Missing prefix or type\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Sequential number. */ - if (seq) - seqnum = (int64_t)atol(seq); - - /* ge and le number */ - if (ge) - genum = atoi(ge); - if (le) - lenum = atoi(le); - - /* Check filter type. */ - if (strncmp("permit", typestr, 1) == 0) - type = PREFIX_PERMIT; - else if (strncmp("deny", typestr, 1) == 0) - type = PREFIX_DENY; - else { - vty_out(vty, "%% prefix type must be permit or deny\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* "any" is special token for matching any IPv4 addresses. */ - switch (afi) { - case AFI_IP: - if (strncmp("any", prefix, strlen(prefix)) == 0) { - ret = str2prefix_ipv4("0.0.0.0/0", - (struct prefix_ipv4 *)&p); - genum = 0; - lenum = IPV4_MAX_BITLEN; - any = true; - } else - ret = str2prefix_ipv4(prefix, (struct prefix_ipv4 *)&p); - - if (ret <= 0) { - vty_out(vty, "%% Malformed IPv4 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make a copy to verify prefix matches mask length */ - prefix_copy(&p_tmp, &p); - apply_mask_ipv4((struct prefix_ipv4 *)&p_tmp); - - break; - case AFI_IP6: - if (strncmp("any", prefix, strlen(prefix)) == 0) { - ret = str2prefix_ipv6("::/0", (struct prefix_ipv6 *)&p); - genum = 0; - lenum = IPV6_MAX_BITLEN; - any = true; - } else - ret = str2prefix_ipv6(prefix, (struct prefix_ipv6 *)&p); - - if (ret <= 0) { - vty_out(vty, "%% Malformed IPv6 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* make a copy to verify prefix matches mask length */ - prefix_copy(&p_tmp, &p); - apply_mask_ipv6((struct prefix_ipv6 *)&p_tmp); - - break; - case AFI_L2VPN: - default: - vty_out(vty, "%% Unrecognized AFI (%d)\n", afi); - return CMD_WARNING_CONFIG_FAILED; - } - - /* If prefix has bits not under the mask, adjust it to fit */ - if (!prefix_same(&p_tmp, &p)) { - char buf[PREFIX2STR_BUFFER]; - char buf_tmp[PREFIX2STR_BUFFER]; - prefix2str(&p, buf, sizeof(buf)); - prefix2str(&p_tmp, buf_tmp, sizeof(buf_tmp)); - vty_out(vty, - "%% Prefix-list %s prefix changed from %s to %s to match length\n", - name, buf, buf_tmp); - zlog_info( - "Prefix-list %s prefix changed from %s to %s to match length", - name, buf, buf_tmp); - p = p_tmp; - } - - /* ge and le check. */ - if (genum && (genum <= p.prefixlen)) - return vty_invalid_prefix_range(vty, prefix); - - if (lenum && (lenum < p.prefixlen)) - return vty_invalid_prefix_range(vty, prefix); - - if (lenum && (genum > lenum)) - return vty_invalid_prefix_range(vty, prefix); - - if (genum && (lenum == (afi == AFI_IP ? 32 : 128))) - lenum = 0; - - /* Get prefix_list with name. */ - plist = prefix_list_get(afi, 0, name); - - /* Make prefix entry. */ - pentry = prefix_list_entry_make(&p, type, seqnum, lenum, genum, any); - - /* Check same policy. */ - dup = prefix_entry_dup_check(plist, pentry); - - if (dup) { - prefix_list_entry_free(pentry); - return CMD_SUCCESS; - } - - /* Install new filter to the access_list. */ - prefix_list_entry_add(plist, pentry); - - return CMD_SUCCESS; -} - -static int vty_prefix_list_uninstall(struct vty *vty, afi_t afi, - const char *name, const char *seq, - const char *typestr, const char *prefix, - const char *ge, const char *le) -{ - int ret; - enum prefix_list_type type; - struct prefix_list *plist; - struct prefix_list_entry *pentry; - struct prefix p; - int64_t seqnum = -1; - int lenum = 0; - int genum = 0; - - /* Check prefix list name. */ - plist = prefix_list_lookup(afi, name); - if (!plist) { - vty_out(vty, "%% Can't find specified prefix-list\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Only prefix-list name specified, delete the entire prefix-list. */ - if (seq == NULL && typestr == NULL && prefix == NULL && ge == NULL - && le == NULL) { - prefix_list_delete(plist); - return CMD_SUCCESS; - } - - /* Check sequence number. */ - if (seq) - seqnum = (int64_t)atol(seq); - - /* Sequence number specified, but nothing else. */ - if (seq && typestr == NULL && prefix == NULL && ge == NULL - && le == NULL) { - pentry = prefix_seq_check(plist, seqnum); - - if (pentry == NULL) { - vty_out(vty, - "%% Can't find prefix-list %s with sequence number %" PRIu64 "\n", - name, seqnum); - return CMD_WARNING_CONFIG_FAILED; - } - - prefix_list_entry_delete(plist, pentry, 1); - return CMD_SUCCESS; - } - - /* ge and le number */ - if (ge) - genum = atoi(ge); - if (le) - lenum = atoi(le); - - /* We must have, at a minimum, both the type and prefix here */ - if ((typestr == NULL) || (prefix == NULL)) - return CMD_WARNING_CONFIG_FAILED; - - /* Check of filter type. */ - if (strncmp("permit", typestr, 1) == 0) - type = PREFIX_PERMIT; - else if (strncmp("deny", typestr, 1) == 0) - type = PREFIX_DENY; - else { - vty_out(vty, "%% prefix type must be permit or deny\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* "any" is special token for matching any IPv4 addresses. */ - if (afi == AFI_IP) { - if (strncmp("any", prefix, strlen(prefix)) == 0) { - ret = str2prefix_ipv4("0.0.0.0/0", - (struct prefix_ipv4 *)&p); - genum = 0; - lenum = IPV4_MAX_BITLEN; - } else - ret = str2prefix_ipv4(prefix, (struct prefix_ipv4 *)&p); - - if (ret <= 0) { - vty_out(vty, "%% Malformed IPv4 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } else if (afi == AFI_IP6) { - if (strncmp("any", prefix, strlen(prefix)) == 0) { - ret = str2prefix_ipv6("::/0", (struct prefix_ipv6 *)&p); - genum = 0; - lenum = IPV6_MAX_BITLEN; - } else - ret = str2prefix_ipv6(prefix, (struct prefix_ipv6 *)&p); - - if (ret <= 0) { - vty_out(vty, "%% Malformed IPv6 prefix\n"); - return CMD_WARNING_CONFIG_FAILED; - } - } - - /* Lookup prefix entry. */ - pentry = - prefix_list_entry_lookup(plist, &p, type, seqnum, lenum, genum); - - if (pentry == NULL) { - vty_out(vty, "%% Can't find specified prefix-list\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - /* Install new filter to the access_list. */ - prefix_list_entry_delete(plist, pentry, 1); - - return CMD_SUCCESS; -} - -static int vty_prefix_list_desc_unset(struct vty *vty, afi_t afi, - const char *name) -{ - struct prefix_list *plist; - - plist = prefix_list_lookup(afi, name); - if (!plist) { - vty_out(vty, "%% Can't find specified prefix-list\n"); - return CMD_WARNING_CONFIG_FAILED; - } - - XFREE(MTYPE_TMP, plist->desc); - - if (plist->head == NULL && plist->tail == NULL && plist->desc == NULL) - prefix_list_delete(plist); - - return CMD_SUCCESS; -} - enum display_type { normal_display, summary_display, @@ -1349,72 +1075,6 @@ static int vty_clear_prefix_list(struct vty *vty, afi_t afi, const char *name, #include "lib/plist_clippy.c" #endif -DEFPY (ip_prefix_list, - ip_prefix_list_cmd, - "ip prefix-list WORD [seq (1-4294967295)] $action ", - IP_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "sequence number of an entry\n" - "Sequence number\n" - "Specify packets to reject\n" - "Specify packets to forward\n" - "Any prefix match. Same as \"0.0.0.0/0 le 32\"\n" - "IP prefix /, e.g., 35.0.0.0/8\n" - "Minimum prefix length to be matched\n" - "Minimum prefix length\n" - "Maximum prefix length to be matched\n" - "Maximum prefix length\n") -{ - return vty_prefix_list_install(vty, AFI_IP, prefix_list, seq_str, - action, dest, ge_str, le_str); -} - -DEFPY (no_ip_prefix_list, - no_ip_prefix_list_cmd, - "no ip prefix-list WORD [seq (1-4294967295)] $action ", - NO_STR - IP_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "sequence number of an entry\n" - "Sequence number\n" - "Specify packets to reject\n" - "Specify packets to forward\n" - "Any prefix match. Same as \"0.0.0.0/0 le 32\"\n" - "IP prefix /, e.g., 35.0.0.0/8\n" - "Minimum prefix length to be matched\n" - "Minimum prefix length\n" - "Maximum prefix length to be matched\n" - "Maximum prefix length\n") -{ - return vty_prefix_list_uninstall(vty, AFI_IP, prefix_list, seq_str, - action, dest, ge_str, le_str); -} - -DEFPY(no_ip_prefix_list_seq, no_ip_prefix_list_seq_cmd, - "no ip prefix-list WORD seq (1-4294967295)", - NO_STR IP_STR PREFIX_LIST_STR - "Name of a prefix list\n" - "sequence number of an entry\n" - "Sequence number\n") -{ - return vty_prefix_list_uninstall(vty, AFI_IP, prefix_list, seq_str, - NULL, NULL, NULL, NULL); -} - -DEFPY (no_ip_prefix_list_all, - no_ip_prefix_list_all_cmd, - "no ip prefix-list WORD", - NO_STR - IP_STR - PREFIX_LIST_STR - "Name of a prefix list\n") -{ - return vty_prefix_list_uninstall(vty, AFI_IP, prefix_list, NULL, NULL, - NULL, NULL, NULL); -} - DEFPY (ip_prefix_list_sequence_number, ip_prefix_list_sequence_number_cmd, "[no] ip prefix-list sequence-number", @@ -1427,56 +1087,6 @@ DEFPY (ip_prefix_list_sequence_number, return CMD_SUCCESS; } -DEFUN (ip_prefix_list_description, - ip_prefix_list_description_cmd, - "ip prefix-list WORD description LINE...", - IP_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "Prefix-list specific description\n" - "Up to 80 characters describing this prefix-list\n") -{ - int idx_word = 2; - int idx_line = 4; - struct prefix_list *plist; - - plist = prefix_list_get(AFI_IP, 0, argv[idx_word]->arg); - - if (plist->desc) { - XFREE(MTYPE_TMP, plist->desc); - plist->desc = NULL; - } - plist->desc = argv_concat(argv, argc, idx_line); - - return CMD_SUCCESS; -} - -DEFUN (no_ip_prefix_list_description, - no_ip_prefix_list_description_cmd, - "no ip prefix-list WORD description", - NO_STR - IP_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "Prefix-list specific description\n") -{ - int idx_word = 3; - return vty_prefix_list_desc_unset(vty, AFI_IP, argv[idx_word]->arg); -} - -/* ALIAS_FIXME */ -DEFUN (no_ip_prefix_list_description_comment, - no_ip_prefix_list_description_comment_cmd, - "no ip prefix-list WORD description LINE...", - NO_STR - IP_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "Prefix-list specific description\n" - "Up to 80 characters describing this prefix-list\n") -{ - return no_ip_prefix_list_description(self, vty, argc, argv); -} DEFPY (show_ip_prefix_list, show_ip_prefix_list_cmd, @@ -1554,61 +1164,6 @@ DEFPY (clear_ip_prefix_list, return vty_clear_prefix_list(vty, AFI_IP, prefix_list, prefix_str); } -DEFPY (ipv6_prefix_list, - ipv6_prefix_list_cmd, - "ipv6 prefix-list WORD [seq (1-4294967295)] $action ", - IPV6_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "sequence number of an entry\n" - "Sequence number\n" - "Specify packets to reject\n" - "Specify packets to forward\n" - "Any prefix match. Same as \"::0/0 le 128\"\n" - "IPv6 prefix /, e.g., 3ffe::/16\n" - "Maximum prefix length to be matched\n" - "Maximum prefix length\n" - "Minimum prefix length to be matched\n" - "Minimum prefix length\n") -{ - return vty_prefix_list_install(vty, AFI_IP6, prefix_list, seq_str, - action, dest, ge_str, le_str); -} - -DEFPY (no_ipv6_prefix_list, - no_ipv6_prefix_list_cmd, - "no ipv6 prefix-list WORD [seq (1-4294967295)] $action ", - NO_STR - IPV6_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "sequence number of an entry\n" - "Sequence number\n" - "Specify packets to reject\n" - "Specify packets to forward\n" - "Any prefix match. Same as \"::0/0 le 128\"\n" - "IPv6 prefix /, e.g., 3ffe::/16\n" - "Maximum prefix length to be matched\n" - "Maximum prefix length\n" - "Minimum prefix length to be matched\n" - "Minimum prefix length\n") -{ - return vty_prefix_list_uninstall(vty, AFI_IP6, prefix_list, seq_str, - action, dest, ge_str, le_str); -} - -DEFPY (no_ipv6_prefix_list_all, - no_ipv6_prefix_list_all_cmd, - "no ipv6 prefix-list WORD", - NO_STR - IPV6_STR - PREFIX_LIST_STR - "Name of a prefix list\n") -{ - return vty_prefix_list_uninstall(vty, AFI_IP6, prefix_list, NULL, NULL, - NULL, NULL, NULL); -} - DEFPY (ipv6_prefix_list_sequence_number, ipv6_prefix_list_sequence_number_cmd, "[no] ipv6 prefix-list sequence-number", @@ -1621,58 +1176,6 @@ DEFPY (ipv6_prefix_list_sequence_number, return CMD_SUCCESS; } -DEFUN (ipv6_prefix_list_description, - ipv6_prefix_list_description_cmd, - "ipv6 prefix-list WORD description LINE...", - IPV6_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "Prefix-list specific description\n" - "Up to 80 characters describing this prefix-list\n") -{ - int idx_word = 2; - int iddx_line = 4; - struct prefix_list *plist; - - plist = prefix_list_get(AFI_IP6, 0, argv[idx_word]->arg); - - if (plist->desc) { - XFREE(MTYPE_TMP, plist->desc); - plist->desc = NULL; - } - plist->desc = argv_concat(argv, argc, iddx_line); - - return CMD_SUCCESS; -} - -DEFUN (no_ipv6_prefix_list_description, - no_ipv6_prefix_list_description_cmd, - "no ipv6 prefix-list WORD description", - NO_STR - IPV6_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "Prefix-list specific description\n") -{ - int idx_word = 3; - return vty_prefix_list_desc_unset(vty, AFI_IP6, argv[idx_word]->arg); -} - -/* ALIAS_FIXME */ -DEFUN (no_ipv6_prefix_list_description_comment, - no_ipv6_prefix_list_description_comment_cmd, - "no ipv6 prefix-list WORD description LINE...", - NO_STR - IPV6_STR - PREFIX_LIST_STR - "Name of a prefix list\n" - "Prefix-list specific description\n" - "Up to 80 characters describing this prefix-list\n") -{ - return no_ipv6_prefix_list_description(self, vty, argc, argv); -} - - DEFPY (show_ipv6_prefix_list, show_ipv6_prefix_list_cmd, "show ipv6 prefix-list [WORD [seq$dseq (1-4294967295)$arg]]", @@ -2090,16 +1593,6 @@ static void prefix_list_init_ipv4(void) { install_node(&prefix_node); - install_element(CONFIG_NODE, &ip_prefix_list_cmd); - install_element(CONFIG_NODE, &no_ip_prefix_list_cmd); - install_element(CONFIG_NODE, &no_ip_prefix_list_seq_cmd); - install_element(CONFIG_NODE, &no_ip_prefix_list_all_cmd); - - install_element(CONFIG_NODE, &ip_prefix_list_description_cmd); - install_element(CONFIG_NODE, &no_ip_prefix_list_description_cmd); - install_element(CONFIG_NODE, - &no_ip_prefix_list_description_comment_cmd); - install_element(CONFIG_NODE, &ip_prefix_list_sequence_number_cmd); install_element(VIEW_NODE, &show_ip_prefix_list_cmd); @@ -2128,15 +1621,6 @@ static void prefix_list_init_ipv6(void) { install_node(&prefix_ipv6_node); - install_element(CONFIG_NODE, &ipv6_prefix_list_cmd); - install_element(CONFIG_NODE, &no_ipv6_prefix_list_cmd); - install_element(CONFIG_NODE, &no_ipv6_prefix_list_all_cmd); - - install_element(CONFIG_NODE, &ipv6_prefix_list_description_cmd); - install_element(CONFIG_NODE, &no_ipv6_prefix_list_description_cmd); - install_element(CONFIG_NODE, - &no_ipv6_prefix_list_description_comment_cmd); - install_element(CONFIG_NODE, &ipv6_prefix_list_sequence_number_cmd); install_element(VIEW_NODE, &show_ipv6_prefix_list_cmd);