* if no match found.
*/
+#include <linux/config.h>
#include <asm/uaccess.h>
#include <asm/system.h>
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
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);
}
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;
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);
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);
*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;
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) {
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))
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;
}
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
.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",
#endif
}
+EXPORT_SYMBOL(devinet_ioctl);
EXPORT_SYMBOL(in_dev_finish_destroy);
EXPORT_SYMBOL(inet_select_addr);
EXPORT_SYMBOL(inetdev_by_index);