diff options
Diffstat (limited to 'lib/command_match.c')
| -rw-r--r-- | lib/command_match.c | 51 |
1 files changed, 20 insertions, 31 deletions
diff --git a/lib/command_match.c b/lib/command_match.c index 24e850ad2e..bc54f1bb09 100644 --- a/lib/command_match.c +++ b/lib/command_match.c @@ -16,10 +16,9 @@ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * - * You should have received a copy of the GNU General Public License - * along with GNU Zebra; see the file COPYING. If not, write to the Free - * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA - * 02111-1307, USA. + * You should have received a copy of the GNU General Public License along + * with this program; see the file COPYING; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ #include <zebra.h> @@ -71,9 +70,7 @@ static enum match_type match_ipv4(const char *); static enum match_type match_ipv4_prefix(const char *); -static enum match_type match_ipv6(const char *); - -static enum match_type match_ipv6_prefix(const char *); +static enum match_type match_ipv6_prefix(const char *, bool); static enum match_type match_range(struct cmd_token *, const char *); @@ -105,7 +102,7 @@ enum matcher_rv command_match(struct graph *cmdgraph, vector vline, struct listnode *tail = listtail(*argv); // delete dummy start node - del_cmd_token((struct cmd_token *)head->data); + cmd_token_del((struct cmd_token *)head->data); list_delete_node(*argv, head); // get cmd_element out of list tail @@ -274,7 +271,7 @@ static struct list *command_match_r(struct graph_node *start, vector vline, struct cmd_element *el = leaf->data; listnode_add(currbest, el); currbest->del = - (void (*)(void *)) & del_cmd_token; + (void (*)(void *)) & cmd_token_del; // do not break immediately; continue walking // through the follow set // to ensure that there is exactly one END_TKN @@ -312,7 +309,7 @@ static struct list *command_match_r(struct graph_node *start, vector vline, } else { // copy token, set arg and prepend to currbest struct cmd_token *token = start->data; - struct cmd_token *copy = copy_cmd_token(token); + struct cmd_token *copy = cmd_token_dup(token); copy->arg = XSTRDUP(MTYPE_CMD_ARG, input_token); listnode_add_before(currbest, currbest->head, copy); matcher_rv = MATCHER_OK; @@ -403,6 +400,7 @@ enum matcher_rv command_complete(struct graph *graph, vector vline, trace_matcher("trivial_match\n"); if (exact_match_exists && !last_token) break; + /* fallthru */ case exact_match: trace_matcher("exact_match\n"); if (last_token) { @@ -653,9 +651,9 @@ static enum match_type match_token(struct cmd_token *token, char *input_token) case IPV4_PREFIX_TKN: return match_ipv4_prefix(input_token); case IPV6_TKN: - return match_ipv6(input_token); + return match_ipv6_prefix(input_token, false); case IPV6_PREFIX_TKN: - return match_ipv6_prefix(input_token); + return match_ipv6_prefix(input_token, true); case RANGE_TKN: return match_range(token, input_token); case VARIABLE_TKN: @@ -798,34 +796,19 @@ static enum match_type match_ipv4_prefix(const char *str) #define STATE_SLASH 6 #define STATE_MASK 7 -static enum match_type match_ipv6(const char *str) -{ - struct sockaddr_in6 sin6_dummy; - int ret; - - if (strspn(str, IPV6_ADDR_STR) != strlen(str)) - return no_match; - - ret = inet_pton(AF_INET6, str, &sin6_dummy.sin6_addr); - - if (ret == 1) - return exact_match; - - return no_match; -} - -static enum match_type match_ipv6_prefix(const char *str) +static enum match_type match_ipv6_prefix(const char *str, bool prefix) { int state = STATE_START; int colons = 0, nums = 0, double_colon = 0; int mask; - const char *sp = NULL; + const char *sp = NULL, *start = str; char *endptr = NULL; if (str == NULL) return partly_match; - if (strspn(str, IPV6_PREFIX_STR) != strlen(str)) + if (strspn(str, prefix ? IPV6_PREFIX_STR : IPV6_ADDR_STR) + != strlen(str)) return no_match; while (*str != '\0' && state != STATE_MASK) { @@ -918,6 +901,12 @@ static enum match_type match_ipv6_prefix(const char *str) str++; } + if (!prefix) { + struct sockaddr_in6 sin6_dummy; + int ret = inet_pton(AF_INET6, start, &sin6_dummy.sin6_addr); + return ret == 1 ? exact_match : partly_match; + } + if (state < STATE_MASK) return partly_match; |
