diff options
| -rw-r--r-- | drivers/net/can/c_can/c_can.c | 6 | ||||
| -rw-r--r-- | drivers/net/macvlan.c | 18 | ||||
| -rw-r--r-- | drivers/net/usb/smsc95xx.c | 17 | ||||
| -rw-r--r-- | drivers/net/veth.c | 2 | ||||
| -rw-r--r-- | include/linux/ethtool.h | 3 | ||||
| -rw-r--r-- | include/net/ip_vs.h | 2 | ||||
| -rw-r--r-- | include/net/route.h | 1 | ||||
| -rw-r--r-- | include/net/snmp.h | 4 | ||||
| -rw-r--r-- | include/net/xfrm.h | 1 | ||||
| -rw-r--r-- | net/appletalk/ddp.c | 3 | ||||
| -rw-r--r-- | net/core/dev.c | 19 | ||||
| -rw-r--r-- | net/core/drop_monitor.c | 2 | ||||
| -rw-r--r-- | net/core/ethtool.c | 2 | ||||
| -rw-r--r-- | net/ipv4/devinet.c | 14 | ||||
| -rw-r--r-- | net/ipv4/fib_frontend.c | 101 | ||||
| -rw-r--r-- | net/ipv4/fib_trie.c | 2 | ||||
| -rw-r--r-- | net/ipv6/sysctl_net_ipv6.c | 18 | ||||
| -rw-r--r-- | net/ipx/af_ipx.c | 2 | ||||
| -rw-r--r-- | net/l2tp/l2tp_eth.c | 2 | ||||
| -rw-r--r-- | net/netfilter/ipvs/ip_vs_app.c | 23 | ||||
| -rw-r--r-- | net/netfilter/ipvs/ip_vs_ctl.c | 2 | ||||
| -rw-r--r-- | net/xfrm/xfrm_state.c | 15 | ||||
| -rw-r--r-- | net/xfrm/xfrm_user.c | 2 | 
23 files changed, 191 insertions, 70 deletions
diff --git a/drivers/net/can/c_can/c_can.c b/drivers/net/can/c_can/c_can.c index 14050786218..110eda01843 100644 --- a/drivers/net/can/c_can/c_can.c +++ b/drivers/net/can/c_can/c_can.c @@ -633,9 +633,6 @@ static void c_can_start(struct net_device *dev)  {  	struct c_can_priv *priv = netdev_priv(dev); -	/* enable status change, error and module interrupts */ -	c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS); -  	/* basic c_can configuration */  	c_can_chip_config(dev); @@ -643,6 +640,9 @@ static void c_can_start(struct net_device *dev)  	/* reset tx helper pointers */  	priv->tx_next = priv->tx_echo = 0; + +	/* enable status change, error and module interrupts */ +	c_can_enable_all_interrupts(priv, ENABLE_ALL_INTERRUPTS);  }  static void c_can_stop(struct net_device *dev) diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c index 5b37d3c191e..78e34e9e4f0 100644 --- a/drivers/net/macvlan.c +++ b/drivers/net/macvlan.c @@ -39,8 +39,11 @@ struct macvlan_port {  	struct list_head	vlans;  	struct rcu_head		rcu;  	bool 			passthru; +	int			count;  }; +static void macvlan_port_destroy(struct net_device *dev); +  #define macvlan_port_get_rcu(dev) \  	((struct macvlan_port *) rcu_dereference(dev->rx_handler_data))  #define macvlan_port_get(dev) ((struct macvlan_port *) dev->rx_handler_data) @@ -457,8 +460,13 @@ static int macvlan_init(struct net_device *dev)  static void macvlan_uninit(struct net_device *dev)  {  	struct macvlan_dev *vlan = netdev_priv(dev); +	struct macvlan_port *port = vlan->port;  	free_percpu(vlan->pcpu_stats); + +	port->count -= 1; +	if (!port->count) +		macvlan_port_destroy(port->dev);  }  static struct rtnl_link_stats64 *macvlan_dev_get_stats64(struct net_device *dev, @@ -691,12 +699,13 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,  		vlan->mode = nla_get_u32(data[IFLA_MACVLAN_MODE]);  	if (vlan->mode == MACVLAN_MODE_PASSTHRU) { -		if (!list_empty(&port->vlans)) +		if (port->count)  			return -EINVAL;  		port->passthru = true;  		memcpy(dev->dev_addr, lowerdev->dev_addr, ETH_ALEN);  	} +	port->count += 1;  	err = register_netdevice(dev);  	if (err < 0)  		goto destroy_port; @@ -707,7 +716,8 @@ int macvlan_common_newlink(struct net *src_net, struct net_device *dev,  	return 0;  destroy_port: -	if (list_empty(&port->vlans)) +	port->count -= 1; +	if (!port->count)  		macvlan_port_destroy(lowerdev);  	return err; @@ -725,13 +735,9 @@ static int macvlan_newlink(struct net *src_net, struct net_device *dev,  void macvlan_dellink(struct net_device *dev, struct list_head *head)  {  	struct macvlan_dev *vlan = netdev_priv(dev); -	struct macvlan_port *port = vlan->port;  	list_del(&vlan->list);  	unregister_netdevice_queue(dev, head); - -	if (list_empty(&port->vlans)) -		macvlan_port_destroy(port->dev);  }  EXPORT_SYMBOL_GPL(macvlan_dellink); diff --git a/drivers/net/usb/smsc95xx.c b/drivers/net/usb/smsc95xx.c index bc86f4b6ecc..727874d9deb 100644 --- a/drivers/net/usb/smsc95xx.c +++ b/drivers/net/usb/smsc95xx.c @@ -49,6 +49,8 @@  struct smsc95xx_priv {  	u32 mac_cr; +	u32 hash_hi; +	u32 hash_lo;  	spinlock_t mac_cr_lock;  	bool use_tx_csum;  	bool use_rx_csum; @@ -370,10 +372,11 @@ static void smsc95xx_set_multicast(struct net_device *netdev)  {  	struct usbnet *dev = netdev_priv(netdev);  	struct smsc95xx_priv *pdata = (struct smsc95xx_priv *)(dev->data[0]); -	u32 hash_hi = 0; -	u32 hash_lo = 0;  	unsigned long flags; +	pdata->hash_hi = 0; +	pdata->hash_lo = 0; +  	spin_lock_irqsave(&pdata->mac_cr_lock, flags);  	if (dev->net->flags & IFF_PROMISC) { @@ -394,13 +397,13 @@ static void smsc95xx_set_multicast(struct net_device *netdev)  			u32 bitnum = smsc95xx_hash(ha->addr);  			u32 mask = 0x01 << (bitnum & 0x1F);  			if (bitnum & 0x20) -				hash_hi |= mask; +				pdata->hash_hi |= mask;  			else -				hash_lo |= mask; +				pdata->hash_lo |= mask;  		}  		netif_dbg(dev, drv, dev->net, "HASHH=0x%08X, HASHL=0x%08X\n", -				   hash_hi, hash_lo); +				   pdata->hash_hi, pdata->hash_lo);  	} else {  		netif_dbg(dev, drv, dev->net, "receive own packets only\n");  		pdata->mac_cr &= @@ -410,8 +413,8 @@ static void smsc95xx_set_multicast(struct net_device *netdev)  	spin_unlock_irqrestore(&pdata->mac_cr_lock, flags);  	/* Initiate async writes, as we can't wait for completion here */ -	smsc95xx_write_reg_async(dev, HASHH, &hash_hi); -	smsc95xx_write_reg_async(dev, HASHL, &hash_lo); +	smsc95xx_write_reg_async(dev, HASHH, &pdata->hash_hi); +	smsc95xx_write_reg_async(dev, HASHL, &pdata->hash_lo);  	smsc95xx_write_reg_async(dev, MAC_CR, &pdata->mac_cr);  } diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 105d7f0630c..2de9b90c5f8 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -171,7 +171,7 @@ static netdev_tx_t veth_xmit(struct sk_buff *skb, struct net_device *dev)  	if (skb->ip_summed == CHECKSUM_NONE)  		skb->ip_summed = rcv_priv->ip_summed; -	length = skb->len + ETH_HLEN; +	length = skb->len;  	if (dev_forward_skb(rcv, skb) != NET_RX_SUCCESS)  		goto rx_drop; diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h index b297f288f6e..ae757bcf128 100644 --- a/include/linux/ethtool.h +++ b/include/linux/ethtool.h @@ -648,6 +648,9 @@ enum ethtool_sfeatures_retval_bits {  #include <linux/rculist.h> +/* needed by dev_disable_lro() */ +extern int __ethtool_set_flags(struct net_device *dev, u32 flags); +  struct ethtool_rx_ntuple_flow_spec_container {  	struct ethtool_rx_ntuple_flow_spec fs;  	struct list_head list; diff --git a/include/net/ip_vs.h b/include/net/ip_vs.h index 272f59336b7..30b49ed72f0 100644 --- a/include/net/ip_vs.h +++ b/include/net/ip_vs.h @@ -801,8 +801,6 @@ struct netns_ipvs {  	struct list_head	rs_table[IP_VS_RTAB_SIZE];  	/* ip_vs_app */  	struct list_head	app_list; -	struct mutex		app_mutex; -	struct lock_class_key	app_key;	/* mutex debuging */  	/* ip_vs_proto */  	#define IP_VS_PROTO_TAB_SIZE	32	/* must be power of 2 */ diff --git a/include/net/route.h b/include/net/route.h index 30d6cae3841..dc102445ec4 100644 --- a/include/net/route.h +++ b/include/net/route.h @@ -207,6 +207,7 @@ extern int		ip_rt_dump(struct sk_buff *skb,  struct netlink_callback *cb);  struct in_ifaddr;  extern void fib_add_ifaddr(struct in_ifaddr *); +extern void fib_del_ifaddr(struct in_ifaddr *, struct in_ifaddr *);  static inline void ip_rt_put(struct rtable * rt)  { diff --git a/include/net/snmp.h b/include/net/snmp.h index 762e2abce88..27461d6dd46 100644 --- a/include/net/snmp.h +++ b/include/net/snmp.h @@ -150,7 +150,7 @@ struct linux_xfrm_mib {  #define SNMP_UPD_PO_STATS_BH(mib, basefield, addend)	\  	do { \  		__typeof__(*mib[0]) *ptr = \ -			__this_cpu_ptr((mib)[!in_softirq()]); \ +			__this_cpu_ptr((mib)[0]); \  		ptr->mibs[basefield##PKTS]++; \  		ptr->mibs[basefield##OCTETS] += addend;\  	} while (0) @@ -202,7 +202,7 @@ struct linux_xfrm_mib {  #define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend)			\  	do {								\  		__typeof__(*mib[0]) *ptr;				\ -		ptr = __this_cpu_ptr((mib)[!in_softirq()]);		\ +		ptr = __this_cpu_ptr((mib)[0]);				\  		u64_stats_update_begin(&ptr->syncp);			\  		ptr->mibs[basefield##PKTS]++;				\  		ptr->mibs[basefield##OCTETS] += addend;			\ diff --git a/include/net/xfrm.h b/include/net/xfrm.h index 42a8c32a10e..cffa5dc6644 100644 --- a/include/net/xfrm.h +++ b/include/net/xfrm.h @@ -1430,6 +1430,7 @@ extern void xfrm_spd_getinfo(struct net *net, struct xfrmk_spdinfo *si);  extern u32 xfrm_replay_seqhi(struct xfrm_state *x, __be32 net_seq);  extern int xfrm_init_replay(struct xfrm_state *x);  extern int xfrm_state_mtu(struct xfrm_state *x, int mtu); +extern int __xfrm_init_state(struct xfrm_state *x, bool init_replay);  extern int xfrm_init_state(struct xfrm_state *x);  extern int xfrm_prepare_input(struct xfrm_state *x, struct sk_buff *skb);  extern int xfrm_input(struct sk_buff *skb, int nexthdr, __be32 spi, diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c index 3d4f4b04340..206e771e82d 100644 --- a/net/appletalk/ddp.c +++ b/net/appletalk/ddp.c @@ -1051,6 +1051,7 @@ static int atalk_release(struct socket *sock)  {  	struct sock *sk = sock->sk; +	sock_hold(sk);  	lock_sock(sk);  	if (sk) {  		sock_orphan(sk); @@ -1058,6 +1059,8 @@ static int atalk_release(struct socket *sock)  		atalk_destroy_socket(sk);  	}  	release_sock(sk); +	sock_put(sk); +  	return 0;  } diff --git a/net/core/dev.c b/net/core/dev.c index 0b88eba97da..f453370131a 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1353,14 +1353,17 @@ EXPORT_SYMBOL(dev_close);   */  void dev_disable_lro(struct net_device *dev)  { -	if (dev->ethtool_ops && dev->ethtool_ops->get_flags && -	    dev->ethtool_ops->set_flags) { -		u32 flags = dev->ethtool_ops->get_flags(dev); -		if (flags & ETH_FLAG_LRO) { -			flags &= ~ETH_FLAG_LRO; -			dev->ethtool_ops->set_flags(dev, flags); -		} -	} +	u32 flags; + +	if (dev->ethtool_ops && dev->ethtool_ops->get_flags) +		flags = dev->ethtool_ops->get_flags(dev); +	else +		flags = ethtool_op_get_flags(dev); + +	if (!(flags & ETH_FLAG_LRO)) +		return; + +	__ethtool_set_flags(dev, flags & ~ETH_FLAG_LRO);  	WARN_ON(dev->features & NETIF_F_LRO);  }  EXPORT_SYMBOL(dev_disable_lro); diff --git a/net/core/drop_monitor.c b/net/core/drop_monitor.c index 36e603c78ce..706502ff64a 100644 --- a/net/core/drop_monitor.c +++ b/net/core/drop_monitor.c @@ -350,7 +350,7 @@ static int __init init_net_drop_monitor(void)  	struct per_cpu_dm_data *data;  	int cpu, rc; -	printk(KERN_INFO "Initalizing network drop monitor service\n"); +	printk(KERN_INFO "Initializing network drop monitor service\n");  	if (sizeof(void *) > 8) {  		printk(KERN_ERR "Unable to store program counters on this arch, Drop monitor failed\n"); diff --git a/net/core/ethtool.c b/net/core/ethtool.c index a1086fb0c0c..24bd57493c0 100644 --- a/net/core/ethtool.c +++ b/net/core/ethtool.c @@ -513,7 +513,7 @@ static int ethtool_set_one_feature(struct net_device *dev,  	}  } -static int __ethtool_set_flags(struct net_device *dev, u32 data) +int __ethtool_set_flags(struct net_device *dev, u32 data)  {  	u32 changed; diff --git a/net/ipv4/devinet.c b/net/ipv4/devinet.c index 6d85800daeb..d5a4553bebc 100644 --- a/net/ipv4/devinet.c +++ b/net/ipv4/devinet.c @@ -345,6 +345,17 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,  		}  	} +	/* On promotion all secondaries from subnet are changing +	 * the primary IP, we must remove all their routes silently +	 * and later to add them back with new prefsrc. Do this +	 * while all addresses are on the device list. +	 */ +	for (ifa = promote; ifa; ifa = ifa->ifa_next) { +		if (ifa1->ifa_mask == ifa->ifa_mask && +		    inet_ifa_match(ifa1->ifa_address, ifa)) +			fib_del_ifaddr(ifa, ifa1); +	} +  	/* 2. Unlink it */  	*ifap = ifa1->ifa_next; @@ -364,6 +375,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,  	blocking_notifier_call_chain(&inetaddr_chain, NETDEV_DOWN, ifa1);  	if (promote) { +		struct in_ifaddr *next_sec = promote->ifa_next;  		if (prev_prom) {  			prev_prom->ifa_next = promote->ifa_next; @@ -375,7 +387,7 @@ static void __inet_del_ifa(struct in_device *in_dev, struct in_ifaddr **ifap,  		rtmsg_ifa(RTM_NEWADDR, promote, nlh, pid);  		blocking_notifier_call_chain(&inetaddr_chain,  				NETDEV_UP, promote); -		for (ifa = promote->ifa_next; ifa; ifa = ifa->ifa_next) { +		for (ifa = next_sec; ifa; ifa = ifa->ifa_next) {  			if (ifa1->ifa_mask != ifa->ifa_mask ||  			    !inet_ifa_match(ifa1->ifa_address, ifa))  					continue; diff --git a/net/ipv4/fib_frontend.c b/net/ipv4/fib_frontend.c index a373a259253..02c3ba61884 100644 --- a/net/ipv4/fib_frontend.c +++ b/net/ipv4/fib_frontend.c @@ -722,12 +722,17 @@ void fib_add_ifaddr(struct in_ifaddr *ifa)  	}  } -static void fib_del_ifaddr(struct in_ifaddr *ifa) +/* Delete primary or secondary address. + * Optionally, on secondary address promotion consider the addresses + * from subnet iprim as deleted, even if they are in device list. + * In this case the secondary ifa can be in device list. + */ +void fib_del_ifaddr(struct in_ifaddr *ifa, struct in_ifaddr *iprim)  {  	struct in_device *in_dev = ifa->ifa_dev;  	struct net_device *dev = in_dev->dev;  	struct in_ifaddr *ifa1; -	struct in_ifaddr *prim = ifa; +	struct in_ifaddr *prim = ifa, *prim1 = NULL;  	__be32 brd = ifa->ifa_address | ~ifa->ifa_mask;  	__be32 any = ifa->ifa_address & ifa->ifa_mask;  #define LOCAL_OK	1 @@ -735,17 +740,26 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)  #define BRD0_OK		4  #define BRD1_OK		8  	unsigned ok = 0; +	int subnet = 0;		/* Primary network */ +	int gone = 1;		/* Address is missing */ +	int same_prefsrc = 0;	/* Another primary with same IP */ -	if (!(ifa->ifa_flags & IFA_F_SECONDARY)) -		fib_magic(RTM_DELROUTE, -			  dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST, -			  any, ifa->ifa_prefixlen, prim); -	else { +	if (ifa->ifa_flags & IFA_F_SECONDARY) {  		prim = inet_ifa_byprefix(in_dev, any, ifa->ifa_mask);  		if (prim == NULL) {  			printk(KERN_WARNING "fib_del_ifaddr: bug: prim == NULL\n");  			return;  		} +		if (iprim && iprim != prim) { +			printk(KERN_WARNING "fib_del_ifaddr: bug: iprim != prim\n"); +			return; +		} +	} else if (!ipv4_is_zeronet(any) && +		   (any != ifa->ifa_local || ifa->ifa_prefixlen < 32)) { +		fib_magic(RTM_DELROUTE, +			  dev->flags & IFF_LOOPBACK ? RTN_LOCAL : RTN_UNICAST, +			  any, ifa->ifa_prefixlen, prim); +		subnet = 1;  	}  	/* Deletion is more complicated than add. @@ -755,6 +769,49 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)  	 */  	for (ifa1 = in_dev->ifa_list; ifa1; ifa1 = ifa1->ifa_next) { +		if (ifa1 == ifa) { +			/* promotion, keep the IP */ +			gone = 0; +			continue; +		} +		/* Ignore IFAs from our subnet */ +		if (iprim && ifa1->ifa_mask == iprim->ifa_mask && +		    inet_ifa_match(ifa1->ifa_address, iprim)) +			continue; + +		/* Ignore ifa1 if it uses different primary IP (prefsrc) */ +		if (ifa1->ifa_flags & IFA_F_SECONDARY) { +			/* Another address from our subnet? */ +			if (ifa1->ifa_mask == prim->ifa_mask && +			    inet_ifa_match(ifa1->ifa_address, prim)) +				prim1 = prim; +			else { +				/* We reached the secondaries, so +				 * same_prefsrc should be determined. +				 */ +				if (!same_prefsrc) +					continue; +				/* Search new prim1 if ifa1 is not +				 * using the current prim1 +				 */ +				if (!prim1 || +				    ifa1->ifa_mask != prim1->ifa_mask || +				    !inet_ifa_match(ifa1->ifa_address, prim1)) +					prim1 = inet_ifa_byprefix(in_dev, +							ifa1->ifa_address, +							ifa1->ifa_mask); +				if (!prim1) +					continue; +				if (prim1->ifa_local != prim->ifa_local) +					continue; +			} +		} else { +			if (prim->ifa_local != ifa1->ifa_local) +				continue; +			prim1 = ifa1; +			if (prim != prim1) +				same_prefsrc = 1; +		}  		if (ifa->ifa_local == ifa1->ifa_local)  			ok |= LOCAL_OK;  		if (ifa->ifa_broadcast == ifa1->ifa_broadcast) @@ -763,19 +820,37 @@ static void fib_del_ifaddr(struct in_ifaddr *ifa)  			ok |= BRD1_OK;  		if (any == ifa1->ifa_broadcast)  			ok |= BRD0_OK; +		/* primary has network specific broadcasts */ +		if (prim1 == ifa1 && ifa1->ifa_prefixlen < 31) { +			__be32 brd1 = ifa1->ifa_address | ~ifa1->ifa_mask; +			__be32 any1 = ifa1->ifa_address & ifa1->ifa_mask; + +			if (!ipv4_is_zeronet(any1)) { +				if (ifa->ifa_broadcast == brd1 || +				    ifa->ifa_broadcast == any1) +					ok |= BRD_OK; +				if (brd == brd1 || brd == any1) +					ok |= BRD1_OK; +				if (any == brd1 || any == any1) +					ok |= BRD0_OK; +			} +		}  	}  	if (!(ok & BRD_OK))  		fib_magic(RTM_DELROUTE, RTN_BROADCAST, ifa->ifa_broadcast, 32, prim); -	if (!(ok & BRD1_OK)) -		fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim); -	if (!(ok & BRD0_OK)) -		fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim); +	if (subnet && ifa->ifa_prefixlen < 31) { +		if (!(ok & BRD1_OK)) +			fib_magic(RTM_DELROUTE, RTN_BROADCAST, brd, 32, prim); +		if (!(ok & BRD0_OK)) +			fib_magic(RTM_DELROUTE, RTN_BROADCAST, any, 32, prim); +	}  	if (!(ok & LOCAL_OK)) {  		fib_magic(RTM_DELROUTE, RTN_LOCAL, ifa->ifa_local, 32, prim);  		/* Check, that this local address finally disappeared. */ -		if (inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) { +		if (gone && +		    inet_addr_type(dev_net(dev), ifa->ifa_local) != RTN_LOCAL) {  			/* And the last, but not the least thing.  			 * We must flush stray FIB entries.  			 * @@ -896,7 +971,7 @@ static int fib_inetaddr_event(struct notifier_block *this, unsigned long event,  		rt_cache_flush(dev_net(dev), -1);  		break;  	case NETDEV_DOWN: -		fib_del_ifaddr(ifa); +		fib_del_ifaddr(ifa, NULL);  		fib_update_nh_saddrs(dev);  		if (ifa->ifa_dev->ifa_list == NULL) {  			/* Last address was deleted from this interface. diff --git a/net/ipv4/fib_trie.c b/net/ipv4/fib_trie.c index 3d28a35c2e1..ac87a49ad50 100644 --- a/net/ipv4/fib_trie.c +++ b/net/ipv4/fib_trie.c @@ -1665,6 +1665,8 @@ int fib_table_delete(struct fib_table *tb, struct fib_config *cfg)  		if ((!cfg->fc_type || fa->fa_type == cfg->fc_type) &&  		    (cfg->fc_scope == RT_SCOPE_NOWHERE ||  		     fa->fa_scope == cfg->fc_scope) && +		    (!cfg->fc_prefsrc || +		     fi->fib_prefsrc == cfg->fc_prefsrc) &&  		    (!cfg->fc_protocol ||  		     fi->fib_protocol == cfg->fc_protocol) &&  		    fib_nh_match(cfg, fi) == 0) { diff --git a/net/ipv6/sysctl_net_ipv6.c b/net/ipv6/sysctl_net_ipv6.c index 7cb65ef79f9..6dcf5e7d661 100644 --- a/net/ipv6/sysctl_net_ipv6.c +++ b/net/ipv6/sysctl_net_ipv6.c @@ -17,6 +17,16 @@  static struct ctl_table empty[1]; +static ctl_table ipv6_static_skeleton[] = { +	{ +		.procname	= "neigh", +		.maxlen		= 0, +		.mode		= 0555, +		.child		= empty, +	}, +	{ } +}; +  static ctl_table ipv6_table_template[] = {  	{  		.procname	= "route", @@ -37,12 +47,6 @@ static ctl_table ipv6_table_template[] = {  		.mode		= 0644,  		.proc_handler	= proc_dointvec  	}, -	{ -		.procname	= "neigh", -		.maxlen		= 0, -		.mode		= 0555, -		.child		= empty, -	},  	{ }  }; @@ -160,7 +164,7 @@ static struct ctl_table_header *ip6_base;  int ipv6_static_sysctl_register(void)  { -	ip6_base = register_sysctl_paths(net_ipv6_ctl_path, empty); +	ip6_base = register_sysctl_paths(net_ipv6_ctl_path, ipv6_static_skeleton);  	if (ip6_base == NULL)  		return -ENOMEM;  	return 0; diff --git a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c index 2731b51923d..9680226640e 100644 --- a/net/ipx/af_ipx.c +++ b/net/ipx/af_ipx.c @@ -148,7 +148,6 @@ static void ipx_destroy_socket(struct sock *sk)  	ipx_remove_socket(sk);  	skb_queue_purge(&sk->sk_receive_queue);  	sk_refcnt_debug_dec(sk); -	sock_put(sk);  }  /* @@ -1404,6 +1403,7 @@ static int ipx_release(struct socket *sock)  	sk_refcnt_debug_release(sk);  	ipx_destroy_socket(sk);  	release_sock(sk); +	sock_put(sk);  out:  	return 0;  } diff --git a/net/l2tp/l2tp_eth.c b/net/l2tp/l2tp_eth.c index 8d9ce0accc9..a8193f52c13 100644 --- a/net/l2tp/l2tp_eth.c +++ b/net/l2tp/l2tp_eth.c @@ -283,7 +283,7 @@ static __net_init int l2tp_eth_init_net(struct net *net)  	return 0;  } -static __net_initdata struct pernet_operations l2tp_eth_net_ops = { +static struct pernet_operations l2tp_eth_net_ops = {  	.init = l2tp_eth_init_net,  	.id   = &l2tp_eth_net_id,  	.size = sizeof(struct l2tp_eth_net), diff --git a/net/netfilter/ipvs/ip_vs_app.c b/net/netfilter/ipvs/ip_vs_app.c index 5c48ffb60c2..2dc6de13ac1 100644 --- a/net/netfilter/ipvs/ip_vs_app.c +++ b/net/netfilter/ipvs/ip_vs_app.c @@ -43,6 +43,8 @@ EXPORT_SYMBOL(register_ip_vs_app);  EXPORT_SYMBOL(unregister_ip_vs_app);  EXPORT_SYMBOL(register_ip_vs_app_inc); +static DEFINE_MUTEX(__ip_vs_app_mutex); +  /*   *	Get an ip_vs_app object   */ @@ -167,14 +169,13 @@ int  register_ip_vs_app_inc(struct net *net, struct ip_vs_app *app, __u16 proto,  		       __u16 port)  { -	struct netns_ipvs *ipvs = net_ipvs(net);  	int result; -	mutex_lock(&ipvs->app_mutex); +	mutex_lock(&__ip_vs_app_mutex);  	result = ip_vs_app_inc_new(net, app, proto, port); -	mutex_unlock(&ipvs->app_mutex); +	mutex_unlock(&__ip_vs_app_mutex);  	return result;  } @@ -189,11 +190,11 @@ int register_ip_vs_app(struct net *net, struct ip_vs_app *app)  	/* increase the module use count */  	ip_vs_use_count_inc(); -	mutex_lock(&ipvs->app_mutex); +	mutex_lock(&__ip_vs_app_mutex);  	list_add(&app->a_list, &ipvs->app_list); -	mutex_unlock(&ipvs->app_mutex); +	mutex_unlock(&__ip_vs_app_mutex);  	return 0;  } @@ -205,10 +206,9 @@ int register_ip_vs_app(struct net *net, struct ip_vs_app *app)   */  void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app)  { -	struct netns_ipvs *ipvs = net_ipvs(net);  	struct ip_vs_app *inc, *nxt; -	mutex_lock(&ipvs->app_mutex); +	mutex_lock(&__ip_vs_app_mutex);  	list_for_each_entry_safe(inc, nxt, &app->incs_list, a_list) {  		ip_vs_app_inc_release(net, inc); @@ -216,7 +216,7 @@ void unregister_ip_vs_app(struct net *net, struct ip_vs_app *app)  	list_del(&app->a_list); -	mutex_unlock(&ipvs->app_mutex); +	mutex_unlock(&__ip_vs_app_mutex);  	/* decrease the module use count */  	ip_vs_use_count_dec(); @@ -501,7 +501,7 @@ static void *ip_vs_app_seq_start(struct seq_file *seq, loff_t *pos)  	struct net *net = seq_file_net(seq);  	struct netns_ipvs *ipvs = net_ipvs(net); -	mutex_lock(&ipvs->app_mutex); +	mutex_lock(&__ip_vs_app_mutex);  	return *pos ? ip_vs_app_idx(ipvs, *pos - 1) : SEQ_START_TOKEN;  } @@ -535,9 +535,7 @@ static void *ip_vs_app_seq_next(struct seq_file *seq, void *v, loff_t *pos)  static void ip_vs_app_seq_stop(struct seq_file *seq, void *v)  { -	struct netns_ipvs *ipvs = net_ipvs(seq_file_net(seq)); - -	mutex_unlock(&ipvs->app_mutex); +	mutex_unlock(&__ip_vs_app_mutex);  }  static int ip_vs_app_seq_show(struct seq_file *seq, void *v) @@ -583,7 +581,6 @@ static int __net_init __ip_vs_app_init(struct net *net)  	struct netns_ipvs *ipvs = net_ipvs(net);  	INIT_LIST_HEAD(&ipvs->app_list); -	__mutex_init(&ipvs->app_mutex, "ipvs->app_mutex", &ipvs->app_key);  	proc_net_fops_create(net, "ip_vs_app", 0, &ip_vs_app_fops);  	return 0;  } diff --git a/net/netfilter/ipvs/ip_vs_ctl.c b/net/netfilter/ipvs/ip_vs_ctl.c index b799cea31f9..33733c8872e 100644 --- a/net/netfilter/ipvs/ip_vs_ctl.c +++ b/net/netfilter/ipvs/ip_vs_ctl.c @@ -3605,7 +3605,7 @@ int __net_init __ip_vs_control_init(struct net *net)  	/* procfs stats */  	ipvs->tot_stats.cpustats = alloc_percpu(struct ip_vs_cpu_stats); -	if (ipvs->tot_stats.cpustats) { +	if (!ipvs->tot_stats.cpustats) {  		pr_err("%s(): alloc_percpu.\n", __func__);  		return -ENOMEM;  	} diff --git a/net/xfrm/xfrm_state.c b/net/xfrm/xfrm_state.c index d575f053486..f83a3d1da81 100644 --- a/net/xfrm/xfrm_state.c +++ b/net/xfrm/xfrm_state.c @@ -1907,7 +1907,7 @@ int xfrm_state_mtu(struct xfrm_state *x, int mtu)  	return res;  } -int xfrm_init_state(struct xfrm_state *x) +int __xfrm_init_state(struct xfrm_state *x, bool init_replay)  {  	struct xfrm_state_afinfo *afinfo;  	struct xfrm_mode *inner_mode; @@ -1980,12 +1980,25 @@ int xfrm_init_state(struct xfrm_state *x)  	if (x->outer_mode == NULL)  		goto error; +	if (init_replay) { +		err = xfrm_init_replay(x); +		if (err) +			goto error; +	} +  	x->km.state = XFRM_STATE_VALID;  error:  	return err;  } +EXPORT_SYMBOL(__xfrm_init_state); + +int xfrm_init_state(struct xfrm_state *x) +{ +	return __xfrm_init_state(x, true); +} +  EXPORT_SYMBOL(xfrm_init_state);  int __net_init xfrm_state_init(struct net *net) diff --git a/net/xfrm/xfrm_user.c b/net/xfrm/xfrm_user.c index 706385ae3e4..fc152d28753 100644 --- a/net/xfrm/xfrm_user.c +++ b/net/xfrm/xfrm_user.c @@ -511,7 +511,7 @@ static struct xfrm_state *xfrm_state_construct(struct net *net,  	xfrm_mark_get(attrs, &x->mark); -	err = xfrm_init_state(x); +	err = __xfrm_init_state(x, false);  	if (err)  		goto error;  |