From: David Ahern <dsahern@kernel.org>
To: netdev@vger.kernel.org, davem@davemloft.net
Cc: David Ahern <dsahern@gmail.com>
Subject: [PATCH v2 net-next 04/11] net/ipv6: Plumb support for filtering route dumps
Date: Mon, 15 Oct 2018 18:56:44 -0700 [thread overview]
Message-ID: <20181016015651.22696-5-dsahern@kernel.org> (raw)
In-Reply-To: <20181016015651.22696-1-dsahern@kernel.org>
From: David Ahern <dsahern@gmail.com>
Implement kernel side filtering of routes by table id, egress device
index, protocol, and route type. If the table id is given in the filter,
lookup the table and call fib6_dump_table directly for it.
Move the existing route flags check for prefix only routes to the new
filter.
Signed-off-by: David Ahern <dsahern@gmail.com>
---
net/ipv6/ip6_fib.c | 28 ++++++++++++++++++++++------
net/ipv6/route.c | 40 ++++++++++++++++++++++++++++++++--------
2 files changed, 54 insertions(+), 14 deletions(-)
diff --git a/net/ipv6/ip6_fib.c b/net/ipv6/ip6_fib.c
index 94e61fe47ff8..a51fc357a05c 100644
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -583,10 +583,12 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
err = ip_valid_fib_dump_req(net, nlh, &arg.filter, cb->extack);
if (err < 0)
return err;
- }
+ } else if (nlmsg_len(nlh) >= sizeof(struct rtmsg)) {
+ struct rtmsg *rtm = nlmsg_data(nlh);
- s_h = cb->args[0];
- s_e = cb->args[1];
+ if (rtm->rtm_flags & RTM_F_PREFIX)
+ arg.filter.flags = RTM_F_PREFIX;
+ }
w = (void *)cb->args[2];
if (!w) {
@@ -612,6 +614,20 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
arg.net = net;
w->args = &arg;
+ if (arg.filter.table_id) {
+ tb = fib6_get_table(net, arg.filter.table_id);
+ if (!tb) {
+ NL_SET_ERR_MSG_MOD(cb->extack, "FIB table does not exist");
+ return -ENOENT;
+ }
+
+ res = fib6_dump_table(tb, skb, cb);
+ goto out;
+ }
+
+ s_h = cb->args[0];
+ s_e = cb->args[1];
+
rcu_read_lock();
for (h = s_h; h < FIB6_TABLE_HASHSZ; h++, s_e = 0) {
e = 0;
@@ -621,16 +637,16 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
goto next;
res = fib6_dump_table(tb, skb, cb);
if (res != 0)
- goto out;
+ goto out_unlock;
next:
e++;
}
}
-out:
+out_unlock:
rcu_read_unlock();
cb->args[1] = e;
cb->args[0] = h;
-
+out:
res = res < 0 ? res : skb->len;
if (res <= 0)
fib6_dump_end(cb);
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index f4e08b0689a8..9fd600e42f9d 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4767,28 +4767,52 @@ static int rt6_fill_node(struct net *net, struct sk_buff *skb,
return -EMSGSIZE;
}
+static bool fib6_info_uses_dev(const struct fib6_info *f6i,
+ const struct net_device *dev)
+{
+ if (f6i->fib6_nh.nh_dev == dev)
+ return true;
+
+ if (f6i->fib6_nsiblings) {
+ struct fib6_info *sibling, *next_sibling;
+
+ list_for_each_entry_safe(sibling, next_sibling,
+ &f6i->fib6_siblings, fib6_siblings) {
+ if (sibling->fib6_nh.nh_dev == dev)
+ return true;
+ }
+ }
+
+ return false;
+}
+
int rt6_dump_route(struct fib6_info *rt, void *p_arg)
{
struct rt6_rtnl_dump_arg *arg = (struct rt6_rtnl_dump_arg *) p_arg;
+ struct fib_dump_filter *filter = &arg->filter;
+ unsigned int flags = NLM_F_MULTI;
struct net *net = arg->net;
if (rt == net->ipv6.fib6_null_entry)
return 0;
- if (nlmsg_len(arg->cb->nlh) >= sizeof(struct rtmsg)) {
- struct rtmsg *rtm = nlmsg_data(arg->cb->nlh);
-
- /* user wants prefix routes only */
- if (rtm->rtm_flags & RTM_F_PREFIX &&
- !(rt->fib6_flags & RTF_PREFIX_RT)) {
- /* success since this is not a prefix route */
+ if ((filter->flags & RTM_F_PREFIX) &&
+ !(rt->fib6_flags & RTF_PREFIX_RT)) {
+ /* success since this is not a prefix route */
+ return 1;
+ }
+ if (filter->filter_set) {
+ if ((filter->rt_type && rt->fib6_type != filter->rt_type) ||
+ (filter->dev && !fib6_info_uses_dev(rt, filter->dev)) ||
+ (filter->protocol && rt->fib6_protocol != filter->protocol)) {
return 1;
}
+ flags |= NLM_F_DUMP_FILTERED;
}
return rt6_fill_node(net, arg->skb, rt, NULL, NULL, NULL, 0,
RTM_NEWROUTE, NETLINK_CB(arg->cb->skb).portid,
- arg->cb->nlh->nlmsg_seq, NLM_F_MULTI);
+ arg->cb->nlh->nlmsg_seq, flags);
}
static int inet6_rtm_getroute(struct sk_buff *in_skb, struct nlmsghdr *nlh,
--
2.11.0
next prev parent reply other threads:[~2018-10-16 9:44 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-10-16 1:56 [PATCH v2 net-next 00/11] net: Kernel side filtering for route dumps David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 01/11] netlink: Add answer_flags to netlink_callback David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 02/11] net: Add struct for fib dump filter David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 03/11] net/ipv4: Plumb support for filtering route dumps David Ahern
2019-07-19 4:17 ` Hangbin Liu
2019-07-19 16:55 ` David Ahern
2019-07-22 3:00 ` Hangbin Liu
2018-10-16 1:56 ` David Ahern [this message]
2018-10-16 1:56 ` [PATCH v2 net-next 05/11] net/mpls: " David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 06/11] ipmr: Refactor mr_rtm_dumproute David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 07/11] net: Plumb support for filtering ipv4 and ipv6 multicast route dumps David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 08/11] net: Enable kernel side filtering of " David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 09/11] net/mpls: Handle " David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 10/11] net/ipv6: Bail early if user only wants cloned entries David Ahern
2018-10-16 1:56 ` [PATCH v2 net-next 11/11] net/ipv4: Bail early if user only wants prefix entries David Ahern
2018-10-16 6:30 ` [PATCH v2 net-next 00/11] net: Kernel side filtering for route dumps David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20181016015651.22696-5-dsahern@kernel.org \
--to=dsahern@kernel.org \
--cc=davem@davemloft.net \
--cc=dsahern@gmail.com \
--cc=netdev@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).