diff options
| author | David S. Miller <davem@davemloft.net> | 2010-06-11 13:32:31 -0700 | 
|---|---|---|
| committer | David S. Miller <davem@davemloft.net> | 2010-06-11 13:32:31 -0700 | 
| commit | 62522d36d74a843e78d17f2dffc90468c6762803 (patch) | |
| tree | d9d21de6724425c1b0ba12991e0865556aeda6b4 /net | |
| parent | a71fba97295db924c0b90266e9833e5059fead24 (diff) | |
| parent | e79aa8671033535c2e9ffc0a68010ae49ed5734c (diff) | |
Merge branch 'master' of master.kernel.org:/pub/scm/linux/kernel/git/davem/net-2.6
Diffstat (limited to 'net')
| -rw-r--r-- | net/8021q/vlan_core.c | 4 | ||||
| -rw-r--r-- | net/caif/cfrfml.c | 2 | ||||
| -rw-r--r-- | net/caif/cfveil.c | 2 | ||||
| -rw-r--r-- | net/core/dev.c | 25 | ||||
| -rw-r--r-- | net/core/gen_estimator.c | 15 | ||||
| -rw-r--r-- | net/core/pktgen.c | 2 | ||||
| -rw-r--r-- | net/ipv4/ipmr.c | 4 | ||||
| -rw-r--r-- | net/ipv6/icmp.c | 4 | ||||
| -rw-r--r-- | net/ipv6/ip6mr.c | 4 | ||||
| -rw-r--r-- | net/mac80211/mlme.c | 40 | 
10 files changed, 80 insertions, 22 deletions
| diff --git a/net/8021q/vlan_core.c b/net/8021q/vlan_core.c index bd537fc10254..50f58f5f1c34 100644 --- a/net/8021q/vlan_core.c +++ b/net/8021q/vlan_core.c @@ -12,7 +12,7 @@ int __vlan_hwaccel_rx(struct sk_buff *skb, struct vlan_group *grp,  		return NET_RX_DROP;  	if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) -		goto drop; +		skb->deliver_no_wcard = 1;  	skb->skb_iif = skb->dev->ifindex;  	__vlan_hwaccel_put_tag(skb, vlan_tci); @@ -84,7 +84,7 @@ vlan_gro_common(struct napi_struct *napi, struct vlan_group *grp,  	struct sk_buff *p;  	if (skb_bond_should_drop(skb, ACCESS_ONCE(skb->dev->master))) -		goto drop; +		skb->deliver_no_wcard = 1;  	skb->skb_iif = skb->dev->ifindex;  	__vlan_hwaccel_put_tag(skb, vlan_tci); diff --git a/net/caif/cfrfml.c b/net/caif/cfrfml.c index cd2830fec935..fd27b172fb5d 100644 --- a/net/caif/cfrfml.c +++ b/net/caif/cfrfml.c @@ -83,7 +83,7 @@ static int cfrfml_transmit(struct cflayer *layr, struct cfpkt *pkt)  	if (!cfsrvl_ready(service, &ret))  		return ret; -	if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { +	if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) {  		pr_err("CAIF: %s():Packet too large - size=%d\n",  			__func__, cfpkt_getlen(pkt));  		return -EOVERFLOW; diff --git a/net/caif/cfveil.c b/net/caif/cfveil.c index 0fd827f49491..e04f7d964e83 100644 --- a/net/caif/cfveil.c +++ b/net/caif/cfveil.c @@ -84,7 +84,7 @@ static int cfvei_transmit(struct cflayer *layr, struct cfpkt *pkt)  		return ret;  	caif_assert(layr->dn != NULL);  	caif_assert(layr->dn->transmit != NULL); -	if (!cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) { +	if (cfpkt_getlen(pkt) > CAIF_MAX_PAYLOAD_SIZE) {  		pr_warning("CAIF: %s(): Packet too large - size=%d\n",  			   __func__, cfpkt_getlen(pkt));  		return -EOVERFLOW; diff --git a/net/core/dev.c b/net/core/dev.c index 6f330cee79a6..277844901ce3 100644 --- a/net/core/dev.c +++ b/net/core/dev.c @@ -2273,11 +2273,9 @@ static int get_rps_cpu(struct net_device *dev, struct sk_buff *skb,  	if (skb_rx_queue_recorded(skb)) {  		u16 index = skb_get_rx_queue(skb);  		if (unlikely(index >= dev->num_rx_queues)) { -			if (net_ratelimit()) { -				pr_warning("%s received packet on queue " -					"%u, but number of RX queues is %u\n", -					dev->name, index, dev->num_rx_queues); -			} +			WARN_ONCE(dev->num_rx_queues > 1, "%s received packet " +				"on queue %u, but number of RX queues is %u\n", +				dev->name, index, dev->num_rx_queues);  			goto done;  		}  		rxqueue = dev->_rx + index; @@ -2815,13 +2813,24 @@ static int __netif_receive_skb(struct sk_buff *skb)  	if (!skb->skb_iif)  		skb->skb_iif = skb->dev->ifindex; +	/* +	 * bonding note: skbs received on inactive slaves should only +	 * be delivered to pkt handlers that are exact matches.  Also +	 * the deliver_no_wcard flag will be set.  If packet handlers +	 * are sensitive to duplicate packets these skbs will need to +	 * be dropped at the handler.  The vlan accel path may have +	 * already set the deliver_no_wcard flag. +	 */  	null_or_orig = NULL;  	orig_dev = skb->dev;  	master = ACCESS_ONCE(orig_dev->master); -	if (master) { -		if (skb_bond_should_drop(skb, master)) +	if (skb->deliver_no_wcard) +		null_or_orig = orig_dev; +	else if (master) { +		if (skb_bond_should_drop(skb, master)) { +			skb->deliver_no_wcard = 1;  			null_or_orig = orig_dev; /* deliver only exact match */ -		else +		} else  			skb->dev = master;  	} diff --git a/net/core/gen_estimator.c b/net/core/gen_estimator.c index cf8e70392fe0..785e5276a300 100644 --- a/net/core/gen_estimator.c +++ b/net/core/gen_estimator.c @@ -107,6 +107,7 @@ static DEFINE_RWLOCK(est_lock);  /* Protects against soft lockup during large deletion */  static struct rb_root est_root = RB_ROOT; +static DEFINE_SPINLOCK(est_tree_lock);  static void est_timer(unsigned long arg)  { @@ -201,7 +202,6 @@ struct gen_estimator *gen_find_node(const struct gnet_stats_basic_packed *bstats   *   * Returns 0 on success or a negative error code.   * - * NOTE: Called under rtnl_mutex   */  int gen_new_estimator(struct gnet_stats_basic_packed *bstats,  		      struct gnet_stats_rate_est *rate_est, @@ -232,6 +232,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,  	est->last_packets = bstats->packets;  	est->avpps = rate_est->pps<<10; +	spin_lock(&est_tree_lock);  	if (!elist[idx].timer.function) {  		INIT_LIST_HEAD(&elist[idx].list);  		setup_timer(&elist[idx].timer, est_timer, idx); @@ -242,6 +243,7 @@ int gen_new_estimator(struct gnet_stats_basic_packed *bstats,  	list_add_rcu(&est->list, &elist[idx].list);  	gen_add_node(est); +	spin_unlock(&est_tree_lock);  	return 0;  } @@ -261,13 +263,13 @@ static void __gen_kill_estimator(struct rcu_head *head)   *   * Removes the rate estimator specified by &bstats and &rate_est.   * - * NOTE: Called under rtnl_mutex   */  void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,  			struct gnet_stats_rate_est *rate_est)  {  	struct gen_estimator *e; +	spin_lock(&est_tree_lock);  	while ((e = gen_find_node(bstats, rate_est))) {  		rb_erase(&e->node, &est_root); @@ -278,6 +280,7 @@ void gen_kill_estimator(struct gnet_stats_basic_packed *bstats,  		list_del_rcu(&e->list);  		call_rcu(&e->e_rcu, __gen_kill_estimator);  	} +	spin_unlock(&est_tree_lock);  }  EXPORT_SYMBOL(gen_kill_estimator); @@ -312,8 +315,14 @@ EXPORT_SYMBOL(gen_replace_estimator);  bool gen_estimator_active(const struct gnet_stats_basic_packed *bstats,  			  const struct gnet_stats_rate_est *rate_est)  { +	bool res; +  	ASSERT_RTNL(); -	return gen_find_node(bstats, rate_est) != NULL; +	spin_lock(&est_tree_lock); +	res = gen_find_node(bstats, rate_est) != NULL; +	spin_unlock(&est_tree_lock); + +	return res;  }  EXPORT_SYMBOL(gen_estimator_active); diff --git a/net/core/pktgen.c b/net/core/pktgen.c index 2ad68da418df..1dacd7ba8dbb 100644 --- a/net/core/pktgen.c +++ b/net/core/pktgen.c @@ -2170,7 +2170,7 @@ static void spin(struct pktgen_dev *pkt_dev, ktime_t spin_until)  	end_time = ktime_now();  	pkt_dev->idle_acc += ktime_to_ns(ktime_sub(end_time, start_time)); -	pkt_dev->next_tx = ktime_add_ns(end_time, pkt_dev->delay); +	pkt_dev->next_tx = ktime_add_ns(spin_until, pkt_dev->delay);  }  static inline void set_pkt_overhead(struct pktgen_dev *pkt_dev) diff --git a/net/ipv4/ipmr.c b/net/ipv4/ipmr.c index 8418afc357ee..539592294f45 100644 --- a/net/ipv4/ipmr.c +++ b/net/ipv4/ipmr.c @@ -267,8 +267,10 @@ static void __net_exit ipmr_rules_exit(struct net *net)  {  	struct mr_table *mrt, *next; -	list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) +	list_for_each_entry_safe(mrt, next, &net->ipv4.mr_tables, list) { +		list_del(&mrt->list);  		kfree(mrt); +	}  	fib_rules_unregister(net->ipv4.mr_rules_ops);  }  #else diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c index ce7992982557..03e62f94ff8e 100644 --- a/net/ipv6/icmp.c +++ b/net/ipv6/icmp.c @@ -483,7 +483,7 @@ route_done:  			      np->tclass, NULL, &fl, (struct rt6_info*)dst,  			      MSG_DONTWAIT, np->dontfrag);  	if (err) { -		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); +		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);  		ip6_flush_pending_frames(sk);  		goto out_put;  	} @@ -565,7 +565,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)  				np->dontfrag);  	if (err) { -		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTMSGS); +		ICMP6_INC_STATS_BH(net, idev, ICMP6_MIB_OUTERRORS);  		ip6_flush_pending_frames(sk);  		goto out_put;  	} diff --git a/net/ipv6/ip6mr.c b/net/ipv6/ip6mr.c index 89c0b077c7aa..66078dad7fe8 100644 --- a/net/ipv6/ip6mr.c +++ b/net/ipv6/ip6mr.c @@ -254,8 +254,10 @@ static void __net_exit ip6mr_rules_exit(struct net *net)  {  	struct mr6_table *mrt, *next; -	list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) +	list_for_each_entry_safe(mrt, next, &net->ipv6.mr6_tables, list) { +		list_del(&mrt->list);  		ip6mr_free_table(mrt); +	}  	fib_rules_unregister(net->ipv6.mr6_rules_ops);  }  #else diff --git a/net/mac80211/mlme.c b/net/mac80211/mlme.c index 2ab4e86d9929..8fb85c3a043d 100644 --- a/net/mac80211/mlme.c +++ b/net/mac80211/mlme.c @@ -1760,9 +1760,45 @@ static void ieee80211_sta_rx_queued_mgmt(struct ieee80211_sub_if_data *sdata,  	mutex_unlock(&ifmgd->mtx);  	if (skb->len >= 24 + 2 /* mgmt + deauth reason */ && -	    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) -		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); +	    (fc & IEEE80211_FCTL_STYPE) == IEEE80211_STYPE_DEAUTH) { +		struct ieee80211_local *local = sdata->local; +		struct ieee80211_work *wk; + +		mutex_lock(&local->work_mtx); +		list_for_each_entry(wk, &local->work_list, list) { +			if (wk->sdata != sdata) +				continue; + +			if (wk->type != IEEE80211_WORK_ASSOC) +				continue; + +			if (memcmp(mgmt->bssid, wk->filter_ta, ETH_ALEN)) +				continue; +			if (memcmp(mgmt->sa, wk->filter_ta, ETH_ALEN)) +				continue; +			/* +			 * Printing the message only here means we can't +			 * spuriously print it, but it also means that it +			 * won't be printed when the frame comes in before +			 * we even tried to associate or in similar cases. +			 * +			 * Ultimately, I suspect cfg80211 should print the +			 * messages instead. +			 */ +			printk(KERN_DEBUG +			       "%s: deauthenticated from %pM (Reason: %u)\n", +			       sdata->name, mgmt->bssid, +			       le16_to_cpu(mgmt->u.deauth.reason_code)); + +			list_del_rcu(&wk->list); +			free_work(wk); +			break; +		} +		mutex_unlock(&local->work_mtx); + +		cfg80211_send_deauth(sdata->dev, (u8 *)mgmt, skb->len); +	}   out:  	kfree_skb(skb);  } | 
