diff options
Diffstat (limited to 'net/dccp/ipv4.c')
-rw-r--r-- | net/dccp/ipv4.c | 50 |
1 files changed, 28 insertions, 22 deletions
diff --git a/net/dccp/ipv4.c b/net/dccp/ipv4.c index 45a434f94169..ae451c6d83ba 100644 --- a/net/dccp/ipv4.c +++ b/net/dccp/ipv4.c | |||
@@ -43,9 +43,9 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
43 | struct inet_sock *inet = inet_sk(sk); | 43 | struct inet_sock *inet = inet_sk(sk); |
44 | struct dccp_sock *dp = dccp_sk(sk); | 44 | struct dccp_sock *dp = dccp_sk(sk); |
45 | const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; | 45 | const struct sockaddr_in *usin = (struct sockaddr_in *)uaddr; |
46 | __be16 orig_sport, orig_dport; | ||
46 | struct rtable *rt; | 47 | struct rtable *rt; |
47 | __be32 daddr, nexthop; | 48 | __be32 daddr, nexthop; |
48 | int tmp; | ||
49 | int err; | 49 | int err; |
50 | 50 | ||
51 | dp->dccps_role = DCCP_ROLE_CLIENT; | 51 | dp->dccps_role = DCCP_ROLE_CLIENT; |
@@ -63,12 +63,14 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
63 | nexthop = inet->opt->faddr; | 63 | nexthop = inet->opt->faddr; |
64 | } | 64 | } |
65 | 65 | ||
66 | tmp = ip_route_connect(&rt, nexthop, inet->inet_saddr, | 66 | orig_sport = inet->inet_sport; |
67 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, | 67 | orig_dport = usin->sin_port; |
68 | IPPROTO_DCCP, | 68 | rt = ip_route_connect(nexthop, inet->inet_saddr, |
69 | inet->inet_sport, usin->sin_port, sk, 1); | 69 | RT_CONN_FLAGS(sk), sk->sk_bound_dev_if, |
70 | if (tmp < 0) | 70 | IPPROTO_DCCP, |
71 | return tmp; | 71 | orig_sport, orig_dport, sk, true); |
72 | if (IS_ERR(rt)) | ||
73 | return PTR_ERR(rt); | ||
72 | 74 | ||
73 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { | 75 | if (rt->rt_flags & (RTCF_MULTICAST | RTCF_BROADCAST)) { |
74 | ip_rt_put(rt); | 76 | ip_rt_put(rt); |
@@ -99,11 +101,13 @@ int dccp_v4_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len) | |||
99 | if (err != 0) | 101 | if (err != 0) |
100 | goto failure; | 102 | goto failure; |
101 | 103 | ||
102 | err = ip_route_newports(&rt, IPPROTO_DCCP, inet->inet_sport, | 104 | rt = ip_route_newports(rt, IPPROTO_DCCP, |
103 | inet->inet_dport, sk); | 105 | orig_sport, orig_dport, |
104 | if (err != 0) | 106 | inet->inet_sport, inet->inet_dport, sk); |
107 | if (IS_ERR(rt)) { | ||
108 | rt = NULL; | ||
105 | goto failure; | 109 | goto failure; |
106 | 110 | } | |
107 | /* OK, now commit destination to socket. */ | 111 | /* OK, now commit destination to socket. */ |
108 | sk_setup_caps(sk, &rt->dst); | 112 | sk_setup_caps(sk, &rt->dst); |
109 | 113 | ||
@@ -461,17 +465,19 @@ static struct dst_entry* dccp_v4_route_skb(struct net *net, struct sock *sk, | |||
461 | struct sk_buff *skb) | 465 | struct sk_buff *skb) |
462 | { | 466 | { |
463 | struct rtable *rt; | 467 | struct rtable *rt; |
464 | struct flowi fl = { .oif = skb_rtable(skb)->rt_iif, | 468 | struct flowi4 fl4 = { |
465 | .fl4_dst = ip_hdr(skb)->saddr, | 469 | .flowi4_oif = skb_rtable(skb)->rt_iif, |
466 | .fl4_src = ip_hdr(skb)->daddr, | 470 | .daddr = ip_hdr(skb)->saddr, |
467 | .fl4_tos = RT_CONN_FLAGS(sk), | 471 | .saddr = ip_hdr(skb)->daddr, |
468 | .proto = sk->sk_protocol, | 472 | .flowi4_tos = RT_CONN_FLAGS(sk), |
469 | .fl_ip_sport = dccp_hdr(skb)->dccph_dport, | 473 | .flowi4_proto = sk->sk_protocol, |
470 | .fl_ip_dport = dccp_hdr(skb)->dccph_sport | 474 | .fl4_sport = dccp_hdr(skb)->dccph_dport, |
471 | }; | 475 | .fl4_dport = dccp_hdr(skb)->dccph_sport, |
472 | 476 | }; | |
473 | security_skb_classify_flow(skb, &fl); | 477 | |
474 | if (ip_route_output_flow(net, &rt, &fl, sk, 0)) { | 478 | security_skb_classify_flow(skb, flowi4_to_flowi(&fl4)); |
479 | rt = ip_route_output_flow(net, &fl4, sk); | ||
480 | if (IS_ERR(rt)) { | ||
475 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); | 481 | IP_INC_STATS_BH(net, IPSTATS_MIB_OUTNOROUTES); |
476 | return NULL; | 482 | return NULL; |
477 | } | 483 | } |