Loading include/net/addrconf.h +4 −6 Original line number Diff line number Diff line Loading @@ -133,20 +133,18 @@ extern int unregister_inet6addr_notifier(struct notifier_block *nb); static inline struct inet6_dev * __in6_dev_get(struct net_device *dev) { return (struct inet6_dev *)dev->ip6_ptr; return rcu_dereference(dev->ip6_ptr); } extern rwlock_t addrconf_lock; static inline struct inet6_dev * in6_dev_get(struct net_device *dev) { struct inet6_dev *idev = NULL; read_lock(&addrconf_lock); idev = dev->ip6_ptr; rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) atomic_inc(&idev->refcnt); read_unlock(&addrconf_lock); rcu_read_unlock(); return idev; } Loading include/net/if_inet6.h +1 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ struct inet6_dev struct ipv6_devconf cnf; struct ipv6_devstat stats; unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ struct rcu_head rcu; }; extern struct ipv6_devconf ipv6_devconf; Loading net/core/pktgen.c +2 −2 Original line number Diff line number Diff line Loading @@ -1786,7 +1786,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) * use ipv6_get_lladdr if/when it's get exported */ read_lock(&addrconf_lock); rcu_read_lock(); if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { struct inet6_ifaddr *ifp; Loading @@ -1805,7 +1805,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); if (err) printk("pktgen: ERROR: IPv6 link address not availble.\n"); } Loading net/ipv6/addrconf.c +24 −22 Original line number Diff line number Diff line Loading @@ -119,9 +119,6 @@ static int ipv6_count_addresses(struct inet6_dev *idev); static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE]; static DEFINE_RWLOCK(addrconf_hash_lock); /* Protects inet6 devices */ DEFINE_RWLOCK(addrconf_lock); static void addrconf_verify(unsigned long); static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0); Loading Loading @@ -318,6 +315,12 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp, /* 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; Loading @@ -332,7 +335,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) return; } snmp6_free_dev(idev); kfree(idev); call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); } static struct inet6_dev * ipv6_add_dev(struct net_device *dev) Loading Loading @@ -408,9 +411,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) if (netif_carrier_ok(dev)) ndev->if_flags |= IF_READY; write_lock_bh(&addrconf_lock); dev->ip6_ptr = ndev; write_unlock_bh(&addrconf_lock); /* protected by rtnl_lock */ rcu_assign_pointer(dev->ip6_ptr, ndev); ipv6_mc_init_dev(ndev); ndev->tstamp = jiffies; Loading Loading @@ -474,7 +476,7 @@ static void addrconf_forward_change(void) read_lock(&dev_base_lock); for (dev=dev_base; dev; dev=dev->next) { read_lock(&addrconf_lock); rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding); Loading @@ -482,7 +484,7 @@ static void addrconf_forward_change(void) if (changed) dev_forward_change(idev); } read_unlock(&addrconf_lock); rcu_read_unlock(); } read_unlock(&dev_base_lock); } Loading Loading @@ -543,7 +545,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, int hash; int err = 0; read_lock_bh(&addrconf_lock); rcu_read_lock_bh(); if (idev->dead) { err = -ENODEV; /*XXX*/ goto out2; Loading Loading @@ -612,7 +614,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, in6_ifa_hold(ifa); write_unlock(&idev->lock); out2: read_unlock_bh(&addrconf_lock); rcu_read_unlock_bh(); if (likely(err == 0)) atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); Loading Loading @@ -915,7 +917,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, memset(&hiscore, 0, sizeof(hiscore)); read_lock(&dev_base_lock); read_lock(&addrconf_lock); rcu_read_lock(); for (dev = dev_base; dev; dev=dev->next) { struct inet6_dev *idev; Loading Loading @@ -1127,7 +1129,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); read_unlock(&dev_base_lock); if (!ifa_result) Loading @@ -1151,7 +1153,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) struct inet6_dev *idev; int err = -EADDRNOTAVAIL; read_lock(&addrconf_lock); rcu_read_lock(); if ((idev = __in6_dev_get(dev)) != NULL) { struct inet6_ifaddr *ifp; Loading @@ -1165,7 +1167,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); return err; } Loading Loading @@ -1466,7 +1468,7 @@ static void ipv6_regen_rndid(unsigned long data) struct inet6_dev *idev = (struct inet6_dev *) data; unsigned long expires; read_lock_bh(&addrconf_lock); rcu_read_lock_bh(); write_lock_bh(&idev->lock); if (idev->dead) Loading @@ -1490,7 +1492,7 @@ static void ipv6_regen_rndid(unsigned long data) out: write_unlock_bh(&idev->lock); read_unlock_bh(&addrconf_lock); rcu_read_unlock_bh(); in6_dev_put(idev); } Loading Loading @@ -2342,10 +2344,10 @@ static int addrconf_ifdown(struct net_device *dev, int how) Do not dev_put! */ if (how == 1) { write_lock_bh(&addrconf_lock); dev->ip6_ptr = NULL; idev->dead = 1; write_unlock_bh(&addrconf_lock); /* protected by rtnl_lock */ rcu_assign_pointer(dev->ip6_ptr, NULL); /* Step 1.5: remove snmp6 entry */ snmp6_unregister_dev(idev); Loading Loading @@ -3573,10 +3575,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) { read_lock_bh(&addrconf_lock); rcu_read_lock_bh(); if (likely(ifp->idev->dead == 0)) __ipv6_ifa_notify(event, ifp); read_unlock_bh(&addrconf_lock); rcu_read_unlock_bh(); } #ifdef CONFIG_SYSCTL Loading net/ipv6/anycast.c +2 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev) int onlink; onlink = 0; read_lock(&addrconf_lock); rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { read_lock_bh(&idev->lock); Loading @@ -68,7 +68,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev) } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); return onlink; } Loading Loading
include/net/addrconf.h +4 −6 Original line number Diff line number Diff line Loading @@ -133,20 +133,18 @@ extern int unregister_inet6addr_notifier(struct notifier_block *nb); static inline struct inet6_dev * __in6_dev_get(struct net_device *dev) { return (struct inet6_dev *)dev->ip6_ptr; return rcu_dereference(dev->ip6_ptr); } extern rwlock_t addrconf_lock; static inline struct inet6_dev * in6_dev_get(struct net_device *dev) { struct inet6_dev *idev = NULL; read_lock(&addrconf_lock); idev = dev->ip6_ptr; rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) atomic_inc(&idev->refcnt); read_unlock(&addrconf_lock); rcu_read_unlock(); return idev; } Loading
include/net/if_inet6.h +1 −0 Original line number Diff line number Diff line Loading @@ -189,6 +189,7 @@ struct inet6_dev struct ipv6_devconf cnf; struct ipv6_devstat stats; unsigned long tstamp; /* ipv6InterfaceTable update timestamp */ struct rcu_head rcu; }; extern struct ipv6_devconf ipv6_devconf; Loading
net/core/pktgen.c +2 −2 Original line number Diff line number Diff line Loading @@ -1786,7 +1786,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) * use ipv6_get_lladdr if/when it's get exported */ read_lock(&addrconf_lock); rcu_read_lock(); if ((idev = __in6_dev_get(pkt_dev->odev)) != NULL) { struct inet6_ifaddr *ifp; Loading @@ -1805,7 +1805,7 @@ static void pktgen_setup_inject(struct pktgen_dev *pkt_dev) } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); if (err) printk("pktgen: ERROR: IPv6 link address not availble.\n"); } Loading
net/ipv6/addrconf.c +24 −22 Original line number Diff line number Diff line Loading @@ -119,9 +119,6 @@ static int ipv6_count_addresses(struct inet6_dev *idev); static struct inet6_ifaddr *inet6_addr_lst[IN6_ADDR_HSIZE]; static DEFINE_RWLOCK(addrconf_hash_lock); /* Protects inet6 devices */ DEFINE_RWLOCK(addrconf_lock); static void addrconf_verify(unsigned long); static DEFINE_TIMER(addr_chk_timer, addrconf_verify, 0, 0); Loading Loading @@ -318,6 +315,12 @@ static void addrconf_mod_timer(struct inet6_ifaddr *ifp, /* 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; Loading @@ -332,7 +335,7 @@ void in6_dev_finish_destroy(struct inet6_dev *idev) return; } snmp6_free_dev(idev); kfree(idev); call_rcu(&idev->rcu, in6_dev_finish_destroy_rcu); } static struct inet6_dev * ipv6_add_dev(struct net_device *dev) Loading Loading @@ -408,9 +411,8 @@ static struct inet6_dev * ipv6_add_dev(struct net_device *dev) if (netif_carrier_ok(dev)) ndev->if_flags |= IF_READY; write_lock_bh(&addrconf_lock); dev->ip6_ptr = ndev; write_unlock_bh(&addrconf_lock); /* protected by rtnl_lock */ rcu_assign_pointer(dev->ip6_ptr, ndev); ipv6_mc_init_dev(ndev); ndev->tstamp = jiffies; Loading Loading @@ -474,7 +476,7 @@ static void addrconf_forward_change(void) read_lock(&dev_base_lock); for (dev=dev_base; dev; dev=dev->next) { read_lock(&addrconf_lock); rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { int changed = (!idev->cnf.forwarding) ^ (!ipv6_devconf.forwarding); Loading @@ -482,7 +484,7 @@ static void addrconf_forward_change(void) if (changed) dev_forward_change(idev); } read_unlock(&addrconf_lock); rcu_read_unlock(); } read_unlock(&dev_base_lock); } Loading Loading @@ -543,7 +545,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, int hash; int err = 0; read_lock_bh(&addrconf_lock); rcu_read_lock_bh(); if (idev->dead) { err = -ENODEV; /*XXX*/ goto out2; Loading Loading @@ -612,7 +614,7 @@ ipv6_add_addr(struct inet6_dev *idev, const struct in6_addr *addr, int pfxlen, in6_ifa_hold(ifa); write_unlock(&idev->lock); out2: read_unlock_bh(&addrconf_lock); rcu_read_unlock_bh(); if (likely(err == 0)) atomic_notifier_call_chain(&inet6addr_chain, NETDEV_UP, ifa); Loading Loading @@ -915,7 +917,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, memset(&hiscore, 0, sizeof(hiscore)); read_lock(&dev_base_lock); read_lock(&addrconf_lock); rcu_read_lock(); for (dev = dev_base; dev; dev=dev->next) { struct inet6_dev *idev; Loading Loading @@ -1127,7 +1129,7 @@ int ipv6_dev_get_saddr(struct net_device *daddr_dev, } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); read_unlock(&dev_base_lock); if (!ifa_result) Loading @@ -1151,7 +1153,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) struct inet6_dev *idev; int err = -EADDRNOTAVAIL; read_lock(&addrconf_lock); rcu_read_lock(); if ((idev = __in6_dev_get(dev)) != NULL) { struct inet6_ifaddr *ifp; Loading @@ -1165,7 +1167,7 @@ int ipv6_get_lladdr(struct net_device *dev, struct in6_addr *addr) } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); return err; } Loading Loading @@ -1466,7 +1468,7 @@ static void ipv6_regen_rndid(unsigned long data) struct inet6_dev *idev = (struct inet6_dev *) data; unsigned long expires; read_lock_bh(&addrconf_lock); rcu_read_lock_bh(); write_lock_bh(&idev->lock); if (idev->dead) Loading @@ -1490,7 +1492,7 @@ static void ipv6_regen_rndid(unsigned long data) out: write_unlock_bh(&idev->lock); read_unlock_bh(&addrconf_lock); rcu_read_unlock_bh(); in6_dev_put(idev); } Loading Loading @@ -2342,10 +2344,10 @@ static int addrconf_ifdown(struct net_device *dev, int how) Do not dev_put! */ if (how == 1) { write_lock_bh(&addrconf_lock); dev->ip6_ptr = NULL; idev->dead = 1; write_unlock_bh(&addrconf_lock); /* protected by rtnl_lock */ rcu_assign_pointer(dev->ip6_ptr, NULL); /* Step 1.5: remove snmp6 entry */ snmp6_unregister_dev(idev); Loading Loading @@ -3573,10 +3575,10 @@ static void __ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) static void ipv6_ifa_notify(int event, struct inet6_ifaddr *ifp) { read_lock_bh(&addrconf_lock); rcu_read_lock_bh(); if (likely(ifp->idev->dead == 0)) __ipv6_ifa_notify(event, ifp); read_unlock_bh(&addrconf_lock); rcu_read_unlock_bh(); } #ifdef CONFIG_SYSCTL Loading
net/ipv6/anycast.c +2 −2 Original line number Diff line number Diff line Loading @@ -56,7 +56,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev) int onlink; onlink = 0; read_lock(&addrconf_lock); rcu_read_lock(); idev = __in6_dev_get(dev); if (idev) { read_lock_bh(&idev->lock); Loading @@ -68,7 +68,7 @@ ip6_onlink(struct in6_addr *addr, struct net_device *dev) } read_unlock_bh(&idev->lock); } read_unlock(&addrconf_lock); rcu_read_unlock(); return onlink; } Loading