Commit 87f3a4c3 authored by Thomas Graf's avatar Thomas Graf Committed by David S. Miller

[NEIGH]: rtnetlink neighbour cleanups

Signed-off-by: default avatarThomas Graf <tgraf@suug.ch>
Acked-by: default avatarHideaki YOSHIFUJI <yoshfuji@linux-ipv6.org>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent c99be4f8
......@@ -1430,6 +1430,7 @@ int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
read_lock(&neigh_tbl_lock);
for (tbl = neigh_tables; tbl; tbl = tbl->next) {
struct rtattr *dst_attr = nda[NDA_DST - 1];
struct neighbour *n;
if (tbl->family != ndm->ndm_family)
......@@ -1437,20 +1438,18 @@ int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
read_unlock(&neigh_tbl_lock);
err = -EINVAL;
if (!nda[NDA_DST - 1] ||
nda[NDA_DST - 1]->rta_len != RTA_LENGTH(tbl->key_len))
if (!dst_attr || RTA_PAYLOAD(dst_attr) < tbl->key_len)
goto out_dev_put;
if (ndm->ndm_flags & NTF_PROXY) {
err = pneigh_delete(tbl,
RTA_DATA(nda[NDA_DST - 1]), dev);
err = pneigh_delete(tbl, RTA_DATA(dst_attr), dev);
goto out_dev_put;
}
if (!dev)
goto out;
n = neigh_lookup(tbl, RTA_DATA(nda[NDA_DST - 1]), dev);
n = neigh_lookup(tbl, RTA_DATA(dst_attr), dev);
if (n) {
err = neigh_update(n, NULL, NUD_FAILED,
NEIGH_UPDATE_F_OVERRIDE|
......@@ -1482,6 +1481,8 @@ int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
read_lock(&neigh_tbl_lock);
for (tbl = neigh_tables; tbl; tbl = tbl->next) {
struct rtattr *lladdr_attr = nda[NDA_LLADDR - 1];
struct rtattr *dst_attr = nda[NDA_DST - 1];
int override = 1;
struct neighbour *n;
......@@ -1490,48 +1491,49 @@ int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
read_unlock(&neigh_tbl_lock);
err = -EINVAL;
if (!nda[NDA_DST - 1] ||
nda[NDA_DST - 1]->rta_len != RTA_LENGTH(tbl->key_len))
if (!dst_attr || RTA_PAYLOAD(dst_attr) < tbl->key_len)
goto out_dev_put;
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(dst_attr), dev, 1))
err = 0;
goto out_dev_put;
}
err = -EINVAL;
if (!dev)
goto out;
if (nda[NDA_LLADDR - 1] &&
nda[NDA_LLADDR - 1]->rta_len != RTA_LENGTH(dev->addr_len))
if (lladdr_attr && RTA_PAYLOAD(lladdr_attr) < dev->addr_len)
goto out_dev_put;
err = 0;
n = neigh_lookup(tbl, RTA_DATA(nda[NDA_DST - 1]), dev);
n = neigh_lookup(tbl, RTA_DATA(dst_attr), dev);
if (n) {
if (nlh->nlmsg_flags & NLM_F_EXCL)
if (nlh->nlmsg_flags & NLM_F_EXCL) {
err = -EEXIST;
neigh_release(n);
goto out_dev_put;
}
override = nlh->nlmsg_flags & NLM_F_REPLACE;
} else if (!(nlh->nlmsg_flags & NLM_F_CREATE))
} else if (!(nlh->nlmsg_flags & NLM_F_CREATE)) {
err = -ENOENT;
else {
n = __neigh_lookup_errno(tbl, RTA_DATA(nda[NDA_DST - 1]),
dev);
goto out_dev_put;
} else {
n = __neigh_lookup_errno(tbl, RTA_DATA(dst_attr), dev);
if (IS_ERR(n)) {
err = PTR_ERR(n);
n = NULL;
goto out_dev_put;
}
}
if (!err) {
err = neigh_update(n, nda[NDA_LLADDR - 1] ?
RTA_DATA(nda[NDA_LLADDR - 1]) :
NULL,
ndm->ndm_state,
(override ? NEIGH_UPDATE_F_OVERRIDE : 0) |
NEIGH_UPDATE_F_ADMIN);
}
if (n)
neigh_release(n);
err = neigh_update(n,
lladdr_attr ? RTA_DATA(lladdr_attr) : NULL,
ndm->ndm_state,
(override ? NEIGH_UPDATE_F_OVERRIDE : 0) |
NEIGH_UPDATE_F_ADMIN);
neigh_release(n);
goto out_dev_put;
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment