summaryrefslogtreecommitdiff
path: root/net/ipv4/ipmr.c
diff options
context:
space:
mode:
authorDavid Ahern <dsahern@gmail.com>2018-10-15 18:56:47 -0700
committerDavid S. Miller <davem@davemloft.net>2018-10-16 00:13:39 -0700
commitcb167893f41e21e6bd283d78e53489289dc0592d (patch)
tree162a0315d6ed8ca0cf056fc854f979a45c2ab2ae /net/ipv4/ipmr.c
parente1cedae1ba6b09ae8376c1486712bf91ea0dfc41 (diff)
net: Plumb support for filtering ipv4 and ipv6 multicast route dumps
Implement kernel side filtering of routes by egress device index and table id. If the table id is given in the filter, lookup table and call mr_table_dump directly for it. Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4/ipmr.c')
-rw-r--r--net/ipv4/ipmr.c18
1 files changed, 15 insertions, 3 deletions
diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c
index 44d777058960..3fa988e6a3df 100644
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -2528,18 +2528,30 @@ errout_free:
static int ipmr_rtm_dumproute(struct sk_buff *skb, struct netlink_callback *cb)
{
struct fib_dump_filter filter = {};
+ int err;
if (cb->strict_check) {
- int err;
-
err = ip_valid_fib_dump_req(sock_net(skb->sk), cb->nlh,
&filter, cb->extack);
if (err < 0)
return err;
}
+ if (filter.table_id) {
+ struct mr_table *mrt;
+
+ mrt = ipmr_get_table(sock_net(skb->sk), filter.table_id);
+ if (!mrt) {
+ NL_SET_ERR_MSG(cb->extack, "ipv4: MR table does not exist");
+ return -ENOENT;
+ }
+ err = mr_table_dump(mrt, skb, cb, _ipmr_fill_mroute,
+ &mfc_unres_lock, &filter);
+ return skb->len ? : err;
+ }
+
return mr_rtm_dumproute(skb, cb, ipmr_mr_table_iter,
- _ipmr_fill_mroute, &mfc_unres_lock);
+ _ipmr_fill_mroute, &mfc_unres_lock, &filter);
}
static const struct nla_policy rtm_ipmr_policy[RTA_MAX + 1] = {