blob: d2a016ef5c417377583952ca142e98fe4e1f5b26 [file] [log] [blame]
xjb04a4022021-11-25 15:01:52 +08001/* SPDX-License-Identifier: GPL-2.0 */
2#ifndef _NDISC_H
3#define _NDISC_H
4
5/*
6 * ICMP codes for neighbour discovery messages
7 */
8
9#define NDISC_ROUTER_SOLICITATION 133
10#define NDISC_ROUTER_ADVERTISEMENT 134
11#define NDISC_NEIGHBOUR_SOLICITATION 135
12#define NDISC_NEIGHBOUR_ADVERTISEMENT 136
13#define NDISC_REDIRECT 137
14
15/*
16 * Router type: cross-layer information from link-layer to
17 * IPv6 layer reported by certain link types (e.g., RFC4214).
18 */
19#define NDISC_NODETYPE_UNSPEC 0 /* unspecified (default) */
20#define NDISC_NODETYPE_HOST 1 /* host or unauthorized router */
21#define NDISC_NODETYPE_NODEFAULT 2 /* non-default router */
22#define NDISC_NODETYPE_DEFAULT 3 /* default router */
23
24/*
25 * ndisc options
26 */
27
28enum {
29 __ND_OPT_PREFIX_INFO_END = 0,
30 ND_OPT_SOURCE_LL_ADDR = 1, /* RFC2461 */
31 ND_OPT_TARGET_LL_ADDR = 2, /* RFC2461 */
32 ND_OPT_PREFIX_INFO = 3, /* RFC2461 */
33 ND_OPT_REDIRECT_HDR = 4, /* RFC2461 */
34 ND_OPT_MTU = 5, /* RFC2461 */
35 ND_OPT_NONCE = 14, /* RFC7527 */
36 __ND_OPT_ARRAY_MAX,
37 ND_OPT_ROUTE_INFO = 24, /* RFC4191 */
38 ND_OPT_RDNSS = 25, /* RFC5006 */
39 ND_OPT_DNSSL = 31, /* RFC6106 */
40 ND_OPT_6CO = 34, /* RFC6775 */
41 ND_OPT_CAPTIVE_PORTAL = 37, /* RFC7710 */
42 __ND_OPT_MAX
43};
44
45#define MAX_RTR_SOLICITATION_DELAY HZ
46
47#define ND_REACHABLE_TIME (30*HZ)
48#define ND_RETRANS_TIMER HZ
49
50#include <linux/compiler.h>
51#include <linux/icmpv6.h>
52#include <linux/in6.h>
53#include <linux/types.h>
54#include <linux/if_arp.h>
55#include <linux/netdevice.h>
56#include <linux/hash.h>
57
58#include <net/neighbour.h>
59
60/* Set to 3 to get tracing... */
61#define ND_DEBUG 1
62
63#define ND_PRINTK(val, level, fmt, ...) \
64do { \
65 if (val <= ND_DEBUG) \
66 net_##level##_ratelimited(fmt, ##__VA_ARGS__); \
67} while (0)
68
69struct ctl_table;
70struct inet6_dev;
71struct net_device;
72struct net_proto_family;
73struct sk_buff;
74struct prefix_info;
75
76extern struct neigh_table nd_tbl;
77
78struct nd_msg {
79 struct icmp6hdr icmph;
80 struct in6_addr target;
81 __u8 opt[0];
82};
83
84struct rs_msg {
85 struct icmp6hdr icmph;
86 __u8 opt[0];
87};
88
89struct ra_msg {
90 struct icmp6hdr icmph;
91 __be32 reachable_time;
92 __be32 retrans_timer;
93};
94
95struct rd_msg {
96 struct icmp6hdr icmph;
97 struct in6_addr target;
98 struct in6_addr dest;
99 __u8 opt[0];
100};
101
102struct nd_opt_hdr {
103 __u8 nd_opt_type;
104 __u8 nd_opt_len;
105} __packed;
106
107/* ND options */
108struct ndisc_options {
109 struct nd_opt_hdr *nd_opt_array[__ND_OPT_ARRAY_MAX];
110#ifdef CONFIG_IPV6_ROUTE_INFO
111 struct nd_opt_hdr *nd_opts_ri;
112 struct nd_opt_hdr *nd_opts_ri_end;
113#endif
114 struct nd_opt_hdr *nd_useropts;
115 struct nd_opt_hdr *nd_useropts_end;
116#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
117 struct nd_opt_hdr *nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR + 1];
118#endif
119};
120
121#define nd_opts_src_lladdr nd_opt_array[ND_OPT_SOURCE_LL_ADDR]
122#define nd_opts_tgt_lladdr nd_opt_array[ND_OPT_TARGET_LL_ADDR]
123#define nd_opts_pi nd_opt_array[ND_OPT_PREFIX_INFO]
124#define nd_opts_pi_end nd_opt_array[__ND_OPT_PREFIX_INFO_END]
125#define nd_opts_rh nd_opt_array[ND_OPT_REDIRECT_HDR]
126#define nd_opts_mtu nd_opt_array[ND_OPT_MTU]
127#define nd_opts_nonce nd_opt_array[ND_OPT_NONCE]
128#define nd_802154_opts_src_lladdr nd_802154_opt_array[ND_OPT_SOURCE_LL_ADDR]
129#define nd_802154_opts_tgt_lladdr nd_802154_opt_array[ND_OPT_TARGET_LL_ADDR]
130
131#define NDISC_OPT_SPACE(len) (((len)+2+7)&~7)
132
133struct ndisc_options *ndisc_parse_options(const struct net_device *dev,
134 u8 *opt, int opt_len,
135 struct ndisc_options *ndopts);
136
137void __ndisc_fill_addr_option(struct sk_buff *skb, int type, void *data,
138 int data_len, int pad);
139
140#define NDISC_OPS_REDIRECT_DATA_SPACE 2
141
142/*
143 * This structure defines the hooks for IPv6 neighbour discovery.
144 * The following hooks can be defined; unless noted otherwise, they are
145 * optional and can be filled with a null pointer.
146 *
147 * int (*is_useropt)(u8 nd_opt_type):
148 * This function is called when IPv6 decide RA userspace options. if
149 * this function returns 1 then the option given by nd_opt_type will
150 * be handled as userspace option additional to the IPv6 options.
151 *
152 * int (*parse_options)(const struct net_device *dev,
153 * struct nd_opt_hdr *nd_opt,
154 * struct ndisc_options *ndopts):
155 * This function is called while parsing ndisc ops and put each position
156 * as pointer into ndopts. If this function return unequal 0, then this
157 * function took care about the ndisc option, if 0 then the IPv6 ndisc
158 * option parser will take care about that option.
159 *
160 * void (*update)(const struct net_device *dev, struct neighbour *n,
161 * u32 flags, u8 icmp6_type,
162 * const struct ndisc_options *ndopts):
163 * This function is called when IPv6 ndisc updates the neighbour cache
164 * entry. Additional options which can be updated may be previously
165 * parsed by parse_opts callback and accessible over ndopts parameter.
166 *
167 * int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
168 * struct neighbour *neigh, u8 *ha_buf,
169 * u8 **ha):
170 * This function is called when the necessary option space will be
171 * calculated before allocating a skb. The parameters neigh, ha_buf
172 * abd ha are available on NDISC_REDIRECT messages only.
173 *
174 * void (*fill_addr_option)(const struct net_device *dev,
175 * struct sk_buff *skb, u8 icmp6_type,
176 * const u8 *ha):
177 * This function is called when the skb will finally fill the option
178 * fields inside skb. NOTE: this callback should fill the option
179 * fields to the skb which are previously indicated by opt_space
180 * parameter. That means the decision to add such option should
181 * not lost between these two callbacks, e.g. protected by interface
182 * up state.
183 *
184 * void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
185 * const struct prefix_info *pinfo,
186 * struct inet6_dev *in6_dev,
187 * struct in6_addr *addr,
188 * int addr_type, u32 addr_flags,
189 * bool sllao, bool tokenized,
190 * __u32 valid_lft, u32 prefered_lft,
191 * bool dev_addr_generated):
192 * This function is called when a RA messages is received with valid
193 * PIO option fields and an IPv6 address will be added to the interface
194 * for autoconfiguration. The parameter dev_addr_generated reports about
195 * if the address was based on dev->dev_addr or not. This can be used
196 * to add a second address if link-layer operates with two link layer
197 * addresses. E.g. 802.15.4 6LoWPAN.
198 */
199struct ndisc_ops {
200 int (*is_useropt)(u8 nd_opt_type);
201 int (*parse_options)(const struct net_device *dev,
202 struct nd_opt_hdr *nd_opt,
203 struct ndisc_options *ndopts);
204 void (*update)(const struct net_device *dev, struct neighbour *n,
205 u32 flags, u8 icmp6_type,
206 const struct ndisc_options *ndopts);
207 int (*opt_addr_space)(const struct net_device *dev, u8 icmp6_type,
208 struct neighbour *neigh, u8 *ha_buf,
209 u8 **ha);
210 void (*fill_addr_option)(const struct net_device *dev,
211 struct sk_buff *skb, u8 icmp6_type,
212 const u8 *ha);
213 void (*prefix_rcv_add_addr)(struct net *net, struct net_device *dev,
214 const struct prefix_info *pinfo,
215 struct inet6_dev *in6_dev,
216 struct in6_addr *addr,
217 int addr_type, u32 addr_flags,
218 bool sllao, bool tokenized,
219 __u32 valid_lft, u32 prefered_lft,
220 bool dev_addr_generated);
221};
222
223#if IS_ENABLED(CONFIG_IPV6)
224static inline int ndisc_ops_is_useropt(const struct net_device *dev,
225 u8 nd_opt_type)
226{
227 if (dev->ndisc_ops && dev->ndisc_ops->is_useropt)
228 return dev->ndisc_ops->is_useropt(nd_opt_type);
229 else
230 return 0;
231}
232
233static inline int ndisc_ops_parse_options(const struct net_device *dev,
234 struct nd_opt_hdr *nd_opt,
235 struct ndisc_options *ndopts)
236{
237 if (dev->ndisc_ops && dev->ndisc_ops->parse_options)
238 return dev->ndisc_ops->parse_options(dev, nd_opt, ndopts);
239 else
240 return 0;
241}
242
243static inline void ndisc_ops_update(const struct net_device *dev,
244 struct neighbour *n, u32 flags,
245 u8 icmp6_type,
246 const struct ndisc_options *ndopts)
247{
248 if (dev->ndisc_ops && dev->ndisc_ops->update)
249 dev->ndisc_ops->update(dev, n, flags, icmp6_type, ndopts);
250}
251
252static inline int ndisc_ops_opt_addr_space(const struct net_device *dev,
253 u8 icmp6_type)
254{
255 if (dev->ndisc_ops && dev->ndisc_ops->opt_addr_space &&
256 icmp6_type != NDISC_REDIRECT)
257 return dev->ndisc_ops->opt_addr_space(dev, icmp6_type, NULL,
258 NULL, NULL);
259 else
260 return 0;
261}
262
263static inline int ndisc_ops_redirect_opt_addr_space(const struct net_device *dev,
264 struct neighbour *neigh,
265 u8 *ha_buf, u8 **ha)
266{
267 if (dev->ndisc_ops && dev->ndisc_ops->opt_addr_space)
268 return dev->ndisc_ops->opt_addr_space(dev, NDISC_REDIRECT,
269 neigh, ha_buf, ha);
270 else
271 return 0;
272}
273
274static inline void ndisc_ops_fill_addr_option(const struct net_device *dev,
275 struct sk_buff *skb,
276 u8 icmp6_type)
277{
278 if (dev->ndisc_ops && dev->ndisc_ops->fill_addr_option &&
279 icmp6_type != NDISC_REDIRECT)
280 dev->ndisc_ops->fill_addr_option(dev, skb, icmp6_type, NULL);
281}
282
283static inline void ndisc_ops_fill_redirect_addr_option(const struct net_device *dev,
284 struct sk_buff *skb,
285 const u8 *ha)
286{
287 if (dev->ndisc_ops && dev->ndisc_ops->fill_addr_option)
288 dev->ndisc_ops->fill_addr_option(dev, skb, NDISC_REDIRECT, ha);
289}
290
291static inline void ndisc_ops_prefix_rcv_add_addr(struct net *net,
292 struct net_device *dev,
293 const struct prefix_info *pinfo,
294 struct inet6_dev *in6_dev,
295 struct in6_addr *addr,
296 int addr_type, u32 addr_flags,
297 bool sllao, bool tokenized,
298 __u32 valid_lft,
299 u32 prefered_lft,
300 bool dev_addr_generated)
301{
302 if (dev->ndisc_ops && dev->ndisc_ops->prefix_rcv_add_addr)
303 dev->ndisc_ops->prefix_rcv_add_addr(net, dev, pinfo, in6_dev,
304 addr, addr_type,
305 addr_flags, sllao,
306 tokenized, valid_lft,
307 prefered_lft,
308 dev_addr_generated);
309}
310#endif
311
312/*
313 * Return the padding between the option length and the start of the
314 * link addr. Currently only IP-over-InfiniBand needs this, although
315 * if RFC 3831 IPv6-over-Fibre Channel is ever implemented it may
316 * also need a pad of 2.
317 */
318static inline int ndisc_addr_option_pad(unsigned short type)
319{
320 switch (type) {
321 case ARPHRD_INFINIBAND: return 2;
322 default: return 0;
323 }
324}
325
326static inline int __ndisc_opt_addr_space(unsigned char addr_len, int pad)
327{
328 return NDISC_OPT_SPACE(addr_len + pad);
329}
330
331#if IS_ENABLED(CONFIG_IPV6)
332static inline int ndisc_opt_addr_space(struct net_device *dev, u8 icmp6_type)
333{
334 return __ndisc_opt_addr_space(dev->addr_len,
335 ndisc_addr_option_pad(dev->type)) +
336 ndisc_ops_opt_addr_space(dev, icmp6_type);
337}
338
339static inline int ndisc_redirect_opt_addr_space(struct net_device *dev,
340 struct neighbour *neigh,
341 u8 *ops_data_buf,
342 u8 **ops_data)
343{
344 return __ndisc_opt_addr_space(dev->addr_len,
345 ndisc_addr_option_pad(dev->type)) +
346 ndisc_ops_redirect_opt_addr_space(dev, neigh, ops_data_buf,
347 ops_data);
348}
349#endif
350
351static inline u8 *__ndisc_opt_addr_data(struct nd_opt_hdr *p,
352 unsigned char addr_len, int prepad)
353{
354 u8 *lladdr = (u8 *)(p + 1);
355 int lladdrlen = p->nd_opt_len << 3;
356 if (lladdrlen != __ndisc_opt_addr_space(addr_len, prepad))
357 return NULL;
358 return lladdr + prepad;
359}
360
361static inline u8 *ndisc_opt_addr_data(struct nd_opt_hdr *p,
362 struct net_device *dev)
363{
364 return __ndisc_opt_addr_data(p, dev->addr_len,
365 ndisc_addr_option_pad(dev->type));
366}
367
368static inline u32 ndisc_hashfn(const void *pkey, const struct net_device *dev, __u32 *hash_rnd)
369{
370 const u32 *p32 = pkey;
371
372 return (((p32[0] ^ hash32_ptr(dev)) * hash_rnd[0]) +
373 (p32[1] * hash_rnd[1]) +
374 (p32[2] * hash_rnd[2]) +
375 (p32[3] * hash_rnd[3]));
376}
377
378static inline struct neighbour *__ipv6_neigh_lookup_noref(struct net_device *dev, const void *pkey)
379{
380 return ___neigh_lookup_noref(&nd_tbl, neigh_key_eq128, ndisc_hashfn, pkey, dev);
381}
382
383static inline struct neighbour *__ipv6_neigh_lookup(struct net_device *dev, const void *pkey)
384{
385 struct neighbour *n;
386
387 rcu_read_lock_bh();
388 n = __ipv6_neigh_lookup_noref(dev, pkey);
389 if (n && !refcount_inc_not_zero(&n->refcnt))
390 n = NULL;
391 rcu_read_unlock_bh();
392
393 return n;
394}
395
396static inline void __ipv6_confirm_neigh(struct net_device *dev,
397 const void *pkey)
398{
399 struct neighbour *n;
400
401 rcu_read_lock_bh();
402 n = __ipv6_neigh_lookup_noref(dev, pkey);
403 if (n) {
404 unsigned long now = jiffies;
405
406 /* avoid dirtying neighbour */
407 if (n->confirmed != now)
408 n->confirmed = now;
409 }
410 rcu_read_unlock_bh();
411}
412
413int ndisc_init(void);
414int ndisc_late_init(void);
415
416void ndisc_late_cleanup(void);
417void ndisc_cleanup(void);
418
419int ndisc_rcv(struct sk_buff *skb);
420
421void ndisc_send_ns(struct net_device *dev, const struct in6_addr *solicit,
422 const struct in6_addr *daddr, const struct in6_addr *saddr,
423 u64 nonce);
424
425void ndisc_send_rs(struct net_device *dev,
426 const struct in6_addr *saddr, const struct in6_addr *daddr);
427void ndisc_send_na(struct net_device *dev, const struct in6_addr *daddr,
428 const struct in6_addr *solicited_addr,
429 bool router, bool solicited, bool override, bool inc_opt);
430
431void ndisc_send_redirect(struct sk_buff *skb, const struct in6_addr *target);
432
433int ndisc_mc_map(const struct in6_addr *addr, char *buf, struct net_device *dev,
434 int dir);
435
436void ndisc_update(const struct net_device *dev, struct neighbour *neigh,
437 const u8 *lladdr, u8 new, u32 flags, u8 icmp6_type,
438 struct ndisc_options *ndopts);
439
440/*
441 * IGMP
442 */
443int igmp6_init(void);
444int igmp6_late_init(void);
445
446void igmp6_cleanup(void);
447void igmp6_late_cleanup(void);
448
449int igmp6_event_query(struct sk_buff *skb);
450
451int igmp6_event_report(struct sk_buff *skb);
452
453
454#ifdef CONFIG_SYSCTL
455int ndisc_ifinfo_sysctl_change(struct ctl_table *ctl, int write,
456 void __user *buffer, size_t *lenp, loff_t *ppos);
457int ndisc_ifinfo_sysctl_strategy(struct ctl_table *ctl,
458 void __user *oldval, size_t __user *oldlenp,
459 void __user *newval, size_t newlen);
460#endif
461
462void inet6_ifinfo_notify(int event, struct inet6_dev *idev);
463
464#endif