]> bbs.cooldavid.org Git - net-next-2.6.git/blobdiff - net/core/neighbour.c
[NET]: Move hardware header operations out of netdevice.
[net-next-2.6.git] / net / core / neighbour.c
index f7de8f24d8dd9a63b9d87bbdcd904333e6ba5b09..c52df858d0be10a597109bed466c860d1177e097 100644 (file)
@@ -25,6 +25,7 @@
 #include <linux/sysctl.h>
 #endif
 #include <linux/times.h>
+#include <net/net_namespace.h>
 #include <net/neighbour.h>
 #include <net/dst.h>
 #include <net/sock.h>
@@ -55,9 +56,8 @@
 #define PNEIGH_HASHMASK                0xF
 
 static void neigh_timer_handler(unsigned long arg);
-#ifdef CONFIG_ARPD
-static void neigh_app_notify(struct neighbour *n);
-#endif
+static void __neigh_notify(struct neighbour *n, int type, int flags);
+static void neigh_update_notify(struct neighbour *neigh);
 static int pneigh_ifdown(struct neigh_table *tbl, struct net_device *dev);
 void neigh_changeaddr(struct neigh_table *tbl, struct net_device *dev);
 
@@ -105,6 +105,15 @@ static int neigh_blackhole(struct sk_buff *skb)
        return -ENETDOWN;
 }
 
+static void neigh_cleanup_and_release(struct neighbour *neigh)
+{
+       if (neigh->parms->neigh_cleanup)
+               neigh->parms->neigh_cleanup(neigh);
+
+       __neigh_notify(neigh, RTM_DELNEIGH, 0);
+       neigh_release(neigh);
+}
+
 /*
  * It is random distribution in the interval (1/2)*base...(3/2)*base.
  * It corresponds to default IPv6 settings and is not overridable,
@@ -141,9 +150,7 @@ static int neigh_forced_gc(struct neigh_table *tbl)
                                n->dead = 1;
                                shrunk  = 1;
                                write_unlock(&n->lock);
-                               if (n->parms->neigh_cleanup)
-                                       n->parms->neigh_cleanup(n);
-                               neigh_release(n);
+                               neigh_cleanup_and_release(n);
                                continue;
                        }
                        write_unlock(&n->lock);
@@ -214,9 +221,7 @@ static void neigh_flush_dev(struct neigh_table *tbl, struct net_device *dev)
                                NEIGH_PRINTK2("neigh %p is stray.\n", n);
                        }
                        write_unlock(&n->lock);
-                       if (n->parms->neigh_cleanup)
-                               n->parms->neigh_cleanup(n);
-                       neigh_release(n);
+                       neigh_cleanup_and_release(n);
                }
        }
 }
@@ -677,9 +682,7 @@ static void neigh_periodic_timer(unsigned long arg)
                        *np = n->next;
                        n->dead = 1;
                        write_unlock(&n->lock);
-                       if (n->parms->neigh_cleanup)
-                               n->parms->neigh_cleanup(n);
-                       neigh_release(n);
+                       neigh_cleanup_and_release(n);
                        continue;
                }
                write_unlock(&n->lock);
@@ -828,13 +831,10 @@ static void neigh_timer_handler(unsigned long arg)
 out:
                write_unlock(&neigh->lock);
        }
+
        if (notify)
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
+               neigh_update_notify(neigh);
 
-#ifdef CONFIG_ARPD
-       if (notify && neigh->parms->app_probes)
-               neigh_app_notify(neigh);
-#endif
        neigh_release(neigh);
 }
 
@@ -897,8 +897,8 @@ out_unlock_bh:
 static void neigh_update_hhs(struct neighbour *neigh)
 {
        struct hh_cache *hh;
-       void (*update)(struct hh_cache*, struct net_device*, unsigned char *) =
-               neigh->dev->header_cache_update;
+       void (*update)(struct hh_cache*, const struct net_device*, const unsigned char *)
+               = neigh->dev->header_ops->cache_update;
 
        if (update) {
                for (hh = neigh->hh; hh; hh = hh->hh_next) {
@@ -1063,11 +1063,8 @@ out:
        write_unlock_bh(&neigh->lock);
 
        if (notify)
-               call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
-#ifdef CONFIG_ARPD
-       if (notify && neigh->parms->app_probes)
-               neigh_app_notify(neigh);
-#endif
+               neigh_update_notify(neigh);
+
        return err;
 }
 
@@ -1098,7 +1095,8 @@ static void neigh_hh_init(struct neighbour *n, struct dst_entry *dst,
                hh->hh_type = protocol;
                atomic_set(&hh->hh_refcnt, 0);
                hh->hh_next = NULL;
-               if (dev->hard_header_cache(n, hh)) {
+
+               if (dev->header_ops->cache(n, hh)) {
                        kfree(hh);
                        hh = NULL;
                } else {
@@ -1128,10 +1126,9 @@ int neigh_compat_output(struct sk_buff *skb)
 
        __skb_pull(skb, skb_network_offset(skb));
 
-       if (dev->hard_header &&
-           dev->hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
-                            skb->len) < 0 &&
-           dev->rebuild_header(skb))
+       if (dev_hard_header(skb, dev, ntohs(skb->protocol), NULL, NULL,
+                           skb->len) < 0 &&
+           dev->header_ops->rebuild(skb))
                return 0;
 
        return dev_queue_xmit(skb);
@@ -1153,17 +1150,17 @@ int neigh_resolve_output(struct sk_buff *skb)
        if (!neigh_event_send(neigh, skb)) {
                int err;
                struct net_device *dev = neigh->dev;
-               if (dev->hard_header_cache && !dst->hh) {
+               if (dev->header_ops->cache && !dst->hh) {
                        write_lock_bh(&neigh->lock);
                        if (!dst->hh)
                                neigh_hh_init(neigh, dst, dst->ops->protocol);
-                       err = dev->hard_header(skb, dev, ntohs(skb->protocol),
-                                              neigh->ha, NULL, skb->len);
+                       err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+                                             neigh->ha, NULL, skb->len);
                        write_unlock_bh(&neigh->lock);
                } else {
                        read_lock_bh(&neigh->lock);
-                       err = dev->hard_header(skb, dev, ntohs(skb->protocol),
-                                              neigh->ha, NULL, skb->len);
+                       err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+                                             neigh->ha, NULL, skb->len);
                        read_unlock_bh(&neigh->lock);
                }
                if (err >= 0)
@@ -1194,8 +1191,8 @@ int neigh_connected_output(struct sk_buff *skb)
        __skb_pull(skb, skb_network_offset(skb));
 
        read_lock_bh(&neigh->lock);
-       err = dev->hard_header(skb, dev, ntohs(skb->protocol),
-                              neigh->ha, NULL, skb->len);
+       err = dev_hard_header(skb, dev, ntohs(skb->protocol),
+                             neigh->ha, NULL, skb->len);
        read_unlock_bh(&neigh->lock);
        if (err >= 0)
                err = neigh->ops->queue_xmit(skb);
@@ -1354,7 +1351,7 @@ void neigh_table_init_no_netlink(struct neigh_table *tbl)
                panic("cannot create neighbour cache statistics");
 
 #ifdef CONFIG_PROC_FS
-       tbl->pde = create_proc_entry(tbl->id, 0, proc_net_stat);
+       tbl->pde = create_proc_entry(tbl->id, 0, init_net.proc_net_stat);
        if (!tbl->pde)
                panic("cannot create neighbour proc dir entry");
        tbl->pde->proc_fops = &neigh_stat_seq_fops;
@@ -1444,6 +1441,7 @@ int neigh_table_clear(struct neigh_table *tbl)
 
 static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct ndmsg *ndm;
        struct nlattr *dst_attr;
        struct neigh_table *tbl;
@@ -1459,7 +1457,7 @@ static int neigh_delete(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
        ndm = nlmsg_data(nlh);
        if (ndm->ndm_ifindex) {
-               dev = dev_get_by_index(ndm->ndm_ifindex);
+               dev = dev_get_by_index(net, ndm->ndm_ifindex);
                if (dev == NULL) {
                        err = -ENODEV;
                        goto out;
@@ -1509,6 +1507,7 @@ out:
 
 static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 {
+       struct net *net = skb->sk->sk_net;
        struct ndmsg *ndm;
        struct nlattr *tb[NDA_MAX+1];
        struct neigh_table *tbl;
@@ -1525,7 +1524,7 @@ static int neigh_add(struct sk_buff *skb, struct nlmsghdr *nlh, void *arg)
 
        ndm = nlmsg_data(nlh);
        if (ndm->ndm_ifindex) {
-               dev = dev_get_by_index(ndm->ndm_ifindex);
+               dev = dev_get_by_index(net, ndm->ndm_ifindex);
                if (dev == NULL) {
                        err = -ENODEV;
                        goto out;
@@ -2000,6 +1999,11 @@ nla_put_failure:
        return -EMSGSIZE;
 }
 
+static void neigh_update_notify(struct neighbour *neigh)
+{
+       call_netevent_notifiers(NETEVENT_NEIGH_UPDATE, neigh);
+       __neigh_notify(neigh, RTM_NEWNEIGH, 0);
+}
 
 static int neigh_dump_table(struct neigh_table *tbl, struct sk_buff *skb,
                            struct netlink_callback *cb)
@@ -2095,11 +2099,8 @@ void __neigh_for_each_release(struct neigh_table *tbl,
                        } else
                                np = &n->next;
                        write_unlock(&n->lock);
-                       if (release) {
-                               if (n->parms->neigh_cleanup)
-                                       n->parms->neigh_cleanup(n);
-                               neigh_release(n);
-                       }
+                       if (release)
+                               neigh_cleanup_and_release(n);
                }
        }
 }
@@ -2422,7 +2423,6 @@ static const struct file_operations neigh_stat_seq_fops = {
 
 #endif /* CONFIG_PROC_FS */
 
-#ifdef CONFIG_ARPD
 static inline size_t neigh_nlmsg_size(void)
 {
        return NLMSG_ALIGN(sizeof(struct ndmsg))
@@ -2454,16 +2454,11 @@ errout:
                rtnl_set_sk_err(RTNLGRP_NEIGH, err);
 }
 
+#ifdef CONFIG_ARPD
 void neigh_app_ns(struct neighbour *n)
 {
        __neigh_notify(n, RTM_GETNEIGH, NLM_F_REQUEST);
 }
-
-static void neigh_app_notify(struct neighbour *n)
-{
-       __neigh_notify(n, RTM_NEWNEIGH, 0);
-}
-
 #endif /* CONFIG_ARPD */
 
 #ifdef CONFIG_SYSCTL