[PATCH net-next v2] net: Add support for filtering neigh dump by master device

Subsystems: networking [general], the rest

STALE4039d

5 messages, 4 authors, 2015-10-02 · open the first message on its own page

[PATCH net-next v2] net: Add support for filtering neigh dump by master device

From: David Ahern <hidden>
Date: 2015-09-29 16:32:22

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 <redacted>
---
v2
- added NLM_F_DUMP_FILTERED flag for userspace feedback that request is
  supported

This method works for other filters as well and other dump commands.
Works fine for all combinations of new and old kernel and new and old ip:
1. new ip command on old kernel, NDA_MASTER attribute is ignored
2. old ip command on new kernel, NDA_MASTER attribute is not present
3. new ip on new kernel ... goodness ensues by limiting data to
   only what user wants

 include/uapi/linux/netlink.h |  1 +
 net/core/neighbour.c         | 32 +++++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index 6f3fe16cd22a..f095155d8749 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -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	*/
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 2b515ba7e94f..8c57fdf4d68e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -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);
@@ -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;
 			}
-- 
1.9.1

Re: [PATCH net-next v2] net: Add support for filtering neigh dump by master device

From: roopa <hidden>
Date: 2015-09-30 04:28:37

On 9/29/15, 9:32 AM, David Ahern wrote:
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 <redacted>
Acked-by: Roopa Prabhu <redacted>

Re: [PATCH net-next v2] net: Add support for filtering neigh dump by master device

From: David Miller <davem@davemloft.net>
Date: 2015-09-30 04:34:09

From: David Ahern <redacted>
Date: Tue, 29 Sep 2015 09:32:03 -0700
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 <redacted>
---
v2
- added NLM_F_DUMP_FILTERED flag for userspace feedback that request is
  supported

This method works for other filters as well and other dump commands.
Works fine for all combinations of new and old kernel and new and old ip:
1. new ip command on old kernel, NDA_MASTER attribute is ignored
2. old ip command on new kernel, NDA_MASTER attribute is not present
3. new ip on new kernel ... goodness ensues by limiting data to
   only what user wants
Applied, thanks.

Re: [PATCH net-next v2] net: Add support for filtering neigh dump by master device

From: Eric W. Biederman <hidden>
Date: 2015-10-02 17:26:19

David Ahern [off-list ref] writes:
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.
*Scratches my head*

I thought you only wanted L3 functionality, and that you did not want a
network namespace.

What is the thinking here because it sure looks like you are busily
adding layer two functionality you swore you did not want.

Eric
quoted hunk
Signed-off-by: David Ahern <redacted>
---
v2
- added NLM_F_DUMP_FILTERED flag for userspace feedback that request is
  supported

This method works for other filters as well and other dump commands.
Works fine for all combinations of new and old kernel and new and old ip:
1. new ip command on old kernel, NDA_MASTER attribute is ignored
2. old ip command on new kernel, NDA_MASTER attribute is not present
3. new ip on new kernel ... goodness ensues by limiting data to
   only what user wants

 include/uapi/linux/netlink.h |  1 +
 net/core/neighbour.c         | 32 +++++++++++++++++++++++++++++++-
 2 files changed, 32 insertions(+), 1 deletion(-)
diff --git a/include/uapi/linux/netlink.h b/include/uapi/linux/netlink.h
index 6f3fe16cd22a..f095155d8749 100644
--- a/include/uapi/linux/netlink.h
+++ b/include/uapi/linux/netlink.h
@@ -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	*/
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index 2b515ba7e94f..8c57fdf4d68e 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -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);
@@ -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;
 			}

Re: [PATCH net-next v2] net: Add support for filtering neigh dump by master device

From: David Ahern <hidden>
Date: 2015-10-02 19:51:17

On 10/2/15 11:18 AM, Eric W. Biederman wrote:
What is the thinking here because it sure looks like you are busily
adding layer two functionality you swore you did not want.
Interfaces are enslaved to a VRF device, but neighbor entries are installed with a reference to the actual interface not the VRF device.

This patch (plus the iproute2 one) fills a gap for usability and debugging. I have one more patch to go and then I will send an update to the documentation, but here is a preview (documentation update has more detail via examples):

Using iproute2 for VRFs
1. Create a VRF
   ip link add dev NAME type vrf table ID

2. List VRFs
   ip [-d] link show type vrf
   --> -d is needed to show table id

3. Assign a Network Interface to a VRF
   ip link set dev NAME master VRF-NAME

4. Show Devices Assigned to a VRF
   ip [-br] link show master VRF-NAME

5. Show Neighbor Entries for a VRF
   ip [-6] neigh show master VRF-NAME

   (This patch is what makes this command work efficiently.)

6. Show Addresses Assigned to Interfaces in a VRF
   ip [-br][-6] addr show master VRF-NAME

7. Show Routes for a VRF
   ip [-6] route show table ID

8. Route Lookup for a VRF
   ip [-6] route get oif VRF-NAME ADDRESS

   (This one needs a kernel patch to display the correct entry.)

David
Keyboard shortcuts
hback out one level
jnext message in thread
kprevious message in thread
ldrill in
Escclose help / fold thread tree
?toggle this help