aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_ipv4.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_ipv4.c')
-rw-r--r--net/ipv4/tcp_ipv4.c43
1 files changed, 21 insertions, 22 deletions
diff --git a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
index 3c23e70885f4..202cf09c4cd4 100644
--- a/net/ipv4/tcp_ipv4.c
+++ b/net/ipv4/tcp_ipv4.c
@@ -519,26 +519,31 @@ out:
519 sock_put(sk); 519 sock_put(sk);
520} 520}
521 521
522/* This routine computes an IPv4 TCP checksum. */ 522static void __tcp_v4_send_check(struct sk_buff *skb,
523void tcp_v4_send_check(struct sock *sk, int len, struct sk_buff *skb) 523 __be32 saddr, __be32 daddr)
524{ 524{
525 struct inet_sock *inet = inet_sk(sk);
526 struct tcphdr *th = tcp_hdr(skb); 525 struct tcphdr *th = tcp_hdr(skb);
527 526
528 if (skb->ip_summed == CHECKSUM_PARTIAL) { 527 if (skb->ip_summed == CHECKSUM_PARTIAL) {
529 th->check = ~tcp_v4_check(len, inet->inet_saddr, 528 th->check = ~tcp_v4_check(skb->len, saddr, daddr, 0);
530 inet->inet_daddr, 0);
531 skb->csum_start = skb_transport_header(skb) - skb->head; 529 skb->csum_start = skb_transport_header(skb) - skb->head;
532 skb->csum_offset = offsetof(struct tcphdr, check); 530 skb->csum_offset = offsetof(struct tcphdr, check);
533 } else { 531 } else {
534 th->check = tcp_v4_check(len, inet->inet_saddr, 532 th->check = tcp_v4_check(skb->len, saddr, daddr,
535 inet->inet_daddr,
536 csum_partial(th, 533 csum_partial(th,
537 th->doff << 2, 534 th->doff << 2,
538 skb->csum)); 535 skb->csum));
539 } 536 }
540} 537}
541 538
539/* This routine computes an IPv4 TCP checksum. */
540void tcp_v4_send_check(struct sock *sk, struct sk_buff *skb)
541{
542 struct inet_sock *inet = inet_sk(sk);
543
544 __tcp_v4_send_check(skb, inet->inet_saddr, inet->inet_daddr);
545}
546
542int tcp_v4_gso_send_check(struct sk_buff *skb) 547int tcp_v4_gso_send_check(struct sk_buff *skb)
543{ 548{
544 const struct iphdr *iph; 549 const struct iphdr *iph;
@@ -551,10 +556,8 @@ int tcp_v4_gso_send_check(struct sk_buff *skb)
551 th = tcp_hdr(skb); 556 th = tcp_hdr(skb);
552 557
553 th->check = 0; 558 th->check = 0;
554 th->check = ~tcp_v4_check(skb->len, iph->saddr, iph->daddr, 0);
555 skb->csum_start = skb_transport_header(skb) - skb->head;
556 skb->csum_offset = offsetof(struct tcphdr, check);
557 skb->ip_summed = CHECKSUM_PARTIAL; 559 skb->ip_summed = CHECKSUM_PARTIAL;
560 __tcp_v4_send_check(skb, iph->saddr, iph->daddr);
558 return 0; 561 return 0;
559} 562}
560 563
@@ -763,13 +766,7 @@ static int tcp_v4_send_synack(struct sock *sk, struct dst_entry *dst,
763 skb = tcp_make_synack(sk, dst, req, rvp); 766 skb = tcp_make_synack(sk, dst, req, rvp);
764 767
765 if (skb) { 768 if (skb) {
766 struct tcphdr *th = tcp_hdr(skb); 769 __tcp_v4_send_check(skb, ireq->loc_addr, ireq->rmt_addr);
767
768 th->check = tcp_v4_check(skb->len,
769 ireq->loc_addr,
770 ireq->rmt_addr,
771 csum_partial(th, skb->len,
772 skb->csum));
773 770
774 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr, 771 err = ip_build_and_send_pkt(skb, sk, ireq->loc_addr,
775 ireq->rmt_addr, 772 ireq->rmt_addr,
@@ -894,7 +891,7 @@ int tcp_v4_md5_do_add(struct sock *sk, __be32 addr,
894 kfree(newkey); 891 kfree(newkey);
895 return -ENOMEM; 892 return -ENOMEM;
896 } 893 }
897 sk->sk_route_caps &= ~NETIF_F_GSO_MASK; 894 sk_nocaps_add(sk, NETIF_F_GSO_MASK);
898 } 895 }
899 if (tcp_alloc_md5sig_pool(sk) == NULL) { 896 if (tcp_alloc_md5sig_pool(sk) == NULL) {
900 kfree(newkey); 897 kfree(newkey);
@@ -1024,7 +1021,7 @@ static int tcp_v4_parse_md5_keys(struct sock *sk, char __user *optval,
1024 return -EINVAL; 1021 return -EINVAL;
1025 1022
1026 tp->md5sig_info = p; 1023 tp->md5sig_info = p;
1027 sk->sk_route_caps &= ~NETIF_F_GSO_MASK; 1024 sk_nocaps_add(sk, NETIF_F_GSO_MASK);
1028 } 1025 }
1029 1026
1030 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, sk->sk_allocation); 1027 newkey = kmemdup(cmd.tcpm_key, cmd.tcpm_keylen, sk->sk_allocation);
@@ -1289,8 +1286,8 @@ int tcp_v4_conn_request(struct sock *sk, struct sk_buff *skb)
1289 goto drop_and_release; 1286 goto drop_and_release;
1290 1287
1291 /* Secret recipe starts with IP addresses */ 1288 /* Secret recipe starts with IP addresses */
1292 *mess++ ^= daddr; 1289 *mess++ ^= (__force u32)daddr;
1293 *mess++ ^= saddr; 1290 *mess++ ^= (__force u32)saddr;
1294 1291
1295 /* plus variable length Initiator Cookie */ 1292 /* plus variable length Initiator Cookie */
1296 c = (u8 *)mess; 1293 c = (u8 *)mess;
@@ -1465,7 +1462,7 @@ struct sock *tcp_v4_syn_recv_sock(struct sock *sk, struct sk_buff *skb,
1465 if (newkey != NULL) 1462 if (newkey != NULL)
1466 tcp_v4_md5_do_add(newsk, newinet->inet_daddr, 1463 tcp_v4_md5_do_add(newsk, newinet->inet_daddr,
1467 newkey, key->keylen); 1464 newkey, key->keylen);
1468 newsk->sk_route_caps &= ~NETIF_F_GSO_MASK; 1465 sk_nocaps_add(newsk, NETIF_F_GSO_MASK);
1469 } 1466 }
1470#endif 1467#endif
1471 1468
@@ -1675,6 +1672,8 @@ process:
1675 1672
1676 skb->dev = NULL; 1673 skb->dev = NULL;
1677 1674
1675 sock_rps_save_rxhash(sk, skb->rxhash);
1676
1678 bh_lock_sock_nested(sk); 1677 bh_lock_sock_nested(sk);
1679 ret = 0; 1678 ret = 0;
1680 if (!sock_owned_by_user(sk)) { 1679 if (!sock_owned_by_user(sk)) {