diff options
Diffstat (limited to 'net')
-rw-r--r-- | net/ipv4/tcp_input.c | 78 | ||||
-rw-r--r-- | net/mac80211/rx.c | 7 | ||||
-rw-r--r-- | net/rfkill/rfkill.c | 2 | ||||
-rw-r--r-- | net/sched/sch_api.c | 3 |
4 files changed, 58 insertions, 32 deletions
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c index 5119856017ab..bbb7d88a16b4 100644 --- a/net/ipv4/tcp_input.c +++ b/net/ipv4/tcp_input.c | |||
@@ -3841,8 +3841,28 @@ static void tcp_ofo_queue(struct sock *sk) | |||
3841 | } | 3841 | } |
3842 | } | 3842 | } |
3843 | 3843 | ||
3844 | static int tcp_prune_ofo_queue(struct sock *sk); | ||
3844 | static int tcp_prune_queue(struct sock *sk); | 3845 | static int tcp_prune_queue(struct sock *sk); |
3845 | 3846 | ||
3847 | static inline int tcp_try_rmem_schedule(struct sock *sk, unsigned int size) | ||
3848 | { | ||
3849 | if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || | ||
3850 | !sk_rmem_schedule(sk, size)) { | ||
3851 | |||
3852 | if (tcp_prune_queue(sk) < 0) | ||
3853 | return -1; | ||
3854 | |||
3855 | if (!sk_rmem_schedule(sk, size)) { | ||
3856 | if (!tcp_prune_ofo_queue(sk)) | ||
3857 | return -1; | ||
3858 | |||
3859 | if (!sk_rmem_schedule(sk, size)) | ||
3860 | return -1; | ||
3861 | } | ||
3862 | } | ||
3863 | return 0; | ||
3864 | } | ||
3865 | |||
3846 | static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | 3866 | static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) |
3847 | { | 3867 | { |
3848 | struct tcphdr *th = tcp_hdr(skb); | 3868 | struct tcphdr *th = tcp_hdr(skb); |
@@ -3892,12 +3912,9 @@ static void tcp_data_queue(struct sock *sk, struct sk_buff *skb) | |||
3892 | if (eaten <= 0) { | 3912 | if (eaten <= 0) { |
3893 | queue_and_out: | 3913 | queue_and_out: |
3894 | if (eaten < 0 && | 3914 | if (eaten < 0 && |
3895 | (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || | 3915 | tcp_try_rmem_schedule(sk, skb->truesize)) |
3896 | !sk_rmem_schedule(sk, skb->truesize))) { | 3916 | goto drop; |
3897 | if (tcp_prune_queue(sk) < 0 || | 3917 | |
3898 | !sk_rmem_schedule(sk, skb->truesize)) | ||
3899 | goto drop; | ||
3900 | } | ||
3901 | skb_set_owner_r(skb, sk); | 3918 | skb_set_owner_r(skb, sk); |
3902 | __skb_queue_tail(&sk->sk_receive_queue, skb); | 3919 | __skb_queue_tail(&sk->sk_receive_queue, skb); |
3903 | } | 3920 | } |
@@ -3966,12 +3983,8 @@ drop: | |||
3966 | 3983 | ||
3967 | TCP_ECN_check_ce(tp, skb); | 3984 | TCP_ECN_check_ce(tp, skb); |
3968 | 3985 | ||
3969 | if (atomic_read(&sk->sk_rmem_alloc) > sk->sk_rcvbuf || | 3986 | if (tcp_try_rmem_schedule(sk, skb->truesize)) |
3970 | !sk_rmem_schedule(sk, skb->truesize)) { | 3987 | goto drop; |
3971 | if (tcp_prune_queue(sk) < 0 || | ||
3972 | !sk_rmem_schedule(sk, skb->truesize)) | ||
3973 | goto drop; | ||
3974 | } | ||
3975 | 3988 | ||
3976 | /* Disable header prediction. */ | 3989 | /* Disable header prediction. */ |
3977 | tp->pred_flags = 0; | 3990 | tp->pred_flags = 0; |
@@ -4198,6 +4211,32 @@ static void tcp_collapse_ofo_queue(struct sock *sk) | |||
4198 | } | 4211 | } |
4199 | } | 4212 | } |
4200 | 4213 | ||
4214 | /* | ||
4215 | * Purge the out-of-order queue. | ||
4216 | * Return true if queue was pruned. | ||
4217 | */ | ||
4218 | static int tcp_prune_ofo_queue(struct sock *sk) | ||
4219 | { | ||
4220 | struct tcp_sock *tp = tcp_sk(sk); | ||
4221 | int res = 0; | ||
4222 | |||
4223 | if (!skb_queue_empty(&tp->out_of_order_queue)) { | ||
4224 | NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED); | ||
4225 | __skb_queue_purge(&tp->out_of_order_queue); | ||
4226 | |||
4227 | /* Reset SACK state. A conforming SACK implementation will | ||
4228 | * do the same at a timeout based retransmit. When a connection | ||
4229 | * is in a sad state like this, we care only about integrity | ||
4230 | * of the connection not performance. | ||
4231 | */ | ||
4232 | if (tp->rx_opt.sack_ok) | ||
4233 | tcp_sack_reset(&tp->rx_opt); | ||
4234 | sk_mem_reclaim(sk); | ||
4235 | res = 1; | ||
4236 | } | ||
4237 | return res; | ||
4238 | } | ||
4239 | |||
4201 | /* Reduce allocated memory if we can, trying to get | 4240 | /* Reduce allocated memory if we can, trying to get |
4202 | * the socket within its memory limits again. | 4241 | * the socket within its memory limits again. |
4203 | * | 4242 | * |
@@ -4231,20 +4270,7 @@ static int tcp_prune_queue(struct sock *sk) | |||
4231 | /* Collapsing did not help, destructive actions follow. | 4270 | /* Collapsing did not help, destructive actions follow. |
4232 | * This must not ever occur. */ | 4271 | * This must not ever occur. */ |
4233 | 4272 | ||
4234 | /* First, purge the out_of_order queue. */ | 4273 | tcp_prune_ofo_queue(sk); |
4235 | if (!skb_queue_empty(&tp->out_of_order_queue)) { | ||
4236 | NET_INC_STATS_BH(LINUX_MIB_OFOPRUNED); | ||
4237 | __skb_queue_purge(&tp->out_of_order_queue); | ||
4238 | |||
4239 | /* Reset SACK state. A conforming SACK implementation will | ||
4240 | * do the same at a timeout based retransmit. When a connection | ||
4241 | * is in a sad state like this, we care only about integrity | ||
4242 | * of the connection not performance. | ||
4243 | */ | ||
4244 | if (tcp_is_sack(tp)) | ||
4245 | tcp_sack_reset(&tp->rx_opt); | ||
4246 | sk_mem_reclaim(sk); | ||
4247 | } | ||
4248 | 4274 | ||
4249 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) | 4275 | if (atomic_read(&sk->sk_rmem_alloc) <= sk->sk_rcvbuf) |
4250 | return 0; | 4276 | return 0; |
diff --git a/net/mac80211/rx.c b/net/mac80211/rx.c index 535407d07fa4..a8a40aba846b 100644 --- a/net/mac80211/rx.c +++ b/net/mac80211/rx.c | |||
@@ -1050,12 +1050,9 @@ ieee80211_drop_unencrypted(struct ieee80211_txrx_data *rx) | |||
1050 | if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) && | 1050 | if (unlikely(!(rx->fc & IEEE80211_FCTL_PROTECTED) && |
1051 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && | 1051 | (rx->fc & IEEE80211_FCTL_FTYPE) == IEEE80211_FTYPE_DATA && |
1052 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC && | 1052 | (rx->fc & IEEE80211_FCTL_STYPE) != IEEE80211_STYPE_NULLFUNC && |
1053 | (rx->key || rx->sdata->drop_unencrypted))) { | 1053 | (rx->key || rx->sdata->drop_unencrypted))) |
1054 | if (net_ratelimit()) | ||
1055 | printk(KERN_DEBUG "%s: RX non-WEP frame, but expected " | ||
1056 | "encryption\n", rx->dev->name); | ||
1057 | return -EACCES; | 1054 | return -EACCES; |
1058 | } | 1055 | |
1059 | return 0; | 1056 | return 0; |
1060 | } | 1057 | } |
1061 | 1058 | ||
diff --git a/net/rfkill/rfkill.c b/net/rfkill/rfkill.c index 140a0a8c6b02..4e10a95de832 100644 --- a/net/rfkill/rfkill.c +++ b/net/rfkill/rfkill.c | |||
@@ -92,7 +92,7 @@ void rfkill_switch_all(enum rfkill_type type, enum rfkill_state state) | |||
92 | rfkill_states[type] = state; | 92 | rfkill_states[type] = state; |
93 | 93 | ||
94 | list_for_each_entry(rfkill, &rfkill_list, node) { | 94 | list_for_each_entry(rfkill, &rfkill_list, node) { |
95 | if (!rfkill->user_claim) | 95 | if ((!rfkill->user_claim) && (rfkill->type == type)) |
96 | rfkill_toggle_radio(rfkill, state); | 96 | rfkill_toggle_radio(rfkill, state); |
97 | } | 97 | } |
98 | 98 | ||
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index 7e3c048ba9b1..fc8708a0a25e 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -386,6 +386,9 @@ void qdisc_tree_decrease_qlen(struct Qdisc *sch, unsigned int n) | |||
386 | if (n == 0) | 386 | if (n == 0) |
387 | return; | 387 | return; |
388 | while ((parentid = sch->parent)) { | 388 | while ((parentid = sch->parent)) { |
389 | if (TC_H_MAJ(parentid) == TC_H_MAJ(TC_H_INGRESS)) | ||
390 | return; | ||
391 | |||
389 | sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid)); | 392 | sch = qdisc_lookup(sch->dev, TC_H_MAJ(parentid)); |
390 | if (sch == NULL) { | 393 | if (sch == NULL) { |
391 | WARN_ON(parentid != TC_H_ROOT); | 394 | WARN_ON(parentid != TC_H_ROOT); |