diff options
Diffstat (limited to 'net/ipv6/addrconf.c')
| -rw-r--r-- | net/ipv6/addrconf.c | 60 | 
1 files changed, 25 insertions, 35 deletions
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c index 1493534116d..498b927f68b 100644 --- a/net/ipv6/addrconf.c +++ b/net/ipv6/addrconf.c @@ -289,19 +289,19 @@ static int snmp6_alloc_dev(struct inet6_dev *idev)  			  sizeof(struct ipstats_mib),  			  __alignof__(struct ipstats_mib)) < 0)  		goto err_ip; -	if (snmp_mib_init((void __percpu **)idev->stats.icmpv6, -			  sizeof(struct icmpv6_mib), -			  __alignof__(struct icmpv6_mib)) < 0) +	idev->stats.icmpv6dev = kzalloc(sizeof(struct icmpv6_mib_device), +					GFP_KERNEL); +	if (!idev->stats.icmpv6dev)  		goto err_icmp; -	if (snmp_mib_init((void __percpu **)idev->stats.icmpv6msg, -			  sizeof(struct icmpv6msg_mib), -			  __alignof__(struct icmpv6msg_mib)) < 0) +	idev->stats.icmpv6msgdev = kzalloc(sizeof(struct icmpv6msg_mib_device), +					   GFP_KERNEL); +	if (!idev->stats.icmpv6msgdev)  		goto err_icmpmsg;  	return 0;  err_icmpmsg: -	snmp_mib_free((void __percpu **)idev->stats.icmpv6); +	kfree(idev->stats.icmpv6dev);  err_icmp:  	snmp_mib_free((void __percpu **)idev->stats.ipv6);  err_ip: @@ -310,19 +310,13 @@ err_ip:  static void snmp6_free_dev(struct inet6_dev *idev)  { -	snmp_mib_free((void __percpu **)idev->stats.icmpv6msg); -	snmp_mib_free((void __percpu **)idev->stats.icmpv6); +	kfree(idev->stats.icmpv6msgdev); +	kfree(idev->stats.icmpv6dev);  	snmp_mib_free((void __percpu **)idev->stats.ipv6);  }  /* Nobody refers to this device, we may destroy it. */ -static void in6_dev_finish_destroy_rcu(struct rcu_head *head) -{ -	struct inet6_dev *idev = container_of(head, struct inet6_dev, rcu); -	kfree(idev); -} -  void in6_dev_finish_destroy(struct inet6_dev *idev)  {  	struct net_device *dev = idev->dev; @@ -339,7 +333,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev)  		return;  	}  	snmp6_free_dev(idev); -	call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); +	kfree_rcu(idev, rcu);  }  EXPORT_SYMBOL(in6_dev_finish_destroy); @@ -535,12 +529,6 @@ static int addrconf_fixup_forwarding(struct ctl_table *table, int *p, int old)  }  #endif -static void inet6_ifa_finish_destroy_rcu(struct rcu_head *head) -{ -	struct inet6_ifaddr *ifp = container_of(head, struct inet6_ifaddr, rcu); -	kfree(ifp); -} -  /* Nobody refers to this ifaddr, destroy it */  void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)  { @@ -561,7 +549,7 @@ void inet6_ifa_finish_destroy(struct inet6_ifaddr *ifp)  	}  	dst_release(&ifp->rt->dst); -	call_rcu(&ifp->rcu, inet6_ifa_finish_destroy_rcu); +	kfree_rcu(ifp, rcu);  }  static void @@ -825,6 +813,8 @@ static void ipv6_del_addr(struct inet6_ifaddr *ifp)  		dst_release(&rt->dst);  	} +	/* clean up prefsrc entries */ +	rt6_remove_prefsrc(ifp);  out:  	in6_ifa_put(ifp);  } @@ -1281,7 +1271,7 @@ static int ipv6_count_addresses(struct inet6_dev *idev)  	return cnt;  } -int ipv6_chk_addr(struct net *net, struct in6_addr *addr, +int ipv6_chk_addr(struct net *net, const struct in6_addr *addr,  		  struct net_device *dev, int strict)  {  	struct inet6_ifaddr *ifp; @@ -1324,7 +1314,7 @@ static bool ipv6_chk_same_addr(struct net *net, const struct in6_addr *addr,  	return false;  } -int ipv6_chk_prefix(struct in6_addr *addr, struct net_device *dev) +int ipv6_chk_prefix(const struct in6_addr *addr, struct net_device *dev)  {  	struct inet6_dev *idev;  	struct inet6_ifaddr *ifa; @@ -1455,7 +1445,7 @@ void addrconf_dad_failure(struct inet6_ifaddr *ifp)  /* Join to solicited addr multicast group. */ -void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr) +void addrconf_join_solict(struct net_device *dev, const struct in6_addr *addr)  {  	struct in6_addr maddr; @@ -1466,7 +1456,7 @@ void addrconf_join_solict(struct net_device *dev, struct in6_addr *addr)  	ipv6_dev_mc_inc(dev, &maddr);  } -void addrconf_leave_solict(struct inet6_dev *idev, struct in6_addr *addr) +void addrconf_leave_solict(struct inet6_dev *idev, const struct in6_addr *addr)  {  	struct in6_addr maddr; @@ -2111,7 +2101,7 @@ err_exit:  /*   *	Manual configuration of address on an interface   */ -static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx, +static int inet6_addr_add(struct net *net, int ifindex, const struct in6_addr *pfx,  			  unsigned int plen, __u8 ifa_flags, __u32 prefered_lft,  			  __u32 valid_lft)  { @@ -2185,7 +2175,7 @@ static int inet6_addr_add(struct net *net, int ifindex, struct in6_addr *pfx,  	return PTR_ERR(ifp);  } -static int inet6_addr_del(struct net *net, int ifindex, struct in6_addr *pfx, +static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx,  			  unsigned int plen)  {  	struct inet6_ifaddr *ifp; @@ -2348,7 +2338,7 @@ static void init_loopback(struct net_device *dev)  	add_addr(idev, &in6addr_loopback, 128, IFA_HOST);  } -static void addrconf_add_linklocal(struct inet6_dev *idev, struct in6_addr *addr) +static void addrconf_add_linklocal(struct inet6_dev *idev, const struct in6_addr *addr)  {  	struct inet6_ifaddr * ifp;  	u32 addr_flags = IFA_F_PERMANENT; @@ -3119,7 +3109,7 @@ void if6_proc_exit(void)  #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)  /* Check if address is a home address configured on any interface. */ -int ipv6_chk_home_addr(struct net *net, struct in6_addr *addr) +int ipv6_chk_home_addr(struct net *net, const struct in6_addr *addr)  {  	int ret = 0;  	struct inet6_ifaddr *ifp = NULL; @@ -3836,7 +3826,7 @@ static inline size_t inet6_if_nlmsg_size(void)  	       + nla_total_size(inet6_ifla6_size()); /* IFLA_PROTINFO */  } -static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib, +static inline void __snmp6_fill_statsdev(u64 *stats, atomic_long_t *mib,  				      int items, int bytes)  {  	int i; @@ -3846,7 +3836,7 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,  	/* Use put_unaligned() because stats may not be aligned for u64. */  	put_unaligned(items, &stats[0]);  	for (i = 1; i < items; i++) -		put_unaligned(snmp_fold_field(mib, i), &stats[i]); +		put_unaligned(atomic_long_read(&mib[i]), &stats[i]);  	memset(&stats[items], 0, pad);  } @@ -3875,7 +3865,7 @@ static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,  				     IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp));  		break;  	case IFLA_INET6_ICMP6STATS: -		__snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes); +		__snmp6_fill_statsdev(stats, idev->stats.icmpv6dev->mibs, ICMP6_MIB_MAX, bytes);  		break;  	}  } @@ -4537,7 +4527,7 @@ static void __addrconf_sysctl_unregister(struct ipv6_devconf *p)  	t = p->sysctl;  	p->sysctl = NULL; -	unregister_sysctl_table(t->sysctl_header); +	unregister_net_sysctl_table(t->sysctl_header);  	kfree(t->dev_name);  	kfree(t);  }  |