From: Cosmin Ratiu <cratiu@ixiacom.com>
To: netdev@vger.kernel.org
Cc: ixlk-cr@farscape.ixiacom.com,
Pinaki Chakrabarti <pchakrabarti@ixiacom.com>
Subject: [RFC PATCH] extend RTM_GETNEIGH to allow getting more precise information
Date: Fri, 15 Jan 2010 18:42:59 +0200 [thread overview]
Message-ID: <201001151842.59813.cratiu@ixiacom.com> (raw)
[-- Attachment #1: Type: Text/Plain, Size: 527 bytes --]
Hello.
Please have a look at this patch which tries to solve a problem we
encountered.
The background is that RTM_GETNEIGH netlink message is used to get a complete
dump of a neighbor table. Sometimes, that's too much (especially when you have
a lot of neighbors). This patch allows one to specify the IPv4/6 address of a
neighbor and the device index through which it is accessible in order to
obtain only that entry.
If you have other suggestions on how to accomplish this task, please let us
know.
Thanks,
Cosmin.
[-- Attachment #2: 0001-Extend-RTM_GETNEIGH-to-allow-getting-more-precise-in.patch --]
[-- Type: text/x-patch, Size: 3341 bytes --]
From beb2cd45109f28b9067d7fa902e49cbbc7667ff5 Mon Sep 17 00:00:00 2001
From: Cosmin Ratiu <cratiu@ixiacom.com>
Date: Fri, 15 Jan 2010 18:34:39 +0200
Subject: [PATCH] Extend RTM_GETNEIGH to allow getting more precise information.
RTM_GETNEIGH makes a complete dump of the neighbour table for a given
net and address family. The patch allows requests for a single entry
by specifying the device and IP address. This should increase
performance when there are many neighbour entries and a specific one is
desired.
Signed-off-by: Pinaki Chakrabarti <pchakrabarti@ixiacom.com>
Signed-off-by: Cosmin Ratiu <cratiu@ixiacom.com>
---
net/core/neighbour.c | 75 ++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 61 insertions(+), 14 deletions(-)
diff --git a/net/core/neighbour.c b/net/core/neighbour.c
index f35377b..243fa5b 100644
--- a/net/core/neighbour.c
+++ b/net/core/neighbour.c
@@ -2119,24 +2119,71 @@ out:
static int neigh_dump_info(struct sk_buff *skb, struct netlink_callback *cb)
{
struct neigh_table *tbl;
- int t, family, s_t;
+ struct net *net = sock_net(skb->sk);
+ const struct nlmsghdr *nlh = cb->nlh;
+ int min_len = NLMSG_LENGTH(sizeof(struct ndmsg));
+ int family = ((struct rtgenmsg *) nlmsg_data(nlh))->rtgen_family;
- read_lock(&neigh_tbl_lock);
- family = ((struct rtgenmsg *) nlmsg_data(cb->nlh))->rtgen_family;
- s_t = cb->args[0];
+ if (nlh->nlmsg_len <= min_len) {
+ struct neigh_table *tbl;
+ int t, s_t;
- for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) {
- if (t < s_t || (family && tbl->family != family))
- continue;
- if (t > s_t)
- memset(&cb->args[1], 0, sizeof(cb->args) -
- sizeof(cb->args[0]));
- if (neigh_dump_table(tbl, skb, cb) < 0)
+ read_lock(&neigh_tbl_lock);
+ s_t = cb->args[0];
+
+ for (tbl = neigh_tables, t = 0; tbl; tbl = tbl->next, t++) {
+ if (t < s_t || (family && tbl->family != family))
+ continue;
+ if (t > s_t)
+ memset(&cb->args[1], 0, sizeof(cb->args) -
+ sizeof(cb->args[0]));
+ if (neigh_dump_table(tbl, skb, cb) < 0)
+ break;
+ }
+ read_unlock(&neigh_tbl_lock);
+ cb->args[0] = t;
+ } else {
+ char key[16] = {0};
+ struct ndmsg *ndm = NULL;
+ struct net_device *dev = NULL;
+ struct rtattr *attr = NULL;
+ int attrlen;
+ struct neighbour *n;
+
+ if (cb->args[0])
+ goto out;
+ cb->args[0] = 1;
+
+ ndm = NLMSG_DATA(nlh);
+ if (!(dev = dev_get_by_index(net, ndm->ndm_ifindex)))
+ goto out;
+
+ attrlen = nlh->nlmsg_len - NLMSG_ALIGN(min_len);
+ attr = (void*)nlh + NLMSG_ALIGN(min_len);
+ if (!RTA_OK(attr, attrlen) || attr->rta_type != NDA_DST)
+ goto out;
+ memcpy(key, RTA_DATA(attr), attr->rta_len);
+
+ /* look for the neighbor */
+ read_lock(&neigh_tbl_lock);
+ for (tbl = neigh_tables; tbl; tbl = tbl->next) {
+ if (tbl->family != family)
+ continue;
+ n = neigh_lookup(tbl, key, dev);
+ if (!n)
+ continue;
+ if (n->nud_state & NUD_CONNECTED) {
+ neigh_fill_info(skb, n, NETLINK_CB(cb->skb).pid,
+ nlh->nlmsg_seq, RTM_NEWNEIGH, 0);
+ neigh_release(n);
+ }
break;
+ }
+ read_unlock(&neigh_tbl_lock);
+out:
+ if (dev)
+ dev_put(dev);
}
- read_unlock(&neigh_tbl_lock);
-
- cb->args[0] = t;
return skb->len;
}
--
1.6.5
next reply other threads:[~2010-01-15 16:43 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2010-01-15 16:42 Cosmin Ratiu [this message]
2010-01-23 10:12 ` [RFC PATCH] extend RTM_GETNEIGH to allow getting more precise information David Miller
2010-01-25 13:51 ` Patrick McHardy
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=201001151842.59813.cratiu@ixiacom.com \
--to=cratiu@ixiacom.com \
--cc=ixlk-cr@farscape.ixiacom.com \
--cc=netdev@vger.kernel.org \
--cc=pchakrabarti@ixiacom.com \
/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).