[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-Id: <1513512131-31902-1-git-send-email-green@msu.ru>
Date: Sun, 17 Dec 2017 13:02:11 +0100
From: Alexander Zubkov <green@....ru>
To: stephen@...workplumber.org
Cc: zubkov318@...il.com, netdev@...r.kernel.org,
Alexander Zubkov <green@....ru>
Subject: [PATCH v3] iproute: list/flush/save filter also by metric
Metric is one of the "unique key" fields of the route in Linux. But
still one can not use its value in filter while running ip list.
Because of this writing checks in scripts for example is incovenient.
Signed-off-by: Alexander Zubkov <green@....ru>
---
ip/iproute.c | 21 ++++++++++++++++++++-
1 file changed, 20 insertions(+), 1 deletion(-)
diff --git a/ip/iproute.c b/ip/iproute.c
index 16eadab..32c93ed 100644
--- a/ip/iproute.c
+++ b/ip/iproute.c
@@ -126,6 +126,7 @@ static struct
int oif, oifmask;
int mark, markmask;
int realm, realmmask;
+ __u32 metric, metricmask;
inet_prefix rprefsrc;
inet_prefix rvia;
inet_prefix rdst;
@@ -288,6 +289,14 @@ static int filter_nlmsg(struct nlmsghdr *n, struct rtattr **tb, int host_len)
if ((mark ^ filter.mark) & filter.markmask)
return 0;
}
+ if (filter.metricmask) {
+ __u32 metric = 0;
+
+ if (tb[RTA_PRIORITY])
+ metric = rta_getattr_u32(tb[RTA_PRIORITY]);
+ if ((metric ^ filter.metric) & filter.metricmask)
+ return 0;
+ }
if (filter.flushb &&
r->rtm_family == AF_INET6 &&
r->rtm_dst_len == 0 &&
@@ -441,7 +450,7 @@ int print_route(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
fprintf(fp, "src %s ",
rt_addr_n2a_rta(r->rtm_family, tb[RTA_PREFSRC]));
}
- if (tb[RTA_PRIORITY])
+ if (tb[RTA_PRIORITY] && filter.metricmask != -1)
fprintf(fp, "metric %u ", rta_getattr_u32(tb[RTA_PRIORITY]));
if (r->rtm_flags & RTNH_F_DEAD)
fprintf(fp, "dead ");
@@ -1518,6 +1527,16 @@ static int iproute_list_flush_or_save(int argc, char **argv, int action)
if (get_unsigned(&mark, *argv, 0))
invarg("invalid mark value", *argv);
filter.markmask = -1;
+ } else if (matches(*argv, "metric") == 0 ||
+ matches(*argv, "priority") == 0 ||
+ strcmp(*argv, "preference") == 0) {
+ __u32 metric;
+
+ NEXT_ARG();
+ if (get_u32(&metric, *argv, 0))
+ invarg("\"metric\" value is invalid\n", *argv);
+ filter.metric = metric;
+ filter.metricmask = -1;
} else if (strcmp(*argv, "via") == 0) {
int family;
Powered by blists - more mailing lists