diff options
author | David S. Miller <davem@davemloft.net> | 2013-05-24 19:48:28 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2013-05-24 19:48:28 -0400 |
commit | e6ff4c75f9095f61b3a66c2a78e47b62864022dd (patch) | |
tree | 425ea9463cbec0b1975b8a33d9a56817143055d0 /net/ipv4 | |
parent | ee9c799c231324de681eb21e06d8bf4842768b75 (diff) | |
parent | 0e255f1c0c9add2f0c920240ac4cadc28ae274c3 (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.c | 3 | ||||
-rw-r--r-- | net/ipv4/netfilter/ipt_ULOG.c | 13 | ||||
-rw-r--r-- | net/ipv4/tcp.c | 29 | ||||
-rw-r--r-- | net/ipv4/tcp_input.c | 23 | ||||
-rw-r--r-- | net/ipv4/tcp_output.c | 10 |
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 | ||
165 | static void ipt_ulog_packet(unsigned int hooknum, | 165 | static 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: | |||
291 | static unsigned int | 291 | static unsigned int |
292 | ulog_tg(struct sk_buff *skb, const struct xt_action_param *par) | 292 | ulog_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 | ||
299 | static void ipt_logfn(u_int8_t pf, | 301 | static 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 | ||
324 | static int ulog_tg_check(const struct xt_tgchk_param *par) | 327 | static 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 | */ |
2681 | static void tcp_fastretrans_alert(struct sock *sk, int pkts_acked, | 2681 | static 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); |