mirror of
https://git.proxmox.com/git/mirror_frr
synced 2025-08-06 10:54:47 +00:00
lib: cli: fix IPv6 address partial matching
A partially-entered IPv6 address would never return a "partly_match", meaning some possible completions weren't listed by the matcher. This specifically breaks autocompleting BGP IPv6 neighbor addresses. Before: aegaeon# show ip bg ne 2001:<?> WORD Neighbor on BGP configured interface After: aegaeon# show ip bg ne 2001:<?> WORD Neighbor on BGP configured interface X:X::X:X Neighbor to display information about 2001:db8::2 Signed-off-by: David Lamparter <equinox@opensourcerouting.org>
This commit is contained in:
parent
4e3e06d638
commit
9a7fc1bd7a
@ -78,10 +78,7 @@ 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 *);
|
||||
match_ipv6_prefix (const char *, bool);
|
||||
|
||||
static enum match_type
|
||||
match_range (struct cmd_token *, const char *);
|
||||
@ -677,9 +674,9 @@ 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:
|
||||
@ -835,35 +832,18 @@ match_ipv4_prefix (const char *str)
|
||||
#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)
|
||||
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)
|
||||
@ -966,6 +946,13 @@ 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;
|
||||
|
||||
|
@ -61,7 +61,7 @@ cmd2 with 3 args.
|
||||
[01]: ipv6
|
||||
[02]: de4d:b33f::cafe
|
||||
test# arg ipv6 de4d:b3
|
||||
% There is no matched command.
|
||||
X:X::X:X 02
|
||||
test# arg ipv6 de4d:b33f::caf
|
||||
X:X::X:X 02
|
||||
test# arg ipv6 de4d:b33f::cafe
|
||||
@ -264,7 +264,8 @@ cmd10 with 3 args.
|
||||
test#
|
||||
test# alt a
|
||||
test# alt a a
|
||||
WORD 02
|
||||
WORD 02
|
||||
X:X::X:X 02
|
||||
test# alt a ab
|
||||
cmd11 with 3 args.
|
||||
[00]: alt
|
||||
@ -281,7 +282,8 @@ cmd12 with 3 args.
|
||||
[02]: 1.2.3.4
|
||||
test# alt a 1
|
||||
test# alt a 1:2
|
||||
WORD 02
|
||||
WORD 02
|
||||
X:X::X:X 02
|
||||
test# alt a 1:2
|
||||
test# alt a 1:2::
|
||||
WORD 02
|
||||
|
Loading…
Reference in New Issue
Block a user