@@ -1211,38 +1211,35 @@ static void print_ifa_flags(FILE *fp, const struct ifaddrmsg *ifa,
static int get_filter(const char *arg)
{
+ bool inv = false;
unsigned int i;
+ if (arg[0] == '-') {
+ inv = true;
+ arg++;
+ }
+
/* Special cases */
if (strcmp(arg, "dynamic") == 0) {
- filter.flags &= ~IFA_F_PERMANENT;
- filter.flagmask |= IFA_F_PERMANENT;
+ inv = !inv;
+ arg = "permanent";
} else if (strcmp(arg, "primary") == 0) {
- filter.flags &= ~IFA_F_SECONDARY;
- filter.flagmask |= IFA_F_SECONDARY;
- } else if (*arg == '-') {
- for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
- if (strcmp(arg + 1, ifa_flag_names[i].name))
- continue;
+ inv = !inv;
+ arg = "secondary";
+ }
- filter.flags &= ifa_flag_names[i].value;
- filter.flagmask |= ifa_flag_names[i].value;
- return 0;
- }
+ for (i = 0; i < ARRAY_SIZE(ifa_flag_names); i++) {
+ if (strcmp(arg, ifa_flag_names[i].name))
+ continue;
- return -1;
- } else {
- 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;
+ filter.flagmask |= ifa_flag_names[i].value;
+ return 0;
}
-
- return 0;
+ return -1;
}
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
.ti -8
-.IR FLAG " := "
-.RB "[ " permanent " | " dynamic " | " secondary " | " primary " |"
-.RB [ - ] tentative " | [" - ] deprecated " | [" - ] dadfailed " |"
-.BR temporary " |"
+.IR FLAG " := ["
+.RB [ - ] permanent " |"
+.RB [ - ] dynamic " |"
+.RB [ - ] secondary " |"
+.RB [ - ] primary " |"
+.RB [ - ] tentative " |"
+.RB [ - ] deprecated " |"
+.RB [ - ] dadfailed " |"
+.RB [ - ] temporary " |"
.IR CONFFLAG-LIST " ]"
.ti -8
@@ -334,7 +339,9 @@ only list running interfaces.
.BR dynamic " and " permanent
(IPv6 only) only list addresses installed due to stateless
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
.B tentative
@@ -365,12 +372,26 @@ address detection.
address detection.
.TP
-.B temporary
-(IPv6 only) only list temporary addresses.
+.BR temporary " or " secondary
+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
-.BR primary " and " secondary
-only list primary (or secondary) addresses.
+.BR -temporary " or " -secondary
+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
This command flushes the protocol addresses selected by some criteria.
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: f73ac674d0abf ("ip: change flag names to an array") Signed-off-by: Phil Sutter <phil@nwl.cc> --- Changes since v1: - Improve "special cases" handling per Stephen's suggestion. - Update man page accordingly. --- ip/ipaddress.c | 43 +++++++++++++++++++--------------------- man/man8/ip-address.8.in | 39 +++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 32 deletions(-)