Blame view

net/ipv6/inet6_connection_sock.c 4.34 KB
8129765ac   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
  /*
   * INET        An implementation of the TCP/IP protocol suite for the LINUX
   *             operating system.  INET is implemented using the  BSD Socket
   *             interface as the means of communication with the user level.
   *
   *             Support for INET6 connection oriented protocols.
   *
   * Authors:    See the TCPv6 sources
   *
   *             This program is free software; you can redistribute it and/or
   *             modify it under the terms of the GNU General Public License
   *             as published by the Free Software Foundation; either version
   *             2 of the License, or(at your option) any later version.
   */
8129765ac   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
15
16
17
18
  #include <linux/module.h>
  #include <linux/in6.h>
  #include <linux/ipv6.h>
  #include <linux/jhash.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
19
  #include <linux/slab.h>
8129765ac   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
20
21
22
  
  #include <net/addrconf.h>
  #include <net/inet_connection_sock.h>
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
23
24
25
  #include <net/inet_ecn.h>
  #include <net/inet_hashtables.h>
  #include <net/ip6_route.h>
8129765ac   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
26
  #include <net/sock.h>
9f5336e21   Adrian Bunk   [IPV6]: small cle...
27
  #include <net/inet6_connection_sock.h>
c125e80b8   Craig Gallek   soreuseport: fast...
28
  #include <net/sock_reuseport.h>
8129765ac   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
29

30d50c61d   Eric Dumazet   ipv6: constify in...
30
  struct dst_entry *inet6_csk_route_req(const struct sock *sk,
3840a06e6   Neal Cardwell   tcp: pass fl6 to ...
31
  				      struct flowi6 *fl6,
f76b33c32   Eric Dumazet   dccp: use inet6_c...
32
33
  				      const struct request_sock *req,
  				      u8 proto)
ae4694b2d   David S. Miller   ipv6: Create inet...
34
  {
634fb979e   Eric Dumazet   inet: includes a ...
35
  	struct inet_request_sock *ireq = inet_rsk(req);
f76b33c32   Eric Dumazet   dccp: use inet6_c...
36
  	const struct ipv6_pinfo *np = inet6_sk(sk);
ae4694b2d   David S. Miller   ipv6: Create inet...
37
38
  	struct in6_addr *final_p, final;
  	struct dst_entry *dst;
4c9483b2f   David S. Miller   ipv6: Convert to ...
39

3840a06e6   Neal Cardwell   tcp: pass fl6 to ...
40
  	memset(fl6, 0, sizeof(*fl6));
f76b33c32   Eric Dumazet   dccp: use inet6_c...
41
  	fl6->flowi6_proto = proto;
634fb979e   Eric Dumazet   inet: includes a ...
42
  	fl6->daddr = ireq->ir_v6_rmt_addr;
45f6fad84   Eric Dumazet   ipv6: add complet...
43
44
45
  	rcu_read_lock();
  	final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
  	rcu_read_unlock();
634fb979e   Eric Dumazet   inet: includes a ...
46
47
  	fl6->saddr = ireq->ir_v6_loc_addr;
  	fl6->flowi6_oif = ireq->ir_iif;
84f39b08d   Lorenzo Colitti   net: support mark...
48
  	fl6->flowi6_mark = ireq->ir_mark;
634fb979e   Eric Dumazet   inet: includes a ...
49
  	fl6->fl6_dport = ireq->ir_rmt_port;
b44084c2c   Eric Dumazet   inet: rename ir_l...
50
  	fl6->fl6_sport = htons(ireq->ir_num);
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
51
  	fl6->flowi6_uid = sk->sk_uid;
3840a06e6   Neal Cardwell   tcp: pass fl6 to ...
52
  	security_req_classify_flow(req, flowi6_to_flowi(fl6));
4c9483b2f   David S. Miller   ipv6: Convert to ...
53

0e0d44ab4   Steffen Klassert   net: Remove FLOWI...
54
  	dst = ip6_dst_lookup_flow(sk, fl6, final_p);
68d0c6d34   David S. Miller   ipv6: Consolidate...
55
  	if (IS_ERR(dst))
ae4694b2d   David S. Miller   ipv6: Create inet...
56
57
58
59
  		return NULL;
  
  	return dst;
  }
f76b33c32   Eric Dumazet   dccp: use inet6_c...
60
  EXPORT_SYMBOL(inet6_csk_route_req);
ae4694b2d   David S. Miller   ipv6: Create inet...
61

67ba4152e   Ian Morris   ipv6: White-space...
62
  void inet6_csk_addr2sockaddr(struct sock *sk, struct sockaddr *uaddr)
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
63
  {
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
64
65
66
  	struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *) uaddr;
  
  	sin6->sin6_family = AF_INET6;
efe4208f4   Eric Dumazet   ipv6: make lookup...
67
  	sin6->sin6_addr = sk->sk_v6_daddr;
c720c7e83   Eric Dumazet   inet: rename some...
68
  	sin6->sin6_port	= inet_sk(sk)->inet_dport;
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
69
70
  	/* We do not store received flowlabel for TCP */
  	sin6->sin6_flowinfo = 0;
842df0739   Hannes Frederic Sowa   ipv6: use newly i...
71
72
  	sin6->sin6_scope_id = ipv6_iface_scope_id(&sin6->sin6_addr,
  						  sk->sk_bound_dev_if);
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
73
  }
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
74
  EXPORT_SYMBOL_GPL(inet6_csk_addr2sockaddr);
a47ed4cd8   Noriaki TAKAMIYA   [IPV6] XFRM: Fix ...
75
  static inline
a47ed4cd8   Noriaki TAKAMIYA   [IPV6] XFRM: Fix ...
76
77
  struct dst_entry *__inet6_csk_dst_check(struct sock *sk, u32 cookie)
  {
6f3118b57   Nicolas Dichtel   ipv6: use net->rt...
78
  	return __sk_dst_check(sk, cookie);
a47ed4cd8   Noriaki TAKAMIYA   [IPV6] XFRM: Fix ...
79
  }
d3818c92a   Eric Dumazet   ipv6: fix inet6_c...
80
81
  static struct dst_entry *inet6_csk_route_socket(struct sock *sk,
  						struct flowi6 *fl6)
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
82
  {
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
83
84
  	struct inet_sock *inet = inet_sk(sk);
  	struct ipv6_pinfo *np = inet6_sk(sk);
20c59de2e   Arnaud Ebalard   ipv6: Refactor up...
85
  	struct in6_addr *final_p, final;
35ad9b9cf   David S. Miller   ipv6: Add helper ...
86
  	struct dst_entry *dst;
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
87

d3818c92a   Eric Dumazet   ipv6: fix inet6_c...
88
89
  	memset(fl6, 0, sizeof(*fl6));
  	fl6->flowi6_proto = sk->sk_protocol;
efe4208f4   Eric Dumazet   ipv6: make lookup...
90
  	fl6->daddr = sk->sk_v6_daddr;
d3818c92a   Eric Dumazet   ipv6: fix inet6_c...
91
92
93
94
95
96
97
  	fl6->saddr = np->saddr;
  	fl6->flowlabel = np->flow_label;
  	IP6_ECN_flow_xmit(sk, fl6->flowlabel);
  	fl6->flowi6_oif = sk->sk_bound_dev_if;
  	fl6->flowi6_mark = sk->sk_mark;
  	fl6->fl6_sport = inet->inet_sport;
  	fl6->fl6_dport = inet->inet_dport;
e2d118a1c   Lorenzo Colitti   net: inet: Suppor...
98
  	fl6->flowi6_uid = sk->sk_uid;
d3818c92a   Eric Dumazet   ipv6: fix inet6_c...
99
  	security_sk_classify_flow(sk, flowi6_to_flowi(fl6));
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
100

45f6fad84   Eric Dumazet   ipv6: add complet...
101
102
103
  	rcu_read_lock();
  	final_p = fl6_update_dst(fl6, rcu_dereference(np->opt), &final);
  	rcu_read_unlock();
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
104

a47ed4cd8   Noriaki TAKAMIYA   [IPV6] XFRM: Fix ...
105
  	dst = __inet6_csk_dst_check(sk, np->dst_cookie);
35ad9b9cf   David S. Miller   ipv6: Add helper ...
106
  	if (!dst) {
0e0d44ab4   Steffen Klassert   net: Remove FLOWI...
107
  		dst = ip6_dst_lookup_flow(sk, fl6, final_p);
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
108

35ad9b9cf   David S. Miller   ipv6: Add helper ...
109
  		if (!IS_ERR(dst))
6bd4f355d   Eric Dumazet   ipv6: kill sk_dst...
110
  			ip6_dst_store(sk, dst, NULL, NULL);
35ad9b9cf   David S. Miller   ipv6: Add helper ...
111
112
113
  	}
  	return dst;
  }
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
114

b0270e910   Eric Dumazet   ipv4: add a sock ...
115
  int inet6_csk_xmit(struct sock *sk, struct sk_buff *skb, struct flowi *fl_unused)
35ad9b9cf   David S. Miller   ipv6: Add helper ...
116
  {
35ad9b9cf   David S. Miller   ipv6: Add helper ...
117
118
119
120
  	struct ipv6_pinfo *np = inet6_sk(sk);
  	struct flowi6 fl6;
  	struct dst_entry *dst;
  	int res;
d3818c92a   Eric Dumazet   ipv6: fix inet6_c...
121
  	dst = inet6_csk_route_socket(sk, &fl6);
35ad9b9cf   David S. Miller   ipv6: Add helper ...
122
123
124
125
126
  	if (IS_ERR(dst)) {
  		sk->sk_err_soft = -PTR_ERR(dst);
  		sk->sk_route_caps = 0;
  		kfree_skb(skb);
  		return PTR_ERR(dst);
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
127
  	}
d14730b8e   Eric Dumazet   ipv6: use RCU in ...
128
129
  	rcu_read_lock();
  	skb_dst_set_noref(skb, dst);
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
130
131
  
  	/* Restore final destination back after routing done */
efe4208f4   Eric Dumazet   ipv6: make lookup...
132
  	fl6.daddr = sk->sk_v6_daddr;
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
133

92e55f412   Pablo Neira   tcp: don't annota...
134
  	res = ip6_xmit(sk, skb, &fl6, sk->sk_mark, rcu_dereference(np->opt),
45f6fad84   Eric Dumazet   ipv6: add complet...
135
  		       np->tclass);
d14730b8e   Eric Dumazet   ipv6: use RCU in ...
136
137
  	rcu_read_unlock();
  	return res;
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
138
  }
b9750ce13   Arnaldo Carvalho de Melo   [IPV6]: Generalis...
139
  EXPORT_SYMBOL_GPL(inet6_csk_xmit);
35ad9b9cf   David S. Miller   ipv6: Add helper ...
140
141
142
  
  struct dst_entry *inet6_csk_update_pmtu(struct sock *sk, u32 mtu)
  {
d3818c92a   Eric Dumazet   ipv6: fix inet6_c...
143
144
  	struct flowi6 fl6;
  	struct dst_entry *dst = inet6_csk_route_socket(sk, &fl6);
35ad9b9cf   David S. Miller   ipv6: Add helper ...
145
146
147
  
  	if (IS_ERR(dst))
  		return NULL;
6700c2709   David S. Miller   net: Pass optiona...
148
  	dst->ops->update_pmtu(dst, sk, NULL, mtu);
35ad9b9cf   David S. Miller   ipv6: Add helper ...
149

b4dd00676   Eric Dumazet   ipv6: fix inet6_c...
150
151
  	dst = inet6_csk_route_socket(sk, &fl6);
  	return IS_ERR(dst) ? NULL : dst;
35ad9b9cf   David S. Miller   ipv6: Add helper ...
152
153
  }
  EXPORT_SYMBOL_GPL(inet6_csk_update_pmtu);