Skip to content

Commit 7e2040d

Browse files
iamkafaidavem330
authored andcommitted
ipv6: datagram: Refactor dst lookup and update codes to a new function
This patch moves the route lookup and update codes for connected datagram sk to a newly created function ip6_datagram_dst_update() It will be reused during the pmtu update in the later patch. Signed-off-by: Martin KaFai Lau <[email protected]> Cc: Cong Wang <[email protected]> Cc: Eric Dumazet <[email protected]> Cc: Wei Wang <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent 80fbdb2 commit 7e2040d

File tree

1 file changed

+57
-46
lines changed

1 file changed

+57
-46
lines changed

net/ipv6/datagram.c

Lines changed: 57 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -64,16 +64,65 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
6464
security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
6565
}
6666

67+
static int ip6_datagram_dst_update(struct sock *sk)
68+
{
69+
struct ip6_flowlabel *flowlabel = NULL;
70+
struct in6_addr *final_p, final;
71+
struct ipv6_txoptions *opt;
72+
struct dst_entry *dst;
73+
struct inet_sock *inet = inet_sk(sk);
74+
struct ipv6_pinfo *np = inet6_sk(sk);
75+
struct flowi6 fl6;
76+
int err = 0;
77+
78+
if (np->sndflow && (np->flow_label & IPV6_FLOWLABEL_MASK)) {
79+
flowlabel = fl6_sock_lookup(sk, np->flow_label);
80+
if (!flowlabel)
81+
return -EINVAL;
82+
}
83+
ip6_datagram_flow_key_init(&fl6, sk);
84+
85+
rcu_read_lock();
86+
opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
87+
final_p = fl6_update_dst(&fl6, opt, &final);
88+
rcu_read_unlock();
89+
90+
dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
91+
if (IS_ERR(dst)) {
92+
err = PTR_ERR(dst);
93+
goto out;
94+
}
95+
96+
if (ipv6_addr_any(&np->saddr))
97+
np->saddr = fl6.saddr;
98+
99+
if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
100+
sk->sk_v6_rcv_saddr = fl6.saddr;
101+
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
102+
if (sk->sk_prot->rehash)
103+
sk->sk_prot->rehash(sk);
104+
}
105+
106+
ip6_dst_store(sk, dst,
107+
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
108+
&sk->sk_v6_daddr : NULL,
109+
#ifdef CONFIG_IPV6_SUBTREES
110+
ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
111+
&np->saddr :
112+
#endif
113+
NULL);
114+
115+
out:
116+
fl6_sock_release(flowlabel);
117+
return err;
118+
}
119+
67120
static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
68121
{
69122
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
70123
struct inet_sock *inet = inet_sk(sk);
71124
struct ipv6_pinfo *np = inet6_sk(sk);
72-
struct in6_addr *daddr, *final_p, final;
73-
struct dst_entry *dst;
74-
struct flowi6 fl6;
75-
struct ip6_flowlabel *flowlabel = NULL;
76-
struct ipv6_txoptions *opt;
125+
struct in6_addr *daddr;
77126
int addr_type;
78127
int err;
79128
__be32 fl6_flowlabel = 0;
@@ -91,14 +140,8 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a
91140
if (usin->sin6_family != AF_INET6)
92141
return -EAFNOSUPPORT;
93142

94-
if (np->sndflow) {
143+
if (np->sndflow)
95144
fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
96-
if (fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
97-
flowlabel = fl6_sock_lookup(sk, fl6_flowlabel);
98-
if (!flowlabel)
99-
return -EINVAL;
100-
}
101-
}
102145

103146
addr_type = ipv6_addr_type(&usin->sin6_addr);
104147

@@ -178,45 +221,13 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a
178221
* destination cache for it.
179222
*/
180223

181-
ip6_datagram_flow_key_init(&fl6, sk);
182-
183-
rcu_read_lock();
184-
opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
185-
final_p = fl6_update_dst(&fl6, opt, &final);
186-
rcu_read_unlock();
187-
188-
dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
189-
err = 0;
190-
if (IS_ERR(dst)) {
191-
err = PTR_ERR(dst);
224+
err = ip6_datagram_dst_update(sk);
225+
if (err)
192226
goto out;
193-
}
194-
195-
/* source address lookup done in ip6_dst_lookup */
196-
197-
if (ipv6_addr_any(&np->saddr))
198-
np->saddr = fl6.saddr;
199-
200-
if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
201-
sk->sk_v6_rcv_saddr = fl6.saddr;
202-
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
203-
if (sk->sk_prot->rehash)
204-
sk->sk_prot->rehash(sk);
205-
}
206-
207-
ip6_dst_store(sk, dst,
208-
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
209-
&sk->sk_v6_daddr : NULL,
210-
#ifdef CONFIG_IPV6_SUBTREES
211-
ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
212-
&np->saddr :
213-
#endif
214-
NULL);
215227

216228
sk->sk_state = TCP_ESTABLISHED;
217229
sk_set_txhash(sk);
218230
out:
219-
fl6_sock_release(flowlabel);
220231
return err;
221232
}
222233

0 commit comments

Comments
 (0)