diff options
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r-- | net/dccp/ipv6.c | 188 |
1 files changed, 80 insertions, 108 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c index dca711df9b60..de1b7e37ad5b 100644 --- a/net/dccp/ipv6.c +++ b/net/dccp/ipv6.c | |||
@@ -147,30 +147,24 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt, | |||
147 | dst = __sk_dst_check(sk, np->dst_cookie); | 147 | dst = __sk_dst_check(sk, np->dst_cookie); |
148 | if (dst == NULL) { | 148 | if (dst == NULL) { |
149 | struct inet_sock *inet = inet_sk(sk); | 149 | struct inet_sock *inet = inet_sk(sk); |
150 | struct flowi fl; | 150 | struct flowi6 fl6; |
151 | 151 | ||
152 | /* BUGGG_FUTURE: Again, it is not clear how | 152 | /* BUGGG_FUTURE: Again, it is not clear how |
153 | to handle rthdr case. Ignore this complexity | 153 | to handle rthdr case. Ignore this complexity |
154 | for now. | 154 | for now. |
155 | */ | 155 | */ |
156 | memset(&fl, 0, sizeof(fl)); | 156 | memset(&fl6, 0, sizeof(fl6)); |
157 | fl.proto = IPPROTO_DCCP; | 157 | fl6.flowi6_proto = IPPROTO_DCCP; |
158 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | 158 | ipv6_addr_copy(&fl6.daddr, &np->daddr); |
159 | ipv6_addr_copy(&fl.fl6_src, &np->saddr); | 159 | ipv6_addr_copy(&fl6.saddr, &np->saddr); |
160 | fl.oif = sk->sk_bound_dev_if; | 160 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
161 | fl.fl_ip_dport = inet->inet_dport; | 161 | fl6.fl6_dport = inet->inet_dport; |
162 | fl.fl_ip_sport = inet->inet_sport; | 162 | fl6.fl6_sport = inet->inet_sport; |
163 | security_sk_classify_flow(sk, &fl); | 163 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
164 | 164 | ||
165 | err = ip6_dst_lookup(sk, &dst, &fl); | 165 | dst = ip6_dst_lookup_flow(sk, &fl6, NULL, false); |
166 | if (err) { | 166 | if (IS_ERR(dst)) { |
167 | sk->sk_err_soft = -err; | 167 | sk->sk_err_soft = -PTR_ERR(dst); |
168 | goto out; | ||
169 | } | ||
170 | |||
171 | err = xfrm_lookup(net, &dst, &fl, sk, 0); | ||
172 | if (err < 0) { | ||
173 | sk->sk_err_soft = -err; | ||
174 | goto out; | 168 | goto out; |
175 | } | 169 | } |
176 | } else | 170 | } else |
@@ -249,34 +243,30 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
249 | struct sk_buff *skb; | 243 | struct sk_buff *skb; |
250 | struct ipv6_txoptions *opt = NULL; | 244 | struct ipv6_txoptions *opt = NULL; |
251 | struct in6_addr *final_p, final; | 245 | struct in6_addr *final_p, final; |
252 | struct flowi fl; | 246 | struct flowi6 fl6; |
253 | int err = -1; | 247 | int err = -1; |
254 | struct dst_entry *dst; | 248 | struct dst_entry *dst; |
255 | 249 | ||
256 | memset(&fl, 0, sizeof(fl)); | 250 | memset(&fl6, 0, sizeof(fl6)); |
257 | fl.proto = IPPROTO_DCCP; | 251 | fl6.flowi6_proto = IPPROTO_DCCP; |
258 | ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); | 252 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); |
259 | ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); | 253 | ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); |
260 | fl.fl6_flowlabel = 0; | 254 | fl6.flowlabel = 0; |
261 | fl.oif = ireq6->iif; | 255 | fl6.flowi6_oif = ireq6->iif; |
262 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 256 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
263 | fl.fl_ip_sport = inet_rsk(req)->loc_port; | 257 | fl6.fl6_sport = inet_rsk(req)->loc_port; |
264 | security_req_classify_flow(req, &fl); | 258 | security_req_classify_flow(req, flowi6_to_flowi(&fl6)); |
265 | 259 | ||
266 | opt = np->opt; | 260 | opt = np->opt; |
267 | 261 | ||
268 | final_p = fl6_update_dst(&fl, opt, &final); | 262 | final_p = fl6_update_dst(&fl6, opt, &final); |
269 | 263 | ||
270 | err = ip6_dst_lookup(sk, &dst, &fl); | 264 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); |
271 | if (err) | 265 | if (IS_ERR(dst)) { |
272 | goto done; | 266 | err = PTR_ERR(dst); |
273 | 267 | dst = NULL; | |
274 | if (final_p) | ||
275 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
276 | |||
277 | err = xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0); | ||
278 | if (err < 0) | ||
279 | goto done; | 268 | goto done; |
269 | } | ||
280 | 270 | ||
281 | skb = dccp_make_response(sk, dst, req); | 271 | skb = dccp_make_response(sk, dst, req); |
282 | if (skb != NULL) { | 272 | if (skb != NULL) { |
@@ -285,8 +275,8 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req, | |||
285 | dh->dccph_checksum = dccp_v6_csum_finish(skb, | 275 | dh->dccph_checksum = dccp_v6_csum_finish(skb, |
286 | &ireq6->loc_addr, | 276 | &ireq6->loc_addr, |
287 | &ireq6->rmt_addr); | 277 | &ireq6->rmt_addr); |
288 | ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); | 278 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); |
289 | err = ip6_xmit(sk, skb, &fl, opt); | 279 | err = ip6_xmit(sk, skb, &fl6, opt); |
290 | err = net_xmit_eval(err); | 280 | err = net_xmit_eval(err); |
291 | } | 281 | } |
292 | 282 | ||
@@ -308,7 +298,7 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) | |||
308 | { | 298 | { |
309 | struct ipv6hdr *rxip6h; | 299 | struct ipv6hdr *rxip6h; |
310 | struct sk_buff *skb; | 300 | struct sk_buff *skb; |
311 | struct flowi fl; | 301 | struct flowi6 fl6; |
312 | struct net *net = dev_net(skb_dst(rxskb)->dev); | 302 | struct net *net = dev_net(skb_dst(rxskb)->dev); |
313 | struct sock *ctl_sk = net->dccp.v6_ctl_sk; | 303 | struct sock *ctl_sk = net->dccp.v6_ctl_sk; |
314 | struct dst_entry *dst; | 304 | struct dst_entry *dst; |
@@ -327,25 +317,24 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb) | |||
327 | dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr, | 317 | dccp_hdr(skb)->dccph_checksum = dccp_v6_csum_finish(skb, &rxip6h->saddr, |
328 | &rxip6h->daddr); | 318 | &rxip6h->daddr); |
329 | 319 | ||
330 | memset(&fl, 0, sizeof(fl)); | 320 | memset(&fl6, 0, sizeof(fl6)); |
331 | ipv6_addr_copy(&fl.fl6_dst, &rxip6h->saddr); | 321 | ipv6_addr_copy(&fl6.daddr, &rxip6h->saddr); |
332 | ipv6_addr_copy(&fl.fl6_src, &rxip6h->daddr); | 322 | ipv6_addr_copy(&fl6.saddr, &rxip6h->daddr); |
333 | 323 | ||
334 | fl.proto = IPPROTO_DCCP; | 324 | fl6.flowi6_proto = IPPROTO_DCCP; |
335 | fl.oif = inet6_iif(rxskb); | 325 | fl6.flowi6_oif = inet6_iif(rxskb); |
336 | fl.fl_ip_dport = dccp_hdr(skb)->dccph_dport; | 326 | fl6.fl6_dport = dccp_hdr(skb)->dccph_dport; |
337 | fl.fl_ip_sport = dccp_hdr(skb)->dccph_sport; | 327 | fl6.fl6_sport = dccp_hdr(skb)->dccph_sport; |
338 | security_skb_classify_flow(rxskb, &fl); | 328 | security_skb_classify_flow(rxskb, flowi6_to_flowi(&fl6)); |
339 | 329 | ||
340 | /* sk = NULL, but it is safe for now. RST socket required. */ | 330 | /* sk = NULL, but it is safe for now. RST socket required. */ |
341 | if (!ip6_dst_lookup(ctl_sk, &dst, &fl)) { | 331 | dst = ip6_dst_lookup_flow(ctl_sk, &fl6, NULL, false); |
342 | if (xfrm_lookup(net, &dst, &fl, NULL, 0) >= 0) { | 332 | if (!IS_ERR(dst)) { |
343 | skb_dst_set(skb, dst); | 333 | skb_dst_set(skb, dst); |
344 | ip6_xmit(ctl_sk, skb, &fl, NULL); | 334 | ip6_xmit(ctl_sk, skb, &fl6, NULL); |
345 | DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); | 335 | DCCP_INC_STATS_BH(DCCP_MIB_OUTSEGS); |
346 | DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); | 336 | DCCP_INC_STATS_BH(DCCP_MIB_OUTRSTS); |
347 | return; | 337 | return; |
348 | } | ||
349 | } | 338 | } |
350 | 339 | ||
351 | kfree_skb(skb); | 340 | kfree_skb(skb); |
@@ -484,7 +473,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
484 | struct inet6_request_sock *ireq6 = inet6_rsk(req); | 473 | struct inet6_request_sock *ireq6 = inet6_rsk(req); |
485 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); | 474 | struct ipv6_pinfo *newnp, *np = inet6_sk(sk); |
486 | struct inet_sock *newinet; | 475 | struct inet_sock *newinet; |
487 | struct dccp_sock *newdp; | ||
488 | struct dccp6_sock *newdp6; | 476 | struct dccp6_sock *newdp6; |
489 | struct sock *newsk; | 477 | struct sock *newsk; |
490 | struct ipv6_txoptions *opt; | 478 | struct ipv6_txoptions *opt; |
@@ -498,7 +486,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
498 | return NULL; | 486 | return NULL; |
499 | 487 | ||
500 | newdp6 = (struct dccp6_sock *)newsk; | 488 | newdp6 = (struct dccp6_sock *)newsk; |
501 | newdp = dccp_sk(newsk); | ||
502 | newinet = inet_sk(newsk); | 489 | newinet = inet_sk(newsk); |
503 | newinet->pinet6 = &newdp6->inet6; | 490 | newinet->pinet6 = &newdp6->inet6; |
504 | newnp = inet6_sk(newsk); | 491 | newnp = inet6_sk(newsk); |
@@ -540,25 +527,20 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
540 | 527 | ||
541 | if (dst == NULL) { | 528 | if (dst == NULL) { |
542 | struct in6_addr *final_p, final; | 529 | struct in6_addr *final_p, final; |
543 | struct flowi fl; | 530 | struct flowi6 fl6; |
544 | 531 | ||
545 | memset(&fl, 0, sizeof(fl)); | 532 | memset(&fl6, 0, sizeof(fl6)); |
546 | fl.proto = IPPROTO_DCCP; | 533 | fl6.flowi6_proto = IPPROTO_DCCP; |
547 | ipv6_addr_copy(&fl.fl6_dst, &ireq6->rmt_addr); | 534 | ipv6_addr_copy(&fl6.daddr, &ireq6->rmt_addr); |
548 | final_p = fl6_update_dst(&fl, opt, &final); | 535 | final_p = fl6_update_dst(&fl6, opt, &final); |
549 | ipv6_addr_copy(&fl.fl6_src, &ireq6->loc_addr); | 536 | ipv6_addr_copy(&fl6.saddr, &ireq6->loc_addr); |
550 | fl.oif = sk->sk_bound_dev_if; | 537 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
551 | fl.fl_ip_dport = inet_rsk(req)->rmt_port; | 538 | fl6.fl6_dport = inet_rsk(req)->rmt_port; |
552 | fl.fl_ip_sport = inet_rsk(req)->loc_port; | 539 | fl6.fl6_sport = inet_rsk(req)->loc_port; |
553 | security_sk_classify_flow(sk, &fl); | 540 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
554 | 541 | ||
555 | if (ip6_dst_lookup(sk, &dst, &fl)) | 542 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, false); |
556 | goto out; | 543 | if (IS_ERR(dst)) |
557 | |||
558 | if (final_p) | ||
559 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
560 | |||
561 | if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0) | ||
562 | goto out; | 544 | goto out; |
563 | } | 545 | } |
564 | 546 | ||
@@ -578,7 +560,6 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk, | |||
578 | newdp6 = (struct dccp6_sock *)newsk; | 560 | newdp6 = (struct dccp6_sock *)newsk; |
579 | newinet = inet_sk(newsk); | 561 | newinet = inet_sk(newsk); |
580 | newinet->pinet6 = &newdp6->inet6; | 562 | newinet->pinet6 = &newdp6->inet6; |
581 | newdp = dccp_sk(newsk); | ||
582 | newnp = inet6_sk(newsk); | 563 | newnp = inet6_sk(newsk); |
583 | 564 | ||
584 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); | 565 | memcpy(newnp, np, sizeof(struct ipv6_pinfo)); |
@@ -878,7 +859,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
878 | struct ipv6_pinfo *np = inet6_sk(sk); | 859 | struct ipv6_pinfo *np = inet6_sk(sk); |
879 | struct dccp_sock *dp = dccp_sk(sk); | 860 | struct dccp_sock *dp = dccp_sk(sk); |
880 | struct in6_addr *saddr = NULL, *final_p, final; | 861 | struct in6_addr *saddr = NULL, *final_p, final; |
881 | struct flowi fl; | 862 | struct flowi6 fl6; |
882 | struct dst_entry *dst; | 863 | struct dst_entry *dst; |
883 | int addr_type; | 864 | int addr_type; |
884 | int err; | 865 | int err; |
@@ -891,14 +872,14 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
891 | if (usin->sin6_family != AF_INET6) | 872 | if (usin->sin6_family != AF_INET6) |
892 | return -EAFNOSUPPORT; | 873 | return -EAFNOSUPPORT; |
893 | 874 | ||
894 | memset(&fl, 0, sizeof(fl)); | 875 | memset(&fl6, 0, sizeof(fl6)); |
895 | 876 | ||
896 | if (np->sndflow) { | 877 | if (np->sndflow) { |
897 | fl.fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; | 878 | fl6.flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK; |
898 | IP6_ECN_flow_init(fl.fl6_flowlabel); | 879 | IP6_ECN_flow_init(fl6.flowlabel); |
899 | if (fl.fl6_flowlabel & IPV6_FLOWLABEL_MASK) { | 880 | if (fl6.flowlabel & IPV6_FLOWLABEL_MASK) { |
900 | struct ip6_flowlabel *flowlabel; | 881 | struct ip6_flowlabel *flowlabel; |
901 | flowlabel = fl6_sock_lookup(sk, fl.fl6_flowlabel); | 882 | flowlabel = fl6_sock_lookup(sk, fl6.flowlabel); |
902 | if (flowlabel == NULL) | 883 | if (flowlabel == NULL) |
903 | return -EINVAL; | 884 | return -EINVAL; |
904 | ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); | 885 | ipv6_addr_copy(&usin->sin6_addr, &flowlabel->dst); |
@@ -935,7 +916,7 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
935 | } | 916 | } |
936 | 917 | ||
937 | ipv6_addr_copy(&np->daddr, &usin->sin6_addr); | 918 | ipv6_addr_copy(&np->daddr, &usin->sin6_addr); |
938 | np->flow_label = fl.fl6_flowlabel; | 919 | np->flow_label = fl6.flowlabel; |
939 | 920 | ||
940 | /* | 921 | /* |
941 | * DCCP over IPv4 | 922 | * DCCP over IPv4 |
@@ -972,33 +953,24 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr, | |||
972 | if (!ipv6_addr_any(&np->rcv_saddr)) | 953 | if (!ipv6_addr_any(&np->rcv_saddr)) |
973 | saddr = &np->rcv_saddr; | 954 | saddr = &np->rcv_saddr; |
974 | 955 | ||
975 | fl.proto = IPPROTO_DCCP; | 956 | fl6.flowi6_proto = IPPROTO_DCCP; |
976 | ipv6_addr_copy(&fl.fl6_dst, &np->daddr); | 957 | ipv6_addr_copy(&fl6.daddr, &np->daddr); |
977 | ipv6_addr_copy(&fl.fl6_src, saddr ? saddr : &np->saddr); | 958 | ipv6_addr_copy(&fl6.saddr, saddr ? saddr : &np->saddr); |
978 | fl.oif = sk->sk_bound_dev_if; | 959 | fl6.flowi6_oif = sk->sk_bound_dev_if; |
979 | fl.fl_ip_dport = usin->sin6_port; | 960 | fl6.fl6_dport = usin->sin6_port; |
980 | fl.fl_ip_sport = inet->inet_sport; | 961 | fl6.fl6_sport = inet->inet_sport; |
981 | security_sk_classify_flow(sk, &fl); | 962 | security_sk_classify_flow(sk, flowi6_to_flowi(&fl6)); |
982 | 963 | ||
983 | final_p = fl6_update_dst(&fl, np->opt, &final); | 964 | final_p = fl6_update_dst(&fl6, np->opt, &final); |
984 | 965 | ||
985 | err = ip6_dst_lookup(sk, &dst, &fl); | 966 | dst = ip6_dst_lookup_flow(sk, &fl6, final_p, true); |
986 | if (err) | 967 | if (IS_ERR(dst)) { |
968 | err = PTR_ERR(dst); | ||
987 | goto failure; | 969 | goto failure; |
988 | |||
989 | if (final_p) | ||
990 | ipv6_addr_copy(&fl.fl6_dst, final_p); | ||
991 | |||
992 | err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT); | ||
993 | if (err < 0) { | ||
994 | if (err == -EREMOTE) | ||
995 | err = ip6_dst_blackhole(sk, &dst, &fl); | ||
996 | if (err < 0) | ||
997 | goto failure; | ||
998 | } | 970 | } |
999 | 971 | ||
1000 | if (saddr == NULL) { | 972 | if (saddr == NULL) { |
1001 | saddr = &fl.fl6_src; | 973 | saddr = &fl6.saddr; |
1002 | ipv6_addr_copy(&np->rcv_saddr, saddr); | 974 | ipv6_addr_copy(&np->rcv_saddr, saddr); |
1003 | } | 975 | } |
1004 | 976 | ||