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);
ip_mc_init_dev(in_dev);
if (dev->flags & IFF_UP)
ip_mc_up(in_dev);
+
+ /* we can receive as soon as ip_ptr is set -- do this last */
+ rcu_assign_pointer(dev->ip_ptr, in_dev);
out:
return in_dev;
out_kfree:
* Determine a default network mask, based on the IP address.
*/
-static __inline__ int inet_abc_len(u32 addr)
+static __inline__ int inet_abc_len(__be32 addr)
{
int rc = -1; /* Something else, probably a multicast. */
if (ZERONET(addr))
rc = 0;
else {
- addr = ntohl(addr);
+ __u32 haddr = ntohl(addr);
- if (IN_CLASSA(addr))
+ if (IN_CLASSA(haddr))
rc = 8;
- else if (IN_CLASSB(addr))
+ else if (IN_CLASSB(haddr))
rc = 16;
- else if (IN_CLASSC(addr))
+ else if (IN_CLASSC(haddr))
rc = 24;
}
int ipv4_doint_and_flush_strategy(ctl_table *table, int __user *name, int nlen,
void __user *oldval, size_t __user *oldlenp,
- void __user *newval, size_t newlen,
- void **context)
+ void __user *newval, size_t newlen)
{
int *valp = table->data;
int new;
{
int i;
struct net_device *dev = in_dev ? in_dev->dev : NULL;
- struct devinet_sysctl_table *t = kmalloc(sizeof(*t), GFP_KERNEL);
+ struct devinet_sysctl_table *t = kmemdup(&devinet_sysctl, sizeof(*t),
+ GFP_KERNEL);
char *dev_name = NULL;
if (!t)
return;
- memcpy(t, &devinet_sysctl, sizeof(*t));
for (i = 0; i < ARRAY_SIZE(t->devinet_vars) - 1; i++) {
t->devinet_vars[i].data += (char *)p - (char *)&ipv4_devconf;
t->devinet_vars[i].de = NULL;