[NEIGH]: Convert neighbour deletion to new netlink api
authorThomas Graf <tgraf@suug.ch>
Tue, 8 Aug 2006 00:53:08 +0000 (17:53 -0700)
committerDavid S. Miller <davem@sunset.davemloft.net>
Fri, 22 Sep 2006 21:53:58 +0000 (14:53 -0700)
Fixes:
  Return ENOENT if the neighbour is not found (was EINVAL)
  Return EAFNOSUPPORT if no table matches the specified
  address family.

Signed-off-by: Thomas Graf <tgraf@suug.ch>
Signed-off-by: David S. Miller <davem@davemloft.net>
net/core/neighbour.c

index fe2113f54e2b644a2b5685a34f154daadf437802..39c07cc66ee747224df7bc1e0aa10fcba9e78f22 100644 (file)
@@ -30,6 +30,7 @@
 #include <net/dst.h>
 #include <net/sock.h>
 #include <net/netevent.h>
+#include <net/netlink.h>
 #include <linux/rtnetlink.h>
 #include <linux/random.h>
 #include <linux/string.h>
@@ -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);