aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/icmp.c12
-rw-r--r--net/ipv4/inetpeer.c11
-rw-r--r--net/ipv4/ipcomp.c2
-rw-r--r--net/ipv4/netfilter/ip_queue.c7
-rw-r--r--net/ipv4/netfilter/ipt_ECN.c17
-rw-r--r--net/ipv4/netfilter/ipt_TCPMSS.c7
-rw-r--r--net/ipv4/tcp.c2
-rw-r--r--net/ipv4/tcp_ipv4.c9
-rw-r--r--net/ipv4/tcp_output.c43
9 files changed, 62 insertions, 48 deletions
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/inetpeer.c b/net/ipv4/inetpeer.c
index 95473953c406..ab18a853d7ce 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -450,10 +450,13 @@ static void peer_check_expire(unsigned long dummy)
450 /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime 450 /* Trigger the timer after inet_peer_gc_mintime .. inet_peer_gc_maxtime
451 * interval depending on the total number of entries (more entries, 451 * interval depending on the total number of entries (more entries,
452 * less interval). */ 452 * less interval). */
453 peer_periodic_timer.expires = jiffies 453 if (peer_total >= inet_peer_threshold)
454 + inet_peer_gc_maxtime 454 peer_periodic_timer.expires = jiffies + inet_peer_gc_mintime;
455 - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ * 455 else
456 peer_total / inet_peer_threshold * HZ; 456 peer_periodic_timer.expires = jiffies
457 + inet_peer_gc_maxtime
458 - (inet_peer_gc_maxtime - inet_peer_gc_mintime) / HZ *
459 peer_total / inet_peer_threshold * HZ;
457 add_timer(&peer_periodic_timer); 460 add_timer(&peer_periodic_timer);
458} 461}
459 462
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/ip_queue.c b/net/ipv4/netfilter/ip_queue.c
index eda1fba431a4..c6baa8174389 100644
--- a/net/ipv4/netfilter/ip_queue.c
+++ b/net/ipv4/netfilter/ip_queue.c
@@ -214,6 +214,12 @@ ipq_build_packet_message(struct ipq_queue_entry *entry, int *errp)
214 break; 214 break;
215 215
216 case IPQ_COPY_PACKET: 216 case IPQ_COPY_PACKET:
217 if (entry->skb->ip_summed == CHECKSUM_HW &&
218 (*errp = skb_checksum_help(entry->skb,
219 entry->info->outdev == NULL))) {
220 read_unlock_bh(&queue_lock);
221 return NULL;
222 }
217 if (copy_range == 0 || copy_range > entry->skb->len) 223 if (copy_range == 0 || copy_range > entry->skb->len)
218 data_len = entry->skb->len; 224 data_len = entry->skb->len;
219 else 225 else
@@ -385,6 +391,7 @@ ipq_mangle_ipv4(ipq_verdict_msg_t *v, struct ipq_queue_entry *e)
385 if (!skb_ip_make_writable(&e->skb, v->data_len)) 391 if (!skb_ip_make_writable(&e->skb, v->data_len))
386 return -ENOMEM; 392 return -ENOMEM;
387 memcpy(e->skb->data, v->payload, v->data_len); 393 memcpy(e->skb->data, v->payload, v->data_len);
394 e->skb->ip_summed = CHECKSUM_NONE;
388 e->skb->nfcache |= NFC_ALTERED; 395 e->skb->nfcache |= NFC_ALTERED;
389 396
390 /* 397 /*
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.c b/net/ipv4/tcp.c
index ddb6ce4ecff2..69b1fcf70077 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -584,7 +584,7 @@ static inline void skb_entail(struct sock *sk, struct tcp_sock *tp,
584 sk_charge_skb(sk, skb); 584 sk_charge_skb(sk, skb);
585 if (!sk->sk_send_head) 585 if (!sk->sk_send_head)
586 sk->sk_send_head = skb; 586 sk->sk_send_head = skb;
587 else if (tp->nonagle&TCP_NAGLE_PUSH) 587 if (tp->nonagle & TCP_NAGLE_PUSH)
588 tp->nonagle &= ~TCP_NAGLE_PUSH; 588 tp->nonagle &= ~TCP_NAGLE_PUSH;
589} 589}
590 590
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 5d91213d34c0..67c670886c1f 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -242,9 +242,14 @@ static int tcp_v4_get_port(struct sock *sk, unsigned short snum)
242 tcp_port_rover = rover; 242 tcp_port_rover = rover;
243 spin_unlock(&tcp_portalloc_lock); 243 spin_unlock(&tcp_portalloc_lock);
244 244
245 /* Exhausted local port range during search? */ 245 /* Exhausted local port range during search? It is not
246 * possible for us to be holding one of the bind hash
247 * locks if this test triggers, because if 'remaining'
248 * drops to zero, we broke out of the do/while loop at
249 * the top level, not from the 'break;' statement.
250 */
246 ret = 1; 251 ret = 1;
247 if (remaining <= 0) 252 if (unlikely(remaining <= 0))
248 goto fail; 253 goto fail;
249 254
250 /* OK, here is the one we will use. HEAD is 255 /* OK, here is the one we will use. HEAD is
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 3ed6fc15815b..dd30dd137b74 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))
@@ -924,10 +925,6 @@ static int tcp_tso_should_defer(struct sock *sk, struct tcp_sock *tp, struct sk_
924 925
925 limit = min(send_win, cong_win); 926 limit = min(send_win, cong_win);
926 927
927 /* If sk_send_head can be sent fully now, just do it. */
928 if (skb->len <= limit)
929 return 0;
930
931 if (sysctl_tcp_tso_win_divisor) { 928 if (sysctl_tcp_tso_win_divisor) {
932 u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache); 929 u32 chunk = min(tp->snd_wnd, tp->snd_cwnd * tp->mss_cache);
933 930
@@ -974,6 +971,8 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
974 971
975 sent_pkts = 0; 972 sent_pkts = 0;
976 while ((skb = sk->sk_send_head)) { 973 while ((skb = sk->sk_send_head)) {
974 unsigned int limit;
975
977 tso_segs = tcp_init_tso_segs(sk, skb, mss_now); 976 tso_segs = tcp_init_tso_segs(sk, skb, mss_now);
978 BUG_ON(!tso_segs); 977 BUG_ON(!tso_segs);
979 978
@@ -994,9 +993,10 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
994 break; 993 break;
995 } 994 }
996 995
996 limit = mss_now;
997 if (tso_segs > 1) { 997 if (tso_segs > 1) {
998 u32 limit = tcp_window_allows(tp, skb, 998 limit = tcp_window_allows(tp, skb,
999 mss_now, cwnd_quota); 999 mss_now, cwnd_quota);
1000 1000
1001 if (skb->len < limit) { 1001 if (skb->len < limit) {
1002 unsigned int trim = skb->len % mss_now; 1002 unsigned int trim = skb->len % mss_now;
@@ -1004,15 +1004,12 @@ static int tcp_write_xmit(struct sock *sk, unsigned int mss_now, int nonagle)
1004 if (trim) 1004 if (trim)
1005 limit = skb->len - trim; 1005 limit = skb->len - trim;
1006 } 1006 }
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 } 1007 }
1015 1008
1009 if (skb->len > limit &&
1010 unlikely(tso_fragment(sk, skb, limit, mss_now)))
1011 break;
1012
1016 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1013 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1017 1014
1018 if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC)))) 1015 if (unlikely(tcp_transmit_skb(sk, skb_clone(skb, GFP_ATOMIC))))
@@ -1064,11 +1061,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); 1061 cwnd_quota = tcp_snd_test(sk, skb, mss_now, TCP_NAGLE_PUSH);
1065 1062
1066 if (likely(cwnd_quota)) { 1063 if (likely(cwnd_quota)) {
1064 unsigned int limit;
1065
1067 BUG_ON(!tso_segs); 1066 BUG_ON(!tso_segs);
1068 1067
1068 limit = mss_now;
1069 if (tso_segs > 1) { 1069 if (tso_segs > 1) {
1070 u32 limit = tcp_window_allows(tp, skb, 1070 limit = tcp_window_allows(tp, skb,
1071 mss_now, cwnd_quota); 1071 mss_now, cwnd_quota);
1072 1072
1073 if (skb->len < limit) { 1073 if (skb->len < limit) {
1074 unsigned int trim = skb->len % mss_now; 1074 unsigned int trim = skb->len % mss_now;
@@ -1076,15 +1076,12 @@ void tcp_push_one(struct sock *sk, unsigned int mss_now)
1076 if (trim) 1076 if (trim)
1077 limit = skb->len - trim; 1077 limit = skb->len - trim;
1078 } 1078 }
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 } 1079 }
1087 1080
1081 if (skb->len > limit &&
1082 unlikely(tso_fragment(sk, skb, limit, mss_now)))
1083 return;
1084
1088 /* Send it out now. */ 1085 /* Send it out now. */
1089 TCP_SKB_CB(skb)->when = tcp_time_stamp; 1086 TCP_SKB_CB(skb)->when = tcp_time_stamp;
1090 1087