Skip to content

Commit

Permalink
ipv6: datagram: Refactor dst lookup and update codes to a new function
Browse files Browse the repository at this point in the history
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 <kafai@fb.com>
Cc: Cong Wang <xiyou.wangcong@gmail.com>
Cc: Eric Dumazet <edumazet@google.com>
Cc: Wei Wang <weiwan@google.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
Martin KaFai Lau authored and David S. Miller committed Apr 14, 2016
1 parent 80fbdb2 commit 7e2040d
Showing 1 changed file with 57 additions and 46 deletions.
103 changes: 57 additions & 46 deletions net/ipv6/datagram.c
Original file line number Diff line number Diff line change
Expand Up @@ -64,16 +64,65 @@ static void ip6_datagram_flow_key_init(struct flowi6 *fl6, struct sock *sk)
security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
}

static int ip6_datagram_dst_update(struct sock *sk)
{
struct ip6_flowlabel *flowlabel = NULL;
struct in6_addr *final_p, final;
struct ipv6_txoptions *opt;
struct dst_entry *dst;
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
struct flowi6 fl6;
int err = 0;

if (np->sndflow && (np->flow_label & IPV6_FLOWLABEL_MASK)) {
flowlabel = fl6_sock_lookup(sk, np->flow_label);
if (!flowlabel)
return -EINVAL;
}
ip6_datagram_flow_key_init(&fl6, sk);

rcu_read_lock();
opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
final_p = fl6_update_dst(&fl6, opt, &final);
rcu_read_unlock();

dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
goto out;
}

if (ipv6_addr_any(&np->saddr))
np->saddr = fl6.saddr;

if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
sk->sk_v6_rcv_saddr = fl6.saddr;
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
if (sk->sk_prot->rehash)
sk->sk_prot->rehash(sk);
}

ip6_dst_store(sk, dst,
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
&sk->sk_v6_daddr : NULL,
#ifdef CONFIG_IPV6_SUBTREES
ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
&np->saddr :
#endif
NULL);

out:
fl6_sock_release(flowlabel);
return err;
}

static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int addr_len)
{
struct sockaddr_in6 *usin = (struct sockaddr_in6 *) uaddr;
struct inet_sock *inet = inet_sk(sk);
struct ipv6_pinfo *np = inet6_sk(sk);
struct in6_addr *daddr, *final_p, final;
struct dst_entry *dst;
struct flowi6 fl6;
struct ip6_flowlabel *flowlabel = NULL;
struct ipv6_txoptions *opt;
struct in6_addr *daddr;
int addr_type;
int err;
__be32 fl6_flowlabel = 0;
Expand All @@ -91,14 +140,8 @@ static int __ip6_datagram_connect(struct sock *sk, struct sockaddr *uaddr, int a
if (usin->sin6_family != AF_INET6)
return -EAFNOSUPPORT;

if (np->sndflow) {
if (np->sndflow)
fl6_flowlabel = usin->sin6_flowinfo & IPV6_FLOWINFO_MASK;
if (fl6_flowlabel & IPV6_FLOWLABEL_MASK) {
flowlabel = fl6_sock_lookup(sk, fl6_flowlabel);
if (!flowlabel)
return -EINVAL;
}
}

addr_type = ipv6_addr_type(&usin->sin6_addr);

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

ip6_datagram_flow_key_init(&fl6, sk);

rcu_read_lock();
opt = flowlabel ? flowlabel->opt : rcu_dereference(np->opt);
final_p = fl6_update_dst(&fl6, opt, &final);
rcu_read_unlock();

dst = ip6_dst_lookup_flow(sk, &fl6, final_p);
err = 0;
if (IS_ERR(dst)) {
err = PTR_ERR(dst);
err = ip6_datagram_dst_update(sk);
if (err)
goto out;
}

/* source address lookup done in ip6_dst_lookup */

if (ipv6_addr_any(&np->saddr))
np->saddr = fl6.saddr;

if (ipv6_addr_any(&sk->sk_v6_rcv_saddr)) {
sk->sk_v6_rcv_saddr = fl6.saddr;
inet->inet_rcv_saddr = LOOPBACK4_IPV6;
if (sk->sk_prot->rehash)
sk->sk_prot->rehash(sk);
}

ip6_dst_store(sk, dst,
ipv6_addr_equal(&fl6.daddr, &sk->sk_v6_daddr) ?
&sk->sk_v6_daddr : NULL,
#ifdef CONFIG_IPV6_SUBTREES
ipv6_addr_equal(&fl6.saddr, &np->saddr) ?
&np->saddr :
#endif
NULL);

sk->sk_state = TCP_ESTABLISHED;
sk_set_txhash(sk);
out:
fl6_sock_release(flowlabel);
return err;
}

Expand Down

0 comments on commit 7e2040d

Please sign in to comment.