aboutsummaryrefslogtreecommitdiffstats
path: root/net/dccp/ipv6.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2011-03-01 16:19:07 -0500
committerDavid S. Miller <davem@davemloft.net>2011-03-01 16:19:07 -0500
commit68d0c6d34d586a893292d4fb633a3bf8c547b222 (patch)
treeb6d812307621873cf16000171563c1f68b5bc255 /net/dccp/ipv6.c
parent903ab86d195cca295379699299c5fc10beba31c7 (diff)
ipv6: Consolidate route lookup sequences.
Route lookups follow a general pattern in the ipv6 code wherein we first find the non-IPSEC route, potentially override the flow destination address due to ipv6 options settings, and then finally make an IPSEC search using either xfrm_lookup() or __xfrm_lookup(). __xfrm_lookup() is used when we want to generate a blackhole route if the key manager needs to resolve the IPSEC rules (in this case -EREMOTE is returned and the original 'dst' is left unchanged). Otherwise plain xfrm_lookup() is used and when asynchronous IPSEC resolution is necessary, we simply fail the lookup completely. All of these cases are encapsulated into two routines, ip6_dst_lookup_flow and ip6_sk_dst_lookup_flow. The latter of which handles unconnected UDP datagram sockets. Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/dccp/ipv6.c')
-rw-r--r--net/dccp/ipv6.c65
1 files changed, 20 insertions, 45 deletions
diff --git a/net/dccp/ipv6.c b/net/dccp/ipv6.c
index 460d545a6509..5efc57f5e605 100644
--- a/net/dccp/ipv6.c
+++ b/net/dccp/ipv6.c
@@ -162,15 +162,9 @@ static void dccp_v6_err(struct sk_buff *skb, struct inet6_skb_parm *opt,
162 fl.fl_ip_sport = inet->inet_sport; 162 fl.fl_ip_sport = inet->inet_sport;
163 security_sk_classify_flow(sk, &fl); 163 security_sk_classify_flow(sk, &fl);
164 164
165 err = ip6_dst_lookup(sk, &dst, &fl); 165 dst = ip6_dst_lookup_flow(sk, &fl, 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
@@ -267,16 +261,12 @@ static int dccp_v6_send_response(struct sock *sk, struct request_sock *req,
267 261
268 final_p = fl6_update_dst(&fl, opt, &final); 262 final_p = fl6_update_dst(&fl, opt, &final);
269 263
270 err = ip6_dst_lookup(sk, &dst, &fl); 264 dst = ip6_dst_lookup_flow(sk, &fl, 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) {
@@ -338,14 +328,13 @@ static void dccp_v6_ctl_send_reset(struct sock *sk, struct sk_buff *rxskb)
338 security_skb_classify_flow(rxskb, &fl); 328 security_skb_classify_flow(rxskb, &fl);
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, &fl, 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, &fl, 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);
@@ -550,13 +539,8 @@ static struct sock *dccp_v6_request_recv_sock(struct sock *sk,
550 fl.fl_ip_sport = inet_rsk(req)->loc_port; 539 fl.fl_ip_sport = inet_rsk(req)->loc_port;
551 security_sk_classify_flow(sk, &fl); 540 security_sk_classify_flow(sk, &fl);
552 541
553 if (ip6_dst_lookup(sk, &dst, &fl)) 542 dst = ip6_dst_lookup_flow(sk, &fl, final_p, false);
554 goto out; 543 if (IS_ERR(dst))
555
556 if (final_p)
557 ipv6_addr_copy(&fl.fl6_dst, final_p);
558
559 if ((xfrm_lookup(sock_net(sk), &dst, &fl, sk, 0)) < 0)
560 goto out; 544 goto out;
561 } 545 }
562 546
@@ -979,19 +963,10 @@ static int dccp_v6_connect(struct sock *sk, struct sockaddr *uaddr,
979 963
980 final_p = fl6_update_dst(&fl, np->opt, &final); 964 final_p = fl6_update_dst(&fl, np->opt, &final);
981 965
982 err = ip6_dst_lookup(sk, &dst, &fl); 966 dst = ip6_dst_lookup_flow(sk, &fl, final_p, true);
983 if (err) 967 if (IS_ERR(dst)) {
968 err = PTR_ERR(dst);
984 goto failure; 969 goto failure;
985
986 if (final_p)
987 ipv6_addr_copy(&fl.fl6_dst, final_p);
988
989 err = __xfrm_lookup(sock_net(sk), &dst, &fl, sk, XFRM_LOOKUP_WAIT);
990 if (err < 0) {
991 if (err == -EREMOTE)
992 err = ip6_dst_blackhole(sk, &dst, &fl);
993 if (err < 0)
994 goto failure;
995 } 970 }
996 971
997 if (saddr == NULL) { 972 if (saddr == NULL) {