Branch data Line data Source code
1 : : /* SPDX-License-Identifier: GPL-2.0 */
2 : : #ifndef _IPV6_H
3 : : #define _IPV6_H
4 : :
5 : : #include <uapi/linux/ipv6.h>
6 : :
7 : : #define ipv6_optlen(p) (((p)->hdrlen+1) << 3)
8 : : #define ipv6_authlen(p) (((p)->hdrlen+2) << 2)
9 : : /*
10 : : * This structure contains configuration options per IPv6 link.
11 : : */
12 : : struct ipv6_devconf {
13 : : __s32 forwarding;
14 : : __s32 hop_limit;
15 : : __s32 mtu6;
16 : : __s32 accept_ra;
17 : : __s32 accept_redirects;
18 : : __s32 autoconf;
19 : : __s32 dad_transmits;
20 : : __s32 rtr_solicits;
21 : : __s32 rtr_solicit_interval;
22 : : __s32 rtr_solicit_max_interval;
23 : : __s32 rtr_solicit_delay;
24 : : __s32 force_mld_version;
25 : : __s32 mldv1_unsolicited_report_interval;
26 : : __s32 mldv2_unsolicited_report_interval;
27 : : __s32 use_tempaddr;
28 : : __s32 temp_valid_lft;
29 : : __s32 temp_prefered_lft;
30 : : __s32 regen_max_retry;
31 : : __s32 max_desync_factor;
32 : : __s32 max_addresses;
33 : : __s32 accept_ra_defrtr;
34 : : __s32 accept_ra_min_hop_limit;
35 : : __s32 accept_ra_pinfo;
36 : : __s32 ignore_routes_with_linkdown;
37 : : #ifdef CONFIG_IPV6_ROUTER_PREF
38 : : __s32 accept_ra_rtr_pref;
39 : : __s32 rtr_probe_interval;
40 : : #ifdef CONFIG_IPV6_ROUTE_INFO
41 : : __s32 accept_ra_rt_info_min_plen;
42 : : __s32 accept_ra_rt_info_max_plen;
43 : : #endif
44 : : #endif
45 : : __s32 proxy_ndp;
46 : : __s32 accept_source_route;
47 : : __s32 accept_ra_from_local;
48 : : #ifdef CONFIG_IPV6_OPTIMISTIC_DAD
49 : : __s32 optimistic_dad;
50 : : __s32 use_optimistic;
51 : : #endif
52 : : #ifdef CONFIG_IPV6_MROUTE
53 : : __s32 mc_forwarding;
54 : : #endif
55 : : __s32 disable_ipv6;
56 : : __s32 drop_unicast_in_l2_multicast;
57 : : __s32 accept_dad;
58 : : __s32 force_tllao;
59 : : __s32 ndisc_notify;
60 : : __s32 suppress_frag_ndisc;
61 : : __s32 accept_ra_mtu;
62 : : __s32 drop_unsolicited_na;
63 : : struct ipv6_stable_secret {
64 : : bool initialized;
65 : : struct in6_addr secret;
66 : : } stable_secret;
67 : : __s32 use_oif_addrs_only;
68 : : __s32 keep_addr_on_down;
69 : : __s32 seg6_enabled;
70 : : #ifdef CONFIG_IPV6_SEG6_HMAC
71 : : __s32 seg6_require_hmac;
72 : : #endif
73 : : __u32 enhanced_dad;
74 : : __u32 addr_gen_mode;
75 : : __s32 disable_policy;
76 : : __s32 ndisc_tclass;
77 : :
78 : : struct ctl_table_header *sysctl_header;
79 : : };
80 : :
81 : : struct ipv6_params {
82 : : __s32 disable_ipv6;
83 : : __s32 autoconf;
84 : : };
85 : : extern struct ipv6_params ipv6_defaults;
86 : : #include <linux/icmpv6.h>
87 : : #include <linux/tcp.h>
88 : : #include <linux/udp.h>
89 : :
90 : : #include <net/inet_sock.h>
91 : :
92 : : static inline struct ipv6hdr *ipv6_hdr(const struct sk_buff *skb)
93 : : {
94 : : return (struct ipv6hdr *)skb_network_header(skb);
95 : : }
96 : :
97 : : static inline struct ipv6hdr *inner_ipv6_hdr(const struct sk_buff *skb)
98 : : {
99 : : return (struct ipv6hdr *)skb_inner_network_header(skb);
100 : : }
101 : :
102 : : static inline struct ipv6hdr *ipipv6_hdr(const struct sk_buff *skb)
103 : : {
104 : : return (struct ipv6hdr *)skb_transport_header(skb);
105 : : }
106 : :
107 : : static inline unsigned int ipv6_transport_len(const struct sk_buff *skb)
108 : : {
109 : 0 : return ntohs(ipv6_hdr(skb)->payload_len) + sizeof(struct ipv6hdr) -
110 : : skb_network_header_len(skb);
111 : : }
112 : :
113 : : /*
114 : : This structure contains results of exthdrs parsing
115 : : as offsets from skb->nh.
116 : : */
117 : :
118 : : struct inet6_skb_parm {
119 : : int iif;
120 : : __be16 ra;
121 : : __u16 dst0;
122 : : __u16 srcrt;
123 : : __u16 dst1;
124 : : __u16 lastopt;
125 : : __u16 nhoff;
126 : : __u16 flags;
127 : : #if defined(CONFIG_IPV6_MIP6) || defined(CONFIG_IPV6_MIP6_MODULE)
128 : : __u16 dsthao;
129 : : #endif
130 : : __u16 frag_max_size;
131 : :
132 : : #define IP6SKB_XFRM_TRANSFORMED 1
133 : : #define IP6SKB_FORWARDED 2
134 : : #define IP6SKB_REROUTED 4
135 : : #define IP6SKB_ROUTERALERT 8
136 : : #define IP6SKB_FRAGMENTED 16
137 : : #define IP6SKB_HOPBYHOP 32
138 : : #define IP6SKB_L3SLAVE 64
139 : : #define IP6SKB_JUMBOGRAM 128
140 : : };
141 : :
142 : : #if defined(CONFIG_NET_L3_MASTER_DEV)
143 : : static inline bool ipv6_l3mdev_skb(__u16 flags)
144 : : {
145 : 8766 : return flags & IP6SKB_L3SLAVE;
146 : : }
147 : : #else
148 : : static inline bool ipv6_l3mdev_skb(__u16 flags)
149 : : {
150 : : return false;
151 : : }
152 : : #endif
153 : :
154 : : #define IP6CB(skb) ((struct inet6_skb_parm*)((skb)->cb))
155 : : #define IP6CBMTU(skb) ((struct ip6_mtuinfo *)((skb)->cb))
156 : :
157 : : static inline int inet6_iif(const struct sk_buff *skb)
158 : : {
159 : 4614 : bool l3_slave = ipv6_l3mdev_skb(IP6CB(skb)->flags);
160 : :
161 [ - + - + : 4614 : return l3_slave ? skb->skb_iif : IP6CB(skb)->iif;
# # - + -
+ # # #
# ]
162 : : }
163 : :
164 : : static inline bool inet6_is_jumbogram(const struct sk_buff *skb)
165 : : {
166 : 376 : return !!(IP6CB(skb)->flags & IP6SKB_JUMBOGRAM);
167 : : }
168 : :
169 : : /* can not be used in TCP layer after tcp_v6_fill_cb */
170 : : static inline int inet6_sdif(const struct sk_buff *skb)
171 : : {
172 : : #if IS_ENABLED(CONFIG_NET_L3_MASTER_DEV)
173 [ + - - + : 12108 : if (skb && ipv6_l3mdev_skb(IP6CB(skb)->flags))
+ - - + +
- - + # #
# # # # #
# ]
174 : 0 : return IP6CB(skb)->iif;
175 : : #endif
176 : : return 0;
177 : : }
178 : :
179 : : /* can not be used in TCP layer after tcp_v6_fill_cb */
180 : : static inline bool inet6_exact_dif_match(struct net *net, struct sk_buff *skb)
181 : : {
182 : : #if defined(CONFIG_NET_L3_MASTER_DEV)
183 [ # # # # ]: 0 : if (!net->ipv4.sysctl_tcp_l3mdev_accept &&
184 [ # # ]: 0 : skb && ipv6_l3mdev_skb(IP6CB(skb)->flags))
185 : : return true;
186 : : #endif
187 : : return false;
188 : : }
189 : :
190 : : struct tcp6_request_sock {
191 : : struct tcp_request_sock tcp6rsk_tcp;
192 : : };
193 : :
194 : : struct ipv6_mc_socklist;
195 : : struct ipv6_ac_socklist;
196 : : struct ipv6_fl_socklist;
197 : :
198 : : struct inet6_cork {
199 : : struct ipv6_txoptions *opt;
200 : : u8 hop_limit;
201 : : u8 tclass;
202 : : };
203 : :
204 : : /**
205 : : * struct ipv6_pinfo - ipv6 private area
206 : : *
207 : : * In the struct sock hierarchy (tcp6_sock, upd6_sock, etc)
208 : : * this _must_ be the last member, so that inet6_sk_generic
209 : : * is able to calculate its offset from the base struct sock
210 : : * by using the struct proto->slab_obj_size member. -acme
211 : : */
212 : : struct ipv6_pinfo {
213 : : struct in6_addr saddr;
214 : : struct in6_pktinfo sticky_pktinfo;
215 : : const struct in6_addr *daddr_cache;
216 : : #ifdef CONFIG_IPV6_SUBTREES
217 : : const struct in6_addr *saddr_cache;
218 : : #endif
219 : :
220 : : __be32 flow_label;
221 : : __u32 frag_size;
222 : :
223 : : /*
224 : : * Packed in 16bits.
225 : : * Omit one shift by by putting the signed field at MSB.
226 : : */
227 : : #if defined(__BIG_ENDIAN_BITFIELD)
228 : : __s16 hop_limit:9;
229 : : __u16 __unused_1:7;
230 : : #else
231 : : __u16 __unused_1:7;
232 : : __s16 hop_limit:9;
233 : : #endif
234 : :
235 : : #if defined(__BIG_ENDIAN_BITFIELD)
236 : : /* Packed in 16bits. */
237 : : __s16 mcast_hops:9;
238 : : __u16 __unused_2:6,
239 : : mc_loop:1;
240 : : #else
241 : : __u16 mc_loop:1,
242 : : __unused_2:6;
243 : : __s16 mcast_hops:9;
244 : : #endif
245 : : int ucast_oif;
246 : : int mcast_oif;
247 : :
248 : : /* pktoption flags */
249 : : union {
250 : : struct {
251 : : __u16 srcrt:1,
252 : : osrcrt:1,
253 : : rxinfo:1,
254 : : rxoinfo:1,
255 : : rxhlim:1,
256 : : rxohlim:1,
257 : : hopopts:1,
258 : : ohopopts:1,
259 : : dstopts:1,
260 : : odstopts:1,
261 : : rxflow:1,
262 : : rxtclass:1,
263 : : rxpmtu:1,
264 : : rxorigdstaddr:1,
265 : : recvfragsize:1;
266 : : /* 1 bits hole */
267 : : } bits;
268 : : __u16 all;
269 : : } rxopt;
270 : :
271 : : /* sockopt flags */
272 : : __u16 recverr:1,
273 : : sndflow:1,
274 : : repflow:1,
275 : : pmtudisc:3,
276 : : padding:1, /* 1 bit hole */
277 : : srcprefs:3, /* 001: prefer temporary address
278 : : * 010: prefer public address
279 : : * 100: prefer care-of address
280 : : */
281 : : dontfrag:1,
282 : : autoflowlabel:1,
283 : : autoflowlabel_set:1,
284 : : mc_all:1,
285 : : rtalert_isolate:1;
286 : : __u8 min_hopcount;
287 : : __u8 tclass;
288 : : __be32 rcv_flowinfo;
289 : :
290 : : __u32 dst_cookie;
291 : : __u32 rx_dst_cookie;
292 : :
293 : : struct ipv6_mc_socklist __rcu *ipv6_mc_list;
294 : : struct ipv6_ac_socklist *ipv6_ac_list;
295 : : struct ipv6_fl_socklist __rcu *ipv6_fl_list;
296 : :
297 : : struct ipv6_txoptions __rcu *opt;
298 : : struct sk_buff *pktoptions;
299 : : struct sk_buff *rxpmtu;
300 : : struct inet6_cork cork;
301 : : };
302 : :
303 : : /* WARNING: don't change the layout of the members in {raw,udp,tcp}6_sock! */
304 : : struct raw6_sock {
305 : : /* inet_sock has to be the first member of raw6_sock */
306 : : struct inet_sock inet;
307 : : __u32 checksum; /* perform checksum */
308 : : __u32 offset; /* checksum offset */
309 : : struct icmp6_filter filter;
310 : : __u32 ip6mr_table;
311 : : /* ipv6_pinfo has to be the last member of raw6_sock, see inet6_sk_generic */
312 : : struct ipv6_pinfo inet6;
313 : : };
314 : :
315 : : struct udp6_sock {
316 : : struct udp_sock udp;
317 : : /* ipv6_pinfo has to be the last member of udp6_sock, see inet6_sk_generic */
318 : : struct ipv6_pinfo inet6;
319 : : };
320 : :
321 : : struct tcp6_sock {
322 : : struct tcp_sock tcp;
323 : : /* ipv6_pinfo has to be the last member of tcp6_sock, see inet6_sk_generic */
324 : : struct ipv6_pinfo inet6;
325 : : };
326 : :
327 : : extern int inet6_sk_rebuild_header(struct sock *sk);
328 : :
329 : : struct tcp6_timewait_sock {
330 : : struct tcp_timewait_sock tcp6tw_tcp;
331 : : };
332 : :
333 : : #if IS_ENABLED(CONFIG_IPV6)
334 : : bool ipv6_mod_enabled(void);
335 : :
336 : 0 : static inline struct ipv6_pinfo *inet6_sk(const struct sock *__sk)
337 : : {
338 [ + - + - : 54428 : return sk_fullsock(__sk) ? inet_sk(__sk)->pinet6 : NULL;
+ - + - +
- + - + -
+ - + - +
- + - + -
# # + - +
- ]
339 : : }
340 : :
341 : : static inline struct raw6_sock *raw6_sk(const struct sock *sk)
342 : : {
343 : : return (struct raw6_sock *)sk;
344 : : }
345 : :
346 : : static inline void inet_sk_copy_descendant(struct sock *sk_to,
347 : : const struct sock *sk_from)
348 : : {
349 : : int ancestor_size = sizeof(struct inet_sock);
350 : :
351 : : if (sk_from->sk_family == PF_INET6)
352 : : ancestor_size += sizeof(struct ipv6_pinfo);
353 : :
354 : : __inet_sk_copy_descendant(sk_to, sk_from, ancestor_size);
355 : : }
356 : :
357 : : #define __ipv6_only_sock(sk) (sk->sk_ipv6only)
358 : : #define ipv6_only_sock(sk) (__ipv6_only_sock(sk))
359 : : #define ipv6_sk_rxinfo(sk) ((sk)->sk_family == PF_INET6 && \
360 : : inet6_sk(sk)->rxopt.bits.rxinfo)
361 : :
362 : : static inline const struct in6_addr *inet6_rcv_saddr(const struct sock *sk)
363 : : {
364 [ # # - + ]: 406 : if (sk->sk_family == AF_INET6)
365 : 0 : return &sk->sk_v6_rcv_saddr;
366 : : return NULL;
367 : : }
368 : :
369 : : static inline int inet_v6_ipv6only(const struct sock *sk)
370 : : {
371 : : /* ipv6only field is at same position for timewait and other sockets */
372 : : return ipv6_only_sock(sk);
373 : : }
374 : : #else
375 : : #define __ipv6_only_sock(sk) 0
376 : : #define ipv6_only_sock(sk) 0
377 : : #define ipv6_sk_rxinfo(sk) 0
378 : :
379 : : static inline bool ipv6_mod_enabled(void)
380 : : {
381 : : return false;
382 : : }
383 : :
384 : : static inline struct ipv6_pinfo * inet6_sk(const struct sock *__sk)
385 : : {
386 : : return NULL;
387 : : }
388 : :
389 : : static inline struct inet6_request_sock *
390 : : inet6_rsk(const struct request_sock *rsk)
391 : : {
392 : : return NULL;
393 : : }
394 : :
395 : : static inline struct raw6_sock *raw6_sk(const struct sock *sk)
396 : : {
397 : : return NULL;
398 : : }
399 : :
400 : : #define inet6_rcv_saddr(__sk) NULL
401 : : #define tcp_twsk_ipv6only(__sk) 0
402 : : #define inet_v6_ipv6only(__sk) 0
403 : : #endif /* IS_ENABLED(CONFIG_IPV6) */
404 : : #endif /* _IPV6_H */
|