Skip to content

Commit

Permalink
net: Add support for filtering neigh dump by master device
Browse files Browse the repository at this point in the history
Add support for filtering neighbor dumps by master device by adding
the NDA_MASTER attribute to the dump request. A new netlink flag,
NLM_F_DUMP_FILTERED, is added to indicate the kernel supports the
request and output is filtered as requested.

Signed-off-by: David Ahern <[email protected]>
Acked-by: Roopa Prabhu <[email protected]>
Signed-off-by: David S. Miller <[email protected]>
  • Loading branch information
David Ahern authored and davem330 committed Sep 30, 2015
1 parent 5172393 commit 21fdd09
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
1 change: 1 addition & 0 deletions include/uapi/linux/netlink.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ struct nlmsghdr {
#define NLM_F_ACK 4 /* Reply with ack, with zero or error code */
#define NLM_F_ECHO 8 /* Echo this request */
#define NLM_F_DUMP_INTR 16 /* Dump was inconsistent due to sequence change */
#define NLM_F_DUMP_FILTERED 32 /* Dump was filtered as requested */

/* Modifiers to GET request */
#define NLM_F_ROOT 0x100 /* specify tree root */
Expand Down
32 changes: 31 additions & 1 deletion net/core/neighbour.c
Original file line number Diff line number Diff line change
Expand Up @@ -2235,14 +2235,42 @@ static void neigh_update_notify(struct neighbour *neigh)
__neigh_notify(neigh, RTM_NEWNEIGH, 0);
}

static bool neigh_master_filtered(struct net_device *dev, int master_idx)
{
struct net_device *master;

if (!master_idx)
return false;

master = netdev_master_upper_dev_get(dev);
if (!master || master->ifindex != master_idx)
return true;

return false;
}

static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
struct netlink_callback *cb)
{
struct net *net = sock_net(skb->sk);
const struct nlmsghdr *nlh = cb->nlh;
struct nlattr *tb[NDA_MAX + 1];
struct neighbour *n;
int rc, h, s_h = cb->args[1];
int idx, s_idx = idx = cb->args[2];
struct neigh_hash_table *nht;
int filter_master_idx = 0;
unsigned int flags = NLM_F_MULTI;
int err;

err = nlmsg_parse(nlh, sizeof(struct ndmsg), tb, NDA_MAX, NULL);
if (!err) {
if (tb[NDA_MASTER])
filter_master_idx = nla_get_u32(tb[NDA_MASTER]);

if (filter_master_idx)
flags |= NLM_F_DUMP_FILTERED;
}

rcu_read_lock_bh();
nht = rcu_dereference_bh(tbl->nht);
Expand All @@ -2255,12 +2283,14 @@ static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
n = rcu_dereference_bh(n->next)) {
if (!net_eq(dev_net(n->dev), net))
continue;
if (neigh_master_filtered(n->dev, filter_master_idx))
continue;
if (idx < s_idx)
goto next;
if (neigh_fill_info(skb, n, NETLINK_CB(cb->skb).portid,
cb->nlh->nlmsg_seq,
RTM_NEWNEIGH,
NLM_F_MULTI) < 0) {
flags) < 0) {
rc = -1;
goto out;
}
Expand Down

0 comments on commit 21fdd09

Please sign in to comment.