net: Add struct for fib dump filter
authorDavid Ahern <dsahern@gmail.com>
Tue, 16 Oct 2018 01:56:42 +0000 (18:56 -0700)
committerDavid S. Miller <davem@davemloft.net>
Tue, 16 Oct 2018 07:13:12 +0000 (00:13 -0700)
Add struct fib_dump_filter for options on limiting which routes are
returned in a dump request. The current list is table id, protocol,
route type, rtm_flags and nexthop device index. struct net is needed
to lookup the net_device from the index.

Declare the filter for each route dump handler and plumb the new
arguments from dump handlers to ip_valid_fib_dump_req.

Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
include/net/ip6_route.h
include/net/ip_fib.h
net/ipv4/fib_frontend.c
net/ipv4/ipmr.c
net/ipv6/ip6_fib.c
net/ipv6/ip6mr.c
net/mpls/af_mpls.c

index cef186dbd2ce5131b994eb04aeeea541516d7879..7ab119936e6979b6fc20a1beb1a3690384e723c0 100644 (file)
@@ -174,6 +174,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);
index 852e4ebf22099de2510e9bf9756d704ed5f42d8c..667013bf42665e49e6333249fbc7618a31f2ebd6 100644 (file)
@@ -222,6 +222,16 @@ struct fib_table {
        unsigned long           __data[0];
 };
 
+struct fib_dump_filter {
+       u32                     table_id;
+       /* filter_set is an optimization that an entry is set */
+       bool                    filter_set;
+       unsigned char           protocol;
+       unsigned char           rt_type;
+       unsigned int            flags;
+       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,6 +463,7 @@ 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,
+int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+                         struct fib_dump_filter *filter,
                          struct netlink_ext_ack *extack);
 #endif  /* _NET_FIB_H */
index 0f1beceb47d5e6058da73a9ce06a7a4cabed68da..850850dd80e1d0f21175bba98accba8edbcc5fd8 100644 (file)
@@ -802,7 +802,8 @@ errout:
        return err;
 }
 
-int ip_valid_fib_dump_req(const struct nlmsghdr *nlh,
+int ip_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+                         struct fib_dump_filter *filter,
                          struct netlink_ext_ack *extack)
 {
        struct rtmsg *rtm;
@@ -837,6 +838,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;
@@ -844,7 +846,7 @@ static int inet_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
        int dumped = 0, err;
 
        if (cb->strict_check) {
-               err = ip_valid_fib_dump_req(nlh, cb->extack);
+               err = ip_valid_fib_dump_req(net, nlh, &filter, cb->extack);
                if (err < 0)
                        return err;
        }
index 91b0d5671649c30b95fbb02a1b0a20636435a263..44d77705896035f7285f2807fda91bcbe0e97542 100644 (file)
@@ -2527,9 +2527,13 @@ errout_free:
 
 static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
 {
+       struct fib_dump_filter filter = {};
+
        if (cb->strict_check) {
-               int err = ip_valid_fib_dump_req(cb->nlh, cb->extack);
+               int err;
 
+               err = ip_valid_fib_dump_req(sock_net(skb->sk), cb->nlh,
+                                           &filter, cb->extack);
                if (err < 0)
                        return err;
        }
index 0783af11b0b7e49d6562233876d5e9627bc080ce..94e61fe47ff8c7951cd42043e89aa31d29872f58 100644 (file)
@@ -569,17 +569,18 @@ 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 (cb->strict_check) {
-               int err = ip_valid_fib_dump_req(nlh, cb->extack);
+               int err;
 
+               err = ip_valid_fib_dump_req(net, nlh, &arg.filter, cb->extack);
                if (err < 0)
                        return err;
        }
index d7563ef76518482dfac68386b6946e9677f1708e..dbd5166c55996bb27b31c7c4666484ef142b8dff 100644 (file)
@@ -2458,10 +2458,13 @@ errout:
 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 (cb->strict_check) {
-               int err = ip_valid_fib_dump_req(nlh, cb->extack);
+               int err;
 
+               err = ip_valid_fib_dump_req(sock_net(skb->sk), nlh,
+                                           &filter, cb->extack);
                if (err < 0)
                        return err;
        }
index 5fe274c47c41f74e745f01fc66a70858e1c8e3f5..bfcb4759c9ee99ee3346af39ed0514781ca148d8 100644 (file)
@@ -2032,13 +2032,15 @@ nla_put_failure:
 }
 
 #if IS_ENABLED(CONFIG_INET)
-static int mpls_valid_fib_dump_req(const struct nlmsghdr *nlh,
+static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+                                  struct fib_dump_filter *filter,
                                   struct netlink_ext_ack *extack)
 {
-       return ip_valid_fib_dump_req(nlh, extack);
+       return ip_valid_fib_dump_req(net, nlh, filter, extack);
 }
 #else
-static int mpls_valid_fib_dump_req(const struct nlmsghdr *nlh,
+static int mpls_valid_fib_dump_req(struct net *net, const struct nlmsghdr *nlh,
+                                  struct fib_dump_filter *filter,
                                   struct netlink_ext_ack *extack)
 {
        struct rtmsg *rtm;
@@ -2070,14 +2072,16 @@ 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 (cb->strict_check) {
-               int err = mpls_valid_fib_dump_req(nlh, cb->extack);
+               int err;
 
+               err = mpls_valid_fib_dump_req(net, nlh, &filter, cb->extack);
                if (err < 0)
                        return err;
        }