From 4f35aa254804c6d9bc818c52d2c25e0c220a1957 Mon Sep 17 00:00:00 2001 From: Thomas Graf Date: Mon, 7 Aug 2006 17:53:08 -0700 Subject: [PATCH] --- yaml --- r: 34431 b: refs/heads/master c: a14a49d2b7b9290e87751f21f503f1954267d4c4 h: refs/heads/master i: 34429: 15182511a0ebc0e8081e13bb05c3dadf34ad0e14 34427: 089d660b32463c5cd3f63711ae604ff389aa86da 34423: 8c3462db81c0be4f63632e08833ba8a716f2b5b7 34415: aae96758e9ba6b7cf31f1b871e92d9522bca51fd 34399: 0cc15d5c35eed7e3ca95324d9c400ca99932e35b 34367: 9701e74864ec69d4dfeb5978f16d1705503a3981 34303: 07eaf9d629c4a14e96fad32bca893228e0c2ddd2 v: v3 --- [refs] | 2 +- trunk/net/core/neighbour.c | 53 ++++++++++++++++++++++++-------------- 2 files changed, 35 insertions(+), 20 deletions(-) diff --git a/[refs] b/[refs] index be5e55cb084a..de8c907cb333 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: 3226f6881719e61e00e92b4c85a8ef49aa4d42b1 +refs/heads/master: a14a49d2b7b9290e87751f21f503f1954267d4c4 diff --git a/trunk/net/core/neighbour.c b/trunk/net/core/neighbour.c index fe2113f54e2b..39c07cc66ee7 100644 --- a/trunk/net/core/neighbour.c +++ b/trunk/net/core/neighbour.c @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -1440,48 +1441,62 @@ int neigh_table_clear(struct neigh_table *tbl) int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg) { - struct ndmsg *ndm = NLMSG_DATA(nlh); - struct rtattr **nda = arg; + struct ndmsg *ndm; + struct nlattr *dst_attr; struct neigh_table *tbl; struct net_device *dev = NULL; - int err = -ENODEV; + int err = -EINVAL; - if (ndm->ndm_ifindex && - (dev = dev_get_by_index(ndm->ndm_ifindex)) == NULL) + if (nlmsg_len(nlh) < sizeof(*ndm)) + goto out; + + dst_attr = nlmsg_find_attr(nlh, sizeof(*ndm), NDA_DST); + if (dst_attr == NULL) goto out; + ndm = nlmsg_data(nlh); + if (ndm->ndm_ifindex) { + dev = dev_get_by_index(ndm->ndm_ifindex); + if (dev == NULL) { + err = -ENODEV; + goto out; + } + } + read_lock(&neigh_tbl_lock); for (tbl = neigh_tables; tbl; tbl = tbl->next) { - struct rtattr *dst_attr = nda[NDA_DST - 1]; - struct neighbour *n; + struct neighbour *neigh; if (tbl->family != ndm->ndm_family) continue; read_unlock(&neigh_tbl_lock); - err = -EINVAL; - if (!dst_attr || RTA_PAYLOAD(dst_attr) < tbl->key_len) + if (nla_len(dst_attr) < tbl->key_len) goto out_dev_put; if (ndm->ndm_flags & NTF_PROXY) { - err = pneigh_delete(tbl, RTA_DATA(dst_attr), dev); + err = pneigh_delete(tbl, nla_data(dst_attr), dev); goto out_dev_put; } - if (!dev) - goto out; + if (dev == NULL) + goto out_dev_put; - n = neigh_lookup(tbl, RTA_DATA(dst_attr), dev); - if (n) { - err = neigh_update(n, NULL, NUD_FAILED, - NEIGH_UPDATE_F_OVERRIDE| - NEIGH_UPDATE_F_ADMIN); - neigh_release(n); + neigh = neigh_lookup(tbl, nla_data(dst_attr), dev); + if (neigh == NULL) { + err = -ENOENT; + goto out_dev_put; } + + err = neigh_update(neigh, NULL, NUD_FAILED, + NEIGH_UPDATE_F_OVERRIDE | + NEIGH_UPDATE_F_ADMIN); + neigh_release(neigh); goto out_dev_put; } read_unlock(&neigh_tbl_lock); - err = -EADDRNOTAVAIL; + err = -EAFNOSUPPORT; + out_dev_put: if (dev) dev_put(dev);