lkml.org 
[lkml]   [2005]   [Jan]   [28]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
Patch in this message
/
Date
From
Subjectmultiple neighbour cache tables for AF_INET
--- linux-2.4.28/net/core/neighbour.c	Fri Jan 28 14:26:59 2005
+++ linux-2.4.28fix/net/core/neighbour.c Fri Jan 28 13:22:06 2005
@@ -1351,7 +1351,6 @@ int neigh_delete(struct sk_buff *skb, st

if (tbl->family != ndm->ndm_family)
continue;
- read_unlock(&neigh_tbl_lock);

err = -EINVAL;
if (nda[NDA_DST-1] == NULL ||
@@ -1360,18 +1359,28 @@ int neigh_delete(struct sk_buff *skb, st

if (ndm->ndm_flags&NTF_PROXY) {
err = pneigh_delete(tbl, RTA_DATA(nda[NDA_DST-1]), dev);
- goto out;
+ if(err) {
+ continue; /* maybe in another table */
+ }
+ else {
+ goto out;
+ }
}

- if (dev == NULL)
- return -EINVAL;
+ if (dev == NULL) {
+ goto out;
+ }

n = neigh_lookup(tbl, RTA_DATA(nda[NDA_DST-1]), dev);
if (n) {
err = neigh_update(n, NULL, NUD_FAILED, 1, 0);
neigh_release(n);
}
+ else {
+ continue; /* maybe in another table */
+ }
out:
+ read_unlock(&neigh_tbl_lock);
if (dev)
dev_put(dev);
return err;
@@ -1390,6 +1399,8 @@ int neigh_add(struct sk_buff *skb, struc
struct rtattr **nda = arg;
struct neigh_table *tbl;
struct net_device *dev = NULL;
+ int err = -EADDRNOTAVAIL;
+ int olderr;

if (ndm->ndm_ifindex) {
if ((dev = dev_get_by_index(ndm->ndm_ifindex)) == NULL)
@@ -1398,35 +1409,47 @@ int neigh_add(struct sk_buff *skb, struc

read_lock(&neigh_tbl_lock);
for (tbl=neigh_tables; tbl; tbl = tbl->next) {
- int err = 0;
int override = 1;
struct neighbour *n;

if (tbl->family != ndm->ndm_family)
continue;
- read_unlock(&neigh_tbl_lock);

- err = -EINVAL;
if (nda[NDA_DST-1] == NULL ||
- nda[NDA_DST-1]->rta_len != RTA_LENGTH(tbl->key_len))
+ nda[NDA_DST-1]->rta_len != RTA_LENGTH(tbl->key_len)) {
+ err = -EINVAL;
goto out;
+ }
+
if (ndm->ndm_flags&NTF_PROXY) {
err = -ENOBUFS;
- if (pneigh_lookup(tbl, RTA_DATA(nda[NDA_DST-1]), dev, 1))
+ if (pneigh_lookup(tbl, RTA_DATA(nda[NDA_DST-1]), dev, 1)) {
err = 0;
+ goto out;
+ }
+ else {
+ continue; /* maybe in another table */
+ }
+ }
+ if (dev == NULL) {
+ err = -EINVAL;
goto out;
}
- if (dev == NULL)
- return -EINVAL;
- err = -EINVAL;
+
if (nda[NDA_LLADDR-1] != NULL &&
- nda[NDA_LLADDR-1]->rta_len != RTA_LENGTH(dev->addr_len))
+ nda[NDA_LLADDR-1]->rta_len != RTA_LENGTH(dev->addr_len)) {
+ err = -EINVAL;
goto out;
+ }
+
+ olderr=err;
err = 0;
n = neigh_lookup(tbl, RTA_DATA(nda[NDA_DST-1]), dev);
if (n) {
- if (nlh->nlmsg_flags&NLM_F_EXCL)
+ if (nlh->nlmsg_flags&NLM_F_EXCL) {
err = -EEXIST;
+ goto outneigh;
+ }
override = nlh->nlmsg_flags&NLM_F_REPLACE;
} else if (!(nlh->nlmsg_flags&NLM_F_CREATE))
err = -ENOENT;
@@ -1442,9 +1465,16 @@ int neigh_add(struct sk_buff *skb, struc
ndm->ndm_state,
override, 0);
}
+ else {
+ err=olderr;
+ continue; /* maybe in another table */
+ }
+
+outneigh:
if (n)
neigh_release(n);
out:
+ read_unlock(&neigh_tbl_lock);
if (dev)
dev_put(dev);
return err;
@@ -1453,7 +1483,7 @@ out:

if (dev)
dev_put(dev);
- return -EADDRNOTAVAIL;
+ return err;
}


@@ -1547,8 +1577,7 @@ int neigh_dump_info(struct sk_buff *skb,
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;
+ neigh_dump_table(tbl, skb, cb);
}
read_unlock(&neigh_tbl_lock);
\
 
 \ /
  Last update: 2005-03-22 14:09    [W:0.084 / U:0.232 seconds]
©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site