aboutsummaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/802/tr.c22
-rw-r--r--net/decnet/dn_neigh.c2
-rw-r--r--net/ipv4/icmp.c12
-rw-r--r--net/ipv4/ipcomp.c2
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c17
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c7
-rw-r--r--net/ipv4/tcp_output.c39
-rw-r--r--net/ipv6/ip6_input.c9
-rw-r--r--net/ipv6/ipcomp6.c2
-rw-r--r--net/ipv6/raw.c2
-rw-r--r--net/sunrpc/xdr.c1
11 files changed, 62 insertions, 53 deletions
diff --git a/net/802/tr.c b/net/802/tr.c
index a755e880f4ba..1bb7dc1b85cd 100644
--- a/net/802/tr.c
+++ b/net/802/tr.c
@@ -251,10 +251,11 @@ void tr_source_route(struct sk_buff *skb,struct trh_hdr *trh,struct net_device *
251 unsigned int hash; 251 unsigned int hash;
252 struct rif_cache *entry; 252 struct rif_cache *entry;
253 unsigned char *olddata; 253 unsigned char *olddata;
254 unsigned long flags;
254 static const unsigned char mcast_func_addr[] 255 static const unsigned char mcast_func_addr[]
255 = {0xC0,0x00,0x00,0x04,0x00,0x00}; 256 = {0xC0,0x00,0x00,0x04,0x00,0x00};
256 257
257 spin_lock_bh(&rif_lock); 258 spin_lock_irqsave(&rif_lock, flags);
258 259
259 /* 260 /*
260 * Broadcasts are single route as stated in RFC 1042 261 * Broadcasts are single route as stated in RFC 1042
@@ -323,7 +324,7 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0],
323 else 324 else
324 slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8); 325 slack = 18 - ((ntohs(trh->rcf) & TR_RCF_LEN_MASK)>>8);
325 olddata = skb->data; 326 olddata = skb->data;
326 spin_unlock_bh(&rif_lock); 327 spin_unlock_irqrestore(&rif_lock, flags);
327 328
328 skb_pull(skb, slack); 329 skb_pull(skb, slack);
329 memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack); 330 memmove(skb->data, olddata, sizeof(struct trh_hdr) - slack);
@@ -337,10 +338,11 @@ printk("source routing for %02X:%02X:%02X:%02X:%02X:%02X\n",trh->daddr[0],
337static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev) 338static void tr_add_rif_info(struct trh_hdr *trh, struct net_device *dev)
338{ 339{
339 unsigned int hash, rii_p = 0; 340 unsigned int hash, rii_p = 0;
341 unsigned long flags;
340 struct rif_cache *entry; 342 struct rif_cache *entry;
341 343
342 344
343 spin_lock_bh(&rif_lock); 345 spin_lock_irqsave(&rif_lock, flags);
344 346
345 /* 347 /*
346 * Firstly see if the entry exists 348 * Firstly see if the entry exists
@@ -378,7 +380,7 @@ printk("adding rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
378 if(!entry) 380 if(!entry)
379 { 381 {
380 printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n"); 382 printk(KERN_DEBUG "tr.c: Couldn't malloc rif cache entry !\n");
381 spin_unlock_bh(&rif_lock); 383 spin_unlock_irqrestore(&rif_lock, flags);
382 return; 384 return;
383 } 385 }
384 386
@@ -420,7 +422,7 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
420 } 422 }
421 entry->last_used=jiffies; 423 entry->last_used=jiffies;
422 } 424 }
423 spin_unlock_bh(&rif_lock); 425 spin_unlock_irqrestore(&rif_lock, flags);
424} 426}
425 427
426/* 428/*
@@ -430,9 +432,9 @@ printk("updating rif_entry: addr:%02X:%02X:%02X:%02X:%02X:%02X rcf:%04X\n",
430static void rif_check_expire(unsigned long dummy) 432static void rif_check_expire(unsigned long dummy)
431{ 433{
432 int i; 434 int i;
433 unsigned long next_interval = jiffies + sysctl_tr_rif_timeout/2; 435 unsigned long flags, next_interval = jiffies + sysctl_tr_rif_timeout/2;
434 436
435 spin_lock_bh(&rif_lock); 437 spin_lock_irqsave(&rif_lock, flags);
436 438
437 for(i =0; i < RIF_TABLE_SIZE; i++) { 439 for(i =0; i < RIF_TABLE_SIZE; i++) {
438 struct rif_cache *entry, **pentry; 440 struct rif_cache *entry, **pentry;
@@ -454,7 +456,7 @@ static void rif_check_expire(unsigned long dummy)
454 } 456 }
455 } 457 }
456 458
457 spin_unlock_bh(&rif_lock); 459 spin_unlock_irqrestore(&rif_lock, flags);
458 460
459 mod_timer(&rif_timer, next_interval); 461 mod_timer(&rif_timer, next_interval);
460 462
@@ -485,7 +487,7 @@ static struct rif_cache *rif_get_idx(loff_t pos)
485 487
486static void *rif_seq_start(struct seq_file *seq, loff_t *pos) 488static void *rif_seq_start(struct seq_file *seq, loff_t *pos)
487{ 489{
488 spin_lock_bh(&rif_lock); 490 spin_lock_irq(&rif_lock);
489 491
490 return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN; 492 return *pos ? rif_get_idx(*pos - 1) : SEQ_START_TOKEN;
491} 493}
@@ -516,7 +518,7 @@ static void *rif_seq_next(struct seq_file *seq, void *v, loff_t *pos)
516 518
517static void rif_seq_stop(struct seq_file *seq, void *v) 519static void rif_seq_stop(struct seq_file *seq, void *v)
518{ 520{
519 spin_unlock_bh(&rif_lock); 521 spin_unlock_irq(&rif_lock);
520} 522}
521 523
522static int rif_seq_show(struct seq_file *seq, void *v) 524static int rif_seq_show(struct seq_file *seq, void *v)
diff --git a/net/decnet/dn_neigh.c b/net/decnet/dn_neigh.c
index f32dba9e26fe..8d0cc3cf3e49 100644
--- a/net/decnet/dn_neigh.c
+++ b/net/decnet/dn_neigh.c
@@ -148,12 +148,12 @@ static int dn_neigh_construct(struct neighbour *neigh)
148 148
149 __neigh_parms_put(neigh->parms); 149 __neigh_parms_put(neigh->parms);
150 neigh->parms = neigh_parms_clone(parms); 150 neigh->parms = neigh_parms_clone(parms);
151 rcu_read_unlock();
152 151
153 if (dn_db->use_long) 152 if (dn_db->use_long)
154 neigh->ops = &dn_long_ops; 153 neigh->ops = &dn_long_ops;
155 else 154 else
156 neigh->ops = &dn_short_ops; 155 neigh->ops = &dn_short_ops;
156 rcu_read_unlock();
157 157
158 if (dn->flags & DN_NDFLAG_P3) 158 if (dn->flags & DN_NDFLAG_P3)
159 neigh->ops = &dn_phase3_ops; 159 neigh->ops = &dn_phase3_ops;
diff --git a/net/ipv4/icmp.c b/net/ipv4/icmp.c
index 3d78464f64ea..badfc5849973 100644
--- a/net/ipv4/icmp.c
+++ b/net/ipv4/icmp.c
@@ -349,12 +349,12 @@ static void icmp_push_reply(struct icmp_bxm *icmp_param,
349{ 349{
350 struct sk_buff *skb; 350 struct sk_buff *skb;
351 351
352 ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, 352 if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param,
353 icmp_param->data_len+icmp_param->head_len, 353 icmp_param->data_len+icmp_param->head_len,
354 icmp_param->head_len, 354 icmp_param->head_len,
355 ipc, rt, MSG_DONTWAIT); 355 ipc, rt, MSG_DONTWAIT) < 0)
356 356 ip_flush_pending_frames(icmp_socket->sk);
357 if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { 357 else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) {
358 struct icmphdr *icmph = skb->h.icmph; 358 struct icmphdr *icmph = skb->h.icmph;
359 unsigned int csum = 0; 359 unsigned int csum = 0;
360 struct sk_buff *skb1; 360 struct sk_buff *skb1;
diff --git a/net/ipv4/ipcomp.c b/net/ipv4/ipcomp.c
index 2065944fd9e5..7ded6e60f43a 100644
--- a/net/ipv4/ipcomp.c
+++ b/net/ipv4/ipcomp.c
@@ -358,7 +358,7 @@ static struct crypto_tfm **ipcomp_alloc_tfms(const char *alg_name)
358 int cpu; 358 int cpu;
359 359
360 /* This can be any valid CPU ID so we don't need locking. */ 360 /* This can be any valid CPU ID so we don't need locking. */
361 cpu = smp_processor_id(); 361 cpu = raw_smp_processor_id();
362 362
363 list_for_each_entry(pos, &ipcomp_tfms_list, list) { 363 list_for_each_entry(pos, &ipcomp_tfms_list, list) {
364 struct crypto_tfm *tfm; 364 struct crypto_tfm *tfm;
diff --git a/net/ipv4/netfilter/ipt_ECN.c b/net/ipv4/netfilter/ipt_ECN.c
index ada9911118e9..94a0ce1c1c9d 100644
--- a/net/ipv4/netfilter/ipt_ECN.c
+++ b/net/ipv4/netfilter/ipt_ECN.c
@@ -61,16 +61,20 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward)
61 if (!tcph) 61 if (!tcph)
62 return 0; 62 return 0;
63 63
64 if (!(einfo->operation & IPT_ECN_OP_SET_ECE 64 if ((!(einfo->operation & IPT_ECN_OP_SET_ECE) ||
65 || tcph->ece == einfo->proto.tcp.ece) 65 tcph->ece == einfo->proto.tcp.ece) &&
66 && (!(einfo->operation & IPT_ECN_OP_SET_CWR 66 ((!(einfo->operation & IPT_ECN_OP_SET_CWR) ||
67 || tcph->cwr == einfo->proto.tcp.cwr))) 67 tcph->cwr == einfo->proto.tcp.cwr)))
68 return 1; 68 return 1;
69 69
70 if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph))) 70 if (!skb_ip_make_writable(pskb, (*pskb)->nh.iph->ihl*4+sizeof(*tcph)))
71 return 0; 71 return 0;
72 tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4; 72 tcph = (void *)(*pskb)->nh.iph + (*pskb)->nh.iph->ihl*4;
73 73
74 if ((*pskb)->ip_summed == CHECKSUM_HW &&
75 skb_checksum_help(*pskb, inward))
76 return 0;
77
74 diffs[0] = ((u_int16_t *)tcph)[6]; 78 diffs[0] = ((u_int16_t *)tcph)[6];
75 if (einfo->operation & IPT_ECN_OP_SET_ECE) 79 if (einfo->operation & IPT_ECN_OP_SET_ECE)
76 tcph->ece = einfo->proto.tcp.ece; 80 tcph->ece = einfo->proto.tcp.ece;
@@ -79,13 +83,10 @@ set_ect_tcp(struct sk_buff **pskb, const struct ipt_ECN_info *einfo, int inward)
79 diffs[1] = ((u_int16_t *)tcph)[6]; 83 diffs[1] = ((u_int16_t *)tcph)[6];
80 diffs[0] = diffs[0] ^ 0xFFFF; 84 diffs[0] = diffs[0] ^ 0xFFFF;
81 85
82 if ((*pskb)->ip_summed != CHECKSUM_HW) 86 if ((*pskb)->ip_summed != CHECKSUM_UNNECESSARY)
83 tcph->check = csum_fold(csum_partial((char *)diffs, 87 tcph->check = csum_fold(csum_partial((char *)diffs,
84 sizeof(diffs), 88 sizeof(diffs),
85 tcph->check^0xFFFF)); 89 tcph->check^0xFFFF));
86 else
87 if (skb_checksum_help(*pskb, inward))
88 return 0;
89 (*pskb)->nfcache |= NFC_ALTERED; 90 (*pskb)->nfcache |= NFC_ALTERED;
90 return 1; 91 return 1;
91} 92}
diff --git a/net/ipv4/netfilter/ipt_TCPMSS.c b/net/ipv4/netfilter/ipt_TCPMSS.c
index 1049050b2bfb..7b84a254440e 100644
--- a/net/ipv4/netfilter/ipt_TCPMSS.c
+++ b/net/ipv4/netfilter/ipt_TCPMSS.c
@@ -61,6 +61,10 @@ ipt_tcpmss_target(struct sk_buff **pskb,
61 if (!skb_ip_make_writable(pskb, (*pskb)->len)) 61 if (!skb_ip_make_writable(pskb, (*pskb)->len))
62 return NF_DROP; 62 return NF_DROP;
63 63
64 if ((*pskb)->ip_summed == CHECKSUM_HW &&
65 skb_checksum_help(*pskb, out == NULL))
66 return NF_DROP;
67
64 iph = (*pskb)->nh.iph; 68 iph = (*pskb)->nh.iph;
65 tcplen = (*pskb)->len - iph->ihl*4; 69 tcplen = (*pskb)->len - iph->ihl*4;
66 70
@@ -186,9 +190,6 @@ ipt_tcpmss_target(struct sk_buff **pskb,
186 newmss); 190 newmss);
187 191
188 retmodified: 192 retmodified:
189 /* We never hw checksum SYN packets. */
190 BUG_ON((*pskb)->ip_summed == CHECKSUM_HW);
191
192 (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED; 193 (*pskb)->nfcache |= NFC_UNKNOWN | NFC_ALTERED;
193 return IPT_CONTINUE; 194 return IPT_CONTINUE;
194} 195}
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3ed6fc15815b..566045e58437 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -861,7 +861,8 @@ static int tso_fragment(struct sock *sk, struct sk_buff *skb, unsigned int len,
861 u16 flags; 861 u16 flags;
862 862
863 /* All of a TSO frame must be composed of paged data. */ 863 /* All of a TSO frame must be composed of paged data. */
864 BUG_ON(skb->len != skb->data_len); 864 if (skb->len != skb->data_len)
865 return tcp_fragment(sk, skb, len, mss_now);
865 866
866 buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC); 867 buff = sk_stream_alloc_pskb(sk, 0, 0, GFP_ATOMIC);
867 if (unlikely(buff == NULL)) 868 if (unlikely(buff == NULL))
@@ -974,6 +975,8 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
974 975
975 sent_pkts = 0; 976 sent_pkts = 0;
976 while ((skb = sk->sk_send_head)) { 977 while ((skb = sk->sk_send_head)) {
978 unsigned int limit;
979
977 tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 980 tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
978 BUG_ON(!tso_segs); 981 BUG_ON(!tso_segs);
979 982
@@ -994,9 +997,10 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
994 break; 997 break;
995 } 998 }
996 999
1000 limit = mss_now;
997 if (tso_segs > 1) { 1001 if (tso_segs > 1) {
998 u32 limit = tcp_window_allows(tp, skb, 1002 limit = tcp_window_allows(tp, skb,
999 mss_now, cwnd_quota); 1003 mss_now, cwnd_quota);
1000 1004
1001 if (skb->len < limit) { 1005 if (skb->len < limit) {
1002 unsigned int trim = skb->len % mss_now; 1006 unsigned int trim = skb->len % mss_now;
@@ -1004,15 +1008,12 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
1004 if (trim) 1008 if (trim)
1005 limit = skb->len - trim; 1009 limit = skb->len - trim;
1006 } 1010 }
1007 if (skb->len > limit) {
1008 if (tso_fragment(sk, skb, limit, mss_now))
1009 break;
1010 }
1011 } else if (unlikely(skb->len > mss_now)) {
1012 if (unlikely(tcp_fragment(sk, skb, mss_now, mss_now)))
1013 break;
1014 } 1011 }
1015 1012
1013 if (skb->len > limit &&
1014 unlikely(tso_fragment(sk, skb, limit, mss_now)))
1015 break;
1016
1016 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1017 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1017 1018
1018 if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))) 1019 if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
@@ -1064,11 +1065,14 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
1064 cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH); 1065 cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH);
1065 1066
1066 if (likely(cwnd_quota)) { 1067 if (likely(cwnd_quota)) {
1068 unsigned int limit;
1069
1067 BUG_ON(!tso_segs); 1070 BUG_ON(!tso_segs);
1068 1071
1072 limit = mss_now;
1069 if (tso_segs > 1) { 1073 if (tso_segs > 1) {
1070 u32 limit = tcp_window_allows(tp, skb, 1074 limit = tcp_window_allows(tp, skb,
1071 mss_now, cwnd_quota); 1075 mss_now, cwnd_quota);
1072 1076
1073 if (skb->len < limit) { 1077 if (skb->len < limit) {
1074 unsigned int trim = skb->len % mss_now; 1078 unsigned int trim = skb->len % mss_now;
@@ -1076,15 +1080,12 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
1076 if (trim) 1080 if (trim)
1077 limit = skb->len - trim; 1081 limit = skb->len - trim;
1078 } 1082 }
1079 if (skb->len > limit) {
1080 if (unlikely(tso_fragment(sk, skb, limit, mss_now)))
1081 return;
1082 }
1083 } else if (unlikely(skb->len > mss_now)) {
1084 if (unlikely(tcp_fragment(sk, skb, mss_now, mss_now)))
1085 return;
1086 } 1083 }
1087 1084
1085 if (skb->len > limit &&
1086 unlikely(tso_fragment(sk, skb, limit, mss_now)))
1087 return;
1088
1088 /* Send it out now. */ 1089 /* Send it out now. */
1089 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1090 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1090 1091
diff --git a/net/ipv6/ip6_input.c b/net/ipv6/ip6_input.c
index 866f10726c58..10fbb50daea4 100644
--- a/net/ipv6/ip6_input.c
+++ b/net/ipv6/ip6_input.c
@@ -198,12 +198,13 @@ resubmit:
198 if (!raw_sk) { 198 if (!raw_sk) {
199 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) { 199 if (xfrm6_policy_check(NULL, XFRM_POLICY_IN, skb)) {
200 IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS); 200 IP6_INC_STATS_BH(IPSTATS_MIB_INUNKNOWNPROTOS);
201 icmpv6_param_prob(skb, ICMPV6_UNK_NEXTHDR, nhoff); 201 icmpv6_send(skb, ICMPV6_PARAMPROB,
202 ICMPV6_UNK_NEXTHDR, nhoff,
203 skb->dev);
202 } 204 }
203 } else { 205 } else
204 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS); 206 IP6_INC_STATS_BH(IPSTATS_MIB_INDELIVERS);
205 kfree_skb(skb); 207 kfree_skb(skb);
206 }
207 } 208 }
208 rcu_read_unlock(); 209 rcu_read_unlock();
209 return 0; 210 return 0;
diff --git a/net/ipv6/ipcomp6.c b/net/ipv6/ipcomp6.c
index 423feb46ccc0..135383ef538f 100644
--- a/net/ipv6/ipcomp6.c
+++ b/net/ipv6/ipcomp6.c
@@ -354,7 +354,7 @@ static struct crypto_tfm **ipcomp6_alloc_tfms(const char *alg_name)
354 int cpu; 354 int cpu;
355 355
356 /* This can be any valid CPU ID so we don't need locking. */ 356 /* This can be any valid CPU ID so we don't need locking. */
357 cpu = smp_processor_id(); 357 cpu = raw_smp_processor_id();
358 358
359 list_for_each_entry(pos, &ipcomp6_tfms_list, list) { 359 list_for_each_entry(pos, &ipcomp6_tfms_list, list) {
360 struct crypto_tfm *tfm; 360 struct crypto_tfm *tfm;
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index e2b848ec9851..1d4d75b34d32 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -328,6 +328,8 @@ int rawv6_rcv(struct sock *sk, struct sk_buff *skb)
328 328
329 if (skb->ip_summed != CHECKSUM_UNNECESSARY) { 329 if (skb->ip_summed != CHECKSUM_UNNECESSARY) {
330 if (skb->ip_summed == CHECKSUM_HW) { 330 if (skb->ip_summed == CHECKSUM_HW) {
331 skb_postpull_rcsum(skb, skb->nh.raw,
332 skb->h.raw - skb->nh.raw);
331 skb->ip_summed = CHECKSUM_UNNECESSARY; 333 skb->ip_summed = CHECKSUM_UNNECESSARY;
332 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr, 334 if (csum_ipv6_magic(&skb->nh.ipv6h->saddr,
333 &skb->nh.ipv6h->daddr, 335 &skb->nh.ipv6h->daddr,
diff --git a/net/sunrpc/xdr.c b/net/sunrpc/xdr.c
index 8a4d9c106af1..fde16f40a581 100644
--- a/net/sunrpc/xdr.c
+++ b/net/sunrpc/xdr.c
@@ -993,6 +993,7 @@ xdr_xcode_array2(struct xdr_buf *buf, unsigned int base,
993 return -EINVAL; 993 return -EINVAL;
994 } else { 994 } else {
995 if (xdr_decode_word(buf, base, &desc->array_len) != 0 || 995 if (xdr_decode_word(buf, base, &desc->array_len) != 0 ||
996 desc->array_len > desc->array_maxlen ||
996 (unsigned long) base + 4 + desc->array_len * 997 (unsigned long) base + 4 + desc->array_len *
997 desc->elem_size > buf->len) 998 desc->elem_size > buf->len)
998 return -EINVAL; 999 return -EINVAL;