Subject: [PATCH RFC v2 net-next 20/25] net: Add struct for fib dump filter

From: David Ahern <[email-masked]>
Date: Mon, 1 Oct 2018 17:28:46 -0700

From: David Ahern <[email-masked]>

Add struct fib_dump_filter for options on limiting which routes are
dumped. The current list is table id, tos, protocol, scope, route type,
flags and nexthop device index.

This patch adds the struct and argument to ip_valid_fib_dump_req so
that per-protocol patches can be done followed by actually parsing any
data from userspace.

Signed-off-by: David Ahern <[email-masked]>
---
 include/net/ip6_route.h |  1 +
 include/net/ip_fib.h    | 12 ++++++++++++
 net/ipv4/fib_frontend.c |  4 +++-
 net/ipv4/ipmr.c         |  3 ++-
 net/ipv6/ip6_fib.c      |  4 ++--
 net/ipv6/ip6mr.c        |  3 ++-
 net/mpls/af_mpls.c      |  3 ++-
 7 files changed, 24 insertions(+), 6 deletions(-)

diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index 7b9c82de11cc..ecaba26b3399 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -175,6 +175,7 @@ struct rt6_rtnl_dump_arg {
 	struct sk_buff *skb;
 	struct netlink_callback *cb;
 	struct net *net;
+	struct fib_dump_filter filter;
 };
 
 int rt6_dump_route(struct fib6_info *f6i, void *p_arg);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index 9846b79c9ee1..d0cd838ca00c 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -222,6 +222,17 @@ struct fib_table {
 	unsigned long		__data[0];
 };
 
+struct fib_dump_filter {
+	u32			table_id;
+	unsigned char		tos;
+	unsigned char		protocol;
+	unsigned char		scope;
+	unsigned char		rt_type;
+	unsigned int		flags;
+	int			ifindex;
+	struct net_device	*dev;
+};
+
 int fib_table_lookup(struct fib_table *tb, const struct flowi4 *flp,
 		     struct fib_result *res, int fib_flags);
 int fib_table_insert(struct net *, struct fib_table *, struct fib_config *,
@@ -453,5 +464,6 @@ static inline void fib_proc_exit(struct net *net)
 u32 ip_mtu_from_fib_result(struct fib_result *res, __be32 daddr);
 
 int ip_valid_fib_dump_req(const struct nlmsghdr *nlh,
+			  struct fib_dump_filter *filter,
 			  struct netlink_ext_ack *extack);
 #endif  /* _NET_FIB_H */
diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c
index c608b393ae49..9d872a4900cd 100644
--- a/net/ipv4/fib_frontend.c
+++ b/net/ipv4/fib_frontend.c
@@ -803,6 +803,7 @@ static int inet_rtm_newroute(struct sk_buff *skb, struct nlmsghdr *nlh,
 }
 
 int ip_valid_fib_dump_req(const struct nlmsghdr *nlh,
+			  struct fib_dump_filter *filter,
 			  struct netlink_ext_ack *extack)
 {
 	struct rtmsg *rtm;
@@ -838,6 +839,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	const struct nlmsghdr *nlh = cb->nlh;
 	struct net *net = sock_net(skb->sk);
+	struct fib_dump_filter filter = {};
 	unsigned int h, s_h;
 	unsigned int e = 0, s_e;
 	struct fib_table *tb;
@@ -845,7 +847,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 	int dumped = 0, err;
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP_PROPER_HDR) {
-		err = ip_valid_fib_dump_req(nlh, cb->extack);
+		err = ip_valid_fib_dump_req(nlh, &filter, cb->extack);
 		if (err)
 			return err;
 	}
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 91b5991ed536..9e9ad60dff6b 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2528,9 +2528,10 @@ static int ipmr_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
 static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	const struct nlmsghdr *nlh = cb->nlh;
+	struct fib_dump_filter filter = {};
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP_PROPER_HDR) {
-		int err = ip_valid_fib_dump_req(nlh, cb->extack);
+		int err = ip_valid_fib_dump_req(nlh, &filter, cb->extack);
 
 		if (err)
 			return err;
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index fc14733fbad8..e0362a21737f 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -570,16 +570,16 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	const struct nlmsghdr *nlh = cb->nlh;
 	struct net *net = sock_net(skb->sk);
+	struct rt6_rtnl_dump_arg arg = {};
 	unsigned int h, s_h;
 	unsigned int e = 0, s_e;
-	struct rt6_rtnl_dump_arg arg;
 	struct fib6_walker *w;
 	struct fib6_table *tb;
 	struct hlist_head *head;
 	int res = 0;
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP_PROPER_HDR) {
-		int err = ip_valid_fib_dump_req(nlh, cb->extack);
+		int err = ip_valid_fib_dump_req(nlh, &arg.filter, cb->extack);
 
 		if (err)
 			return err;
diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c
index aa668214edc2..b3084b2c8f88 100644
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -2434,9 +2434,10 @@ static void mrt6msg_netlink_event(struct mr_table *mrt, struct sk_buff *pkt)
 static int ip6mr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
 {
 	const struct nlmsghdr *nlh = cb->nlh;
+	struct fib_dump_filter filter = {};
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP_PROPER_HDR) {
-		int err = ip_valid_fib_dump_req(nlh, cb->extack);
+		int err = ip_valid_fib_dump_req(nlh, &filter, cb->extack);
 
 		if (err)
 			return err;
diff --git a/net/mpls/af_mpls.c b/net/mpls/af_mpls.c
index 64de2f8c3847..f94d1db63eb5 100644
--- a/net/mpls/af_mpls.c
+++ b/net/mpls/af_mpls.c
@@ -2036,13 +2036,14 @@ static int mpls_dump_routes(struct sk_buff *skb, struct netlink_callback *cb)
 	const struct nlmsghdr *nlh = cb->nlh;
 	struct net *net = sock_net(skb->sk);
 	struct mpls_route __rcu **platform_label;
+	struct fib_dump_filter filter = {};
 	size_t platform_labels;
 	unsigned int index;
 
 	ASSERT_RTNL();
 
 	if (nlh->nlmsg_flags & NLM_F_DUMP_PROPER_HDR) {
-		int err = ip_valid_fib_dump_req(nlh, cb->extack);
+		int err = ip_valid_fib_dump_req(nlh, &filter, cb->extack);
 
 		if (err)
 			return err;
-- 
2.11.0