diff options
| -rw-r--r-- | drivers/net/gianfar.c | 2 | ||||
| -rw-r--r-- | drivers/net/phy/micrel.c | 1 | ||||
| -rw-r--r-- | drivers/net/veth.c | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ar9170/usb.c | 11 | ||||
| -rw-r--r-- | drivers/net/wireless/ath/ar9170/usb.h | 1 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-commands.h | 4 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl-scan.c | 23 | ||||
| -rw-r--r-- | drivers/net/wireless/iwlwifi/iwl3945-base.c | 3 | ||||
| -rw-r--r-- | include/net/sctp/sm.h | 1 | ||||
| -rw-r--r-- | include/net/sctp/structs.h | 3 | ||||
| -rw-r--r-- | net/core/dev.c | 11 | ||||
| -rw-r--r-- | net/ipv4/arp.c | 6 | ||||
| -rw-r--r-- | net/ipv4/ipmr.c | 3 | ||||
| -rw-r--r-- | net/ipv4/udp.c | 6 | ||||
| -rw-r--r-- | net/ipv6/datagram.c | 8 | ||||
| -rw-r--r-- | net/llc/llc_sap.c | 2 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 3 | ||||
| -rw-r--r-- | net/sctp/input.c | 22 | ||||
| -rw-r--r-- | net/sctp/sm_sideeffect.c | 35 | ||||
| -rw-r--r-- | net/sctp/transport.c | 2 | 
20 files changed, 118 insertions, 30 deletions
diff --git a/drivers/net/gianfar.c b/drivers/net/gianfar.c index 4e97ca182997..5d3763fb3472 100644 --- a/drivers/net/gianfar.c +++ b/drivers/net/gianfar.c @@ -1649,6 +1649,7 @@ static void free_skb_resources(struct gfar_private *priv)  			sizeof(struct rxbd8) * priv->total_rx_ring_size,  			priv->tx_queue[0]->tx_bd_base,  			priv->tx_queue[0]->tx_bd_dma_base); +	skb_queue_purge(&priv->rx_recycle);  }  void gfar_start(struct net_device *dev) @@ -2088,7 +2089,6 @@ static int gfar_close(struct net_device *dev)  	disable_napi(priv); -	skb_queue_purge(&priv->rx_recycle);  	cancel_work_sync(&priv->reset_task);  	stop_gfar(dev); diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c index 0cd80e4d71d9..e67691dca4ab 100644 --- a/drivers/net/phy/micrel.c +++ b/drivers/net/phy/micrel.c @@ -32,6 +32,7 @@ static int kszphy_config_init(struct phy_device *phydev)  static struct phy_driver ks8001_driver = {  	.phy_id		= PHY_ID_KS8001, +	.name		= "Micrel KS8001",  	.phy_id_mask	= 0x00fffff0,  	.features	= PHY_BASIC_FEATURES,  	.flags		= PHY_POLL, diff --git a/drivers/net/veth.c b/drivers/net/veth.c index f9f0730b53d5..5ec542dd5b50 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -187,7 +187,6 @@ tx_drop:  	return NETDEV_TX_OK;  rx_drop: -	kfree_skb(skb);  	rcv_stats->rx_dropped++;  	return NETDEV_TX_OK;  } diff --git a/drivers/net/wireless/ath/ar9170/usb.c b/drivers/net/wireless/ath/ar9170/usb.c index 99a6da464bd3..e1c2fcaa8bed 100644 --- a/drivers/net/wireless/ath/ar9170/usb.c +++ b/drivers/net/wireless/ath/ar9170/usb.c @@ -727,12 +727,16 @@ static void ar9170_usb_firmware_failed(struct ar9170_usb *aru)  {  	struct device *parent = aru->udev->dev.parent; +	complete(&aru->firmware_loading_complete); +  	/* unbind anything failed */  	if (parent)  		down(&parent->sem);  	device_release_driver(&aru->udev->dev);  	if (parent)  		up(&parent->sem); + +	usb_put_dev(aru->udev);  }  static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context) @@ -761,6 +765,8 @@ static void ar9170_usb_firmware_finish(const struct firmware *fw, void *context)  	if (err)  		goto err_unrx; +	complete(&aru->firmware_loading_complete); +	usb_put_dev(aru->udev);  	return;   err_unrx: @@ -858,6 +864,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,  	init_usb_anchor(&aru->tx_pending);  	init_usb_anchor(&aru->tx_submitted);  	init_completion(&aru->cmd_wait); +	init_completion(&aru->firmware_loading_complete);  	spin_lock_init(&aru->tx_urb_lock);  	aru->tx_pending_urbs = 0; @@ -877,6 +884,7 @@ static int ar9170_usb_probe(struct usb_interface *intf,  	if (err)  		goto err_freehw; +	usb_get_dev(aru->udev);  	return request_firmware_nowait(THIS_MODULE, 1, "ar9170.fw",  				       &aru->udev->dev, GFP_KERNEL, aru,  				       ar9170_usb_firmware_step2); @@ -896,6 +904,9 @@ static void ar9170_usb_disconnect(struct usb_interface *intf)  		return;  	aru->common.state = AR9170_IDLE; + +	wait_for_completion(&aru->firmware_loading_complete); +  	ar9170_unregister(&aru->common);  	ar9170_usb_cancel_urbs(aru); diff --git a/drivers/net/wireless/ath/ar9170/usb.h b/drivers/net/wireless/ath/ar9170/usb.h index a2ce3b169ceb..919b06046eb3 100644 --- a/drivers/net/wireless/ath/ar9170/usb.h +++ b/drivers/net/wireless/ath/ar9170/usb.h @@ -71,6 +71,7 @@ struct ar9170_usb {  	unsigned int tx_pending_urbs;  	struct completion cmd_wait; +	struct completion firmware_loading_complete;  	int readlen;  	u8 *readbuf; diff --git a/drivers/net/wireless/iwlwifi/iwl-commands.h b/drivers/net/wireless/iwlwifi/iwl-commands.h index 6383d9f8c9b3..f4e59ae07f8e 100644 --- a/drivers/net/wireless/iwlwifi/iwl-commands.h +++ b/drivers/net/wireless/iwlwifi/iwl-commands.h @@ -2621,7 +2621,9 @@ struct iwl_ssid_ie {  #define PROBE_OPTION_MAX_3945		4  #define PROBE_OPTION_MAX		20  #define TX_CMD_LIFE_TIME_INFINITE	cpu_to_le32(0xFFFFFFFF) -#define IWL_GOOD_CRC_TH			cpu_to_le16(1) +#define IWL_GOOD_CRC_TH_DISABLED	0 +#define IWL_GOOD_CRC_TH_DEFAULT		cpu_to_le16(1) +#define IWL_GOOD_CRC_TH_NEVER		cpu_to_le16(0xffff)  #define IWL_MAX_SCAN_SIZE 1024  #define IWL_MAX_CMD_SIZE 4096  #define IWL_MAX_PROBE_REQUEST		200 diff --git a/drivers/net/wireless/iwlwifi/iwl-scan.c b/drivers/net/wireless/iwlwifi/iwl-scan.c index 12e455a4b90e..741e65ec8301 100644 --- a/drivers/net/wireless/iwlwifi/iwl-scan.c +++ b/drivers/net/wireless/iwlwifi/iwl-scan.c @@ -813,16 +813,29 @@ static void iwl_bg_request_scan(struct work_struct *data)  			rate = IWL_RATE_1M_PLCP;  			rate_flags = RATE_MCS_CCK_MSK;  		} -		scan->good_CRC_th = 0; +		scan->good_CRC_th = IWL_GOOD_CRC_TH_DISABLED;  	} else if (priv->scan_bands & BIT(IEEE80211_BAND_5GHZ)) {  		band = IEEE80211_BAND_5GHZ;  		rate = IWL_RATE_6M_PLCP;  		/* -		 * If active scaning is requested but a certain channel -		 * is marked passive, we can do active scanning if we -		 * detect transmissions. +		 * If active scanning is requested but a certain channel is +		 * marked passive, we can do active scanning if we detect +		 * transmissions. +		 * +		 * There is an issue with some firmware versions that triggers +		 * a sysassert on a "good CRC threshold" of zero (== disabled), +		 * on a radar channel even though this means that we should NOT +		 * send probes. +		 * +		 * The "good CRC threshold" is the number of frames that we +		 * need to receive during our dwell time on a channel before +		 * sending out probes -- setting this to a huge value will +		 * mean we never reach it, but at the same time work around +		 * the aforementioned issue. Thus use IWL_GOOD_CRC_TH_NEVER +		 * here instead of IWL_GOOD_CRC_TH_DISABLED.  		 */ -		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; +		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : +						IWL_GOOD_CRC_TH_NEVER;  		/* Force use of chains B and C (0x6) for scan Rx for 4965  		 * Avoid A (0x1) because of its off-channel reception on A-band. diff --git a/drivers/net/wireless/iwlwifi/iwl3945-base.c b/drivers/net/wireless/iwlwifi/iwl3945-base.c index b55e4f39a9e1..b74a56c48d26 100644 --- a/drivers/net/wireless/iwlwifi/iwl3945-base.c +++ b/drivers/net/wireless/iwlwifi/iwl3945-base.c @@ -2967,7 +2967,8 @@ static void iwl3945_bg_request_scan(struct work_struct *data)  		 * is marked passive, we can do active scanning if we  		 * detect transmissions.  		 */ -		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH : 0; +		scan->good_CRC_th = is_active ? IWL_GOOD_CRC_TH_DEFAULT : +						IWL_GOOD_CRC_TH_DISABLED;  		band = IEEE80211_BAND_5GHZ;  	} else {  		IWL_WARN(priv, "Invalid scan band count\n"); diff --git a/include/net/sctp/sm.h b/include/net/sctp/sm.h index 851c813adb3a..61d73e37d543 100644 --- a/include/net/sctp/sm.h +++ b/include/net/sctp/sm.h @@ -279,6 +279,7 @@ int sctp_do_sm(sctp_event_t event_type, sctp_subtype_t subtype,  /* 2nd level prototypes */  void sctp_generate_t3_rtx_event(unsigned long peer);  void sctp_generate_heartbeat_event(unsigned long peer); +void sctp_generate_proto_unreach_event(unsigned long peer);  void sctp_ootb_pkt_free(struct sctp_packet *); diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h index 597f8e27aaf6..219043a67bf7 100644 --- a/include/net/sctp/structs.h +++ b/include/net/sctp/structs.h @@ -1010,6 +1010,9 @@ struct sctp_transport {  	/* Heartbeat timer is per destination. */  	struct timer_list hb_timer; +	/* Timer to handle ICMP proto unreachable envets */ +	struct timer_list proto_unreach_timer; +  	/* Since we're using per-destination retransmission timers  	 * (see above), we're also using per-destination "transmitted"  	 * queues.  This probably ought to be a private struct diff --git a/net/core/dev.c b/net/core/dev.c index f769098774b7..264137fce3a2 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -1451,7 +1451,7 @@ static inline void net_timestamp(struct sk_buff *skb)   *   * return values:   *	NET_RX_SUCCESS	(no congestion) - *	NET_RX_DROP     (packet was dropped) + *	NET_RX_DROP     (packet was dropped, but freed)   *   * dev_forward_skb can be used for injecting an skb from the   * start_xmit function of one device into the receive queue @@ -1465,12 +1465,11 @@ int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)  {  	skb_orphan(skb); -	if (!(dev->flags & IFF_UP)) -		return NET_RX_DROP; - -	if (skb->len > (dev->mtu + dev->hard_header_len)) +	if (!(dev->flags & IFF_UP) || +	    (skb->len > (dev->mtu + dev->hard_header_len))) { +		kfree_skb(skb);  		return NET_RX_DROP; - +	}  	skb_set_dev(skb, dev);  	skb->tstamp.tv64 = 0;  	skb->pkt_type = PACKET_HOST; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index 6e747065c202..80769f1f9fab 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -661,13 +661,13 @@ struct sk_buff *arp_create(int type, int ptype, __be32 dest_ip,  #endif  #endif -#ifdef CONFIG_FDDI +#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)  	case ARPHRD_FDDI:  		arp->ar_hrd = htons(ARPHRD_ETHER);  		arp->ar_pro = htons(ETH_P_IP);  		break;  #endif -#ifdef CONFIG_TR +#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)  	case ARPHRD_IEEE802_TR:  		arp->ar_hrd = htons(ARPHRD_IEEE802);  		arp->ar_pro = htons(ETH_P_IP); @@ -1051,7 +1051,7 @@ static int arp_req_set(struct net *net, struct arpreq *r,  			return -EINVAL;  	}  	switch (dev->type) { -#ifdef CONFIG_FDDI +#if defined(CONFIG_FDDI) || defined(CONFIG_FDDI_MODULE)  	case ARPHRD_FDDI:  		/*  		 * According to RFC 1390, FDDI devices should accept ARP diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 9d4f6d1340a4..ec19a890c9a0 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -754,7 +754,8 @@ ipmr_cache_unresolved(struct net *net, vifi_t vifi, struct sk_buff *skb)  		c->next = mfc_unres_queue;  		mfc_unres_queue = c; -		mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires); +		if (atomic_read(&net->ipv4.cache_resolve_queue_len) == 1) +			mod_timer(&ipmr_expire_timer, c->mfc_un.unres.expires);  	}  	/* diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c index 8fef859db35d..c36522a0f113 100644 --- a/net/ipv4/udp.c +++ b/net/ipv4/udp.c @@ -1527,6 +1527,9 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,  	uh   = udp_hdr(skb);  	ulen = ntohs(uh->len); +	saddr = ip_hdr(skb)->saddr; +	daddr = ip_hdr(skb)->daddr; +  	if (ulen > skb->len)  		goto short_packet; @@ -1540,9 +1543,6 @@ int __udp4_lib_rcv(struct sk_buff *skb, struct udp_table *udptable,  	if (udp4_csum_init(skb, uh, proto))  		goto csum_error; -	saddr = ip_hdr(skb)->saddr; -	daddr = ip_hdr(skb)->daddr; -  	if (rt->rt_flags & (RTCF_BROADCAST|RTCF_MULTICAST))  		return __udp4_lib_mcast_deliver(net, skb, uh,  				saddr, daddr, udptable); diff --git a/net/ipv6/datagram.c b/net/ipv6/datagram.c index 622dc7939a1b..61573885e451 100644 --- a/net/ipv6/datagram.c +++ b/net/ipv6/datagram.c @@ -222,6 +222,8 @@ void ipv6_icmp_error(struct sock *sk, struct sk_buff *skb, int err,  	if (!skb)  		return; +	skb->protocol = htons(ETH_P_IPV6); +  	serr = SKB_EXT_ERR(skb);  	serr->ee.ee_errno = err;  	serr->ee.ee_origin = SO_EE_ORIGIN_ICMP6; @@ -255,6 +257,8 @@ void ipv6_local_error(struct sock *sk, int err, struct flowi *fl, u32 info)  	if (!skb)  		return; +	skb->protocol = htons(ETH_P_IPV6); +  	skb_put(skb, sizeof(struct ipv6hdr));  	skb_reset_network_header(skb);  	iph = ipv6_hdr(skb); @@ -319,7 +323,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)  		sin->sin6_flowinfo = 0;  		sin->sin6_port = serr->port;  		sin->sin6_scope_id = 0; -		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { +		if (skb->protocol == htons(ETH_P_IPV6)) {  			ipv6_addr_copy(&sin->sin6_addr,  				  (struct in6_addr *)(nh + serr->addr_offset));  			if (np->sndflow) @@ -341,7 +345,7 @@ int ipv6_recv_error(struct sock *sk, struct msghdr *msg, int len)  		sin->sin6_family = AF_INET6;  		sin->sin6_flowinfo = 0;  		sin->sin6_scope_id = 0; -		if (serr->ee.ee_origin == SO_EE_ORIGIN_ICMP6) { +		if (skb->protocol == htons(ETH_P_IPV6)) {  			ipv6_addr_copy(&sin->sin6_addr, &ipv6_hdr(skb)->saddr);  			if (np->rxopt.all)  				datagram_recv_ctl(sk, msg, skb); diff --git a/net/llc/llc_sap.c b/net/llc/llc_sap.c index a432f0ec051c..94e7fca75b85 100644 --- a/net/llc/llc_sap.c +++ b/net/llc/llc_sap.c @@ -31,7 +31,7 @@ static int llc_mac_header_len(unsigned short devtype)  	case ARPHRD_ETHER:  	case ARPHRD_LOOPBACK:  		return sizeof(struct ethhdr); -#ifdef CONFIG_TR +#if defined(CONFIG_TR) || defined(CONFIG_TR_MODULE)  	case ARPHRD_IEEE802_TR:  		return sizeof(struct trh_hdr);  #endif diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 4aefa6dc3091..875c8dec940a 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -2030,7 +2030,8 @@ int ieee80211_mgd_deauth(struct ieee80211_sub_if_data *sdata,  				continue;  			if (wk->type != IEEE80211_WORK_DIRECT_PROBE && -			    wk->type != IEEE80211_WORK_AUTH) +			    wk->type != IEEE80211_WORK_AUTH && +			    wk->type != IEEE80211_WORK_ASSOC)  				continue;  			if (memcmp(req->bss->bssid, wk->filter_ta, ETH_ALEN)) diff --git a/net/sctp/input.c b/net/sctp/input.c index 2a570184e5a9..ea2192444ce6 100644 --- a/net/sctp/input.c +++ b/net/sctp/input.c @@ -440,11 +440,25 @@ void sctp_icmp_proto_unreachable(struct sock *sk,  {  	SCTP_DEBUG_PRINTK("%s\n",  __func__); -	sctp_do_sm(SCTP_EVENT_T_OTHER, -		   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), -		   asoc->state, asoc->ep, asoc, t, -		   GFP_ATOMIC); +	if (sock_owned_by_user(sk)) { +		if (timer_pending(&t->proto_unreach_timer)) +			return; +		else { +			if (!mod_timer(&t->proto_unreach_timer, +						jiffies + (HZ/20))) +				sctp_association_hold(asoc); +		} +			 +	} else { +		if (timer_pending(&t->proto_unreach_timer) && +		    del_timer(&t->proto_unreach_timer)) +			sctp_association_put(asoc); +		sctp_do_sm(SCTP_EVENT_T_OTHER, +			   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), +			   asoc->state, asoc->ep, asoc, t, +			   GFP_ATOMIC); +	}  }  /* Common lookup code for icmp/icmpv6 error handler. */ diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c index d5ae450b6f02..eb1f42f45fdd 100644 --- a/net/sctp/sm_sideeffect.c +++ b/net/sctp/sm_sideeffect.c @@ -397,6 +397,41 @@ out_unlock:  	sctp_transport_put(transport);  } +/* Handle the timeout of the ICMP protocol unreachable timer.  Trigger + * the correct state machine transition that will close the association. + */ +void sctp_generate_proto_unreach_event(unsigned long data) +{ +	struct sctp_transport *transport = (struct sctp_transport *) data; +	struct sctp_association *asoc = transport->asoc; +	 +	sctp_bh_lock_sock(asoc->base.sk); +	if (sock_owned_by_user(asoc->base.sk)) { +		SCTP_DEBUG_PRINTK("%s:Sock is busy.\n", __func__); + +		/* Try again later.  */ +		if (!mod_timer(&transport->proto_unreach_timer, +				jiffies + (HZ/20))) +			sctp_association_hold(asoc); +		goto out_unlock; +	} + +	/* Is this structure just waiting around for us to actually +	 * get destroyed? +	 */ +	if (asoc->base.dead) +		goto out_unlock; + +	sctp_do_sm(SCTP_EVENT_T_OTHER, +		   SCTP_ST_OTHER(SCTP_EVENT_ICMP_PROTO_UNREACH), +		   asoc->state, asoc->ep, asoc, transport, GFP_ATOMIC); + +out_unlock: +	sctp_bh_unlock_sock(asoc->base.sk); +	sctp_association_put(asoc); +} + +  /* Inject a SACK Timeout event into the state machine.  */  static void sctp_generate_sack_event(unsigned long data)  { diff --git a/net/sctp/transport.c b/net/sctp/transport.c index be4d63d5a5cc..4a368038d46f 100644 --- a/net/sctp/transport.c +++ b/net/sctp/transport.c @@ -108,6 +108,8 @@ static struct sctp_transport *sctp_transport_init(struct sctp_transport *peer,  			(unsigned long)peer);  	setup_timer(&peer->hb_timer, sctp_generate_heartbeat_event,  			(unsigned long)peer); +	setup_timer(&peer->proto_unreach_timer, +		    sctp_generate_proto_unreach_event, (unsigned long)peer);  	/* Initialize the 64-bit random nonce sent with heartbeat. */  	get_random_bytes(&peer->hb_nonce, sizeof(peer->hb_nonce));  | 
