mac80211: fix ie memory allocation for scheduled scans
[pandora-kernel.git] / net / ipv6 / addrconf.c
index a7bda07..498b927 100644 (file)
@@ -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;
        }
 }