Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netinet6/nd6_nbr.c
39475 views
1
/*-
2
* SPDX-License-Identifier: BSD-3-Clause
3
*
4
* Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
5
* All rights reserved.
6
*
7
* Redistribution and use in source and binary forms, with or without
8
* modification, are permitted provided that the following conditions
9
* are met:
10
* 1. Redistributions of source code must retain the above copyright
11
* notice, this list of conditions and the following disclaimer.
12
* 2. Redistributions in binary form must reproduce the above copyright
13
* notice, this list of conditions and the following disclaimer in the
14
* documentation and/or other materials provided with the distribution.
15
* 3. Neither the name of the project nor the names of its contributors
16
* may be used to endorse or promote products derived from this software
17
* without specific prior written permission.
18
*
19
* THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22
* ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29
* SUCH DAMAGE.
30
*
31
* $KAME: nd6_nbr.c,v 1.86 2002/01/21 02:33:04 jinmei Exp $
32
*/
33
34
#include <sys/cdefs.h>
35
#include "opt_inet.h"
36
#include "opt_inet6.h"
37
#include "opt_ipsec.h"
38
39
#include <sys/param.h>
40
#include <sys/systm.h>
41
#include <sys/counter.h>
42
#include <sys/eventhandler.h>
43
#include <sys/malloc.h>
44
#include <sys/libkern.h>
45
#include <sys/lock.h>
46
#include <sys/rwlock.h>
47
#include <sys/mbuf.h>
48
#include <sys/socket.h>
49
#include <sys/sockio.h>
50
#include <sys/time.h>
51
#include <sys/kernel.h>
52
#include <sys/errno.h>
53
#include <sys/sysctl.h>
54
#include <sys/syslog.h>
55
#include <sys/queue.h>
56
#include <sys/callout.h>
57
#include <sys/refcount.h>
58
59
#include <net/if.h>
60
#include <net/if_types.h>
61
#include <net/if_dl.h>
62
#include <net/if_var.h>
63
#include <net/if_private.h>
64
#include <net/route.h>
65
#include <net/vnet.h>
66
67
#include <netinet/in.h>
68
#include <netinet/in_var.h>
69
#include <net/if_llatbl.h>
70
#include <netinet6/in6_var.h>
71
#include <netinet6/in6_ifattach.h>
72
#include <netinet/ip6.h>
73
#include <netinet6/ip6_var.h>
74
#include <netinet6/scope6_var.h>
75
#include <netinet6/nd6.h>
76
#include <netinet/icmp6.h>
77
#include <netinet/ip_carp.h>
78
#include <netinet6/send.h>
79
80
#include <machine/atomic.h>
81
82
#define SDL(s) ((struct sockaddr_dl *)s)
83
84
struct dadq;
85
static struct dadq *nd6_dad_find(struct ifaddr *, struct nd_opt_nonce *);
86
static void nd6_dad_add(struct dadq *dp);
87
static void nd6_dad_del(struct dadq *dp);
88
static void nd6_dad_rele(struct dadq *);
89
static void nd6_dad_starttimer(struct dadq *, int);
90
static void nd6_dad_stoptimer(struct dadq *);
91
static void nd6_dad_timer(void *);
92
static void nd6_dad_duplicated(struct ifaddr *, struct dadq *);
93
static void nd6_dad_ns_output(struct dadq *);
94
static void nd6_dad_ns_input(struct ifaddr *, struct nd_opt_nonce *);
95
static void nd6_dad_na_input(struct ifaddr *);
96
static void nd6_na_output_fib(struct ifnet *, const struct in6_addr *,
97
const struct in6_addr *, u_long, int, struct sockaddr *, u_int);
98
static void nd6_ns_output_fib(struct ifnet *, const struct in6_addr *,
99
const struct in6_addr *, const struct in6_addr *, uint8_t *, u_int);
100
101
static struct ifaddr *nd6_proxy_fill_sdl(struct ifnet *,
102
const struct in6_addr *, struct sockaddr_dl *);
103
104
VNET_DEFINE_STATIC(int, dad_enhanced) = 1;
105
#define V_dad_enhanced VNET(dad_enhanced)
106
107
SYSCTL_DECL(_net_inet6_ip6);
108
SYSCTL_INT(_net_inet6_ip6, OID_AUTO, dad_enhanced, CTLFLAG_VNET | CTLFLAG_RW,
109
&VNET_NAME(dad_enhanced), 0,
110
"Enable Enhanced DAD, which adds a random nonce to NS messages for DAD.");
111
112
VNET_DEFINE_STATIC(int, dad_maxtry) = 15; /* max # of *tries* to
113
transmit DAD packet */
114
#define V_dad_maxtry VNET(dad_maxtry)
115
116
VNET_DEFINE_STATIC(int, nd6_onlink_ns_rfc4861) = 0;
117
#define V_nd6_onlink_ns_rfc4861 VNET(nd6_onlink_ns_rfc4861)
118
SYSCTL_INT(_net_inet6_icmp6, ICMPV6CTL_ND6_ONLINKNSRFC4861,
119
nd6_onlink_ns_rfc4861, CTLFLAG_VNET | CTLFLAG_RW,
120
&VNET_NAME(nd6_onlink_ns_rfc4861), 0,
121
"Accept 'on-link' ICMPv6 NS messages in compliance with RFC 4861");
122
123
/*
124
* Input a Neighbor Solicitation Message.
125
*
126
* Based on RFC 2461
127
* Based on RFC 2462 (duplicate address detection)
128
*/
129
void
130
nd6_ns_input(struct mbuf *m, int off, int icmp6len)
131
{
132
struct ifnet *ifp;
133
struct ip6_hdr *ip6;
134
struct nd_neighbor_solicit *nd_ns;
135
struct in6_addr daddr6, myaddr6, saddr6, taddr6;
136
struct ifaddr *ifa;
137
struct sockaddr_dl proxydl;
138
union nd_opts ndopts;
139
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
140
char *lladdr;
141
int anycast, lladdrlen, proxy, rflag, tentative, tlladdr;
142
143
ifa = NULL;
144
145
/* RFC 6980: Nodes MUST silently ignore fragments */
146
if(m->m_flags & M_FRAGMENTED)
147
goto freeit;
148
149
ifp = m->m_pkthdr.rcvif;
150
ip6 = mtod(m, struct ip6_hdr *);
151
if (__predict_false(ip6->ip6_hlim != 255)) {
152
ICMP6STAT_INC(icp6s_invlhlim);
153
nd6log((LOG_ERR,
154
"nd6_ns_input: invalid hlim (%d) from %s to %s on %s\n",
155
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
156
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
157
goto bads;
158
}
159
160
if (m->m_len < off + icmp6len) {
161
m = m_pullup(m, off + icmp6len);
162
if (m == NULL) {
163
IP6STAT_INC(ip6s_exthdrtoolong);
164
return;
165
}
166
}
167
ip6 = mtod(m, struct ip6_hdr *);
168
nd_ns = (struct nd_neighbor_solicit *)((caddr_t)ip6 + off);
169
170
saddr6 = ip6->ip6_src;
171
daddr6 = ip6->ip6_dst;
172
taddr6 = nd_ns->nd_ns_target;
173
if (in6_setscope(&taddr6, ifp, NULL) != 0)
174
goto bad;
175
176
rflag = (V_ip6_forwarding) ? ND_NA_FLAG_ROUTER : 0;
177
if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV && V_ip6_norbit_raif)
178
rflag = 0;
179
180
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
181
/* dst has to be a solicited node multicast address. */
182
if (daddr6.s6_addr16[0] == IPV6_ADDR_INT16_MLL &&
183
/* don't check ifindex portion */
184
daddr6.s6_addr32[1] == 0 &&
185
daddr6.s6_addr32[2] == IPV6_ADDR_INT32_ONE &&
186
daddr6.s6_addr8[12] == 0xff) {
187
; /* good */
188
} else {
189
nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
190
"(wrong ip6 dst)\n"));
191
goto bad;
192
}
193
} else if (!V_nd6_onlink_ns_rfc4861) {
194
struct sockaddr_in6 src_sa6;
195
196
/*
197
* According to recent IETF discussions, it is not a good idea
198
* to accept a NS from an address which would not be deemed
199
* to be a neighbor otherwise. This point is expected to be
200
* clarified in future revisions of the specification.
201
*/
202
bzero(&src_sa6, sizeof(src_sa6));
203
src_sa6.sin6_family = AF_INET6;
204
src_sa6.sin6_len = sizeof(src_sa6);
205
src_sa6.sin6_addr = saddr6;
206
if (nd6_is_addr_neighbor(&src_sa6, ifp) == 0) {
207
nd6log((LOG_INFO, "nd6_ns_input: "
208
"NS packet from non-neighbor\n"));
209
goto bad;
210
}
211
}
212
213
if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
214
nd6log((LOG_INFO, "nd6_ns_input: bad NS target (multicast)\n"));
215
goto bad;
216
}
217
218
icmp6len -= sizeof(*nd_ns);
219
nd6_option_init(nd_ns + 1, icmp6len, &ndopts);
220
if (nd6_options(&ndopts) < 0) {
221
nd6log((LOG_INFO,
222
"nd6_ns_input: invalid ND option, ignored\n"));
223
/* nd6_options have incremented stats */
224
goto freeit;
225
}
226
227
lladdr = NULL;
228
lladdrlen = 0;
229
if (ndopts.nd_opts_src_lladdr) {
230
lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
231
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
232
}
233
234
if (IN6_IS_ADDR_UNSPECIFIED(&ip6->ip6_src) && lladdr) {
235
nd6log((LOG_INFO, "nd6_ns_input: bad DAD packet "
236
"(link-layer address option)\n"));
237
goto bad;
238
}
239
240
/*
241
* Attaching target link-layer address to the NA?
242
* (RFC 2461 7.2.4)
243
*
244
* NS IP dst is unicast/anycast MUST NOT add
245
* NS IP dst is solicited-node multicast MUST add
246
*
247
* In implementation, we add target link-layer address by default.
248
* We do not add one in MUST NOT cases.
249
*/
250
tlladdr = 0;
251
if (IN6_IS_ADDR_MULTICAST(&daddr6))
252
tlladdr |= ND6_NA_OPT_LLA;
253
254
/*
255
* Target address (taddr6) must be either:
256
* (1) Valid unicast/anycast address for my receiving interface,
257
* (2) Unicast address for which I'm offering proxy service, or
258
* (3) "tentative" address on which DAD is being performed.
259
*/
260
/* (1) and (3) check. */
261
if (ifp->if_carp) {
262
ifa = (*carp_iamatch6_p)(ifp, &taddr6);
263
if (ifa != NULL)
264
tlladdr |= ND6_NA_CARP_MASTER;
265
} else
266
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
267
268
/* (2) check. */
269
proxy = 0;
270
if (ifa == NULL) {
271
if ((ifa = nd6_proxy_fill_sdl(ifp, &taddr6, &proxydl)) != NULL)
272
proxy = 1;
273
}
274
if (ifa == NULL) {
275
/*
276
* We've got an NS packet, and we don't have that address
277
* assigned for us. We MUST silently ignore it.
278
* See RFC2461 7.2.3.
279
*/
280
goto freeit;
281
}
282
myaddr6 = *IFA_IN6(ifa);
283
anycast = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST;
284
tentative = ((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE;
285
if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DUPLICATED)
286
goto freeit;
287
288
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
289
nd6log((LOG_INFO, "nd6_ns_input: lladdrlen mismatch for %s "
290
"(if %d, NS packet %d)\n",
291
ip6_sprintf(ip6bufs, &taddr6),
292
ifp->if_addrlen, lladdrlen - 2));
293
goto bad;
294
}
295
296
if (IN6_ARE_ADDR_EQUAL(&myaddr6, &saddr6)) {
297
nd6log((LOG_INFO, "nd6_ns_input: duplicate IP6 address %s\n",
298
ip6_sprintf(ip6bufs, &saddr6)));
299
goto freeit;
300
}
301
302
/*
303
* We have neighbor solicitation packet, with target address equals to
304
* one of my tentative address.
305
*
306
* src addr how to process?
307
* --- ---
308
* multicast of course, invalid (rejected in ip6_input)
309
* unicast somebody is doing address resolution -> ignore
310
* unspec dup address detection
311
*
312
* The processing is defined in RFC 2462.
313
*/
314
if (tentative) {
315
/*
316
* If source address is unspecified address, it is for
317
* duplicate address detection.
318
*
319
* If not, the packet is for addess resolution;
320
* silently ignore it.
321
*/
322
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
323
nd6_dad_ns_input(ifa, ndopts.nd_opts_nonce);
324
325
goto freeit;
326
}
327
328
/*
329
* If the Target Address is either an anycast address or a unicast
330
* address for which the node is providing proxy service, or the Target
331
* Link-Layer Address option is not included, the Override flag SHOULD
332
* be set to zero. Otherwise, the Override flag SHOULD be set to one.
333
*/
334
if (anycast == 0 && proxy == 0 && (tlladdr & ND6_NA_OPT_LLA) != 0)
335
rflag |= ND_NA_FLAG_OVERRIDE;
336
/*
337
* If the source address is unspecified address, entries must not
338
* be created or updated.
339
* It looks that sender is performing DAD. nd6_na_output() will
340
* send NA toward all-node multicast address, to tell the sender
341
* that I'm using the address.
342
* S bit ("solicited") must be zero.
343
*/
344
if (!IN6_IS_ADDR_UNSPECIFIED(&saddr6)) {
345
nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen,
346
ND_NEIGHBOR_SOLICIT, 0);
347
rflag |= ND_NA_FLAG_SOLICITED;
348
}
349
350
nd6_na_output_fib(ifp, &saddr6, &taddr6, rflag, tlladdr,
351
proxy ? (struct sockaddr *)&proxydl : NULL, M_GETFIB(m));
352
freeit:
353
if (ifa != NULL)
354
ifa_free(ifa);
355
m_freem(m);
356
return;
357
358
bad:
359
nd6log((LOG_ERR, "nd6_ns_input: src=%s\n",
360
ip6_sprintf(ip6bufs, &saddr6)));
361
nd6log((LOG_ERR, "nd6_ns_input: dst=%s\n",
362
ip6_sprintf(ip6bufs, &daddr6)));
363
nd6log((LOG_ERR, "nd6_ns_input: tgt=%s\n",
364
ip6_sprintf(ip6bufs, &taddr6)));
365
bads:
366
ICMP6STAT_INC(icp6s_badns);
367
if (ifa != NULL)
368
ifa_free(ifa);
369
m_freem(m);
370
}
371
372
static struct ifaddr *
373
nd6_proxy_fill_sdl(struct ifnet *ifp, const struct in6_addr *taddr6,
374
struct sockaddr_dl *sdl)
375
{
376
struct ifaddr *ifa;
377
struct llentry *ln;
378
379
ifa = NULL;
380
ln = nd6_lookup(taddr6, LLE_SF(AF_INET6, 0), ifp);
381
if (ln == NULL)
382
return (ifa);
383
if ((ln->la_flags & (LLE_PUB | LLE_VALID)) == (LLE_PUB | LLE_VALID)) {
384
link_init_sdl(ifp, (struct sockaddr *)sdl, ifp->if_type);
385
sdl->sdl_alen = ifp->if_addrlen;
386
bcopy(ln->ll_addr, &sdl->sdl_data, ifp->if_addrlen);
387
LLE_RUNLOCK(ln);
388
ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
389
IN6_IFF_NOTREADY|IN6_IFF_ANYCAST);
390
} else
391
LLE_RUNLOCK(ln);
392
393
return (ifa);
394
}
395
396
/*
397
* Output a Neighbor Solicitation Message. Caller specifies:
398
* - ICMP6 header source IP6 address
399
* - ND6 header target IP6 address
400
* - ND6 header source datalink address
401
*
402
* Based on RFC 2461
403
* Based on RFC 2462 (duplicate address detection)
404
*
405
* ln - for source address determination
406
* nonce - If non-NULL, NS is used for duplicate address detection and
407
* the value (length is ND_OPT_NONCE_LEN) is used as a random nonce.
408
*/
409
static void
410
nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6,
411
const struct in6_addr *daddr6, const struct in6_addr *taddr6,
412
uint8_t *nonce, u_int fibnum)
413
{
414
struct mbuf *m;
415
struct m_tag *mtag;
416
struct ip6_hdr *ip6;
417
struct nd_neighbor_solicit *nd_ns;
418
struct ip6_moptions im6o;
419
int icmp6len;
420
int maxlen;
421
422
NET_EPOCH_ASSERT();
423
424
if (IN6_IS_ADDR_MULTICAST(taddr6))
425
return;
426
427
/* estimate the size of message */
428
maxlen = sizeof(*ip6) + sizeof(*nd_ns);
429
maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
430
KASSERT(max_linkhdr + maxlen <= MCLBYTES, (
431
"%s: max_linkhdr + maxlen > MCLBYTES (%d + %d > %d)",
432
__func__, max_linkhdr, maxlen, MCLBYTES));
433
434
if (max_linkhdr + maxlen > MHLEN)
435
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
436
else
437
m = m_gethdr(M_NOWAIT, MT_DATA);
438
if (m == NULL)
439
return;
440
M_SETFIB(m, fibnum);
441
442
icmp6len = sizeof(*nd_ns);
443
m->m_pkthdr.len = m->m_len = sizeof(*ip6) + icmp6len;
444
m->m_data += max_linkhdr; /* or M_ALIGN() equivalent? */
445
446
/* fill neighbor solicitation packet */
447
ip6 = mtod(m, struct ip6_hdr *);
448
ip6->ip6_flow = 0;
449
ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
450
ip6->ip6_vfc |= IPV6_VERSION;
451
/* ip6->ip6_plen will be set later */
452
ip6->ip6_nxt = IPPROTO_ICMPV6;
453
ip6->ip6_hlim = 255;
454
if (daddr6)
455
ip6->ip6_dst = *daddr6;
456
else {
457
ip6->ip6_dst.s6_addr16[0] = IPV6_ADDR_INT16_MLL;
458
ip6->ip6_dst.s6_addr16[1] = 0;
459
ip6->ip6_dst.s6_addr32[1] = 0;
460
ip6->ip6_dst.s6_addr32[2] = IPV6_ADDR_INT32_ONE;
461
ip6->ip6_dst.s6_addr32[3] = taddr6->s6_addr32[3];
462
ip6->ip6_dst.s6_addr8[12] = 0xff;
463
if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0)
464
goto bad;
465
}
466
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst)) {
467
m->m_flags |= M_MCAST;
468
im6o.im6o_multicast_ifp = ifp;
469
im6o.im6o_multicast_hlim = 255;
470
im6o.im6o_multicast_loop = 0;
471
}
472
if (nonce == NULL) {
473
char ip6buf[INET6_ADDRSTRLEN];
474
struct ifaddr *ifa = NULL;
475
476
/*
477
* RFC2461 7.2.2:
478
* "If the source address of the packet prompting the
479
* solicitation is the same as one of the addresses assigned
480
* to the outgoing interface, that address SHOULD be placed
481
* in the IP Source Address of the outgoing solicitation.
482
* Otherwise, any one of the addresses assigned to the
483
* interface should be used."
484
*
485
* We use the source address for the prompting packet
486
* (saddr6), if saddr6 belongs to the outgoing interface.
487
* Otherwise, we perform the source address selection as usual.
488
*/
489
if (saddr6 != NULL)
490
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, saddr6);
491
if (ifa == NULL) {
492
int error;
493
494
error = in6_selectsrc_nbr(fibnum, &ip6->ip6_dst, &im6o,
495
ifp, &ip6->ip6_src);
496
if (error) {
497
nd6log((LOG_DEBUG, "%s: source can't be "
498
"determined: dst=%s, error=%d\n", __func__,
499
ip6_sprintf(ip6buf, &ip6->ip6_dst),
500
error));
501
goto bad;
502
}
503
} else
504
ip6->ip6_src = *saddr6;
505
506
if (ifp->if_carp != NULL) {
507
/*
508
* Check that selected source address belongs to
509
* CARP addresses.
510
*/
511
if (ifa == NULL)
512
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
513
&ip6->ip6_src);
514
/*
515
* Do not send NS for CARP address if we are not
516
* the CARP master.
517
*/
518
if (ifa != NULL && ifa->ifa_carp != NULL &&
519
!(*carp_master_p)(ifa)) {
520
nd6log((LOG_DEBUG,
521
"nd6_ns_output: NS from BACKUP CARP address %s\n",
522
ip6_sprintf(ip6buf, &ip6->ip6_src)));
523
ifa_free(ifa);
524
goto bad;
525
}
526
}
527
if (ifa != NULL)
528
ifa_free(ifa);
529
} else {
530
/*
531
* Source address for DAD packet must always be IPv6
532
* unspecified address. (0::0)
533
* We actually don't have to 0-clear the address (we did it
534
* above), but we do so here explicitly to make the intention
535
* clearer.
536
*/
537
bzero(&ip6->ip6_src, sizeof(ip6->ip6_src));
538
}
539
nd_ns = (struct nd_neighbor_solicit *)(ip6 + 1);
540
nd_ns->nd_ns_type = ND_NEIGHBOR_SOLICIT;
541
nd_ns->nd_ns_code = 0;
542
nd_ns->nd_ns_reserved = 0;
543
nd_ns->nd_ns_target = *taddr6;
544
in6_clearscope(&nd_ns->nd_ns_target); /* XXX */
545
546
/*
547
* Add source link-layer address option.
548
*
549
* spec implementation
550
* --- ---
551
* DAD packet MUST NOT do not add the option
552
* there's no link layer address:
553
* impossible do not add the option
554
* there's link layer address:
555
* Multicast NS MUST add one add the option
556
* Unicast NS SHOULD add one add the option
557
*/
558
if (nonce == NULL) {
559
struct nd_opt_hdr *nd_opt;
560
char *mac;
561
int optlen;
562
563
mac = NULL;
564
if (ifp->if_carp)
565
mac = (*carp_macmatch6_p)(ifp, m, &ip6->ip6_src);
566
if (mac == NULL)
567
mac = nd6_ifptomac(ifp);
568
569
if (mac != NULL) {
570
nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
571
optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
572
/* 8 byte alignments... */
573
optlen = (optlen + 7) & ~7;
574
m->m_pkthdr.len += optlen;
575
m->m_len += optlen;
576
icmp6len += optlen;
577
bzero(nd_opt, optlen);
578
nd_opt->nd_opt_type = ND_OPT_SOURCE_LINKADDR;
579
nd_opt->nd_opt_len = optlen >> 3;
580
bcopy(mac, nd_opt + 1, ifp->if_addrlen);
581
}
582
}
583
/*
584
* Add a Nonce option (RFC 3971) to detect looped back NS messages.
585
* This behavior is documented as Enhanced Duplicate Address
586
* Detection in RFC 7527.
587
* net.inet6.ip6.dad_enhanced=0 disables this.
588
*/
589
if (V_dad_enhanced != 0 && nonce != NULL) {
590
int optlen = sizeof(struct nd_opt_hdr) + ND_OPT_NONCE_LEN;
591
struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_ns + 1);
592
/* 8-byte alignment is required. */
593
optlen = (optlen + 7) & ~7;
594
595
m->m_pkthdr.len += optlen;
596
m->m_len += optlen;
597
icmp6len += optlen;
598
bzero((caddr_t)nd_opt, optlen);
599
nd_opt->nd_opt_type = ND_OPT_NONCE;
600
nd_opt->nd_opt_len = optlen >> 3;
601
bcopy(nonce, (caddr_t)(nd_opt + 1), ND_OPT_NONCE_LEN);
602
}
603
ip6->ip6_plen = htons((u_short)icmp6len);
604
nd_ns->nd_ns_cksum = 0;
605
nd_ns->nd_ns_cksum =
606
in6_cksum(m, IPPROTO_ICMPV6, sizeof(*ip6), icmp6len);
607
608
if (send_sendso_input_hook != NULL) {
609
mtag = m_tag_get(PACKET_TAG_ND_OUTGOING,
610
sizeof(unsigned short), M_NOWAIT);
611
if (mtag == NULL)
612
goto bad;
613
*(unsigned short *)(mtag + 1) = nd_ns->nd_ns_type;
614
m_tag_prepend(m, mtag);
615
}
616
617
ip6_output(m, NULL, NULL, (nonce != NULL) ? IPV6_UNSPECSRC : 0,
618
&im6o, NULL, NULL);
619
icmp6_ifstat_inc(ifp, ifs6_out_msg);
620
icmp6_ifstat_inc(ifp, ifs6_out_neighborsolicit);
621
ICMP6STAT_INC2(icp6s_outhist, ND_NEIGHBOR_SOLICIT);
622
623
return;
624
625
bad:
626
m_freem(m);
627
}
628
629
#ifndef BURN_BRIDGES
630
void
631
nd6_ns_output(struct ifnet *ifp, const struct in6_addr *saddr6,
632
const struct in6_addr *daddr6, const struct in6_addr *taddr6,uint8_t *nonce)
633
{
634
635
nd6_ns_output_fib(ifp, saddr6, daddr6, taddr6, nonce, RT_DEFAULT_FIB);
636
}
637
#endif
638
/*
639
* Neighbor advertisement input handling.
640
*
641
* Based on RFC 2461
642
* Based on RFC 2462 (duplicate address detection)
643
*
644
* the following items are not implemented yet:
645
* - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
646
* - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
647
*/
648
void
649
nd6_na_input(struct mbuf *m, int off, int icmp6len)
650
{
651
struct ifnet *ifp;
652
struct ip6_hdr *ip6;
653
struct ifaddr *ifa;
654
struct llentry *ln;
655
struct mbuf *chain;
656
struct nd_neighbor_advert *nd_na;
657
struct in6_addr daddr6, taddr6;
658
union nd_opts ndopts;
659
u_char linkhdr[LLE_MAX_LINKHDR];
660
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
661
char *lladdr;
662
size_t linkhdrsize;
663
int flags, is_override, is_router, is_solicited;
664
int lladdr_off, lladdrlen, checklink;
665
bool flush_holdchain = false;
666
667
NET_EPOCH_ASSERT();
668
669
chain = NULL;
670
ln = NULL;
671
checklink = 0;
672
673
/* RFC 6980: Nodes MUST silently ignore fragments */
674
if(m->m_flags & M_FRAGMENTED)
675
goto freeit;
676
677
ifp = m->m_pkthdr.rcvif;
678
ip6 = mtod(m, struct ip6_hdr *);
679
if (__predict_false(ip6->ip6_hlim != 255)) {
680
ICMP6STAT_INC(icp6s_invlhlim);
681
nd6log((LOG_ERR,
682
"nd6_na_input: invalid hlim (%d) from %s to %s on %s\n",
683
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
684
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
685
goto bad;
686
}
687
688
if (m->m_len < off + icmp6len) {
689
m = m_pullup(m, off + icmp6len);
690
if (m == NULL) {
691
IP6STAT_INC(ip6s_exthdrtoolong);
692
return;
693
}
694
}
695
ip6 = mtod(m, struct ip6_hdr *);
696
nd_na = (struct nd_neighbor_advert *)((caddr_t)ip6 + off);
697
698
flags = nd_na->nd_na_flags_reserved;
699
is_router = ((flags & ND_NA_FLAG_ROUTER) != 0);
700
is_solicited = ((flags & ND_NA_FLAG_SOLICITED) != 0);
701
is_override = ((flags & ND_NA_FLAG_OVERRIDE) != 0);
702
703
taddr6 = nd_na->nd_na_target;
704
if (in6_setscope(&taddr6, ifp, NULL))
705
goto bad; /* XXX: impossible */
706
707
if (IN6_IS_ADDR_MULTICAST(&taddr6)) {
708
nd6log((LOG_ERR,
709
"nd6_na_input: invalid target address %s\n",
710
ip6_sprintf(ip6bufs, &taddr6)));
711
goto bad;
712
}
713
714
daddr6 = ip6->ip6_dst;
715
if (IN6_IS_ADDR_MULTICAST(&daddr6))
716
if (is_solicited) {
717
nd6log((LOG_ERR,
718
"nd6_na_input: a solicited adv is multicasted\n"));
719
goto bad;
720
}
721
722
icmp6len -= sizeof(*nd_na);
723
nd6_option_init(nd_na + 1, icmp6len, &ndopts);
724
if (nd6_options(&ndopts) < 0) {
725
nd6log((LOG_INFO,
726
"nd6_na_input: invalid ND option, ignored\n"));
727
/* nd6_options have incremented stats */
728
goto freeit;
729
}
730
731
lladdr = NULL;
732
lladdrlen = 0;
733
if (ndopts.nd_opts_tgt_lladdr) {
734
lladdr = (char *)(ndopts.nd_opts_tgt_lladdr + 1);
735
lladdrlen = ndopts.nd_opts_tgt_lladdr->nd_opt_len << 3;
736
}
737
738
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp, &taddr6);
739
if (ifa != NULL && ifa->ifa_carp != NULL) {
740
/*
741
* Silently ignore NAs for CARP addresses if we are not
742
* the CARP master.
743
*/
744
if (!(*carp_master_p)(ifa)) {
745
nd6log((LOG_DEBUG,
746
"nd6_na_input: NA for BACKUP CARP address %s\n",
747
ip6_sprintf(ip6bufs, &taddr6)));
748
ifa_free(ifa);
749
goto freeit;
750
}
751
}
752
/*
753
* Target address matches one of my interface address.
754
*
755
* If my address is tentative, this means that there's somebody
756
* already using the same address as mine. This indicates DAD failure.
757
* This is defined in RFC 2462.
758
*
759
* Otherwise, process as defined in RFC 2461.
760
*/
761
if (ifa
762
&& (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_TENTATIVE)) {
763
nd6_dad_na_input(ifa);
764
ifa_free(ifa);
765
goto freeit;
766
}
767
768
/* Just for safety, maybe unnecessary. */
769
if (ifa) {
770
ifa_free(ifa);
771
log(LOG_ERR,
772
"nd6_na_input: duplicate IP6 address %s\n",
773
ip6_sprintf(ip6bufs, &taddr6));
774
goto freeit;
775
}
776
777
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
778
nd6log((LOG_INFO, "nd6_na_input: lladdrlen mismatch for %s "
779
"(if %d, NA packet %d)\n", ip6_sprintf(ip6bufs, &taddr6),
780
ifp->if_addrlen, lladdrlen - 2));
781
goto bad;
782
}
783
784
/*
785
* If no neighbor cache entry is found, NA SHOULD silently be
786
* discarded.
787
*/
788
ln = nd6_lookup(&taddr6, LLE_SF(AF_INET6, LLE_EXCLUSIVE), ifp);
789
if (ln == NULL) {
790
goto freeit;
791
}
792
793
/*
794
* Do not try to override static entry.
795
*/
796
if (ln->la_flags & LLE_STATIC)
797
goto freeit;
798
799
if (ln->ln_state == ND6_LLINFO_INCOMPLETE) {
800
/*
801
* If the link-layer has address, and no lladdr option came,
802
* discard the packet.
803
*/
804
if (ifp->if_addrlen && lladdr == NULL) {
805
goto freeit;
806
}
807
808
/*
809
* Record link-layer address, and update the state.
810
*/
811
if (!nd6_try_set_entry_addr(ifp, ln, lladdr))
812
goto freeit;
813
814
flush_holdchain = true;
815
if (is_solicited)
816
nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE);
817
else
818
nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
819
EVENTHANDLER_INVOKE(lle_event, ln, LLENTRY_RESOLVED);
820
if ((ln->ln_router = is_router) != 0) {
821
/*
822
* This means a router's state has changed from
823
* non-reachable to probably reachable, and might
824
* affect the status of associated prefixes..
825
*/
826
checklink = 1;
827
}
828
} else {
829
int llchange;
830
831
/*
832
* Check if the link-layer address has changed or not.
833
*/
834
if (lladdr == NULL)
835
llchange = 0;
836
else {
837
if (ln->la_flags & LLE_VALID) {
838
if (bcmp(lladdr, ln->ll_addr, ifp->if_addrlen))
839
llchange = 1;
840
else
841
llchange = 0;
842
} else
843
llchange = 1;
844
}
845
846
/*
847
* This is VERY complex. Look at it with care.
848
*
849
* override solicit lladdr llchange action
850
* (L: record lladdr)
851
*
852
* 0 0 n -- (2c)
853
* 0 0 y n (2b) L
854
* 0 0 y y (1) REACHABLE->STALE
855
* 0 1 n -- (2c) *->REACHABLE
856
* 0 1 y n (2b) L *->REACHABLE
857
* 0 1 y y (1) REACHABLE->STALE
858
* 1 0 n -- (2a)
859
* 1 0 y n (2a) L
860
* 1 0 y y (2a) L *->STALE
861
* 1 1 n -- (2a) *->REACHABLE
862
* 1 1 y n (2a) L *->REACHABLE
863
* 1 1 y y (2a) L *->REACHABLE
864
*/
865
if (!is_override && (lladdr != NULL && llchange)) { /* (1) */
866
/*
867
* If state is REACHABLE, make it STALE.
868
* no other updates should be done.
869
*/
870
if (ln->ln_state == ND6_LLINFO_REACHABLE)
871
nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
872
goto freeit;
873
} else if (is_override /* (2a) */
874
|| (!is_override && (lladdr != NULL && !llchange)) /* (2b) */
875
|| lladdr == NULL) { /* (2c) */
876
/*
877
* Update link-local address, if any.
878
*/
879
if (lladdr != NULL) {
880
linkhdrsize = sizeof(linkhdr);
881
if (lltable_calc_llheader(ifp, AF_INET6, lladdr,
882
linkhdr, &linkhdrsize, &lladdr_off) != 0)
883
goto freeit;
884
if (lltable_try_set_entry_addr(ifp, ln, linkhdr,
885
linkhdrsize, lladdr_off) == 0)
886
goto freeit;
887
EVENTHANDLER_INVOKE(lle_event, ln,
888
LLENTRY_RESOLVED);
889
}
890
891
/*
892
* If solicited, make the state REACHABLE.
893
* If not solicited and the link-layer address was
894
* changed, make it STALE.
895
*/
896
if (is_solicited)
897
nd6_llinfo_setstate(ln, ND6_LLINFO_REACHABLE);
898
else {
899
if (lladdr != NULL && llchange)
900
nd6_llinfo_setstate(ln, ND6_LLINFO_STALE);
901
}
902
}
903
904
if (ln->ln_router && !is_router) {
905
/*
906
* The peer dropped the router flag.
907
* Remove the sender from the Default Router List and
908
* update the Destination Cache entries.
909
*/
910
struct ifnet *nd6_ifp;
911
912
nd6_ifp = lltable_get_ifp(ln->lle_tbl);
913
if (!defrouter_remove(&ln->r_l3addr.addr6, nd6_ifp) &&
914
(ND_IFINFO(nd6_ifp)->flags &
915
ND6_IFF_ACCEPT_RTADV) != 0)
916
/*
917
* Even if the neighbor is not in the default
918
* router list, the neighbor may be used as a
919
* next hop for some destinations (e.g. redirect
920
* case). So we must call rt6_flush explicitly.
921
*/
922
rt6_flush(&ip6->ip6_src, ifp);
923
}
924
ln->ln_router = is_router;
925
}
926
/* XXX - QL
927
* Does this matter?
928
* rt->rt_flags &= ~RTF_REJECT;
929
*/
930
ln->la_asked = 0;
931
if (ln->la_hold != NULL)
932
chain = nd6_grab_holdchain(ln);
933
freeit:
934
if (ln != NULL)
935
LLE_WUNLOCK(ln);
936
937
if (chain != NULL)
938
nd6_flush_holdchain(ifp, ln, chain);
939
if (flush_holdchain)
940
nd6_flush_children_holdchain(ifp, ln);
941
942
if (checklink)
943
pfxlist_onlink_check();
944
945
m_freem(m);
946
return;
947
948
bad:
949
if (ln != NULL)
950
LLE_WUNLOCK(ln);
951
952
ICMP6STAT_INC(icp6s_badna);
953
m_freem(m);
954
}
955
956
/*
957
* Neighbor advertisement output handling.
958
*
959
* Based on RFC 2461
960
*
961
* the following items are not implemented yet:
962
* - proxy advertisement delay rule (RFC2461 7.2.8, last paragraph, SHOULD)
963
* - anycast advertisement delay rule (RFC2461 7.2.7, SHOULD)
964
*
965
* tlladdr:
966
* - 0x01 if include target link-layer address
967
* - 0x02 if target address is CARP MASTER
968
* sdl0 - sockaddr_dl (= proxy NA) or NULL
969
*/
970
static void
971
nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0,
972
const struct in6_addr *taddr6, u_long flags, int tlladdr,
973
struct sockaddr *sdl0, u_int fibnum)
974
{
975
struct mbuf *m;
976
struct m_tag *mtag;
977
struct ip6_hdr *ip6;
978
struct nd_neighbor_advert *nd_na;
979
struct ip6_moptions im6o;
980
struct in6_addr daddr6;
981
982
NET_EPOCH_ASSERT();
983
984
int icmp6len, maxlen, error;
985
caddr_t mac = NULL;
986
987
daddr6 = *daddr6_0; /* make a local copy for modification */
988
989
/* estimate the size of message */
990
maxlen = sizeof(*ip6) + sizeof(*nd_na);
991
maxlen += (sizeof(struct nd_opt_hdr) + ifp->if_addrlen + 7) & ~7;
992
KASSERT(max_linkhdr + maxlen <= MCLBYTES, (
993
"%s: max_linkhdr + maxlen > MCLBYTES (%d + %d > %d)",
994
__func__, max_linkhdr, maxlen, MCLBYTES));
995
996
if (max_linkhdr + maxlen > MHLEN)
997
m = m_getcl(M_NOWAIT, MT_DATA, M_PKTHDR);
998
else
999
m = m_gethdr(M_NOWAIT, MT_DATA);
1000
if (m == NULL)
1001
return;
1002
M_SETFIB(m, fibnum);
1003
1004
icmp6len = sizeof(*nd_na);
1005
m->m_pkthdr.len = m->m_len = sizeof(struct ip6_hdr) + icmp6len;
1006
m->m_data += max_linkhdr; /* or M_ALIGN() equivalent? */
1007
1008
/* fill neighbor advertisement packet */
1009
ip6 = mtod(m, struct ip6_hdr *);
1010
ip6->ip6_flow = 0;
1011
ip6->ip6_vfc &= ~IPV6_VERSION_MASK;
1012
ip6->ip6_vfc |= IPV6_VERSION;
1013
ip6->ip6_nxt = IPPROTO_ICMPV6;
1014
ip6->ip6_hlim = 255;
1015
1016
if (IN6_IS_ADDR_UNSPECIFIED(&daddr6)) {
1017
/* reply to DAD */
1018
daddr6 = in6addr_linklocal_allnodes;
1019
if (in6_setscope(&daddr6, ifp, NULL))
1020
goto bad;
1021
1022
flags &= ~ND_NA_FLAG_SOLICITED;
1023
}
1024
if (IN6_IS_ADDR_MULTICAST(&daddr6)) {
1025
m->m_flags |= M_MCAST;
1026
im6o.im6o_multicast_ifp = ifp;
1027
im6o.im6o_multicast_hlim = 255;
1028
im6o.im6o_multicast_loop = 0;
1029
}
1030
1031
ip6->ip6_dst = daddr6;
1032
error = in6_selectsrc_nbr(fibnum, &daddr6, &im6o, ifp, &ip6->ip6_src);
1033
if (error) {
1034
char ip6buf[INET6_ADDRSTRLEN];
1035
nd6log((LOG_DEBUG, "nd6_na_output: source can't be "
1036
"determined: dst=%s, error=%d\n",
1037
ip6_sprintf(ip6buf, &daddr6), error));
1038
goto bad;
1039
}
1040
nd_na = (struct nd_neighbor_advert *)(ip6 + 1);
1041
nd_na->nd_na_type = ND_NEIGHBOR_ADVERT;
1042
nd_na->nd_na_code = 0;
1043
nd_na->nd_na_target = *taddr6;
1044
in6_clearscope(&nd_na->nd_na_target); /* XXX */
1045
1046
/*
1047
* If we respond from CARP address, we need to prepare mac address
1048
* for carp_output().
1049
*/
1050
if (ifp->if_carp && (tlladdr & ND6_NA_CARP_MASTER))
1051
mac = (*carp_macmatch6_p)(ifp, m, taddr6);
1052
/*
1053
* "tlladdr" indicates NS's condition for adding tlladdr or not.
1054
* see nd6_ns_input() for details.
1055
* Basically, if NS packet is sent to unicast/anycast addr,
1056
* target lladdr option SHOULD NOT be included.
1057
*/
1058
if (tlladdr & ND6_NA_OPT_LLA) {
1059
/*
1060
* sdl0 != NULL indicates proxy NA. If we do proxy, use
1061
* lladdr in sdl0. If we are not proxying (sending NA for
1062
* my address) use lladdr configured for the interface.
1063
*/
1064
if (sdl0 == NULL) {
1065
if (mac == NULL)
1066
mac = nd6_ifptomac(ifp);
1067
} else if (sdl0->sa_family == AF_LINK) {
1068
struct sockaddr_dl *sdl;
1069
sdl = (struct sockaddr_dl *)sdl0;
1070
if (sdl->sdl_alen == ifp->if_addrlen)
1071
mac = LLADDR(sdl);
1072
}
1073
}
1074
if ((tlladdr & ND6_NA_OPT_LLA) && mac != NULL) {
1075
int optlen = sizeof(struct nd_opt_hdr) + ifp->if_addrlen;
1076
struct nd_opt_hdr *nd_opt = (struct nd_opt_hdr *)(nd_na + 1);
1077
1078
/* roundup to 8 bytes alignment! */
1079
optlen = (optlen + 7) & ~7;
1080
1081
m->m_pkthdr.len += optlen;
1082
m->m_len += optlen;
1083
icmp6len += optlen;
1084
bzero((caddr_t)nd_opt, optlen);
1085
nd_opt->nd_opt_type = ND_OPT_TARGET_LINKADDR;
1086
nd_opt->nd_opt_len = optlen >> 3;
1087
bcopy(mac, (caddr_t)(nd_opt + 1), ifp->if_addrlen);
1088
} else
1089
flags &= ~ND_NA_FLAG_OVERRIDE;
1090
1091
ip6->ip6_plen = htons((u_short)icmp6len);
1092
nd_na->nd_na_flags_reserved = flags;
1093
nd_na->nd_na_cksum = 0;
1094
nd_na->nd_na_cksum =
1095
in6_cksum(m, IPPROTO_ICMPV6, sizeof(struct ip6_hdr), icmp6len);
1096
1097
if (send_sendso_input_hook != NULL) {
1098
mtag = m_tag_get(PACKET_TAG_ND_OUTGOING,
1099
sizeof(unsigned short), M_NOWAIT);
1100
if (mtag == NULL)
1101
goto bad;
1102
*(unsigned short *)(mtag + 1) = nd_na->nd_na_type;
1103
m_tag_prepend(m, mtag);
1104
}
1105
1106
ip6_output(m, NULL, NULL, 0, &im6o, NULL, NULL);
1107
icmp6_ifstat_inc(ifp, ifs6_out_msg);
1108
icmp6_ifstat_inc(ifp, ifs6_out_neighboradvert);
1109
ICMP6STAT_INC2(icp6s_outhist, ND_NEIGHBOR_ADVERT);
1110
1111
return;
1112
1113
bad:
1114
m_freem(m);
1115
}
1116
1117
#ifndef BURN_BRIDGES
1118
void
1119
nd6_na_output(struct ifnet *ifp, const struct in6_addr *daddr6_0,
1120
const struct in6_addr *taddr6, u_long flags, int tlladdr,
1121
struct sockaddr *sdl0)
1122
{
1123
1124
nd6_na_output_fib(ifp, daddr6_0, taddr6, flags, tlladdr, sdl0,
1125
RT_DEFAULT_FIB);
1126
}
1127
#endif
1128
1129
caddr_t
1130
nd6_ifptomac(struct ifnet *ifp)
1131
{
1132
switch (ifp->if_type) {
1133
case IFT_ETHER:
1134
case IFT_IEEE1394:
1135
case IFT_L2VLAN:
1136
case IFT_INFINIBAND:
1137
case IFT_BRIDGE:
1138
return IF_LLADDR(ifp);
1139
default:
1140
return NULL;
1141
}
1142
}
1143
1144
struct dadq {
1145
TAILQ_ENTRY(dadq) dad_list;
1146
struct ifaddr *dad_ifa;
1147
int dad_count; /* max NS to send */
1148
int dad_ns_tcount; /* # of trials to send NS */
1149
int dad_ns_ocount; /* NS sent so far */
1150
int dad_ns_icount;
1151
int dad_na_icount;
1152
int dad_ns_lcount; /* looped back NS */
1153
int dad_loopbackprobe; /* probing state for loopback detection */
1154
struct callout dad_timer_ch;
1155
struct vnet *dad_vnet;
1156
u_int dad_refcnt;
1157
#define ND_OPT_NONCE_LEN32 \
1158
((ND_OPT_NONCE_LEN + sizeof(uint32_t) - 1)/sizeof(uint32_t))
1159
uint32_t dad_nonce[ND_OPT_NONCE_LEN32];
1160
bool dad_ondadq; /* on dadq? Protected by DADQ_WLOCK. */
1161
};
1162
1163
VNET_DEFINE_STATIC(TAILQ_HEAD(, dadq), dadq);
1164
VNET_DEFINE_STATIC(struct rwlock, dad_rwlock);
1165
#define V_dadq VNET(dadq)
1166
#define V_dad_rwlock VNET(dad_rwlock)
1167
1168
#define DADQ_LOCKPTR() (&V_dad_rwlock)
1169
#define DADQ_LOCK_INIT() rw_init(DADQ_LOCKPTR(), "nd6 DAD queue")
1170
#define DADQ_RLOCK() rw_rlock(DADQ_LOCKPTR())
1171
#define DADQ_RUNLOCK() rw_runlock(DADQ_LOCKPTR())
1172
#define DADQ_WLOCK() rw_wlock(DADQ_LOCKPTR())
1173
#define DADQ_WUNLOCK() rw_wunlock(DADQ_LOCKPTR())
1174
1175
#define DADQ_LOCK_ASSERT() rw_assert(DADQ_LOCKPTR(), RA_LOCKED);
1176
#define DADQ_RLOCK_ASSERT() rw_assert(DADQ_LOCKPTR(), RA_RLOCKED);
1177
#define DADQ_WLOCK_ASSERT() rw_assert(DADQ_LOCKPTR(), RA_WLOCKED);
1178
1179
static void
1180
nd6_dad_add(struct dadq *dp)
1181
{
1182
DADQ_WLOCK_ASSERT();
1183
1184
TAILQ_INSERT_TAIL(&V_dadq, dp, dad_list);
1185
dp->dad_ondadq = true;
1186
}
1187
1188
static void
1189
nd6_dad_del(struct dadq *dp)
1190
{
1191
DADQ_WLOCK_ASSERT();
1192
1193
if (dp->dad_ondadq) {
1194
/*
1195
* Remove dp from the dadq and release the dadq's
1196
* reference.
1197
*/
1198
TAILQ_REMOVE(&V_dadq, dp, dad_list);
1199
dp->dad_ondadq = false;
1200
nd6_dad_rele(dp);
1201
}
1202
}
1203
1204
static struct dadq *
1205
nd6_dad_find(struct ifaddr *ifa, struct nd_opt_nonce *n)
1206
{
1207
struct dadq *dp;
1208
1209
DADQ_LOCK_ASSERT();
1210
1211
TAILQ_FOREACH(dp, &V_dadq, dad_list) {
1212
if (dp->dad_ifa != ifa)
1213
continue;
1214
1215
/*
1216
* Skip if the nonce matches the received one.
1217
* +2 in the length is required because of type and
1218
* length fields are included in a header.
1219
*/
1220
if (n != NULL &&
1221
n->nd_opt_nonce_len == (ND_OPT_NONCE_LEN + 2) / 8 &&
1222
memcmp(&n->nd_opt_nonce[0], &dp->dad_nonce[0],
1223
ND_OPT_NONCE_LEN) == 0) {
1224
dp->dad_ns_lcount++;
1225
continue;
1226
}
1227
break;
1228
}
1229
1230
return (dp);
1231
}
1232
1233
static void
1234
nd6_dad_starttimer(struct dadq *dp, int ticks)
1235
{
1236
DADQ_WLOCK_ASSERT();
1237
1238
callout_reset(&dp->dad_timer_ch, ticks, nd6_dad_timer, dp);
1239
}
1240
1241
static void
1242
nd6_dad_stoptimer(struct dadq *dp)
1243
{
1244
callout_drain(&dp->dad_timer_ch);
1245
}
1246
1247
static void
1248
nd6_dad_rele(struct dadq *dp)
1249
{
1250
if (refcount_release(&dp->dad_refcnt)) {
1251
KASSERT(!dp->dad_ondadq, ("dp %p still on DAD queue", dp));
1252
ifa_free(dp->dad_ifa);
1253
free(dp, M_IP6NDP);
1254
}
1255
}
1256
1257
void
1258
nd6_dad_init(void)
1259
{
1260
DADQ_LOCK_INIT();
1261
TAILQ_INIT(&V_dadq);
1262
}
1263
1264
/*
1265
* Start Duplicate Address Detection (DAD) for specified interface address.
1266
*/
1267
void
1268
nd6_dad_start(struct ifaddr *ifa, int delay)
1269
{
1270
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1271
struct dadq *dp;
1272
char ip6buf[INET6_ADDRSTRLEN];
1273
1274
KASSERT((ia->ia6_flags & IN6_IFF_TENTATIVE) != 0,
1275
("starting DAD on non-tentative address %p", ifa));
1276
1277
/*
1278
* If we don't need DAD, don't do it.
1279
* There are several cases:
1280
* - DAD is disabled globally or on the interface
1281
* - the interface address is anycast
1282
*/
1283
if ((ia->ia6_flags & IN6_IFF_ANYCAST) != 0 ||
1284
V_ip6_dad_count == 0 ||
1285
(ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_NO_DAD) != 0) {
1286
ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1287
return;
1288
}
1289
if ((ifa->ifa_ifp->if_flags & IFF_UP) == 0 ||
1290
(ifa->ifa_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 ||
1291
(ND_IFINFO(ifa->ifa_ifp)->flags & ND6_IFF_IFDISABLED) != 0)
1292
return;
1293
1294
DADQ_WLOCK();
1295
if ((dp = nd6_dad_find(ifa, NULL)) != NULL) {
1296
/*
1297
* DAD is already in progress. Let the existing entry
1298
* finish it.
1299
*/
1300
DADQ_WUNLOCK();
1301
return;
1302
}
1303
1304
dp = malloc(sizeof(*dp), M_IP6NDP, M_NOWAIT | M_ZERO);
1305
if (dp == NULL) {
1306
log(LOG_ERR, "nd6_dad_start: memory allocation failed for "
1307
"%s(%s)\n",
1308
ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
1309
ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1310
return;
1311
}
1312
callout_init_rw(&dp->dad_timer_ch, DADQ_LOCKPTR(),
1313
CALLOUT_RETURNUNLOCKED);
1314
#ifdef VIMAGE
1315
dp->dad_vnet = curvnet;
1316
#endif
1317
nd6log((LOG_DEBUG, "%s: starting DAD for %s\n", if_name(ifa->ifa_ifp),
1318
ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr)));
1319
1320
/*
1321
* Send NS packet for DAD, ip6_dad_count times.
1322
* Note that we must delay the first transmission, if this is the
1323
* first packet to be sent from the interface after interface
1324
* (re)initialization.
1325
*/
1326
dp->dad_ifa = ifa;
1327
ifa_ref(dp->dad_ifa);
1328
dp->dad_count = V_ip6_dad_count;
1329
dp->dad_ns_icount = dp->dad_na_icount = 0;
1330
dp->dad_ns_ocount = dp->dad_ns_tcount = 0;
1331
dp->dad_ns_lcount = dp->dad_loopbackprobe = 0;
1332
1333
/* Add this to the dadq and add a reference for the dadq. */
1334
refcount_init(&dp->dad_refcnt, 1);
1335
nd6_dad_add(dp);
1336
nd6_dad_starttimer(dp, delay);
1337
DADQ_WUNLOCK();
1338
}
1339
1340
/*
1341
* terminate DAD unconditionally. used for address removals.
1342
*/
1343
void
1344
nd6_dad_stop(struct ifaddr *ifa)
1345
{
1346
struct dadq *dp;
1347
1348
DADQ_WLOCK();
1349
dp = nd6_dad_find(ifa, NULL);
1350
if (dp == NULL) {
1351
DADQ_WUNLOCK();
1352
/* DAD wasn't started yet */
1353
return;
1354
}
1355
1356
/*
1357
* Acquire a temporary reference so that we can safely stop the callout.
1358
*/
1359
(void)refcount_acquire(&dp->dad_refcnt);
1360
nd6_dad_del(dp);
1361
DADQ_WUNLOCK();
1362
1363
nd6_dad_stoptimer(dp);
1364
nd6_dad_rele(dp);
1365
}
1366
1367
static void
1368
nd6_dad_timer(void *arg)
1369
{
1370
struct dadq *dp = arg;
1371
struct ifaddr *ifa = dp->dad_ifa;
1372
struct ifnet *ifp = dp->dad_ifa->ifa_ifp;
1373
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1374
char ip6buf[INET6_ADDRSTRLEN];
1375
struct epoch_tracker et;
1376
1377
CURVNET_SET(dp->dad_vnet);
1378
KASSERT(ia != NULL, ("DAD entry %p with no address", dp));
1379
1380
NET_EPOCH_ENTER(et);
1381
if (ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) {
1382
/* Do not need DAD for ifdisabled interface. */
1383
log(LOG_ERR, "nd6_dad_timer: cancel DAD on %s because of "
1384
"ND6_IFF_IFDISABLED.\n", ifp->if_xname);
1385
goto err;
1386
}
1387
if (ia->ia6_flags & IN6_IFF_DUPLICATED) {
1388
log(LOG_ERR, "nd6_dad_timer: called with duplicated address "
1389
"%s(%s)\n",
1390
ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
1391
ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1392
goto err;
1393
}
1394
if ((ia->ia6_flags & IN6_IFF_TENTATIVE) == 0) {
1395
log(LOG_ERR, "nd6_dad_timer: called with non-tentative address "
1396
"%s(%s)\n",
1397
ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
1398
ifa->ifa_ifp ? if_name(ifa->ifa_ifp) : "???");
1399
goto err;
1400
}
1401
1402
/* Stop DAD if the interface is down even after dad_maxtry attempts. */
1403
if ((dp->dad_ns_tcount > V_dad_maxtry) &&
1404
(((ifp->if_flags & IFF_UP) == 0) ||
1405
((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0))) {
1406
nd6log((LOG_INFO, "%s: could not run DAD "
1407
"because the interface was down or not running.\n",
1408
if_name(ifa->ifa_ifp)));
1409
goto err;
1410
}
1411
1412
/* Need more checks? */
1413
if (dp->dad_ns_ocount < dp->dad_count) {
1414
/*
1415
* We have more NS to go. Send NS packet for DAD.
1416
*/
1417
nd6_dad_starttimer(dp,
1418
(long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1419
nd6_dad_ns_output(dp);
1420
goto done;
1421
} else {
1422
/*
1423
* We have transmitted sufficient number of DAD packets.
1424
* See what we've got.
1425
*/
1426
if (dp->dad_ns_icount > 0 || dp->dad_na_icount > 0) {
1427
/* We've seen NS or NA, means DAD has failed. */
1428
nd6_dad_duplicated(ifa, dp);
1429
} else if (V_dad_enhanced != 0 &&
1430
dp->dad_ns_lcount > 0 &&
1431
dp->dad_ns_lcount > dp->dad_loopbackprobe) {
1432
/*
1433
* Sec. 4.1 in RFC 7527 requires transmission of
1434
* additional probes until the loopback condition
1435
* becomes clear when a looped back probe is detected.
1436
*/
1437
log(LOG_ERR, "%s: a looped back NS message is "
1438
"detected during DAD for %s. "
1439
"Another DAD probes are being sent.\n",
1440
if_name(ifa->ifa_ifp),
1441
ip6_sprintf(ip6buf, IFA_IN6(ifa)));
1442
dp->dad_loopbackprobe = dp->dad_ns_lcount;
1443
/*
1444
* Send an NS immediately and increase dad_count by
1445
* V_nd6_mmaxtries - 1.
1446
*/
1447
dp->dad_count =
1448
dp->dad_ns_ocount + V_nd6_mmaxtries - 1;
1449
nd6_dad_starttimer(dp,
1450
(long)ND_IFINFO(ifa->ifa_ifp)->retrans * hz / 1000);
1451
nd6_dad_ns_output(dp);
1452
goto done;
1453
} else {
1454
/*
1455
* We are done with DAD. No NA came, no NS came.
1456
* No duplicate address found. Check IFDISABLED flag
1457
* again in case that it is changed between the
1458
* beginning of this function and here.
1459
*
1460
* Reset DAD failures counter if using stable addresses.
1461
*/
1462
if ((ND_IFINFO(ifp)->flags & ND6_IFF_IFDISABLED) == 0) {
1463
ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1464
if ((ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR) && !(ia->ia6_flags & IN6_IFF_TEMPORARY))
1465
atomic_store_int(&DAD_FAILURES(ifp), 0);
1466
}
1467
1468
nd6log((LOG_DEBUG,
1469
"%s: DAD complete for %s - no duplicates found\n",
1470
if_name(ifa->ifa_ifp),
1471
ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr)));
1472
if (dp->dad_ns_lcount > 0)
1473
log(LOG_ERR, "%s: DAD completed while "
1474
"a looped back NS message is detected "
1475
"during DAD for %s.\n",
1476
if_name(ifa->ifa_ifp),
1477
ip6_sprintf(ip6buf, IFA_IN6(ifa)));
1478
}
1479
}
1480
err:
1481
nd6_dad_del(dp);
1482
DADQ_WUNLOCK();
1483
done:
1484
NET_EPOCH_EXIT(et);
1485
CURVNET_RESTORE();
1486
}
1487
1488
static void
1489
nd6_dad_duplicated(struct ifaddr *ifa, struct dadq *dp)
1490
{
1491
struct in6_ifaddr *ia = (struct in6_ifaddr *)ifa;
1492
struct ifnet *ifp;
1493
char ip6buf[INET6_ADDRSTRLEN];
1494
1495
ifp = ifa->ifa_ifp;
1496
1497
log(LOG_ERR, "%s: DAD detected duplicate IPv6 address %s: "
1498
"NS in/out/loopback=%d/%d/%d, NA in=%d\n",
1499
if_name(ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr),
1500
dp->dad_ns_icount, dp->dad_ns_ocount, dp->dad_ns_lcount,
1501
dp->dad_na_icount);
1502
1503
ia->ia6_flags &= ~IN6_IFF_TENTATIVE;
1504
ia->ia6_flags |= IN6_IFF_DUPLICATED;
1505
1506
log(LOG_ERR, "%s: DAD complete for %s - duplicate found\n",
1507
if_name(ifp), ip6_sprintf(ip6buf, &ia->ia_addr.sin6_addr));
1508
1509
/*
1510
* For RFC 7217 stable addresses, increment failure counter here if we still have retries.
1511
* More addresses will be generated as long as retries are not exhausted.
1512
*/
1513
if ((ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR) && !(ia->ia6_flags & IN6_IFF_TEMPORARY)) {
1514
u_int dad_failures = atomic_load_int(&DAD_FAILURES(ifp));
1515
1516
if (dad_failures <= V_ip6_stableaddr_maxretries) {
1517
atomic_add_int(&DAD_FAILURES(ifp), 1);
1518
/* if retries exhausted, output an informative error message */
1519
if (dad_failures == V_ip6_stableaddr_maxretries)
1520
log(LOG_ERR, "%s: manual intervention required, consider disabling \"stableaddr\" on the interface"
1521
" or checking hostuuid for uniqueness\n",
1522
if_name(ifp));
1523
}
1524
} else {
1525
log(LOG_ERR, "%s: manual intervention required\n",
1526
if_name(ifp));
1527
}
1528
1529
/*
1530
* If the address is a link-local address formed from an interface
1531
* identifier based on the hardware address which is supposed to be
1532
* uniquely assigned (e.g., EUI-64 for an Ethernet interface), IP
1533
* operation on the interface SHOULD be disabled.
1534
* [RFC 4862, Section 5.4.5]
1535
*/
1536
if (IN6_IS_ADDR_LINKLOCAL(&ia->ia_addr.sin6_addr)) {
1537
struct in6_addr in6;
1538
1539
/*
1540
* To avoid over-reaction, we only apply this logic when we are
1541
* very sure that hardware addresses are supposed to be unique.
1542
*/
1543
switch (ifp->if_type) {
1544
case IFT_ETHER:
1545
case IFT_ATM:
1546
case IFT_IEEE1394:
1547
case IFT_INFINIBAND:
1548
in6 = ia->ia_addr.sin6_addr;
1549
if (in6_get_hw_ifid(ifp, &in6) == 0 &&
1550
IN6_ARE_ADDR_EQUAL(&ia->ia_addr.sin6_addr, &in6)) {
1551
ND_IFINFO(ifp)->flags |= ND6_IFF_IFDISABLED;
1552
log(LOG_ERR, "%s: possible hardware address "
1553
"duplication detected, disable IPv6\n",
1554
if_name(ifp));
1555
}
1556
break;
1557
}
1558
}
1559
}
1560
1561
/*
1562
* Transmit a neighbour solicitation for the purpose of DAD. Returns with the
1563
* DAD queue unlocked.
1564
*/
1565
static void
1566
nd6_dad_ns_output(struct dadq *dp)
1567
{
1568
struct in6_ifaddr *ia = (struct in6_ifaddr *)dp->dad_ifa;
1569
struct ifnet *ifp = dp->dad_ifa->ifa_ifp;
1570
int i;
1571
1572
DADQ_WLOCK_ASSERT();
1573
1574
dp->dad_ns_tcount++;
1575
if ((ifp->if_flags & IFF_UP) == 0) {
1576
DADQ_WUNLOCK();
1577
return;
1578
}
1579
if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) {
1580
DADQ_WUNLOCK();
1581
return;
1582
}
1583
1584
dp->dad_ns_ocount++;
1585
if (V_dad_enhanced != 0) {
1586
for (i = 0; i < ND_OPT_NONCE_LEN32; i++)
1587
dp->dad_nonce[i] = arc4random();
1588
/*
1589
* XXXHRS: Note that in the case that
1590
* DupAddrDetectTransmits > 1, multiple NS messages with
1591
* different nonces can be looped back in an unexpected
1592
* order. The current implementation recognizes only
1593
* the latest nonce on the sender side. Practically it
1594
* should work well in almost all cases.
1595
*/
1596
}
1597
DADQ_WUNLOCK();
1598
nd6_ns_output(ifp, NULL, NULL, &ia->ia_addr.sin6_addr,
1599
(uint8_t *)&dp->dad_nonce[0]);
1600
}
1601
1602
static void
1603
nd6_dad_ns_input(struct ifaddr *ifa, struct nd_opt_nonce *ndopt_nonce)
1604
{
1605
struct dadq *dp;
1606
1607
if (ifa == NULL)
1608
panic("ifa == NULL in nd6_dad_ns_input");
1609
1610
/* Ignore Nonce option when Enhanced DAD is disabled. */
1611
if (V_dad_enhanced == 0)
1612
ndopt_nonce = NULL;
1613
DADQ_RLOCK();
1614
dp = nd6_dad_find(ifa, ndopt_nonce);
1615
if (dp != NULL)
1616
dp->dad_ns_icount++;
1617
DADQ_RUNLOCK();
1618
}
1619
1620
static void
1621
nd6_dad_na_input(struct ifaddr *ifa)
1622
{
1623
struct dadq *dp;
1624
1625
if (ifa == NULL)
1626
panic("ifa == NULL in nd6_dad_na_input");
1627
1628
DADQ_RLOCK();
1629
dp = nd6_dad_find(ifa, NULL);
1630
if (dp != NULL)
1631
dp->dad_na_icount++;
1632
DADQ_RUNLOCK();
1633
}
1634
1635