aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv6/tcp_ipv6.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv6/tcp_ipv6.c')
-rw-r--r--net/ipv6/tcp_ipv6.c23
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
1025static int tcp_v6_checksum_init(struct sk_buff *skb) 1034static 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;