diff options
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r-- | net/ipv6/tcp_ipv6.c | 23 |
1 files changed, 16 insertions, 7 deletions
diff --git a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c index 802a1a6b1037..2546fc9f0a78 100644 --- a/net/ipv6/tcp_ipv6.c +++ b/net/ipv6/tcp_ipv6.c | |||
@@ -251,6 +251,8 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
251 | final_p = &final; | 251 | final_p = &final; |
252 | } | 252 | } |
253 | 253 | ||
254 | security_sk_classify_flow(sk, &fl); | ||
255 | |||
254 | err = ip6_dst_lookup(sk, &dst, &fl); | 256 | err = ip6_dst_lookup(sk, &dst, &fl); |
255 | if (err) | 257 | if (err) |
256 | goto failure; | 258 | goto failure; |
@@ -270,7 +272,7 @@ static int tcp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
270 | inet->rcv_saddr = LOOPBACK4_IPV6; | 272 | inet->rcv_saddr = LOOPBACK4_IPV6; |
271 | 273 | ||
272 | sk->sk_gso_type = SKB_GSO_TCPV6; | 274 | sk->sk_gso_type = SKB_GSO_TCPV6; |
273 | __ip6_dst_store(sk, dst, NULL); | 275 | __ip6_dst_store(sk, dst, NULL, NULL); |
274 | 276 | ||
275 | icsk->icsk_ext_hdr_len = 0; | 277 | icsk->icsk_ext_hdr_len = 0; |
276 | if (np->opt) | 278 | if (np->opt) |
@@ -374,6 +376,7 @@ static void tcp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
374 | fl.oif = sk->sk_bound_dev_if; | 376 | fl.oif = sk->sk_bound_dev_if; |
375 | fl.fl_ip_dport = inet->dport; | 377 | fl.fl_ip_dport = inet->dport; |
376 | fl.fl_ip_sport = inet->sport; | 378 | fl.fl_ip_sport = inet->sport; |
379 | security_skb_classify_flow(skb, &fl); | ||
377 | 380 | ||
378 | if ((err = ip6_dst_lookup(sk, &dst, &fl))) { | 381 | if ((err = ip6_dst_lookup(sk, &dst, &fl))) { |
379 | sk->sk_err_soft = -err; | 382 | sk->sk_err_soft = -err; |
@@ -467,6 +470,7 @@ static int tcp_v6_send_synack(struct sock *sk, struct request_sock *req, | |||
467 | fl.oif = treq->iif; | 470 | fl.oif = treq->iif; |
468 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 471 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
469 | fl.fl_ip_sport = inet_sk(sk)->sport; | 472 | fl.fl_ip_sport = inet_sk(sk)->sport; |
473 | security_req_classify_flow(req, &fl); | ||
470 | 474 | ||
471 | if (dst == NULL) { | 475 | if (dst == NULL) { |
472 | opt = np->opt; | 476 | opt = np->opt; |
@@ -541,7 +545,7 @@ static void tcp_v6_send_check(struct sock *sk, int len, struct sk_buff *skb) | |||
541 | struct ipv6_pinfo *np = inet6_sk(sk); | 545 | struct ipv6_pinfo *np = inet6_sk(sk); |
542 | struct tcphdr *th = skb->h.th; | 546 | struct tcphdr *th = skb->h.th; |
543 | 547 | ||
544 | if (skb->ip_summed == CHECKSUM_HW) { | 548 | if (skb->ip_summed == CHECKSUM_PARTIAL) { |
545 | th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); | 549 | th->check = ~csum_ipv6_magic(&np->saddr, &np->daddr, len, IPPROTO_TCP, 0); |
546 | skb->csum = offsetof(struct tcphdr, check); | 550 | skb->csum = offsetof(struct tcphdr, check); |
547 | } else { | 551 | } else { |
@@ -566,7 +570,7 @@ static int tcp_v6_gso_send_check(struct sk_buff *skb) | |||
566 | th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, | 570 | th->check = ~csum_ipv6_magic(&ipv6h->saddr, &ipv6h->daddr, skb->len, |
567 | IPPROTO_TCP, 0); | 571 | IPPROTO_TCP, 0); |
568 | skb->csum = offsetof(struct tcphdr, check); | 572 | skb->csum = offsetof(struct tcphdr, check); |
569 | skb->ip_summed = CHECKSUM_HW; | 573 | skb->ip_summed = CHECKSUM_PARTIAL; |
570 | return 0; | 574 | return 0; |
571 | } | 575 | } |
572 | 576 | ||
@@ -625,6 +629,7 @@ static void tcp_v6_send_reset(struct sk_buff *skb) | |||
625 | fl.oif = inet6_iif(skb); | 629 | fl.oif = inet6_iif(skb); |
626 | fl.fl_ip_dport = t1->dest; | 630 | fl.fl_ip_dport = t1->dest; |
627 | fl.fl_ip_sport = t1->source; | 631 | fl.fl_ip_sport = t1->source; |
632 | security_skb_classify_flow(skb, &fl); | ||
628 | 633 | ||
629 | /* sk = NULL, but it is safe for now. RST socket required. */ | 634 | /* sk = NULL, but it is safe for now. RST socket required. */ |
630 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 635 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
@@ -691,6 +696,7 @@ static void tcp_v6_send_ack(struct sk_buff *skb, u32 seq, u32 ack, u32 win, u32 | |||
691 | fl.oif = inet6_iif(skb); | 696 | fl.oif = inet6_iif(skb); |
692 | fl.fl_ip_dport = t1->dest; | 697 | fl.fl_ip_dport = t1->dest; |
693 | fl.fl_ip_sport = t1->source; | 698 | fl.fl_ip_sport = t1->source; |
699 | security_skb_classify_flow(skb, &fl); | ||
694 | 700 | ||
695 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { | 701 | if (!ip6_dst_lookup(NULL, &buff->dst, &fl)) { |
696 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { | 702 | if (xfrm_lookup(&buff->dst, &fl, NULL, 0) >= 0) { |
@@ -820,6 +826,8 @@ static int tcp_v6_conn_request(struct sock *sk, struct sk_buff *skb) | |||
820 | 826 | ||
821 | tcp_rsk(req)->snt_isn = isn; | 827 | tcp_rsk(req)->snt_isn = isn; |
822 | 828 | ||
829 | security_inet_conn_request(sk, skb, req); | ||
830 | |||
823 | if (tcp_v6_send_synack(sk, req, NULL)) | 831 | if (tcp_v6_send_synack(sk, req, NULL)) |
824 | goto drop; | 832 | goto drop; |
825 | 833 | ||
@@ -923,6 +931,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
923 | fl.oif = sk->sk_bound_dev_if; | 931 | fl.oif = sk->sk_bound_dev_if; |
924 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 932 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; |
925 | fl.fl_ip_sport = inet_sk(sk)->sport; | 933 | fl.fl_ip_sport = inet_sk(sk)->sport; |
934 | security_req_classify_flow(req, &fl); | ||
926 | 935 | ||
927 | if (ip6_dst_lookup(sk, &dst, &fl)) | 936 | if (ip6_dst_lookup(sk, &dst, &fl)) |
928 | goto out; | 937 | goto out; |
@@ -945,7 +954,7 @@ static struct sock * tcp_v6_syn_recv_sock(struct sock *sk, struct sk_buff *skb, | |||
945 | */ | 954 | */ |
946 | 955 | ||
947 | newsk->sk_gso_type = SKB_GSO_TCPV6; | 956 | newsk->sk_gso_type = SKB_GSO_TCPV6; |
948 | __ip6_dst_store(newsk, dst, NULL); | 957 | __ip6_dst_store(newsk, dst, NULL, NULL); |
949 | 958 | ||
950 | newtcp6sk = (struct tcp6_sock *)newsk; | 959 | newtcp6sk = (struct tcp6_sock *)newsk; |
951 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; | 960 | inet_sk(newsk)->pinet6 = &newtcp6sk->inet6; |
@@ -1024,7 +1033,7 @@ out: | |||
1024 | 1033 | ||
1025 | static int tcp_v6_checksum_init(struct sk_buff *skb) | 1034 | static int tcp_v6_checksum_init(struct sk_buff *skb) |
1026 | { | 1035 | { |
1027 | if (skb->ip_summed == CHECKSUM_HW) { | 1036 | if (skb->ip_summed == CHECKSUM_COMPLETE) { |
1028 | if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, | 1037 | if (!tcp_v6_check(skb->h.th,skb->len,&skb->nh.ipv6h->saddr, |
1029 | &skb->nh.ipv6h->daddr,skb->csum)) { | 1038 | &skb->nh.ipv6h->daddr,skb->csum)) { |
1030 | skb->ip_summed = CHECKSUM_UNNECESSARY; | 1039 | skb->ip_summed = CHECKSUM_UNNECESSARY; |
@@ -1066,7 +1075,7 @@ static int tcp_v6_do_rcv(struct sock *sk, struct sk_buff *skb) | |||
1066 | if (skb->protocol == htons(ETH_P_IP)) | 1075 | if (skb->protocol == htons(ETH_P_IP)) |
1067 | return tcp_v4_do_rcv(sk, skb); | 1076 | return tcp_v4_do_rcv(sk, skb); |
1068 | 1077 | ||
1069 | if (sk_filter(sk, skb, 0)) | 1078 | if (sk_filter(sk, skb)) |
1070 | goto discard; | 1079 | goto discard; |
1071 | 1080 | ||
1072 | /* | 1081 | /* |
@@ -1223,7 +1232,7 @@ process: | |||
1223 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) | 1232 | if (!xfrm6_policy_check(sk, XFRM_POLICY_IN, skb)) |
1224 | goto discard_and_relse; | 1233 | goto discard_and_relse; |
1225 | 1234 | ||
1226 | if (sk_filter(sk, skb, 0)) | 1235 | if (sk_filter(sk, skb)) |
1227 | goto discard_and_relse; | 1236 | goto discard_and_relse; |
1228 | 1237 | ||
1229 | skb->dev = NULL; | 1238 | skb->dev = NULL; |