linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / net / ipv4 / devinet.c
index dc62b78..9d713e0 100644 (file)
@@ -27,6 +27,7 @@
  *                                     if no match found.
  */
 
+#include <linux/config.h>
 
 #include <asm/uaccess.h>
 #include <asm/system.h>
@@ -80,7 +81,7 @@ static struct ipv4_devconf ipv4_devconf_dflt = {
 
 static void rtmsg_ifa(int event, struct in_ifaddr *);
 
-static BLOCKING_NOTIFIER_HEAD(inetaddr_chain);
+static struct notifier_block *inetaddr_chain;
 static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                         int destroy);
 #ifdef CONFIG_SYSCTL
@@ -93,9 +94,10 @@ static void devinet_sysctl_unregister(struct ipv4_devconf *p);
 
 static struct in_ifaddr *inet_alloc_ifa(void)
 {
-       struct in_ifaddr *ifa = kzalloc(sizeof(*ifa), GFP_KERNEL);
+       struct in_ifaddr *ifa = kmalloc(sizeof(*ifa), GFP_KERNEL);
 
        if (ifa) {
+               memset(ifa, 0, sizeof(*ifa));
                INIT_RCU_HEAD(&ifa->rcu_head);
        }
 
@@ -139,9 +141,10 @@ struct in_device *inetdev_init(struct net_device *dev)
 
        ASSERT_RTNL();
 
-       in_dev = kzalloc(sizeof(*in_dev), GFP_KERNEL);
+       in_dev = kmalloc(sizeof(*in_dev), GFP_KERNEL);
        if (!in_dev)
                goto out;
+       memset(in_dev, 0, sizeof(*in_dev));
        INIT_RCU_HEAD(&in_dev->rcu_head);
        memcpy(&in_dev->cnf, &ipv4_devconf_dflt, sizeof(in_dev->cnf));
        in_dev->cnf.sysctl = NULL;
@@ -155,9 +158,8 @@ struct in_device *inetdev_init(struct net_device *dev)
                              NET_IPV4_NEIGH, "ipv4", NULL, NULL);
 #endif
 
-       /* Account for reference dev->ip_ptr */
+       /* Account for reference dev->ip_ptr (below) */
        in_dev_hold(in_dev);
-       rcu_assign_pointer(dev->ip_ptr, in_dev);
 
 #ifdef CONFIG_SYSCTL
        devinet_sysctl_register(in_dev, &in_dev->cnf);
@@ -166,6 +168,8 @@ struct in_device *inetdev_init(struct net_device *dev)
        if (dev->flags & IFF_UP)
                ip_mc_up(in_dev);
 out:
+       /* we can receive as soon as ip_ptr is set -- do this last */
+       rcu_assign_pointer(dev->ip_ptr, in_dev);
        return in_dev;
 out_kfree:
        kfree(in_dev);
@@ -264,8 +268,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
                                *ifap1 = ifa->ifa_next;
 
                                rtmsg_ifa(RTM_DELADDR, ifa);
-                               blocking_notifier_call_chain(&inetaddr_chain,
-                                               NETDEV_DOWN, ifa);
+                               notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa);
                                inet_free_ifa(ifa);
                        } else {
                                promote = ifa;
@@ -289,7 +292,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
           So that, this order is correct.
         */
        rtmsg_ifa(RTM_DELADDR, ifa1);
-       blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
+       notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);
 
        if (promote) {
 
@@ -301,8 +304,7 @@ static void inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,
 
                promote->ifa_flags &= ~IFA_F_SECONDARY;
                rtmsg_ifa(RTM_NEWADDR, promote);
-               blocking_notifier_call_chain(&inetaddr_chain,
-                               NETDEV_UP, promote);
+               notifier_call_chain(&inetaddr_chain, NETDEV_UP, promote);
                for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) {
                        if (ifa1->ifa_mask != ifa->ifa_mask ||
                            !inet_ifa_match(ifa1->ifa_address, ifa))
@@ -365,7 +367,7 @@ static int inet_insert_ifa(struct in_ifaddr *ifa)
           Notifier will trigger FIB update, so that
           listeners of netlink will know about new ifaddr */
        rtmsg_ifa(RTM_NEWADDR, ifa);
-       blocking_notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
+       notifier_call_chain(&inetaddr_chain, NETDEV_UP, ifa);
 
        return 0;
 }
@@ -948,12 +950,12 @@ u32 inet_confirm_addr(const struct net_device *dev, u32 dst, u32 local, int scop
 
 int register_inetaddr_notifier(struct notifier_block *nb)
 {
-       return blocking_notifier_chain_register(&inetaddr_chain, nb);
+       return notifier_chain_register(&inetaddr_chain, nb);
 }
 
 int unregister_inetaddr_notifier(struct notifier_block *nb)
 {
-       return blocking_notifier_chain_unregister(&inetaddr_chain, nb);
+       return notifier_chain_unregister(&inetaddr_chain, nb);
 }
 
 /* Rename ifa_labels for a device name change. Make some effort to preserve existing
@@ -1407,14 +1409,6 @@ static struct devinet_sysctl_table {
                        .mode           = 0644,
                        .proc_handler   = &proc_dointvec,
                },
-               {
-                       .ctl_name       = NET_IPV4_CONF_ARP_ACCEPT,
-                       .procname       = "arp_accept",
-                       .data           = &ipv4_devconf.arp_accept,
-                       .maxlen         = sizeof(int),
-                       .mode           = 0644,
-                       .proc_handler   = &proc_dointvec,
-               },
                {
                        .ctl_name       = NET_IPV4_CONF_NOXFRM,
                        .procname       = "disable_xfrm",
@@ -1568,6 +1562,7 @@ void __init devinet_init(void)
 #endif
 }
 
+EXPORT_SYMBOL(devinet_ioctl);
 EXPORT_SYMBOL(in_dev_finish_destroy);
 EXPORT_SYMBOL(inet_select_addr);
 EXPORT_SYMBOL(inetdev_by_index);