ip-address: Fix filtering by negated address flags
When disabling a flag, one needs to AND with the inverse not the flag
itself. Otherwise specifying for instance 'home -nodad' will effectively
clear the flags variable.
While being at it, simplify the code a bit by merging common parts of
negated and non-negated case branches. Also allow for the "special
cases" to be inverted, too.
Fixes: f73ac674d0 ("ip: change flag names to an array")
Signed-off-by: Phil Sutter <phil@nwl.cc>
Signed-off-by: Stephen Hemminger <stephen@networkplumber.org>
This commit is contained in:
parent
87e3ec0e2f
commit
133db49b49
|
|
@ -1211,38 +1211,35 @@ static void print_ifa_flags(FILE *fp, const struct ifaddrmsg *ifa,
|
||||||
|
|
||||||
static int get_filter(const char *arg)
|
static int get_filter(const char *arg)
|
||||||
{
|
{
|
||||||
|
bool inv = false;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
|
if (arg[0] == '-') {
|
||||||
|
inv = true;
|
||||||
|
arg++;
|
||||||
|
}
|
||||||
|
|
||||||
/* Special cases */
|
/* Special cases */
|
||||||
if (strcmp(arg, "dynamic") == 0) {
|
if (strcmp(arg, "dynamic") == 0) {
|
||||||
filter.flags &= ~IFA_F_PERMANENT;
|
inv = !inv;
|
||||||
filter.flagmask |= IFA_F_PERMANENT;
|
arg = "permanent";
|
||||||
} else if (strcmp(arg, "primary") == 0) {
|
} else if (strcmp(arg, "primary") == 0) {
|
||||||
filter.flags &= ~IFA_F_SECONDARY;
|
inv = !inv;
|
||||||
filter.flagmask |= IFA_F_SECONDARY;
|
arg = "secondary";
|
||||||
} else if (*arg == '-') {
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
|
|
||||||
if (strcmp(arg + 1, ifa_flag_names[i].name))
|
|
||||||
continue;
|
|
||||||
|
|
||||||
filter.flags &= ifa_flag_names[i].value;
|
|
||||||
filter.flagmask |= ifa_flag_names[i].value;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
|
||||||
} else {
|
|
||||||
for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
|
|
||||||
if (strcmp(arg, ifa_flag_names[i].name))
|
|
||||||
continue;
|
|
||||||
filter.flags |= ifa_flag_names[i].value;
|
|
||||||
filter.flagmask |= ifa_flag_names[i].value;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
|
||||||
|
if (strcmp(arg, ifa_flag_names[i].name))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (inv)
|
||||||
|
filter.flags &= ~ifa_flag_names[i].value;
|
||||||
|
else
|
||||||
|
filter.flags |= ifa_flag_names[i].value;
|
||||||
|
filter.flagmask |= ifa_flag_names[i].value;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
|
static int ifa_label_match_rta(int ifindex, const struct rtattr *rta)
|
||||||
|
|
|
||||||
|
|
@ -76,10 +76,15 @@ ip-address \- protocol address management
|
||||||
.IR FLAG-LIST " := [ " FLAG-LIST " ] " FLAG
|
.IR FLAG-LIST " := [ " FLAG-LIST " ] " FLAG
|
||||||
|
|
||||||
.ti -8
|
.ti -8
|
||||||
.IR FLAG " := "
|
.IR FLAG " := ["
|
||||||
.RB "[ " permanent " | " dynamic " | " secondary " | " primary " |"
|
.RB [ - ] permanent " |"
|
||||||
.RB [ - ] tentative " | [" - ] deprecated " | [" - ] dadfailed " |"
|
.RB [ - ] dynamic " |"
|
||||||
.BR temporary " |"
|
.RB [ - ] secondary " |"
|
||||||
|
.RB [ - ] primary " |"
|
||||||
|
.RB [ - ] tentative " |"
|
||||||
|
.RB [ - ] deprecated " |"
|
||||||
|
.RB [ - ] dadfailed " |"
|
||||||
|
.RB [ - ] temporary " |"
|
||||||
.IR CONFFLAG-LIST " ]"
|
.IR CONFFLAG-LIST " ]"
|
||||||
|
|
||||||
.ti -8
|
.ti -8
|
||||||
|
|
@ -334,7 +339,9 @@ only list running interfaces.
|
||||||
.BR dynamic " and " permanent
|
.BR dynamic " and " permanent
|
||||||
(IPv6 only) only list addresses installed due to stateless
|
(IPv6 only) only list addresses installed due to stateless
|
||||||
address configuration or only list permanent (not dynamic)
|
address configuration or only list permanent (not dynamic)
|
||||||
addresses.
|
addresses. These two flags are inverses of each other, so
|
||||||
|
.BR -dynamic " is equal to " permanent " and "
|
||||||
|
.BR -permanent " is equal to " dynamic .
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B tentative
|
.B tentative
|
||||||
|
|
@ -365,12 +372,26 @@ address detection.
|
||||||
address detection.
|
address detection.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.B temporary
|
.BR temporary " or " secondary
|
||||||
(IPv6 only) only list temporary addresses.
|
List temporary IPv6 or secondary IPv4 addresses only. The Linux kernel shares a
|
||||||
|
single bit for those, so they are actually aliases for each other although the
|
||||||
|
meaning differs depending on address family.
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.BR primary " and " secondary
|
.BR -temporary " or " -secondary
|
||||||
only list primary (or secondary) addresses.
|
These flags are aliases for
|
||||||
|
.BR primary .
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B primary
|
||||||
|
List only primary addresses, in IPv6 exclude temporary ones. This flag is the
|
||||||
|
inverse of
|
||||||
|
.BR temporary " and " secondary .
|
||||||
|
|
||||||
|
.TP
|
||||||
|
.B -primary
|
||||||
|
This is an alias for
|
||||||
|
.BR temporary " or " secondary .
|
||||||
|
|
||||||
.SS ip address flush - flush protocol addresses
|
.SS ip address flush - flush protocol addresses
|
||||||
This command flushes the protocol addresses selected by some criteria.
|
This command flushes the protocol addresses selected by some criteria.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue