aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2013-05-24 19:48:28 -0400
committerDavid S. Miller <davem@davemloft.net>2013-05-24 19:48:28 -0400
commite6ff4c75f9095f61b3a66c2a78e47b62864022dd (patch)
tree425ea9463cbec0b1975b8a33d9a56817143055d0 /net/ipv4
parentee9c799c231324de681eb21e06d8bf4842768b75 (diff)
parent0e255f1c0c9add2f0c920240ac4cadc28ae274c3 (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net
Merge net into net-next because some upcoming net-next changes build on top of bug fixes that went into net. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ipv4')
-rw-r--r--net/ipv4/ip_gre.c3
-rw-r--r--net/ipv4/netfilter/ipt_ULOG.c13
-rw-r--r--net/ipv4/tcp.c29
-rw-r--r--net/ipv4/tcp_input.c23
-rw-r--r--net/ipv4/tcp_output.c10
5 files changed, 55 insertions, 23 deletions
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index c625e4dad4b0..2a83591492dd 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -235,7 +235,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
235 */ 235 */
236 struct net *net = dev_net(skb->dev); 236 struct net *net = dev_net(skb->dev);
237 struct ip_tunnel_net *itn; 237 struct ip_tunnel_net *itn;
238 const struct iphdr *iph = (const struct iphdr *)skb->data; 238 const struct iphdr *iph;
239 const int type = icmp_hdr(skb)->type; 239 const int type = icmp_hdr(skb)->type;
240 const int code = icmp_hdr(skb)->code; 240 const int code = icmp_hdr(skb)->code;
241 struct ip_tunnel *t; 241 struct ip_tunnel *t;
@@ -281,6 +281,7 @@ static void ipgre_err(struct sk_buff *skb, u32 info)
281 else 281 else
282 itn = net_generic(net, ipgre_net_id); 282 itn = net_generic(net, ipgre_net_id);
283 283
284 iph = (const struct iphdr *)skb->data;
284 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags, 285 t = ip_tunnel_lookup(itn, skb->dev->ifindex, tpi.flags,
285 iph->daddr, iph->saddr, tpi.key); 286 iph->daddr, iph->saddr, tpi.key);
286 287
diff --git a/net/ipv4/netfilter/ipt_ULOG.c b/net/ipv4/netfilter/ipt_ULOG.c
index f8a222cb6448..cf08218ddbcf 100644
--- a/net/ipv4/netfilter/ipt_ULOG.c
+++ b/net/ipv4/netfilter/ipt_ULOG.c
@@ -162,7 +162,8 @@ static struct sk_buff *ulog_alloc_skb(unsigned int size)
162 return skb; 162 return skb;
163} 163}
164 164
165static void ipt_ulog_packet(unsigned int hooknum, 165static void ipt_ulog_packet(struct net *net,
166 unsigned int hooknum,
166 const struct sk_buff *skb, 167 const struct sk_buff *skb,
167 const struct net_device *in, 168 const struct net_device *in,
168 const struct net_device *out, 169 const struct net_device *out,
@@ -174,7 +175,6 @@ static void ipt_ulog_packet(unsigned int hooknum,
174 size_t size, copy_len; 175 size_t size, copy_len;
175 struct nlmsghdr *nlh; 176 struct nlmsghdr *nlh;
176 struct timeval tv; 177 struct timeval tv;
177 struct net *net = dev_net(in ? in : out);
178 struct ulog_net *ulog = ulog_pernet(net); 178 struct ulog_net *ulog = ulog_pernet(net);
179 179
180 /* ffs == find first bit set, necessary because userspace 180 /* ffs == find first bit set, necessary because userspace
@@ -291,12 +291,15 @@ alloc_failure:
291static unsigned int 291static unsigned int
292ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) 292ulog_tg(struct sk_buff *skb, const struct xt_action_param *par)
293{ 293{
294 ipt_ulog_packet(par->hooknum, skb, par->in, par->out, 294 struct net *net = dev_net(par->in ? par->in : par->out);
295
296 ipt_ulog_packet(net, par->hooknum, skb, par->in, par->out,
295 par->targinfo, NULL); 297 par->targinfo, NULL);
296 return XT_CONTINUE; 298 return XT_CONTINUE;
297} 299}
298 300
299static void ipt_logfn(u_int8_t pf, 301static void ipt_logfn(struct net *net,
302 u_int8_t pf,
300 unsigned int hooknum, 303 unsigned int hooknum,
301 const struct sk_buff *skb, 304 const struct sk_buff *skb,
302 const struct net_device *in, 305 const struct net_device *in,
@@ -318,7 +321,7 @@ static void ipt_logfn(u_int8_t pf,
318 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix)); 321 strlcpy(loginfo.prefix, prefix, sizeof(loginfo.prefix));
319 } 322 }
320 323
321 ipt_ulog_packet(hooknum, skb, in, out, &loginfo, prefix); 324 ipt_ulog_packet(net, hooknum, skb, in, out, &loginfo, prefix);
322} 325}
323 326
324static int ulog_tg_check(const struct xt_tgchk_param *par) 327static int ulog_tg_check(const struct xt_tgchk_param *par)
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 53d9c120fbb8..d87ce72ca8aa 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2887,6 +2887,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
2887 unsigned int mss; 2887 unsigned int mss;
2888 struct sk_buff *gso_skb = skb; 2888 struct sk_buff *gso_skb = skb;
2889 __sum16 newcheck; 2889 __sum16 newcheck;
2890 bool ooo_okay, copy_destructor;
2890 2891
2891 if (!pskb_may_pull(skb, sizeof(*th))) 2892 if (!pskb_may_pull(skb, sizeof(*th)))
2892 goto out; 2893 goto out;
@@ -2927,10 +2928,18 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
2927 goto out; 2928 goto out;
2928 } 2929 }
2929 2930
2931 copy_destructor = gso_skb->destructor == tcp_wfree;
2932 ooo_okay = gso_skb->ooo_okay;
2933 /* All segments but the first should have ooo_okay cleared */
2934 skb->ooo_okay = 0;
2935
2930 segs = skb_segment(skb, features); 2936 segs = skb_segment(skb, features);
2931 if (IS_ERR(segs)) 2937 if (IS_ERR(segs))
2932 goto out; 2938 goto out;
2933 2939
2940 /* Only first segment might have ooo_okay set */
2941 segs->ooo_okay = ooo_okay;
2942
2934 delta = htonl(oldlen + (thlen + mss)); 2943 delta = htonl(oldlen + (thlen + mss));
2935 2944
2936 skb = segs; 2945 skb = segs;
@@ -2950,6 +2959,17 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
2950 thlen, skb->csum)); 2959 thlen, skb->csum));
2951 2960
2952 seq += mss; 2961 seq += mss;
2962 if (copy_destructor) {
2963 skb->destructor = gso_skb->destructor;
2964 skb->sk = gso_skb->sk;
2965 /* {tcp|sock}_wfree() use exact truesize accounting :
2966 * sum(skb->truesize) MUST be exactly be gso_skb->truesize
2967 * So we account mss bytes of 'true size' for each segment.
2968 * The last segment will contain the remaining.
2969 */
2970 skb->truesize = mss;
2971 gso_skb->truesize -= mss;
2972 }
2953 skb = skb->next; 2973 skb = skb->next;
2954 th = tcp_hdr(skb); 2974 th = tcp_hdr(skb);
2955 2975
@@ -2962,7 +2982,7 @@ struct sk_buff *tcp_tso_segment(struct sk_buff *skb,
2962 * is freed at TX completion, and not right now when gso_skb 2982 * is freed at TX completion, and not right now when gso_skb
2963 * is freed by GSO engine 2983 * is freed by GSO engine
2964 */ 2984 */
2965 if (gso_skb->destructor == tcp_wfree) { 2985 if (copy_destructor) {
2966 swap(gso_skb->sk, skb->sk); 2986 swap(gso_skb->sk, skb->sk);
2967 swap(gso_skb->destructor, skb->destructor); 2987 swap(gso_skb->destructor, skb->destructor);
2968 swap(gso_skb->truesize, skb->truesize); 2988 swap(gso_skb->truesize, skb->truesize);
@@ -3213,8 +3233,11 @@ int tcp_md5_hash_skb_data(struct tcp_md5sig_pool *hp,
3213 3233
3214 for (i = 0; i < shi->nr_frags; ++i) { 3234 for (i = 0; i < shi->nr_frags; ++i) {
3215 const struct skb_frag_struct *f = &shi->frags[i]; 3235 const struct skb_frag_struct *f = &shi->frags[i];
3216 struct page *page = skb_frag_page(f); 3236 unsigned int offset = f->page_offset;
3217 sg_set_page(&sg, page, skb_frag_size(f), f->page_offset); 3237 struct page *page = skb_frag_page(f) + (offset >> PAGE_SHIFT);
3238
3239 sg_set_page(&sg, page, skb_frag_size(f),
3240 offset_in_page(offset));
3218 if (crypto_hash_update(desc, &sg, skb_frag_size(f))) 3241 if (crypto_hash_update(desc, &sg, skb_frag_size(f)))
3219 return 1; 3242 return 1;
3220 } 3243 }
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d7d369428ae4..8230cd6243aa 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -2679,8 +2679,8 @@ static void tcp_process_loss(struct sock *sk, int flag, bool is_dupack)
2679 * tcp_xmit_retransmit_queue(). 2679 * tcp_xmit_retransmit_queue().
2680 */ 2680 */
2681static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, 2681static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
2682 int prior_sacked, bool is_dupack, 2682 int prior_sacked, int prior_packets,
2683 int flag) 2683 bool is_dupack, int flag)
2684{ 2684{
2685 struct inet_connection_sock *icsk = inet_csk(sk); 2685 struct inet_connection_sock *icsk = inet_csk(sk);
2686 struct tcp_sock *tp = tcp_sk(sk); 2686 struct tcp_sock *tp = tcp_sk(sk);
@@ -2740,7 +2740,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
2740 tcp_add_reno_sack(sk); 2740 tcp_add_reno_sack(sk);
2741 } else 2741 } else
2742 do_lost = tcp_try_undo_partial(sk, pkts_acked); 2742 do_lost = tcp_try_undo_partial(sk, pkts_acked);
2743 newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; 2743 newly_acked_sacked = prior_packets - tp->packets_out +
2744 tp->sacked_out - prior_sacked;
2744 break; 2745 break;
2745 case TCP_CA_Loss: 2746 case TCP_CA_Loss:
2746 tcp_process_loss(sk, flag, is_dupack); 2747 tcp_process_loss(sk, flag, is_dupack);
@@ -2754,7 +2755,8 @@ static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked,
2754 if (is_dupack) 2755 if (is_dupack)
2755 tcp_add_reno_sack(sk); 2756 tcp_add_reno_sack(sk);
2756 } 2757 }
2757 newly_acked_sacked = pkts_acked + tp->sacked_out - prior_sacked; 2758 newly_acked_sacked = prior_packets - tp->packets_out +
2759 tp->sacked_out - prior_sacked;
2758 2760
2759 if (icsk->icsk_ca_state <= TCP_CA_Disorder) 2761 if (icsk->icsk_ca_state <= TCP_CA_Disorder)
2760 tcp_try_undo_dsack(sk); 2762 tcp_try_undo_dsack(sk);
@@ -3265,9 +3267,10 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3265 bool is_dupack = false; 3267 bool is_dupack = false;
3266 u32 prior_in_flight; 3268 u32 prior_in_flight;
3267 u32 prior_fackets; 3269 u32 prior_fackets;
3268 int prior_packets; 3270 int prior_packets = tp->packets_out;
3269 int prior_sacked = tp->sacked_out; 3271 int prior_sacked = tp->sacked_out;
3270 int pkts_acked = 0; 3272 int pkts_acked = 0;
3273 int previous_packets_out = 0;
3271 3274
3272 /* If the ack is older than previous acks 3275 /* If the ack is older than previous acks
3273 * then we can probably ignore it. 3276 * then we can probably ignore it.
@@ -3338,14 +3341,14 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3338 sk->sk_err_soft = 0; 3341 sk->sk_err_soft = 0;
3339 icsk->icsk_probes_out = 0; 3342 icsk->icsk_probes_out = 0;
3340 tp->rcv_tstamp = tcp_time_stamp; 3343 tp->rcv_tstamp = tcp_time_stamp;
3341 prior_packets = tp->packets_out;
3342 if (!prior_packets) 3344 if (!prior_packets)
3343 goto no_queue; 3345 goto no_queue;
3344 3346
3345 /* See if we can take anything off of the retransmit queue. */ 3347 /* See if we can take anything off of the retransmit queue. */
3348 previous_packets_out = tp->packets_out;
3346 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una); 3349 flag |= tcp_clean_rtx_queue(sk, prior_fackets, prior_snd_una);
3347 3350
3348 pkts_acked = prior_packets - tp->packets_out; 3351 pkts_acked = previous_packets_out - tp->packets_out;
3349 3352
3350 if (tcp_ack_is_dubious(sk, flag)) { 3353 if (tcp_ack_is_dubious(sk, flag)) {
3351 /* Advance CWND, if state allows this. */ 3354 /* Advance CWND, if state allows this. */
@@ -3353,7 +3356,7 @@ static int tcp_ack(struct sock *sk, const struct sk_buff *skb, int flag)
3353 tcp_cong_avoid(sk, ack, prior_in_flight); 3356 tcp_cong_avoid(sk, ack, prior_in_flight);
3354 is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP)); 3357 is_dupack = !(flag & (FLAG_SND_UNA_ADVANCED | FLAG_NOT_DUP));
3355 tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, 3358 tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
3356 is_dupack, flag); 3359 prior_packets, is_dupack, flag);
3357 } else { 3360 } else {
3358 if (flag & FLAG_DATA_ACKED) 3361 if (flag & FLAG_DATA_ACKED)
3359 tcp_cong_avoid(sk, ack, prior_in_flight); 3362 tcp_cong_avoid(sk, ack, prior_in_flight);
@@ -3376,7 +3379,7 @@ no_queue:
3376 /* If data was DSACKed, see if we can undo a cwnd reduction. */ 3379 /* If data was DSACKed, see if we can undo a cwnd reduction. */
3377 if (flag & FLAG_DSACKING_ACK) 3380 if (flag & FLAG_DSACKING_ACK)
3378 tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, 3381 tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
3379 is_dupack, flag); 3382 prior_packets, is_dupack, flag);
3380 /* If this ack opens up a zero window, clear backoff. It was 3383 /* If this ack opens up a zero window, clear backoff. It was
3381 * being used to time the probes, and is probably far higher than 3384 * being used to time the probes, and is probably far higher than
3382 * it needs to be for normal retransmission. 3385 * it needs to be for normal retransmission.
@@ -3399,7 +3402,7 @@ old_ack:
3399 if (TCP_SKB_CB(skb)->sacked) { 3402 if (TCP_SKB_CB(skb)->sacked) {
3400 flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una); 3403 flag |= tcp_sacktag_write_queue(sk, skb, prior_snd_una);
3401 tcp_fastretrans_alert(sk, pkts_acked, prior_sacked, 3404 tcp_fastretrans_alert(sk, pkts_acked, prior_sacked,
3402 is_dupack, flag); 3405 prior_packets, is_dupack, flag);
3403 } 3406 }
3404 3407
3405 SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt); 3408 SOCK_DEBUG(sk, "Ack %u before %u:%u\n", ack, tp->snd_una, tp->snd_nxt);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 536d40929ba6..ec335fabd5cc 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -874,11 +874,13 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
874 &md5); 874 &md5);
875 tcp_header_size = tcp_options_size + sizeof(struct tcphdr); 875 tcp_header_size = tcp_options_size + sizeof(struct tcphdr);
876 876
877 if (tcp_packets_in_flight(tp) == 0) { 877 if (tcp_packets_in_flight(tp) == 0)
878 tcp_ca_event(sk, CA_EVENT_TX_START); 878 tcp_ca_event(sk, CA_EVENT_TX_START);
879 skb->ooo_okay = 1; 879
880 } else 880 /* if no packet is in qdisc/device queue, then allow XPS to select
881 skb->ooo_okay = 0; 881 * another queue.
882 */
883 skb->ooo_okay = sk_wmem_alloc_get(sk) == 0;
882 884
883 skb_push(skb, tcp_header_size); 885 skb_push(skb, tcp_header_size);
884 skb_reset_transport_header(skb); 886 skb_reset_transport_header(skb);