diff mbox series

[v3] iproute: list/flush/save filter also by metric

Message ID 1513512131-31902-1-git-send-email-green@msu.ru
State Accepted, archived
Delegated to: stephen hemminger
Headers show
Series [v3] iproute: list/flush/save filter also by metric | expand

Commit Message

Alexander Zubkov Dec. 17, 2017, 12:02 p.m. UTC
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@msu.ru>
---
 ip/iproute.c | 21 ++++++++++++++++++++-
 1 file changed, 20 insertions(+), 1 deletion(-)

Comments

Stephen Hemminger Dec. 19, 2017, 4:22 p.m. UTC | #1
On Sun, 17 Dec 2017 13:02:11 +0100
Alexander Zubkov <green@msu.ru> wrote:

> 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@msu.ru>

Applied, thanks Alexander
diff mbox series

Patch

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;