Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/sys/netinet6/nd6_rtr.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_rtr.c,v 1.111 2001/04/27 01:37:15 jinmei Exp $
32
*/
33
34
#include <sys/cdefs.h>
35
#include "opt_inet.h"
36
#include "opt_inet6.h"
37
38
#include <sys/param.h>
39
#include <sys/systm.h>
40
#include <sys/malloc.h>
41
#include <sys/mbuf.h>
42
#include <sys/refcount.h>
43
#include <sys/socket.h>
44
#include <sys/sockio.h>
45
#include <sys/time.h>
46
#include <sys/kernel.h>
47
#include <sys/lock.h>
48
#include <sys/errno.h>
49
#include <sys/rmlock.h>
50
#include <sys/rwlock.h>
51
#include <sys/sysctl.h>
52
#include <sys/syslog.h>
53
#include <sys/queue.h>
54
#include <sys/random.h>
55
56
#include <net/if.h>
57
#include <net/if_var.h>
58
#include <net/if_private.h>
59
#include <net/if_types.h>
60
#include <net/if_dl.h>
61
#include <net/route.h>
62
#include <net/route/nhop.h>
63
#include <net/route/route_ctl.h>
64
#include <net/radix.h>
65
#include <net/vnet.h>
66
67
#include <netinet/in.h>
68
#include <net/if_llatbl.h>
69
#include <netinet6/in6_var.h>
70
#include <netinet6/in6_ifattach.h>
71
#include <netinet/ip6.h>
72
#include <netinet6/ip6_var.h>
73
#include <netinet6/nd6.h>
74
#include <netinet/icmp6.h>
75
#include <netinet6/scope6_var.h>
76
77
#include <machine/atomic.h>
78
79
static struct nd_defrouter *defrtrlist_update(struct nd_defrouter *);
80
static int prelist_update(struct nd_prefixctl *, struct nd_defrouter *,
81
struct mbuf *, int);
82
static int nd6_prefix_onlink(struct nd_prefix *);
83
static int in6_get_tmp_ifid(struct in6_aliasreq *);
84
85
TAILQ_HEAD(nd6_drhead, nd_defrouter);
86
VNET_DEFINE_STATIC(struct nd6_drhead, nd6_defrouter);
87
#define V_nd6_defrouter VNET(nd6_defrouter)
88
89
VNET_DECLARE(int, nd6_recalc_reachtm_interval);
90
#define V_nd6_recalc_reachtm_interval VNET(nd6_recalc_reachtm_interval)
91
92
VNET_DEFINE_STATIC(struct ifnet *, nd6_defifp);
93
VNET_DEFINE(int, nd6_defifindex);
94
#define V_nd6_defifp VNET(nd6_defifp)
95
96
VNET_DEFINE(int, ip6_use_tempaddr) = 0;
97
VNET_DEFINE(bool, ip6_use_stableaddr) = 0;
98
99
VNET_DEFINE(int, ip6_desync_factor);
100
VNET_DEFINE(uint32_t, ip6_temp_max_desync_factor) = TEMP_MAX_DESYNC_FACTOR_BASE;
101
VNET_DEFINE(u_int32_t, ip6_temp_preferred_lifetime) = DEF_TEMP_PREFERRED_LIFETIME;
102
VNET_DEFINE(u_int32_t, ip6_temp_valid_lifetime) = DEF_TEMP_VALID_LIFETIME;
103
104
VNET_DEFINE(int, ip6_temp_regen_advance) = TEMPADDR_REGEN_ADVANCE;
105
106
#ifdef EXPERIMENTAL
107
VNET_DEFINE_STATIC(int, nd6_ignore_ipv6_only_ra) = 1;
108
#define V_nd6_ignore_ipv6_only_ra VNET(nd6_ignore_ipv6_only_ra)
109
SYSCTL_INT(_net_inet6_icmp6, OID_AUTO,
110
nd6_ignore_ipv6_only_ra, CTLFLAG_VNET | CTLFLAG_RW,
111
&VNET_NAME(nd6_ignore_ipv6_only_ra), 0,
112
"Ignore the 'IPv6-Only flag' in RA messages in compliance with "
113
"draft-ietf-6man-ipv6only-flag");
114
#endif
115
116
/* RTPREF_MEDIUM has to be 0! */
117
#define RTPREF_HIGH 1
118
#define RTPREF_MEDIUM 0
119
#define RTPREF_LOW (-1)
120
#define RTPREF_RESERVED (-2)
121
#define RTPREF_INVALID (-3) /* internal */
122
123
static void
124
defrouter_ref(struct nd_defrouter *dr)
125
{
126
127
refcount_acquire(&dr->refcnt);
128
}
129
130
void
131
defrouter_rele(struct nd_defrouter *dr)
132
{
133
134
if (refcount_release(&dr->refcnt))
135
free(dr, M_IP6NDP);
136
}
137
138
/*
139
* Remove a router from the global list and optionally stash it in a
140
* caller-supplied queue.
141
*/
142
static void
143
defrouter_unlink(struct nd_defrouter *dr, struct nd6_drhead *drq)
144
{
145
146
ND6_WLOCK_ASSERT();
147
148
TAILQ_REMOVE(&V_nd6_defrouter, dr, dr_entry);
149
V_nd6_list_genid++;
150
if (drq != NULL)
151
TAILQ_INSERT_TAIL(drq, dr, dr_entry);
152
}
153
154
/*
155
* Receive Router Solicitation Message - just for routers.
156
* Router solicitation/advertisement is mostly managed by userland program
157
* (rtadvd) so here we have no function like nd6_ra_output().
158
*
159
* Based on RFC 2461
160
*/
161
void
162
nd6_rs_input(struct mbuf *m, int off, int icmp6len)
163
{
164
struct ifnet *ifp;
165
struct ip6_hdr *ip6;
166
struct nd_router_solicit *nd_rs;
167
struct in6_addr saddr6;
168
union nd_opts ndopts;
169
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
170
char *lladdr;
171
int lladdrlen;
172
173
ifp = m->m_pkthdr.rcvif;
174
175
/*
176
* Accept RS only when V_ip6_forwarding=1 and the interface has
177
* no ND6_IFF_ACCEPT_RTADV.
178
*/
179
if (!V_ip6_forwarding || ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV)
180
goto freeit;
181
182
/* RFC 6980: Nodes MUST silently ignore fragments */
183
if(m->m_flags & M_FRAGMENTED)
184
goto freeit;
185
186
/* Sanity checks */
187
ip6 = mtod(m, struct ip6_hdr *);
188
if (__predict_false(ip6->ip6_hlim != 255)) {
189
ICMP6STAT_INC(icp6s_invlhlim);
190
nd6log((LOG_ERR,
191
"%s: invalid hlim (%d) from %s to %s on %s\n", __func__,
192
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
193
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
194
goto bad;
195
}
196
197
/*
198
* Don't update the neighbor cache, if src = ::.
199
* This indicates that the src has no IP address assigned yet.
200
*/
201
saddr6 = ip6->ip6_src;
202
if (IN6_IS_ADDR_UNSPECIFIED(&saddr6))
203
goto freeit;
204
205
if (m->m_len < off + icmp6len) {
206
m = m_pullup(m, off + icmp6len);
207
if (m == NULL) {
208
IP6STAT_INC(ip6s_exthdrtoolong);
209
return;
210
}
211
}
212
ip6 = mtod(m, struct ip6_hdr *);
213
nd_rs = (struct nd_router_solicit *)((caddr_t)ip6 + off);
214
215
icmp6len -= sizeof(*nd_rs);
216
nd6_option_init(nd_rs + 1, icmp6len, &ndopts);
217
if (nd6_options(&ndopts) < 0) {
218
nd6log((LOG_INFO,
219
"%s: invalid ND option, ignored\n", __func__));
220
/* nd6_options have incremented stats */
221
goto freeit;
222
}
223
224
lladdr = NULL;
225
lladdrlen = 0;
226
if (ndopts.nd_opts_src_lladdr) {
227
lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
228
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
229
}
230
231
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
232
nd6log((LOG_INFO,
233
"%s: lladdrlen mismatch for %s (if %d, RS packet %d)\n",
234
__func__, ip6_sprintf(ip6bufs, &saddr6),
235
ifp->if_addrlen, lladdrlen - 2));
236
goto bad;
237
}
238
239
nd6_cache_lladdr(ifp, &saddr6, lladdr, lladdrlen, ND_ROUTER_SOLICIT, 0);
240
241
freeit:
242
m_freem(m);
243
return;
244
245
bad:
246
ICMP6STAT_INC(icp6s_badrs);
247
m_freem(m);
248
}
249
250
#ifdef EXPERIMENTAL
251
/*
252
* An initial update routine for draft-ietf-6man-ipv6only-flag.
253
* We need to iterate over all default routers for the given
254
* interface to see whether they are all advertising the "S"
255
* (IPv6-Only) flag. If they do set, otherwise unset, the
256
* interface flag we later use to filter on.
257
*/
258
static void
259
defrtr_ipv6_only_ifp(struct ifnet *ifp)
260
{
261
struct nd_defrouter *dr;
262
bool ipv6_only, ipv6_only_old;
263
#ifdef INET
264
struct epoch_tracker et;
265
struct ifaddr *ifa;
266
bool has_ipv4_addr;
267
#endif
268
269
if (V_nd6_ignore_ipv6_only_ra != 0)
270
return;
271
272
ipv6_only = true;
273
ND6_RLOCK();
274
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
275
if (dr->ifp == ifp &&
276
(dr->raflags & ND_RA_FLAG_IPV6_ONLY) == 0)
277
ipv6_only = false;
278
ND6_RUNLOCK();
279
280
IF_AFDATA_WLOCK(ifp);
281
ipv6_only_old = ND_IFINFO(ifp)->flags & ND6_IFF_IPV6_ONLY;
282
IF_AFDATA_WUNLOCK(ifp);
283
284
/* If nothing changed, we have an early exit. */
285
if (ipv6_only == ipv6_only_old)
286
return;
287
288
#ifdef INET
289
/*
290
* Should we want to set the IPV6-ONLY flag, check if the
291
* interface has a non-0/0 and non-link-local IPv4 address
292
* configured on it. If it has we will assume working
293
* IPv4 operations and will clear the interface flag.
294
*/
295
has_ipv4_addr = false;
296
if (ipv6_only) {
297
NET_EPOCH_ENTER(et);
298
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
299
if (ifa->ifa_addr->sa_family != AF_INET)
300
continue;
301
if (in_canforward(
302
satosin(ifa->ifa_addr)->sin_addr)) {
303
has_ipv4_addr = true;
304
break;
305
}
306
}
307
NET_EPOCH_EXIT(et);
308
}
309
if (ipv6_only && has_ipv4_addr) {
310
log(LOG_NOTICE, "%s rcvd RA w/ IPv6-Only flag set but has IPv4 "
311
"configured, ignoring IPv6-Only flag.\n", ifp->if_xname);
312
ipv6_only = false;
313
}
314
#endif
315
316
IF_AFDATA_WLOCK(ifp);
317
if (ipv6_only)
318
ND_IFINFO(ifp)->flags |= ND6_IFF_IPV6_ONLY;
319
else
320
ND_IFINFO(ifp)->flags &= ~ND6_IFF_IPV6_ONLY;
321
IF_AFDATA_WUNLOCK(ifp);
322
323
#ifdef notyet
324
/* Send notification of flag change. */
325
#endif
326
}
327
328
static void
329
defrtr_ipv6_only_ipf_down(struct ifnet *ifp)
330
{
331
332
IF_AFDATA_WLOCK(ifp);
333
ND_IFINFO(ifp)->flags &= ~ND6_IFF_IPV6_ONLY;
334
IF_AFDATA_WUNLOCK(ifp);
335
}
336
#endif /* EXPERIMENTAL */
337
338
void
339
nd6_ifnet_link_event(void *arg __unused, struct ifnet *ifp, int linkstate)
340
{
341
342
/*
343
* XXX-BZ we might want to trigger re-evaluation of our default router
344
* availability. E.g., on link down the default router might be
345
* unreachable but a different interface might still have connectivity.
346
*/
347
348
#ifdef EXPERIMENTAL
349
if (linkstate == LINK_STATE_DOWN)
350
defrtr_ipv6_only_ipf_down(ifp);
351
#endif
352
}
353
354
/*
355
* Receive Router Advertisement Message.
356
*
357
* Based on RFC 2461
358
* TODO: on-link bit on prefix information
359
* TODO: ND_RA_FLAG_{OTHER,MANAGED} processing
360
*/
361
void
362
nd6_ra_input(struct mbuf *m, int off, int icmp6len)
363
{
364
struct ifnet *ifp;
365
struct nd_ifinfo *ndi;
366
struct ip6_hdr *ip6;
367
struct nd_router_advert *nd_ra;
368
struct in6_addr saddr6;
369
struct nd_defrouter *dr;
370
union nd_opts ndopts;
371
char ip6bufs[INET6_ADDRSTRLEN], ip6bufd[INET6_ADDRSTRLEN];
372
int mcast;
373
374
/*
375
* We only accept RAs only when the per-interface flag
376
* ND6_IFF_ACCEPT_RTADV is on the receiving interface.
377
*/
378
ifp = m->m_pkthdr.rcvif;
379
ndi = ND_IFINFO(ifp);
380
if (!(ndi->flags & ND6_IFF_ACCEPT_RTADV))
381
goto freeit;
382
383
/* RFC 6980: Nodes MUST silently ignore fragments */
384
if(m->m_flags & M_FRAGMENTED)
385
goto freeit;
386
387
ip6 = mtod(m, struct ip6_hdr *);
388
if (__predict_false(ip6->ip6_hlim != 255)) {
389
ICMP6STAT_INC(icp6s_invlhlim);
390
nd6log((LOG_ERR,
391
"%s: invalid hlim (%d) from %s to %s on %s\n", __func__,
392
ip6->ip6_hlim, ip6_sprintf(ip6bufs, &ip6->ip6_src),
393
ip6_sprintf(ip6bufd, &ip6->ip6_dst), if_name(ifp)));
394
goto bad;
395
}
396
397
saddr6 = ip6->ip6_src;
398
if (!IN6_IS_ADDR_LINKLOCAL(&saddr6)) {
399
nd6log((LOG_ERR,
400
"%s: src %s is not link-local\n", __func__,
401
ip6_sprintf(ip6bufs, &saddr6)));
402
goto bad;
403
}
404
405
if (m->m_len < off + icmp6len) {
406
m = m_pullup(m, off + icmp6len);
407
if (m == NULL) {
408
IP6STAT_INC(ip6s_exthdrtoolong);
409
return;
410
}
411
}
412
ip6 = mtod(m, struct ip6_hdr *);
413
nd_ra = (struct nd_router_advert *)((caddr_t)ip6 + off);
414
415
icmp6len -= sizeof(*nd_ra);
416
nd6_option_init(nd_ra + 1, icmp6len, &ndopts);
417
if (nd6_options(&ndopts) < 0) {
418
nd6log((LOG_INFO,
419
"%s: invalid ND option, ignored\n", __func__));
420
/* nd6_options have incremented stats */
421
goto freeit;
422
}
423
424
mcast = 0;
425
dr = NULL;
426
{
427
struct nd_defrouter dr0;
428
u_int32_t advreachable = nd_ra->nd_ra_reachable;
429
430
/* remember if this is a multicasted advertisement */
431
if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_dst))
432
mcast = 1;
433
434
bzero(&dr0, sizeof(dr0));
435
dr0.rtaddr = saddr6;
436
dr0.raflags = nd_ra->nd_ra_flags_reserved;
437
/*
438
* Effectively-disable routes from RA messages when
439
* ND6_IFF_NO_RADR enabled on the receiving interface or
440
* (ip6.forwarding == 1 && ip6.rfc6204w3 != 1).
441
*/
442
if (ndi->flags & ND6_IFF_NO_RADR)
443
dr0.rtlifetime = 0;
444
else if (V_ip6_forwarding && !V_ip6_rfc6204w3)
445
dr0.rtlifetime = 0;
446
else
447
dr0.rtlifetime = ntohs(nd_ra->nd_ra_router_lifetime);
448
dr0.expire = time_uptime + dr0.rtlifetime;
449
dr0.ifp = ifp;
450
/* unspecified or not? (RFC 2461 6.3.4) */
451
if (advreachable) {
452
advreachable = ntohl(advreachable);
453
if (advreachable <= MAX_REACHABLE_TIME &&
454
ndi->basereachable != advreachable) {
455
ndi->basereachable = advreachable;
456
ndi->reachable = ND_COMPUTE_RTIME(ndi->basereachable);
457
ndi->recalctm = V_nd6_recalc_reachtm_interval; /* reset */
458
}
459
}
460
if (nd_ra->nd_ra_retransmit)
461
ndi->retrans = ntohl(nd_ra->nd_ra_retransmit);
462
if (nd_ra->nd_ra_curhoplimit) {
463
if (ndi->chlim < nd_ra->nd_ra_curhoplimit)
464
ndi->chlim = nd_ra->nd_ra_curhoplimit;
465
else if (ndi->chlim != nd_ra->nd_ra_curhoplimit) {
466
log(LOG_ERR, "RA with a lower CurHopLimit sent from "
467
"%s on %s (current = %d, received = %d). "
468
"Ignored.\n", ip6_sprintf(ip6bufs, &ip6->ip6_src),
469
if_name(ifp), ndi->chlim, nd_ra->nd_ra_curhoplimit);
470
}
471
}
472
dr = defrtrlist_update(&dr0);
473
#ifdef EXPERIMENTAL
474
defrtr_ipv6_only_ifp(ifp);
475
#endif
476
}
477
478
/*
479
* prefix
480
*/
481
if (ndopts.nd_opts_pi) {
482
struct nd_opt_hdr *pt;
483
struct nd_opt_prefix_info *pi = NULL;
484
struct nd_prefixctl pr;
485
486
for (pt = (struct nd_opt_hdr *)ndopts.nd_opts_pi;
487
pt <= (struct nd_opt_hdr *)ndopts.nd_opts_pi_end;
488
pt = (struct nd_opt_hdr *)((caddr_t)pt +
489
(pt->nd_opt_len << 3))) {
490
if (pt->nd_opt_type != ND_OPT_PREFIX_INFORMATION)
491
continue;
492
pi = (struct nd_opt_prefix_info *)pt;
493
494
if (pi->nd_opt_pi_len != 4) {
495
nd6log((LOG_INFO,
496
"%s: invalid option len %d for prefix "
497
"information option, ignored\n", __func__,
498
pi->nd_opt_pi_len));
499
continue;
500
}
501
502
if (128 < pi->nd_opt_pi_prefix_len) {
503
nd6log((LOG_INFO,
504
"%s: invalid prefix len %d for prefix "
505
"information option, ignored\n", __func__,
506
pi->nd_opt_pi_prefix_len));
507
continue;
508
}
509
510
if (IN6_IS_ADDR_MULTICAST(&pi->nd_opt_pi_prefix)
511
|| IN6_IS_ADDR_LINKLOCAL(&pi->nd_opt_pi_prefix)) {
512
nd6log((LOG_INFO,
513
"%s: invalid prefix %s, ignored\n",
514
__func__, ip6_sprintf(ip6bufs,
515
&pi->nd_opt_pi_prefix)));
516
continue;
517
}
518
519
bzero(&pr, sizeof(pr));
520
pr.ndpr_prefix.sin6_family = AF_INET6;
521
pr.ndpr_prefix.sin6_len = sizeof(pr.ndpr_prefix);
522
pr.ndpr_prefix.sin6_addr = pi->nd_opt_pi_prefix;
523
pr.ndpr_ifp = (struct ifnet *)m->m_pkthdr.rcvif;
524
525
pr.ndpr_raf_onlink = (pi->nd_opt_pi_flags_reserved &
526
ND_OPT_PI_FLAG_ONLINK) ? 1 : 0;
527
pr.ndpr_raf_auto = (pi->nd_opt_pi_flags_reserved &
528
ND_OPT_PI_FLAG_AUTO) ? 1 : 0;
529
pr.ndpr_plen = pi->nd_opt_pi_prefix_len;
530
pr.ndpr_vltime = ntohl(pi->nd_opt_pi_valid_time);
531
pr.ndpr_pltime = ntohl(pi->nd_opt_pi_preferred_time);
532
(void)prelist_update(&pr, dr, m, mcast);
533
}
534
}
535
if (dr != NULL) {
536
defrouter_rele(dr);
537
dr = NULL;
538
}
539
540
/*
541
* MTU
542
*/
543
if (ndopts.nd_opts_mtu && ndopts.nd_opts_mtu->nd_opt_mtu_len == 1) {
544
u_long mtu;
545
u_long maxmtu;
546
547
mtu = (u_long)ntohl(ndopts.nd_opts_mtu->nd_opt_mtu_mtu);
548
549
/* lower bound */
550
if (mtu < IPV6_MMTU) {
551
nd6log((LOG_INFO, "%s: bogus mtu option mtu=%lu sent "
552
"from %s, ignoring\n", __func__,
553
mtu, ip6_sprintf(ip6bufs, &ip6->ip6_src)));
554
goto skip;
555
}
556
557
/* upper bound */
558
maxmtu = (ndi->maxmtu && ndi->maxmtu < ifp->if_mtu)
559
? ndi->maxmtu : ifp->if_mtu;
560
if (mtu <= maxmtu) {
561
if (ndi->linkmtu != mtu) {
562
ndi->linkmtu = mtu;
563
rt_updatemtu(ifp);
564
}
565
} else {
566
nd6log((LOG_INFO, "%s: bogus mtu=%lu sent from %s; "
567
"exceeds maxmtu %lu, ignoring\n", __func__,
568
mtu, ip6_sprintf(ip6bufs, &ip6->ip6_src), maxmtu));
569
}
570
}
571
572
skip:
573
574
/*
575
* Source link layer address
576
*/
577
{
578
char *lladdr = NULL;
579
int lladdrlen = 0;
580
581
if (ndopts.nd_opts_src_lladdr) {
582
lladdr = (char *)(ndopts.nd_opts_src_lladdr + 1);
583
lladdrlen = ndopts.nd_opts_src_lladdr->nd_opt_len << 3;
584
}
585
586
if (lladdr && ((ifp->if_addrlen + 2 + 7) & ~7) != lladdrlen) {
587
nd6log((LOG_INFO,
588
"%s: lladdrlen mismatch for %s (if %d, RA packet %d)\n",
589
__func__, ip6_sprintf(ip6bufs, &saddr6),
590
ifp->if_addrlen, lladdrlen - 2));
591
goto bad;
592
}
593
594
nd6_cache_lladdr(ifp, &saddr6, lladdr,
595
lladdrlen, ND_ROUTER_ADVERT, 0);
596
597
/*
598
* Installing a link-layer address might change the state of the
599
* router's neighbor cache, which might also affect our on-link
600
* detection of adveritsed prefixes.
601
*/
602
pfxlist_onlink_check();
603
}
604
605
freeit:
606
m_freem(m);
607
return;
608
609
bad:
610
ICMP6STAT_INC(icp6s_badra);
611
m_freem(m);
612
}
613
614
/* PFXRTR */
615
static struct nd_pfxrouter *
616
pfxrtr_lookup(struct nd_prefix *pr, struct nd_defrouter *dr)
617
{
618
struct nd_pfxrouter *search;
619
620
ND6_LOCK_ASSERT();
621
622
LIST_FOREACH(search, &pr->ndpr_advrtrs, pfr_entry) {
623
if (search->router == dr)
624
break;
625
}
626
return (search);
627
}
628
629
static void
630
pfxrtr_add(struct nd_prefix *pr, struct nd_defrouter *dr)
631
{
632
struct nd_pfxrouter *new;
633
bool update;
634
635
ND6_UNLOCK_ASSERT();
636
637
ND6_RLOCK();
638
if (pfxrtr_lookup(pr, dr) != NULL) {
639
ND6_RUNLOCK();
640
return;
641
}
642
ND6_RUNLOCK();
643
644
new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
645
if (new == NULL)
646
return;
647
defrouter_ref(dr);
648
new->router = dr;
649
650
ND6_WLOCK();
651
if (pfxrtr_lookup(pr, dr) == NULL) {
652
LIST_INSERT_HEAD(&pr->ndpr_advrtrs, new, pfr_entry);
653
update = true;
654
} else {
655
/* We lost a race to add the reference. */
656
defrouter_rele(dr);
657
free(new, M_IP6NDP);
658
update = false;
659
}
660
ND6_WUNLOCK();
661
662
if (update)
663
pfxlist_onlink_check();
664
}
665
666
static void
667
pfxrtr_del(struct nd_pfxrouter *pfr)
668
{
669
670
ND6_WLOCK_ASSERT();
671
672
LIST_REMOVE(pfr, pfr_entry);
673
defrouter_rele(pfr->router);
674
free(pfr, M_IP6NDP);
675
}
676
677
/* Default router list processing sub routines. */
678
static void
679
defrouter_addreq(struct nd_defrouter *new)
680
{
681
uint32_t fibnum = new->ifp->if_fib;
682
struct rib_cmd_info rc = {};
683
int error = 0;
684
685
NET_EPOCH_ASSERT();
686
687
struct sockaddr_in6 gw = {
688
.sin6_family = AF_INET6,
689
.sin6_len = sizeof(struct sockaddr_in6),
690
.sin6_addr = new->rtaddr,
691
};
692
693
error = rib_add_default_route(fibnum, AF_INET6, new->ifp,
694
(struct sockaddr *)&gw, &rc);
695
696
if (error == 0) {
697
struct nhop_object *nh = nhop_select_func(rc.rc_nh_new, 0);
698
rt_routemsg(RTM_ADD, rc.rc_rt, nh, fibnum);
699
new->installed = 1;
700
}
701
}
702
703
/*
704
* Remove the default route for a given router.
705
* This is just a subroutine function for defrouter_select_fib(), and
706
* should not be called from anywhere else.
707
*/
708
static void
709
defrouter_delreq(struct nd_defrouter *dr)
710
{
711
uint32_t fibnum = dr->ifp->if_fib;
712
struct epoch_tracker et;
713
struct rib_cmd_info rc;
714
int error;
715
716
struct sockaddr_in6 dst = {
717
.sin6_family = AF_INET6,
718
.sin6_len = sizeof(struct sockaddr_in6),
719
};
720
721
struct sockaddr_in6 gw = {
722
.sin6_family = AF_INET6,
723
.sin6_len = sizeof(struct sockaddr_in6),
724
.sin6_addr = dr->rtaddr,
725
};
726
727
NET_EPOCH_ENTER(et);
728
error = rib_del_route_px(fibnum, (struct sockaddr *)&dst, 0,
729
rib_match_gw, (struct sockaddr *)&gw, 0, &rc);
730
if (error == 0) {
731
struct nhop_object *nh = nhop_select_func(rc.rc_nh_old, 0);
732
rt_routemsg(RTM_DELETE, rc.rc_rt, nh, fibnum);
733
}
734
NET_EPOCH_EXIT(et);
735
736
dr->installed = 0;
737
}
738
739
static void
740
defrouter_del(struct nd_defrouter *dr)
741
{
742
struct nd_defrouter *deldr = NULL;
743
struct nd_prefix *pr;
744
struct nd_pfxrouter *pfxrtr;
745
746
ND6_UNLOCK_ASSERT();
747
748
/*
749
* Flush all the routing table entries that use the router
750
* as a next hop.
751
*/
752
if (ND_IFINFO(dr->ifp)->flags & ND6_IFF_ACCEPT_RTADV)
753
rt6_flush(&dr->rtaddr, dr->ifp);
754
755
#ifdef EXPERIMENTAL
756
defrtr_ipv6_only_ifp(dr->ifp);
757
#endif
758
759
if (dr->installed) {
760
deldr = dr;
761
defrouter_delreq(dr);
762
}
763
764
/*
765
* Also delete all the pointers to the router in each prefix lists.
766
*/
767
ND6_WLOCK();
768
LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
769
if ((pfxrtr = pfxrtr_lookup(pr, dr)) != NULL)
770
pfxrtr_del(pfxrtr);
771
}
772
ND6_WUNLOCK();
773
774
pfxlist_onlink_check();
775
776
/*
777
* If the router is the primary one, choose a new one.
778
* Note that defrouter_select_fib() will remove the current
779
* gateway from the routing table.
780
*/
781
if (deldr)
782
defrouter_select_fib(deldr->ifp->if_fib);
783
784
/*
785
* Release the list reference.
786
*/
787
defrouter_rele(dr);
788
}
789
790
struct nd_defrouter *
791
defrouter_lookup_locked(const struct in6_addr *addr, struct ifnet *ifp)
792
{
793
struct nd_defrouter *dr;
794
795
ND6_LOCK_ASSERT();
796
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
797
if (dr->ifp == ifp && IN6_ARE_ADDR_EQUAL(addr, &dr->rtaddr)) {
798
defrouter_ref(dr);
799
return (dr);
800
}
801
return (NULL);
802
}
803
804
struct nd_defrouter *
805
defrouter_lookup(const struct in6_addr *addr, struct ifnet *ifp)
806
{
807
struct nd_defrouter *dr;
808
809
ND6_RLOCK();
810
dr = defrouter_lookup_locked(addr, ifp);
811
ND6_RUNLOCK();
812
return (dr);
813
}
814
815
/*
816
* Remove all default routes from default router list.
817
*/
818
void
819
defrouter_reset(void)
820
{
821
struct nd_defrouter *dr, **dra;
822
int count, i;
823
824
count = i = 0;
825
826
/*
827
* We can't delete routes with the ND lock held, so make a copy of the
828
* current default router list and use that when deleting routes.
829
*/
830
ND6_RLOCK();
831
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry)
832
count++;
833
ND6_RUNLOCK();
834
835
dra = malloc(count * sizeof(*dra), M_TEMP, M_WAITOK | M_ZERO);
836
837
ND6_RLOCK();
838
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
839
if (i == count)
840
break;
841
defrouter_ref(dr);
842
dra[i++] = dr;
843
}
844
ND6_RUNLOCK();
845
846
for (i = 0; i < count && dra[i] != NULL; i++) {
847
defrouter_delreq(dra[i]);
848
defrouter_rele(dra[i]);
849
}
850
free(dra, M_TEMP);
851
852
/*
853
* XXX should we also nuke any default routers in the kernel, by
854
* going through them by rtalloc1()?
855
*/
856
}
857
858
/*
859
* Look up a matching default router list entry and remove it. Returns true if a
860
* matching entry was found, false otherwise.
861
*/
862
bool
863
defrouter_remove(struct in6_addr *addr, struct ifnet *ifp)
864
{
865
struct nd_defrouter *dr;
866
867
ND6_WLOCK();
868
dr = defrouter_lookup_locked(addr, ifp);
869
if (dr == NULL) {
870
ND6_WUNLOCK();
871
return (false);
872
}
873
874
defrouter_unlink(dr, NULL);
875
ND6_WUNLOCK();
876
defrouter_del(dr);
877
defrouter_rele(dr);
878
return (true);
879
}
880
881
/*
882
* for default router selection
883
* regards router-preference field as a 2-bit signed integer
884
*/
885
static int
886
rtpref(struct nd_defrouter *dr)
887
{
888
switch (dr->raflags & ND_RA_FLAG_RTPREF_MASK) {
889
case ND_RA_FLAG_RTPREF_HIGH:
890
return (RTPREF_HIGH);
891
case ND_RA_FLAG_RTPREF_MEDIUM:
892
case ND_RA_FLAG_RTPREF_RSV:
893
return (RTPREF_MEDIUM);
894
case ND_RA_FLAG_RTPREF_LOW:
895
return (RTPREF_LOW);
896
default:
897
/*
898
* This case should never happen. If it did, it would mean a
899
* serious bug of kernel internal. We thus always bark here.
900
* Or, can we even panic?
901
*/
902
log(LOG_ERR, "rtpref: impossible RA flag %x\n", dr->raflags);
903
return (RTPREF_INVALID);
904
}
905
/* NOTREACHED */
906
}
907
908
static bool
909
is_dr_reachable(const struct nd_defrouter *dr) {
910
struct llentry *ln = NULL;
911
912
ln = nd6_lookup(&dr->rtaddr, LLE_SF(AF_INET6, 0), dr->ifp);
913
if (ln == NULL)
914
return (false);
915
bool reachable = ND6_IS_LLINFO_PROBREACH(ln);
916
LLE_RUNLOCK(ln);
917
return reachable;
918
}
919
920
/*
921
* Default Router Selection according to Section 6.3.6 of RFC 2461 and
922
* draft-ietf-ipngwg-router-selection:
923
* 1) Routers that are reachable or probably reachable should be preferred.
924
* If we have more than one (probably) reachable router, prefer ones
925
* with the highest router preference.
926
* 2) When no routers on the list are known to be reachable or
927
* probably reachable, routers SHOULD be selected in a round-robin
928
* fashion, regardless of router preference values.
929
* 3) If the Default Router List is empty, assume that all
930
* destinations are on-link.
931
*
932
* We assume nd_defrouter is sorted by router preference value.
933
* Since the code below covers both with and without router preference cases,
934
* we do not need to classify the cases by ifdef.
935
*
936
* At this moment, we do not try to install more than one default router,
937
* even when the multipath routing is available, because we're not sure about
938
* the benefits for stub hosts comparing to the risk of making the code
939
* complicated and the possibility of introducing bugs.
940
*
941
* We maintain a single list of routers for multiple FIBs, only considering one
942
* at a time based on the receiving interface's FIB. If @fibnum is RT_ALL_FIBS,
943
* we do the whole thing multiple times.
944
*/
945
void
946
defrouter_select_fib(int fibnum)
947
{
948
struct epoch_tracker et;
949
struct nd_defrouter *dr, *selected_dr, *installed_dr;
950
951
if (fibnum == RT_ALL_FIBS) {
952
for (fibnum = 0; fibnum < rt_numfibs; fibnum++) {
953
defrouter_select_fib(fibnum);
954
}
955
return;
956
}
957
958
ND6_RLOCK();
959
/*
960
* Let's handle easy case (3) first:
961
* If default router list is empty, there's nothing to be done.
962
*/
963
if (TAILQ_EMPTY(&V_nd6_defrouter)) {
964
ND6_RUNLOCK();
965
return;
966
}
967
968
/*
969
* Search for a (probably) reachable router from the list.
970
* We just pick up the first reachable one (if any), assuming that
971
* the ordering rule of the list described in defrtrlist_update().
972
*/
973
selected_dr = installed_dr = NULL;
974
NET_EPOCH_ENTER(et);
975
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
976
if (dr->ifp->if_fib != fibnum)
977
continue;
978
979
if (selected_dr == NULL && is_dr_reachable(dr)) {
980
selected_dr = dr;
981
defrouter_ref(selected_dr);
982
}
983
984
if (dr->installed) {
985
if (installed_dr == NULL) {
986
installed_dr = dr;
987
defrouter_ref(installed_dr);
988
} else {
989
/*
990
* this should not happen.
991
* warn for diagnosis.
992
*/
993
log(LOG_ERR, "defrouter_select_fib: more than "
994
"one router is installed\n");
995
}
996
}
997
}
998
999
/*
1000
* If none of the default routers was found to be reachable,
1001
* round-robin the list regardless of preference.
1002
* Otherwise, if we have an installed router, check if the selected
1003
* (reachable) router should really be preferred to the installed one.
1004
* We only prefer the new router when the old one is not reachable
1005
* or when the new one has a really higher preference value.
1006
*/
1007
if (selected_dr == NULL) {
1008
if (installed_dr == NULL ||
1009
TAILQ_NEXT(installed_dr, dr_entry) == NULL)
1010
dr = TAILQ_FIRST(&V_nd6_defrouter);
1011
else
1012
dr = TAILQ_NEXT(installed_dr, dr_entry);
1013
1014
/* Ensure we select a router for this FIB. */
1015
TAILQ_FOREACH_FROM(dr, &V_nd6_defrouter, dr_entry) {
1016
if (dr->ifp->if_fib == fibnum) {
1017
selected_dr = dr;
1018
defrouter_ref(selected_dr);
1019
break;
1020
}
1021
}
1022
} else if (installed_dr != NULL) {
1023
if (is_dr_reachable(installed_dr) &&
1024
rtpref(selected_dr) <= rtpref(installed_dr)) {
1025
defrouter_rele(selected_dr);
1026
selected_dr = installed_dr;
1027
}
1028
}
1029
ND6_RUNLOCK();
1030
1031
/*
1032
* If we selected a router for this FIB and it's different
1033
* than the installed one, remove the installed router and
1034
* install the selected one in its place.
1035
*/
1036
if (installed_dr != selected_dr) {
1037
if (installed_dr != NULL) {
1038
defrouter_delreq(installed_dr);
1039
defrouter_rele(installed_dr);
1040
}
1041
if (selected_dr != NULL)
1042
defrouter_addreq(selected_dr);
1043
}
1044
if (selected_dr != NULL)
1045
defrouter_rele(selected_dr);
1046
NET_EPOCH_EXIT(et);
1047
}
1048
1049
static struct nd_defrouter *
1050
defrtrlist_update(struct nd_defrouter *new)
1051
{
1052
struct nd_defrouter *dr, *n;
1053
uint64_t genid;
1054
int oldpref;
1055
bool writelocked;
1056
1057
if (new->rtlifetime == 0) {
1058
defrouter_remove(&new->rtaddr, new->ifp);
1059
return (NULL);
1060
}
1061
1062
ND6_RLOCK();
1063
writelocked = false;
1064
restart:
1065
dr = defrouter_lookup_locked(&new->rtaddr, new->ifp);
1066
if (dr != NULL) {
1067
oldpref = rtpref(dr);
1068
1069
/* override */
1070
dr->raflags = new->raflags; /* XXX flag check */
1071
dr->rtlifetime = new->rtlifetime;
1072
dr->expire = new->expire;
1073
1074
/*
1075
* If the preference does not change, there's no need
1076
* to sort the entries. Also make sure the selected
1077
* router is still installed in the kernel.
1078
*/
1079
if (dr->installed && rtpref(new) == oldpref) {
1080
if (writelocked)
1081
ND6_WUNLOCK();
1082
else
1083
ND6_RUNLOCK();
1084
return (dr);
1085
}
1086
}
1087
1088
/*
1089
* The router needs to be reinserted into the default router
1090
* list, so upgrade to a write lock. If that fails and the list
1091
* has potentially changed while the lock was dropped, we'll
1092
* redo the lookup with the write lock held.
1093
*/
1094
if (!writelocked) {
1095
writelocked = true;
1096
if (!ND6_TRY_UPGRADE()) {
1097
genid = V_nd6_list_genid;
1098
ND6_RUNLOCK();
1099
ND6_WLOCK();
1100
if (genid != V_nd6_list_genid)
1101
goto restart;
1102
}
1103
}
1104
1105
if (dr != NULL) {
1106
/*
1107
* The preferred router may have changed, so relocate this
1108
* router.
1109
*/
1110
TAILQ_REMOVE(&V_nd6_defrouter, dr, dr_entry);
1111
n = dr;
1112
} else {
1113
n = malloc(sizeof(*n), M_IP6NDP, M_NOWAIT | M_ZERO);
1114
if (n == NULL) {
1115
ND6_WUNLOCK();
1116
return (NULL);
1117
}
1118
memcpy(n, new, sizeof(*n));
1119
/* Initialize with an extra reference for the caller. */
1120
refcount_init(&n->refcnt, 2);
1121
}
1122
1123
/*
1124
* Insert the new router in the Default Router List;
1125
* The Default Router List should be in the descending order
1126
* of router-preferece. Routers with the same preference are
1127
* sorted in the arriving time order.
1128
*/
1129
1130
/* insert at the end of the group */
1131
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
1132
if (rtpref(n) > rtpref(dr))
1133
break;
1134
}
1135
if (dr != NULL)
1136
TAILQ_INSERT_BEFORE(dr, n, dr_entry);
1137
else
1138
TAILQ_INSERT_TAIL(&V_nd6_defrouter, n, dr_entry);
1139
V_nd6_list_genid++;
1140
ND6_WUNLOCK();
1141
1142
defrouter_select_fib(new->ifp->if_fib);
1143
1144
return (n);
1145
}
1146
1147
static int
1148
in6_init_prefix_ltimes(struct nd_prefix *ndpr)
1149
{
1150
if (ndpr->ndpr_pltime == ND6_INFINITE_LIFETIME)
1151
ndpr->ndpr_preferred = 0;
1152
else
1153
ndpr->ndpr_preferred = time_uptime + ndpr->ndpr_pltime;
1154
if (ndpr->ndpr_vltime == ND6_INFINITE_LIFETIME)
1155
ndpr->ndpr_expire = 0;
1156
else
1157
ndpr->ndpr_expire = time_uptime + ndpr->ndpr_vltime;
1158
1159
return 0;
1160
}
1161
1162
static void
1163
in6_init_address_ltimes(struct nd_prefix *new, struct in6_addrlifetime *lt6)
1164
{
1165
/* init ia6t_expire */
1166
if (lt6->ia6t_vltime == ND6_INFINITE_LIFETIME)
1167
lt6->ia6t_expire = 0;
1168
else {
1169
lt6->ia6t_expire = time_uptime;
1170
lt6->ia6t_expire += lt6->ia6t_vltime;
1171
}
1172
1173
/* init ia6t_preferred */
1174
if (lt6->ia6t_pltime == ND6_INFINITE_LIFETIME)
1175
lt6->ia6t_preferred = 0;
1176
else {
1177
lt6->ia6t_preferred = time_uptime;
1178
lt6->ia6t_preferred += lt6->ia6t_pltime;
1179
}
1180
}
1181
1182
static struct in6_ifaddr *
1183
in6_ifadd(struct nd_prefixctl *pr, int mcast)
1184
{
1185
struct ifnet *ifp = pr->ndpr_ifp;
1186
struct ifaddr *ifa;
1187
struct in6_aliasreq ifra;
1188
struct in6_ifaddr *ia = NULL, *ib = NULL;
1189
int error, plen0;
1190
struct in6_addr *ifid_addr = NULL, mask, newaddr;
1191
int prefixlen = pr->ndpr_plen;
1192
int updateflags;
1193
char ip6buf[INET6_ADDRSTRLEN];
1194
1195
in6_prefixlen2mask(&mask, prefixlen);
1196
1197
/*
1198
* find a link-local address (will be interface ID).
1199
* Is it really mandatory? Theoretically, a global or a site-local
1200
* address can be configured without a link-local address, if we
1201
* have a unique interface identifier...
1202
*
1203
* it is not mandatory to have a link-local address, we can generate
1204
* interface identifier on the fly. we do this because:
1205
* (1) it should be the easiest way to find interface identifier.
1206
* (2) RFC2462 5.4 suggesting the use of the same interface identifier
1207
* for multiple addresses on a single interface, and possible shortcut
1208
* of DAD. we omitted DAD for this reason in the past.
1209
* (3) a user can prevent autoconfiguration of global address
1210
* by removing link-local address by hand (this is partly because we
1211
* don't have other way to control the use of IPv6 on an interface.
1212
* this has been our design choice - cf. NRL's "ifconfig auto").
1213
* (4) it is easier to manage when an interface has addresses
1214
* with the same interface identifier, than to have multiple addresses
1215
* with different interface identifiers.
1216
*
1217
* If using stable privacy generation, generate a new address with
1218
* the algorithm specified in RFC 7217 section 5
1219
*/
1220
1221
/* make ifaddr */
1222
in6_prepare_ifra(&ifra, &pr->ndpr_prefix.sin6_addr, &mask);
1223
1224
if (ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR) {
1225
memcpy(&newaddr, &pr->ndpr_prefix.sin6_addr, sizeof(pr->ndpr_prefix.sin6_addr));
1226
1227
if(!in6_get_stableifid(ifp, &newaddr, prefixlen))
1228
return NULL;
1229
} else {
1230
ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp, 0); /* 0 is OK? */
1231
if (ifa) {
1232
ib = (struct in6_ifaddr *)ifa;
1233
ifid_addr = &ib->ia_addr.sin6_addr;
1234
1235
/* prefixlen + ifidlen must be equal to 128 */
1236
plen0 = in6_mask2len(&ib->ia_prefixmask.sin6_addr, NULL);
1237
if (prefixlen != plen0) {
1238
ifa_free(ifa);
1239
ifid_addr = NULL;
1240
nd6log((LOG_DEBUG,
1241
"%s: wrong prefixlen for %s (prefix=%d ifid=%d)\n",
1242
__func__, if_name(ifp), prefixlen, 128 - plen0));
1243
}
1244
}
1245
1246
/* No suitable LL address, get the ifid directly */
1247
if (ifid_addr == NULL) {
1248
ifa = ifa_alloc(sizeof(struct in6_ifaddr), M_NOWAIT);
1249
if (ifa != NULL) {
1250
ib = (struct in6_ifaddr *)ifa;
1251
ifid_addr = &ib->ia_addr.sin6_addr;
1252
if(in6_get_ifid(ifp, NULL, ifid_addr) != 0) {
1253
nd6log((LOG_DEBUG,
1254
"%s: failed to get ifid for %s\n",
1255
__func__, if_name(ifp)));
1256
ifa_free(ifa);
1257
ifid_addr = NULL;
1258
}
1259
}
1260
}
1261
1262
if (ifid_addr == NULL) {
1263
nd6log((LOG_INFO,
1264
"%s: could not determine ifid for %s\n",
1265
__func__, if_name(ifp)));
1266
return NULL;
1267
}
1268
1269
memcpy(&newaddr, &ib->ia_addr.sin6_addr, sizeof(ib->ia_addr.sin6_addr));
1270
ifa_free(ifa);
1271
}
1272
1273
IN6_MASK_ADDR(&ifra.ifra_addr.sin6_addr, &mask);
1274
/* interface ID */
1275
ifra.ifra_addr.sin6_addr.s6_addr32[0] |= (newaddr.s6_addr32[0] & ~mask.s6_addr32[0]);
1276
ifra.ifra_addr.sin6_addr.s6_addr32[1] |= (newaddr.s6_addr32[1] & ~mask.s6_addr32[1]);
1277
ifra.ifra_addr.sin6_addr.s6_addr32[2] |= (newaddr.s6_addr32[2] & ~mask.s6_addr32[2]);
1278
ifra.ifra_addr.sin6_addr.s6_addr32[3] |= (newaddr.s6_addr32[3] & ~mask.s6_addr32[3]);
1279
1280
/* lifetimes. */
1281
ifra.ifra_lifetime.ia6t_vltime = pr->ndpr_vltime;
1282
ifra.ifra_lifetime.ia6t_pltime = pr->ndpr_pltime;
1283
1284
/* XXX: scope zone ID? */
1285
1286
ifra.ifra_flags |= IN6_IFF_AUTOCONF; /* obey autoconf */
1287
1288
/*
1289
* Make sure that we do not have this address already. This should
1290
* usually not happen, but we can still see this case, e.g., if we
1291
* have manually configured the exact address to be configured.
1292
*/
1293
ifa = (struct ifaddr *)in6ifa_ifpwithaddr(ifp,
1294
&ifra.ifra_addr.sin6_addr);
1295
if (ifa != NULL) {
1296
ifa_free(ifa);
1297
/* this should be rare enough to make an explicit log */
1298
log(LOG_INFO, "in6_ifadd: %s is already configured\n",
1299
ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr));
1300
return (NULL);
1301
}
1302
1303
/*
1304
* Allocate ifaddr structure, link into chain, etc.
1305
* If we are going to create a new address upon receiving a multicasted
1306
* RA, we need to impose a random delay before starting DAD.
1307
* [draft-ietf-ipv6-rfc2462bis-02.txt, Section 5.4.2]
1308
*/
1309
updateflags = 0;
1310
if (mcast)
1311
updateflags |= IN6_IFAUPDATE_DADDELAY;
1312
if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) {
1313
nd6log((LOG_ERR,
1314
"%s: failed to make ifaddr %s on %s (errno=%d)\n", __func__,
1315
ip6_sprintf(ip6buf, &ifra.ifra_addr.sin6_addr),
1316
if_name(ifp), error));
1317
return (NULL); /* ifaddr must not have been allocated. */
1318
}
1319
1320
ia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
1321
/*
1322
* XXXRW: Assumption of non-NULLness here might not be true with
1323
* fine-grained locking -- should we validate it? Or just return
1324
* earlier ifa rather than looking it up again?
1325
*/
1326
return (ia); /* this is always non-NULL and referenced. */
1327
}
1328
1329
static struct nd_prefix *
1330
nd6_prefix_lookup_locked(struct nd_prefixctl *key)
1331
{
1332
struct nd_prefix *search;
1333
1334
ND6_LOCK_ASSERT();
1335
1336
LIST_FOREACH(search, &V_nd_prefix, ndpr_entry) {
1337
if (key->ndpr_ifp == search->ndpr_ifp &&
1338
key->ndpr_plen == search->ndpr_plen &&
1339
in6_are_prefix_equal(&key->ndpr_prefix.sin6_addr,
1340
&search->ndpr_prefix.sin6_addr, key->ndpr_plen)) {
1341
nd6_prefix_ref(search);
1342
break;
1343
}
1344
}
1345
return (search);
1346
}
1347
1348
struct nd_prefix *
1349
nd6_prefix_lookup(struct nd_prefixctl *key)
1350
{
1351
struct nd_prefix *search;
1352
1353
ND6_RLOCK();
1354
search = nd6_prefix_lookup_locked(key);
1355
ND6_RUNLOCK();
1356
return (search);
1357
}
1358
1359
void
1360
nd6_prefix_ref(struct nd_prefix *pr)
1361
{
1362
1363
refcount_acquire(&pr->ndpr_refcnt);
1364
}
1365
1366
void
1367
nd6_prefix_rele(struct nd_prefix *pr)
1368
{
1369
1370
if (refcount_release(&pr->ndpr_refcnt)) {
1371
KASSERT(LIST_EMPTY(&pr->ndpr_advrtrs),
1372
("prefix %p has advertising routers", pr));
1373
free(pr, M_IP6NDP);
1374
}
1375
}
1376
1377
int
1378
nd6_prelist_add(struct nd_prefixctl *pr, struct nd_defrouter *dr,
1379
struct nd_prefix **newp)
1380
{
1381
struct nd_prefix *new;
1382
char ip6buf[INET6_ADDRSTRLEN];
1383
int error;
1384
1385
new = malloc(sizeof(*new), M_IP6NDP, M_NOWAIT | M_ZERO);
1386
if (new == NULL)
1387
return (ENOMEM);
1388
refcount_init(&new->ndpr_refcnt, newp != NULL ? 2 : 1);
1389
new->ndpr_ifp = pr->ndpr_ifp;
1390
new->ndpr_prefix = pr->ndpr_prefix;
1391
new->ndpr_plen = pr->ndpr_plen;
1392
new->ndpr_vltime = pr->ndpr_vltime;
1393
new->ndpr_pltime = pr->ndpr_pltime;
1394
new->ndpr_flags = pr->ndpr_flags;
1395
if ((error = in6_init_prefix_ltimes(new)) != 0) {
1396
free(new, M_IP6NDP);
1397
return (error);
1398
}
1399
new->ndpr_lastupdate = time_uptime;
1400
1401
/* initialization */
1402
LIST_INIT(&new->ndpr_advrtrs);
1403
in6_prefixlen2mask(&new->ndpr_mask, new->ndpr_plen);
1404
/* make prefix in the canonical form */
1405
IN6_MASK_ADDR(&new->ndpr_prefix.sin6_addr, &new->ndpr_mask);
1406
1407
ND6_WLOCK();
1408
LIST_INSERT_HEAD(&V_nd_prefix, new, ndpr_entry);
1409
V_nd6_list_genid++;
1410
ND6_WUNLOCK();
1411
1412
/* ND_OPT_PI_FLAG_ONLINK processing */
1413
if (new->ndpr_raf_onlink) {
1414
struct epoch_tracker et;
1415
1416
ND6_ONLINK_LOCK();
1417
NET_EPOCH_ENTER(et);
1418
if ((error = nd6_prefix_onlink(new)) != 0) {
1419
nd6log((LOG_ERR, "%s: failed to make the prefix %s/%d "
1420
"on-link on %s (errno=%d)\n", __func__,
1421
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
1422
pr->ndpr_plen, if_name(pr->ndpr_ifp), error));
1423
/* proceed anyway. XXX: is it correct? */
1424
}
1425
NET_EPOCH_EXIT(et);
1426
ND6_ONLINK_UNLOCK();
1427
}
1428
1429
if (dr != NULL)
1430
pfxrtr_add(new, dr);
1431
if (newp != NULL)
1432
*newp = new;
1433
return (0);
1434
}
1435
1436
/*
1437
* Remove a prefix from the prefix list and optionally stash it in a
1438
* caller-provided list.
1439
*
1440
* The ND6 lock must be held.
1441
*/
1442
void
1443
nd6_prefix_unlink(struct nd_prefix *pr, struct nd_prhead *list)
1444
{
1445
1446
ND6_WLOCK_ASSERT();
1447
1448
LIST_REMOVE(pr, ndpr_entry);
1449
V_nd6_list_genid++;
1450
if (list != NULL)
1451
LIST_INSERT_HEAD(list, pr, ndpr_entry);
1452
}
1453
1454
/*
1455
* Free an unlinked prefix, first marking it off-link if necessary.
1456
*/
1457
void
1458
nd6_prefix_del(struct nd_prefix *pr)
1459
{
1460
struct nd_pfxrouter *pfr, *next;
1461
int e;
1462
char ip6buf[INET6_ADDRSTRLEN];
1463
1464
KASSERT(pr->ndpr_addrcnt == 0,
1465
("prefix %p has referencing addresses", pr));
1466
ND6_UNLOCK_ASSERT();
1467
1468
/*
1469
* Though these flags are now meaningless, we'd rather keep the value
1470
* of pr->ndpr_raf_onlink and pr->ndpr_raf_auto not to confuse users
1471
* when executing "ndp -p".
1472
*/
1473
if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0) {
1474
ND6_ONLINK_LOCK();
1475
if ((e = nd6_prefix_offlink(pr)) != 0) {
1476
nd6log((LOG_ERR,
1477
"%s: failed to make the prefix %s/%d offlink on %s "
1478
"(errno=%d)\n", __func__,
1479
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
1480
pr->ndpr_plen, if_name(pr->ndpr_ifp), e));
1481
/* what should we do? */
1482
}
1483
ND6_ONLINK_UNLOCK();
1484
}
1485
1486
/* Release references to routers that have advertised this prefix. */
1487
ND6_WLOCK();
1488
LIST_FOREACH_SAFE(pfr, &pr->ndpr_advrtrs, pfr_entry, next)
1489
pfxrtr_del(pfr);
1490
ND6_WUNLOCK();
1491
1492
nd6_prefix_rele(pr);
1493
1494
pfxlist_onlink_check();
1495
}
1496
1497
static int
1498
prelist_update(struct nd_prefixctl *new, struct nd_defrouter *dr,
1499
struct mbuf *m, int mcast)
1500
{
1501
struct in6_ifaddr *ia6 = NULL, *ia6_match = NULL;
1502
struct ifaddr *ifa;
1503
struct ifnet *ifp = new->ndpr_ifp;
1504
struct nd_prefix *pr;
1505
int error = 0;
1506
int auth;
1507
struct in6_addrlifetime lt6_tmp;
1508
char ip6buf[INET6_ADDRSTRLEN];
1509
bool has_temporary = false;
1510
1511
NET_EPOCH_ASSERT();
1512
1513
auth = 0;
1514
if (m) {
1515
/*
1516
* Authenticity for NA consists authentication for
1517
* both IP header and IP datagrams, doesn't it ?
1518
*/
1519
#if defined(M_AUTHIPHDR) && defined(M_AUTHIPDGM)
1520
auth = ((m->m_flags & M_AUTHIPHDR) &&
1521
(m->m_flags & M_AUTHIPDGM));
1522
#endif
1523
}
1524
1525
if ((pr = nd6_prefix_lookup(new)) != NULL) {
1526
/*
1527
* nd6_prefix_lookup() ensures that pr and new have the same
1528
* prefix on a same interface.
1529
*/
1530
1531
/*
1532
* Update prefix information. Note that the on-link (L) bit
1533
* and the autonomous (A) bit should NOT be changed from 1
1534
* to 0.
1535
*/
1536
if (new->ndpr_raf_onlink == 1)
1537
pr->ndpr_raf_onlink = 1;
1538
if (new->ndpr_raf_auto == 1)
1539
pr->ndpr_raf_auto = 1;
1540
if (new->ndpr_raf_onlink) {
1541
pr->ndpr_vltime = new->ndpr_vltime;
1542
pr->ndpr_pltime = new->ndpr_pltime;
1543
(void)in6_init_prefix_ltimes(pr); /* XXX error case? */
1544
pr->ndpr_lastupdate = time_uptime;
1545
}
1546
1547
if (new->ndpr_raf_onlink &&
1548
(pr->ndpr_stateflags & NDPRF_ONLINK) == 0) {
1549
ND6_ONLINK_LOCK();
1550
if ((error = nd6_prefix_onlink(pr)) != 0) {
1551
nd6log((LOG_ERR,
1552
"%s: failed to make the prefix %s/%d "
1553
"on-link on %s (errno=%d)\n", __func__,
1554
ip6_sprintf(ip6buf,
1555
&pr->ndpr_prefix.sin6_addr),
1556
pr->ndpr_plen, if_name(pr->ndpr_ifp),
1557
error));
1558
/* proceed anyway. XXX: is it correct? */
1559
}
1560
ND6_ONLINK_UNLOCK();
1561
}
1562
1563
if (dr != NULL)
1564
pfxrtr_add(pr, dr);
1565
} else {
1566
if (new->ndpr_vltime == 0)
1567
goto end;
1568
if (new->ndpr_raf_onlink == 0 && new->ndpr_raf_auto == 0)
1569
goto end;
1570
1571
error = nd6_prelist_add(new, dr, &pr);
1572
if (error != 0) {
1573
nd6log((LOG_NOTICE, "%s: nd6_prelist_add() failed for "
1574
"the prefix %s/%d on %s (errno=%d)\n", __func__,
1575
ip6_sprintf(ip6buf, &new->ndpr_prefix.sin6_addr),
1576
new->ndpr_plen, if_name(new->ndpr_ifp), error));
1577
goto end; /* we should just give up in this case. */
1578
}
1579
1580
/*
1581
* XXX: from the ND point of view, we can ignore a prefix
1582
* with the on-link bit being zero. However, we need a
1583
* prefix structure for references from autoconfigured
1584
* addresses. Thus, we explicitly make sure that the prefix
1585
* itself expires now.
1586
*/
1587
if (pr->ndpr_raf_onlink == 0) {
1588
pr->ndpr_vltime = 0;
1589
pr->ndpr_pltime = 0;
1590
in6_init_prefix_ltimes(pr);
1591
}
1592
}
1593
1594
/*
1595
* Address autoconfiguration based on Section 5.5.3 of RFC 2462.
1596
* Note that pr must be non NULL at this point.
1597
*/
1598
1599
/* 5.5.3 (a). Ignore the prefix without the A bit set. */
1600
if (!new->ndpr_raf_auto)
1601
goto end;
1602
1603
/*
1604
* 5.5.3 (b). the link-local prefix should have been ignored in
1605
* nd6_ra_input.
1606
*/
1607
1608
/* 5.5.3 (c). Consistency check on lifetimes: pltime <= vltime. */
1609
if (new->ndpr_pltime > new->ndpr_vltime) {
1610
error = EINVAL; /* XXX: won't be used */
1611
goto end;
1612
}
1613
1614
/*
1615
* 5.5.3 (d). If the prefix advertised is not equal to the prefix of
1616
* an address configured by stateless autoconfiguration already in the
1617
* list of addresses associated with the interface, and the Valid
1618
* Lifetime is not 0, form an address. We first check if we have
1619
* a matching prefix.
1620
* Note: we apply a clarification in rfc2462bis-02 here. We only
1621
* consider autoconfigured addresses while RFC2462 simply said
1622
* "address".
1623
*/
1624
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
1625
struct in6_ifaddr *ifa6;
1626
u_int32_t remaininglifetime;
1627
1628
if (ifa->ifa_addr->sa_family != AF_INET6)
1629
continue;
1630
1631
ifa6 = (struct in6_ifaddr *)ifa;
1632
1633
/*
1634
* We only consider autoconfigured addresses as per rfc2462bis.
1635
*/
1636
if (!(ifa6->ia6_flags & IN6_IFF_AUTOCONF))
1637
continue;
1638
1639
/*
1640
* Spec is not clear here, but I believe we should concentrate
1641
* on unicast (i.e. not anycast) addresses.
1642
* XXX: other ia6_flags? detached or duplicated?
1643
*/
1644
if ((ifa6->ia6_flags & IN6_IFF_ANYCAST) != 0)
1645
continue;
1646
1647
/*
1648
* Ignore the address if it is not associated with a prefix
1649
* or is associated with a prefix that is different from this
1650
* one. (pr is never NULL here)
1651
*/
1652
if (ifa6->ia6_ndpr != pr)
1653
continue;
1654
1655
/*
1656
* An already autoconfigured address matched. Now that we
1657
* are sure there is at least one matched address, we can
1658
* proceed to 5.5.3. (e): update the lifetimes according to the
1659
* "two hours" rule and the privacy extension.
1660
* We apply some clarifications in rfc2462bis:
1661
* - use remaininglifetime instead of storedlifetime as a
1662
* variable name
1663
* - remove the dead code in the "two-hour" rule
1664
*/
1665
#define TWOHOUR (120*60)
1666
lt6_tmp = ifa6->ia6_lifetime;
1667
1668
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME)
1669
remaininglifetime = ND6_INFINITE_LIFETIME;
1670
else if (time_uptime - ifa6->ia6_updatetime >
1671
lt6_tmp.ia6t_vltime) {
1672
/*
1673
* The case of "invalid" address. We should usually
1674
* not see this case.
1675
*/
1676
remaininglifetime = 0;
1677
} else
1678
remaininglifetime = lt6_tmp.ia6t_vltime -
1679
(time_uptime - ifa6->ia6_updatetime);
1680
1681
/* when not updating, keep the current stored lifetime. */
1682
lt6_tmp.ia6t_vltime = remaininglifetime;
1683
1684
if (TWOHOUR < new->ndpr_vltime ||
1685
remaininglifetime < new->ndpr_vltime) {
1686
lt6_tmp.ia6t_vltime = new->ndpr_vltime;
1687
} else if (remaininglifetime <= TWOHOUR) {
1688
if (auth) {
1689
lt6_tmp.ia6t_vltime = new->ndpr_vltime;
1690
}
1691
} else {
1692
/*
1693
* new->ndpr_vltime <= TWOHOUR &&
1694
* TWOHOUR < remaininglifetime
1695
*/
1696
lt6_tmp.ia6t_vltime = TWOHOUR;
1697
}
1698
1699
/* The 2 hour rule is not imposed for preferred lifetime. */
1700
lt6_tmp.ia6t_pltime = new->ndpr_pltime;
1701
1702
in6_init_address_ltimes(pr, &lt6_tmp);
1703
1704
/*
1705
* We need to treat lifetimes for temporary addresses
1706
* differently, according to
1707
* draft-ietf-ipv6-privacy-addrs-v2-01.txt 3.3 (1);
1708
* we only update the lifetimes when they are in the maximum
1709
* intervals.
1710
*/
1711
if ((ifa6->ia6_flags & IN6_IFF_TEMPORARY) != 0) {
1712
u_int32_t maxvltime, maxpltime;
1713
1714
/*
1715
* if stable addresses (RFC 7217) are enabled, mark that a temporary address has been found
1716
* to avoid generating uneeded extra ones.
1717
*/
1718
if (ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR)
1719
has_temporary = true;
1720
1721
if (V_ip6_temp_valid_lifetime >
1722
(u_int32_t)((time_uptime - ifa6->ia6_createtime) +
1723
V_ip6_desync_factor)) {
1724
maxvltime = V_ip6_temp_valid_lifetime -
1725
(time_uptime - ifa6->ia6_createtime) -
1726
V_ip6_desync_factor;
1727
} else
1728
maxvltime = 0;
1729
if (V_ip6_temp_preferred_lifetime >
1730
(u_int32_t)((time_uptime - ifa6->ia6_createtime) +
1731
V_ip6_desync_factor)) {
1732
maxpltime = V_ip6_temp_preferred_lifetime -
1733
(time_uptime - ifa6->ia6_createtime) -
1734
V_ip6_desync_factor;
1735
} else
1736
maxpltime = 0;
1737
1738
if (lt6_tmp.ia6t_vltime == ND6_INFINITE_LIFETIME ||
1739
lt6_tmp.ia6t_vltime > maxvltime) {
1740
lt6_tmp.ia6t_vltime = maxvltime;
1741
}
1742
if (lt6_tmp.ia6t_pltime == ND6_INFINITE_LIFETIME ||
1743
lt6_tmp.ia6t_pltime > maxpltime) {
1744
lt6_tmp.ia6t_pltime = maxpltime;
1745
}
1746
}
1747
ifa6->ia6_lifetime = lt6_tmp;
1748
ifa6->ia6_updatetime = time_uptime;
1749
1750
/*
1751
* If using stable addresses (RFC 7217) and we still have retries to perform, ignore
1752
* addresses already marked as duplicated, since a new one will be generated.
1753
* Also ignore addresses marked as temporary, since their generation is orthogonal to
1754
* opaque stable ones.
1755
*
1756
* There is a small race condition, in that the dad_counter could be incremented
1757
* between here and when a new address is generated, but this will cause that generation
1758
* to fail and no further retries should happen.
1759
*/
1760
if (ND_IFINFO(ifp)->flags & ND6_IFF_STABLEADDR &&
1761
atomic_load_int(&DAD_FAILURES(ifp)) <= V_ip6_stableaddr_maxretries &&
1762
ifa6->ia6_flags & (IN6_IFF_DUPLICATED | IN6_IFF_TEMPORARY))
1763
continue;
1764
1765
if (ia6_match == NULL) /* remember the first one */
1766
ia6_match = ifa6;
1767
}
1768
if (ia6_match == NULL && new->ndpr_vltime) {
1769
int ifidlen;
1770
1771
/*
1772
* 5.5.3 (d) (continued)
1773
* No address matched and the valid lifetime is non-zero.
1774
* Create a new address.
1775
*/
1776
1777
/*
1778
* Prefix Length check:
1779
* If the sum of the prefix length and interface identifier
1780
* length does not equal 128 bits, the Prefix Information
1781
* option MUST be ignored. The length of the interface
1782
* identifier is defined in a separate link-type specific
1783
* document.
1784
*/
1785
ifidlen = in6_if2idlen(ifp);
1786
if (ifidlen < 0) {
1787
/* this should not happen, so we always log it. */
1788
log(LOG_ERR, "prelist_update: IFID undefined (%s)\n",
1789
if_name(ifp));
1790
goto end;
1791
}
1792
if (ifidlen + pr->ndpr_plen != 128) {
1793
nd6log((LOG_INFO,
1794
"%s: invalid prefixlen %d for %s, ignored\n",
1795
__func__, pr->ndpr_plen, if_name(ifp)));
1796
goto end;
1797
}
1798
1799
if ((ia6 = in6_ifadd(new, mcast)) != NULL) {
1800
/*
1801
* note that we should use pr (not new) for reference.
1802
*/
1803
pr->ndpr_addrcnt++;
1804
ia6->ia6_ndpr = pr;
1805
1806
/*
1807
* RFC 3041 3.3 (2).
1808
* When a new public address is created as described
1809
* in RFC2462, also create a new temporary address.
1810
*
1811
* RFC 3041 3.5.
1812
* When an interface connects to a new link, a new
1813
* randomized interface identifier should be generated
1814
* immediately together with a new set of temporary
1815
* addresses. Thus, we specifiy 1 as the 2nd arg of
1816
* in6_tmpifadd().
1817
*
1818
* Skip this if a temporary address has been marked as
1819
* found (happens only if stable addresses (RFC 7217) is in use)
1820
*/
1821
if (V_ip6_use_tempaddr && !has_temporary) {
1822
int e;
1823
if ((e = in6_tmpifadd(ia6, 1, 1)) != 0) {
1824
nd6log((LOG_NOTICE, "%s: failed to "
1825
"create a temporary address "
1826
"(errno=%d)\n", __func__, e));
1827
}
1828
}
1829
ifa_free(&ia6->ia_ifa);
1830
1831
/*
1832
* A newly added address might affect the status
1833
* of other addresses, so we check and update it.
1834
* XXX: what if address duplication happens?
1835
*/
1836
pfxlist_onlink_check();
1837
} else {
1838
/* just set an error. do not bark here. */
1839
error = EADDRNOTAVAIL; /* XXX: might be unused. */
1840
}
1841
}
1842
1843
end:
1844
if (pr != NULL)
1845
nd6_prefix_rele(pr);
1846
return (error);
1847
}
1848
1849
/*
1850
* A supplement function used in the on-link detection below;
1851
* detect if a given prefix has a (probably) reachable advertising router.
1852
* XXX: lengthy function name...
1853
*/
1854
static struct nd_pfxrouter *
1855
find_pfxlist_reachable_router(struct nd_prefix *pr)
1856
{
1857
struct epoch_tracker et;
1858
struct nd_pfxrouter *pfxrtr;
1859
1860
ND6_LOCK_ASSERT();
1861
1862
NET_EPOCH_ENTER(et);
1863
LIST_FOREACH(pfxrtr, &pr->ndpr_advrtrs, pfr_entry) {
1864
if (is_dr_reachable(pfxrtr->router))
1865
break;
1866
}
1867
NET_EPOCH_EXIT(et);
1868
return (pfxrtr);
1869
}
1870
1871
/*
1872
* Check if each prefix in the prefix list has at least one available router
1873
* that advertised the prefix (a router is "available" if its neighbor cache
1874
* entry is reachable or probably reachable).
1875
* If the check fails, the prefix may be off-link, because, for example,
1876
* we have moved from the network but the lifetime of the prefix has not
1877
* expired yet. So we should not use the prefix if there is another prefix
1878
* that has an available router.
1879
* But, if there is no prefix that has an available router, we still regard
1880
* all the prefixes as on-link. This is because we can't tell if all the
1881
* routers are simply dead or if we really moved from the network and there
1882
* is no router around us.
1883
*/
1884
void
1885
pfxlist_onlink_check(void)
1886
{
1887
struct nd_prefix *pr;
1888
struct in6_ifaddr *ifa;
1889
struct nd_defrouter *dr;
1890
struct nd_pfxrouter *pfxrtr = NULL;
1891
struct rm_priotracker in6_ifa_tracker;
1892
uint64_t genid;
1893
uint32_t flags;
1894
1895
ND6_ONLINK_LOCK();
1896
ND6_RLOCK();
1897
1898
/*
1899
* Check if there is a prefix that has a reachable advertising
1900
* router.
1901
*/
1902
LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
1903
if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr))
1904
break;
1905
}
1906
1907
/*
1908
* If we have no such prefix, check whether we still have a router
1909
* that does not advertise any prefixes.
1910
*/
1911
if (pr == NULL) {
1912
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
1913
struct nd_prefix *pr0;
1914
1915
LIST_FOREACH(pr0, &V_nd_prefix, ndpr_entry) {
1916
if ((pfxrtr = pfxrtr_lookup(pr0, dr)) != NULL)
1917
break;
1918
}
1919
if (pfxrtr != NULL)
1920
break;
1921
}
1922
}
1923
if (pr != NULL || (!TAILQ_EMPTY(&V_nd6_defrouter) && pfxrtr == NULL)) {
1924
/*
1925
* There is at least one prefix that has a reachable router,
1926
* or at least a router which probably does not advertise
1927
* any prefixes. The latter would be the case when we move
1928
* to a new link where we have a router that does not provide
1929
* prefixes and we configure an address by hand.
1930
* Detach prefixes which have no reachable advertising
1931
* router, and attach other prefixes.
1932
*/
1933
LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
1934
/* XXX: a link-local prefix should never be detached */
1935
if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
1936
pr->ndpr_raf_onlink == 0 ||
1937
pr->ndpr_raf_auto == 0)
1938
continue;
1939
1940
if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 &&
1941
find_pfxlist_reachable_router(pr) == NULL)
1942
pr->ndpr_stateflags |= NDPRF_DETACHED;
1943
else if ((pr->ndpr_stateflags & NDPRF_DETACHED) != 0 &&
1944
find_pfxlist_reachable_router(pr) != NULL)
1945
pr->ndpr_stateflags &= ~NDPRF_DETACHED;
1946
}
1947
} else {
1948
/* there is no prefix that has a reachable router */
1949
LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
1950
if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
1951
pr->ndpr_raf_onlink == 0 ||
1952
pr->ndpr_raf_auto == 0)
1953
continue;
1954
pr->ndpr_stateflags &= ~NDPRF_DETACHED;
1955
}
1956
}
1957
1958
/*
1959
* Remove each interface route associated with a (just) detached
1960
* prefix, and reinstall the interface route for a (just) attached
1961
* prefix. Note that all attempt of reinstallation does not
1962
* necessarily success, when a same prefix is shared among multiple
1963
* interfaces. Such cases will be handled in nd6_prefix_onlink,
1964
* so we don't have to care about them.
1965
*/
1966
restart:
1967
LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) {
1968
char ip6buf[INET6_ADDRSTRLEN];
1969
int e;
1970
1971
if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) ||
1972
pr->ndpr_raf_onlink == 0 ||
1973
pr->ndpr_raf_auto == 0)
1974
continue;
1975
1976
flags = pr->ndpr_stateflags & (NDPRF_DETACHED | NDPRF_ONLINK);
1977
if (flags == 0 || flags == (NDPRF_DETACHED | NDPRF_ONLINK)) {
1978
genid = V_nd6_list_genid;
1979
ND6_RUNLOCK();
1980
if ((flags & NDPRF_ONLINK) != 0 &&
1981
(e = nd6_prefix_offlink(pr)) != 0) {
1982
nd6log((LOG_ERR,
1983
"%s: failed to make %s/%d offlink "
1984
"(errno=%d)\n", __func__,
1985
ip6_sprintf(ip6buf,
1986
&pr->ndpr_prefix.sin6_addr),
1987
pr->ndpr_plen, e));
1988
} else if ((flags & NDPRF_ONLINK) == 0 &&
1989
(e = nd6_prefix_onlink(pr)) != 0) {
1990
nd6log((LOG_ERR,
1991
"%s: failed to make %s/%d onlink "
1992
"(errno=%d)\n", __func__,
1993
ip6_sprintf(ip6buf,
1994
&pr->ndpr_prefix.sin6_addr),
1995
pr->ndpr_plen, e));
1996
}
1997
ND6_RLOCK();
1998
if (genid != V_nd6_list_genid)
1999
goto restart;
2000
}
2001
}
2002
2003
/*
2004
* Changes on the prefix status might affect address status as well.
2005
* Make sure that all addresses derived from an attached prefix are
2006
* attached, and that all addresses derived from a detached prefix are
2007
* detached. Note, however, that a manually configured address should
2008
* always be attached.
2009
* The precise detection logic is same as the one for prefixes.
2010
*/
2011
IN6_IFADDR_RLOCK(&in6_ifa_tracker);
2012
CK_STAILQ_FOREACH(ifa, &V_in6_ifaddrhead, ia_link) {
2013
if (!(ifa->ia6_flags & IN6_IFF_AUTOCONF))
2014
continue;
2015
2016
if (ifa->ia6_ndpr == NULL) {
2017
/*
2018
* This can happen when we first configure the address
2019
* (i.e. the address exists, but the prefix does not).
2020
* XXX: complicated relationships...
2021
*/
2022
continue;
2023
}
2024
2025
if (find_pfxlist_reachable_router(ifa->ia6_ndpr))
2026
break;
2027
}
2028
if (ifa) {
2029
CK_STAILQ_FOREACH(ifa, &V_in6_ifaddrhead, ia_link) {
2030
if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
2031
continue;
2032
2033
if (ifa->ia6_ndpr == NULL) /* XXX: see above. */
2034
continue;
2035
2036
if (find_pfxlist_reachable_router(ifa->ia6_ndpr)) {
2037
if (ifa->ia6_flags & IN6_IFF_DETACHED) {
2038
ifa->ia6_flags &= ~IN6_IFF_DETACHED;
2039
ifa->ia6_flags |= IN6_IFF_TENTATIVE;
2040
nd6_dad_start((struct ifaddr *)ifa, 0);
2041
}
2042
} else {
2043
ifa->ia6_flags |= IN6_IFF_DETACHED;
2044
}
2045
}
2046
} else {
2047
CK_STAILQ_FOREACH(ifa, &V_in6_ifaddrhead, ia_link) {
2048
if ((ifa->ia6_flags & IN6_IFF_AUTOCONF) == 0)
2049
continue;
2050
2051
if (ifa->ia6_flags & IN6_IFF_DETACHED) {
2052
ifa->ia6_flags &= ~IN6_IFF_DETACHED;
2053
ifa->ia6_flags |= IN6_IFF_TENTATIVE;
2054
/* Do we need a delay in this case? */
2055
nd6_dad_start((struct ifaddr *)ifa, 0);
2056
}
2057
}
2058
}
2059
IN6_IFADDR_RUNLOCK(&in6_ifa_tracker);
2060
ND6_RUNLOCK();
2061
ND6_ONLINK_UNLOCK();
2062
}
2063
2064
/*
2065
* Add or remove interface route specified by @dst, @netmask and @ifp.
2066
* ifa can be NULL.
2067
* Returns 0 on success
2068
*/
2069
static int
2070
nd6_prefix_rtrequest(uint32_t fibnum, int cmd, struct sockaddr_in6 *dst,
2071
struct sockaddr_in6 *netmask, struct ifnet *ifp, struct ifaddr *ifa)
2072
{
2073
struct epoch_tracker et;
2074
int error;
2075
2076
/* Prepare gateway */
2077
struct sockaddr_dl_short sdl = {
2078
.sdl_family = AF_LINK,
2079
.sdl_len = sizeof(struct sockaddr_dl_short),
2080
.sdl_type = ifp->if_type,
2081
.sdl_index = ifp->if_index,
2082
};
2083
2084
struct rt_addrinfo info = {
2085
.rti_ifa = ifa,
2086
.rti_ifp = ifp,
2087
.rti_flags = RTF_PINNED | ((netmask != NULL) ? 0 : RTF_HOST),
2088
.rti_info = {
2089
[RTAX_DST] = (struct sockaddr *)dst,
2090
[RTAX_NETMASK] = (struct sockaddr *)netmask,
2091
[RTAX_GATEWAY] = (struct sockaddr *)&sdl,
2092
},
2093
};
2094
/* Don't set additional per-gw filters on removal */
2095
2096
NET_EPOCH_ENTER(et);
2097
error = rib_handle_ifaddr_info(fibnum, cmd, &info);
2098
NET_EPOCH_EXIT(et);
2099
return (error);
2100
}
2101
2102
static int
2103
nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
2104
{
2105
int error;
2106
2107
struct sockaddr_in6 mask6 = {
2108
.sin6_family = AF_INET6,
2109
.sin6_len = sizeof(struct sockaddr_in6),
2110
.sin6_addr = pr->ndpr_mask,
2111
};
2112
struct sockaddr_in6 *pmask6 = (pr->ndpr_plen != 128) ? &mask6 : NULL;
2113
2114
error = nd6_prefix_rtrequest(pr->ndpr_ifp->if_fib, RTM_ADD,
2115
&pr->ndpr_prefix, pmask6, pr->ndpr_ifp, ifa);
2116
if (error == 0)
2117
pr->ndpr_stateflags |= NDPRF_ONLINK;
2118
2119
return (error);
2120
}
2121
2122
static int
2123
nd6_prefix_onlink(struct nd_prefix *pr)
2124
{
2125
struct epoch_tracker et;
2126
struct ifaddr *ifa;
2127
struct ifnet *ifp = pr->ndpr_ifp;
2128
struct nd_prefix *opr;
2129
char ip6buf[INET6_ADDRSTRLEN];
2130
int error;
2131
2132
ND6_ONLINK_LOCK_ASSERT();
2133
ND6_UNLOCK_ASSERT();
2134
2135
if ((pr->ndpr_stateflags & NDPRF_ONLINK) != 0)
2136
return (EEXIST);
2137
2138
/*
2139
* Add the interface route associated with the prefix. Before
2140
* installing the route, check if there's the same prefix on another
2141
* interface, and the prefix has already installed the interface route.
2142
* Although such a configuration is expected to be rare, we explicitly
2143
* allow it.
2144
*/
2145
ND6_RLOCK();
2146
LIST_FOREACH(opr, &V_nd_prefix, ndpr_entry) {
2147
if (opr == pr)
2148
continue;
2149
2150
if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0)
2151
continue;
2152
2153
if (!V_rt_add_addr_allfibs &&
2154
opr->ndpr_ifp->if_fib != pr->ndpr_ifp->if_fib)
2155
continue;
2156
2157
if (opr->ndpr_plen == pr->ndpr_plen &&
2158
in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
2159
&opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) {
2160
ND6_RUNLOCK();
2161
return (0);
2162
}
2163
}
2164
ND6_RUNLOCK();
2165
2166
/*
2167
* We prefer link-local addresses as the associated interface address.
2168
*/
2169
/* search for a link-local addr */
2170
NET_EPOCH_ENTER(et);
2171
ifa = (struct ifaddr *)in6ifa_ifpforlinklocal(ifp,
2172
IN6_IFF_NOTREADY | IN6_IFF_ANYCAST);
2173
if (ifa == NULL) {
2174
/* XXX: freebsd does not have ifa_ifwithaf */
2175
CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
2176
if (ifa->ifa_addr->sa_family == AF_INET6) {
2177
ifa_ref(ifa);
2178
break;
2179
}
2180
}
2181
/* should we care about ia6_flags? */
2182
}
2183
if (ifa == NULL) {
2184
/*
2185
* This can still happen, when, for example, we receive an RA
2186
* containing a prefix with the L bit set and the A bit clear,
2187
* after removing all IPv6 addresses on the receiving
2188
* interface. This should, of course, be rare though.
2189
*/
2190
nd6log((LOG_NOTICE,
2191
"%s: failed to find any ifaddr to add route for a "
2192
"prefix(%s/%d) on %s\n", __func__,
2193
ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
2194
pr->ndpr_plen, if_name(ifp)));
2195
error = 0;
2196
} else {
2197
error = nd6_prefix_onlink_rtrequest(pr, ifa);
2198
ifa_free(ifa);
2199
}
2200
NET_EPOCH_EXIT(et);
2201
2202
return (error);
2203
}
2204
2205
int
2206
nd6_prefix_offlink(struct nd_prefix *pr)
2207
{
2208
int error = 0;
2209
struct ifnet *ifp = pr->ndpr_ifp;
2210
struct nd_prefix *opr;
2211
char ip6buf[INET6_ADDRSTRLEN];
2212
uint64_t genid;
2213
int a_failure;
2214
2215
ND6_ONLINK_LOCK_ASSERT();
2216
ND6_UNLOCK_ASSERT();
2217
2218
if ((pr->ndpr_stateflags & NDPRF_ONLINK) == 0)
2219
return (EEXIST);
2220
2221
struct sockaddr_in6 mask6 = {
2222
.sin6_family = AF_INET6,
2223
.sin6_len = sizeof(struct sockaddr_in6),
2224
.sin6_addr = pr->ndpr_mask,
2225
};
2226
struct sockaddr_in6 *pmask6 = (pr->ndpr_plen != 128) ? &mask6 : NULL;
2227
2228
error = nd6_prefix_rtrequest(ifp->if_fib, RTM_DELETE,
2229
&pr->ndpr_prefix, pmask6, ifp, NULL);
2230
2231
a_failure = 1;
2232
if (error == 0) {
2233
pr->ndpr_stateflags &= ~NDPRF_ONLINK;
2234
2235
/*
2236
* There might be the same prefix on another interface,
2237
* the prefix which could not be on-link just because we have
2238
* the interface route (see comments in nd6_prefix_onlink).
2239
* If there's one, try to make the prefix on-link on the
2240
* interface.
2241
*/
2242
ND6_RLOCK();
2243
restart:
2244
LIST_FOREACH(opr, &V_nd_prefix, ndpr_entry) {
2245
/*
2246
* KAME specific: detached prefixes should not be
2247
* on-link.
2248
*/
2249
if (opr == pr || (opr->ndpr_stateflags &
2250
(NDPRF_ONLINK | NDPRF_DETACHED)) != 0)
2251
continue;
2252
2253
if (opr->ndpr_plen == pr->ndpr_plen &&
2254
in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr,
2255
&opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) {
2256
int e;
2257
2258
genid = V_nd6_list_genid;
2259
ND6_RUNLOCK();
2260
if ((e = nd6_prefix_onlink(opr)) != 0) {
2261
nd6log((LOG_ERR,
2262
"%s: failed to recover a prefix "
2263
"%s/%d from %s to %s (errno=%d)\n",
2264
__func__, ip6_sprintf(ip6buf,
2265
&opr->ndpr_prefix.sin6_addr),
2266
opr->ndpr_plen, if_name(ifp),
2267
if_name(opr->ndpr_ifp), e));
2268
} else
2269
a_failure = 0;
2270
ND6_RLOCK();
2271
if (genid != V_nd6_list_genid)
2272
goto restart;
2273
}
2274
}
2275
ND6_RUNLOCK();
2276
} else {
2277
/* XXX: can we still set the NDPRF_ONLINK flag? */
2278
nd6log((LOG_ERR,
2279
"%s: failed to delete route: %s/%d on %s (errno=%d)\n",
2280
__func__, ip6_sprintf(ip6buf, &pr->ndpr_prefix.sin6_addr),
2281
pr->ndpr_plen, if_name(ifp), error));
2282
}
2283
2284
if (a_failure)
2285
lltable_prefix_free(AF_INET6,
2286
(struct sockaddr *)&pr->ndpr_prefix,
2287
(struct sockaddr *)&mask6, LLE_STATIC);
2288
2289
return (error);
2290
}
2291
2292
/*
2293
* Get a randomized interface identifier for a temporary address
2294
* Based on RFC 8981, Section 3.3.1.
2295
*/
2296
static int
2297
in6_get_tmp_ifid(struct in6_aliasreq *ifra)
2298
{
2299
struct in6_addr *addr;
2300
2301
if(!is_random_seeded()){
2302
return 1;
2303
}
2304
2305
addr = &(ifra->ifra_addr.sin6_addr);
2306
regen:
2307
ifra->ifra_addr.sin6_addr.s6_addr32[2] |=
2308
(arc4random() & ~(ifra->ifra_prefixmask.sin6_addr.s6_addr32[2]));
2309
ifra->ifra_addr.sin6_addr.s6_addr32[3] |=
2310
(arc4random() & ~(ifra->ifra_prefixmask.sin6_addr.s6_addr32[3]));
2311
2312
/*
2313
* Check if generated address is not inappropriate:
2314
*
2315
* - Reserved IPv6 Interface aIdentifers
2316
* (https://www.iana.org/assignments/ipv6-interface-ids/)
2317
*/
2318
2319
/* Subnet-router anycast: 0000:0000:0000:0000 */
2320
if (!(addr->s6_addr32[2] | addr->s6_addr32[3]))
2321
goto regen;
2322
2323
/*
2324
* IANA Ethernet block: 0200:5EFF:FE00:0000-0200:5EFF:FE00:5212
2325
* Proxy Mobile IPv6: 0200:5EFF:FE00:5213
2326
* IANA Ethernet block: 0200:5EFF:FE00:5214-0200:5EFF:FEFF:FFFF
2327
*/
2328
if (ntohl(addr->s6_addr32[2]) == 0x02005eff &&
2329
(ntohl(addr->s6_addr32[3]) & 0Xff000000) == 0xfe000000)
2330
goto regen;
2331
2332
/* Reserved subnet anycast addresses */
2333
if (ntohl(addr->s6_addr32[2]) == 0xfdffffff &&
2334
ntohl(addr->s6_addr32[3]) >= 0Xffffff80)
2335
goto regen;
2336
2337
return 0;
2338
}
2339
2340
/*
2341
* ia0 - corresponding public address
2342
*/
2343
int
2344
in6_tmpifadd(const struct in6_ifaddr *ia0, int forcegen, int delay)
2345
{
2346
struct ifnet *ifp = ia0->ia_ifa.ifa_ifp;
2347
struct in6_ifaddr *newia;
2348
struct in6_aliasreq ifra;
2349
int error;
2350
int trylimit = 3; /* XXX: adhoc value */
2351
int updateflags;
2352
time_t vltime0, pltime0;
2353
2354
in6_prepare_ifra(&ifra, &ia0->ia_addr.sin6_addr,
2355
&ia0->ia_prefixmask.sin6_addr);
2356
2357
ifra.ifra_addr = ia0->ia_addr; /* XXX: do we need this ? */
2358
/* clear the old IFID */
2359
IN6_MASK_ADDR(&ifra.ifra_addr.sin6_addr,
2360
&ifra.ifra_prefixmask.sin6_addr);
2361
2362
again:
2363
if (in6_get_tmp_ifid(&ifra) != 0) {
2364
nd6log((LOG_NOTICE, "%s: failed to find a good random IFID\n",
2365
__func__));
2366
return (EINVAL);
2367
}
2368
2369
/*
2370
* in6_get_tmpifid() quite likely provided a unique interface ID.
2371
* However, we may still have a chance to see collision, because
2372
* there may be a time lag between generation of the ID and generation
2373
* of the address. So, we'll do one more sanity check.
2374
*/
2375
2376
if (in6_localip(&ifra.ifra_addr.sin6_addr) != 0) {
2377
if (trylimit-- > 0) {
2378
forcegen = 1;
2379
goto again;
2380
}
2381
2382
/* Give up. Something strange should have happened. */
2383
nd6log((LOG_NOTICE, "%s: failed to find a unique random IFID\n",
2384
__func__));
2385
return (EEXIST);
2386
}
2387
2388
/*
2389
* The Valid Lifetime is the lower of the Valid Lifetime of the
2390
* public address or TEMP_VALID_LIFETIME.
2391
* The Preferred Lifetime is the lower of the Preferred Lifetime
2392
* of the public address or TEMP_PREFERRED_LIFETIME -
2393
* DESYNC_FACTOR.
2394
*/
2395
if (ia0->ia6_lifetime.ia6t_vltime != ND6_INFINITE_LIFETIME) {
2396
vltime0 = IFA6_IS_INVALID(ia0) ? 0 :
2397
(ia0->ia6_lifetime.ia6t_vltime -
2398
(time_uptime - ia0->ia6_updatetime));
2399
if (vltime0 > V_ip6_temp_valid_lifetime)
2400
vltime0 = V_ip6_temp_valid_lifetime;
2401
} else
2402
vltime0 = V_ip6_temp_valid_lifetime;
2403
if (ia0->ia6_lifetime.ia6t_pltime != ND6_INFINITE_LIFETIME) {
2404
pltime0 = IFA6_IS_DEPRECATED(ia0) ? 0 :
2405
(ia0->ia6_lifetime.ia6t_pltime -
2406
(time_uptime - ia0->ia6_updatetime));
2407
if (pltime0 > V_ip6_temp_preferred_lifetime - V_ip6_desync_factor){
2408
pltime0 = V_ip6_temp_preferred_lifetime -
2409
V_ip6_desync_factor;
2410
}
2411
} else
2412
pltime0 = V_ip6_temp_preferred_lifetime - V_ip6_desync_factor;
2413
ifra.ifra_lifetime.ia6t_vltime = vltime0;
2414
ifra.ifra_lifetime.ia6t_pltime = pltime0;
2415
2416
/*
2417
* A temporary address is created only if this calculated Preferred
2418
* Lifetime is greater than REGEN_ADVANCE time units.
2419
*/
2420
if (ifra.ifra_lifetime.ia6t_pltime <= V_ip6_temp_regen_advance)
2421
return (0);
2422
2423
/* XXX: scope zone ID? */
2424
2425
ifra.ifra_flags |= (IN6_IFF_AUTOCONF|IN6_IFF_TEMPORARY);
2426
2427
/* allocate ifaddr structure, link into chain, etc. */
2428
updateflags = 0;
2429
if (delay)
2430
updateflags |= IN6_IFAUPDATE_DADDELAY;
2431
if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0)
2432
return (error);
2433
2434
newia = in6ifa_ifpwithaddr(ifp, &ifra.ifra_addr.sin6_addr);
2435
if (newia == NULL) { /* XXX: can it happen? */
2436
nd6log((LOG_ERR,
2437
"%s: ifa update succeeded, but we got no ifaddr\n",
2438
__func__));
2439
return (EINVAL); /* XXX */
2440
}
2441
newia->ia6_ndpr = ia0->ia6_ndpr;
2442
newia->ia6_ndpr->ndpr_addrcnt++;
2443
ifa_free(&newia->ia_ifa);
2444
2445
/*
2446
* A newly added address might affect the status of other addresses.
2447
* XXX: when the temporary address is generated with a new public
2448
* address, the onlink check is redundant. However, it would be safe
2449
* to do the check explicitly everywhere a new address is generated,
2450
* and, in fact, we surely need the check when we create a new
2451
* temporary address due to deprecation of an old temporary address.
2452
*/
2453
pfxlist_onlink_check();
2454
2455
return (0);
2456
}
2457
2458
static int
2459
rt6_deleteroute(const struct rtentry *rt, const struct nhop_object *nh,
2460
void *arg)
2461
{
2462
struct in6_addr *gate = (struct in6_addr *)arg;
2463
int nh_rt_flags;
2464
2465
if (nh->gw_sa.sa_family != AF_INET6)
2466
return (0);
2467
2468
if (!IN6_ARE_ADDR_EQUAL(gate, &nh->gw6_sa.sin6_addr)) {
2469
return (0);
2470
}
2471
2472
/*
2473
* Do not delete a static route.
2474
* XXX: this seems to be a bit ad-hoc. Should we consider the
2475
* 'cloned' bit instead?
2476
*/
2477
nh_rt_flags = nhop_get_rtflags(nh);
2478
if ((nh_rt_flags & RTF_STATIC) != 0)
2479
return (0);
2480
2481
/*
2482
* We delete only host route. This means, in particular, we don't
2483
* delete default route.
2484
*/
2485
if ((nh_rt_flags & RTF_HOST) == 0)
2486
return (0);
2487
2488
return (1);
2489
#undef SIN6
2490
}
2491
2492
/*
2493
* Delete all the routing table entries that use the specified gateway.
2494
* XXX: this function causes search through all entries of routing table, so
2495
* it shouldn't be called when acting as a router.
2496
*/
2497
void
2498
rt6_flush(struct in6_addr *gateway, struct ifnet *ifp)
2499
{
2500
2501
/* We'll care only link-local addresses */
2502
if (!IN6_IS_ADDR_LINKLOCAL(gateway))
2503
return;
2504
2505
/* XXX Do we really need to walk any but the default FIB? */
2506
rib_foreach_table_walk_del(AF_INET6, rt6_deleteroute, (void *)gateway);
2507
}
2508
2509
int
2510
nd6_setdefaultiface(int ifindex)
2511
{
2512
2513
if (V_nd6_defifindex != ifindex) {
2514
V_nd6_defifindex = ifindex;
2515
if (V_nd6_defifindex != 0) {
2516
struct epoch_tracker et;
2517
2518
/*
2519
* XXXGL: this function should use ifnet_byindex_ref!
2520
*/
2521
NET_EPOCH_ENTER(et);
2522
V_nd6_defifp = ifnet_byindex(V_nd6_defifindex);
2523
NET_EPOCH_EXIT(et);
2524
if (V_nd6_defifp == NULL)
2525
return (EINVAL);
2526
} else
2527
V_nd6_defifp = NULL;
2528
2529
/*
2530
* Our current implementation assumes one-to-one mapping between
2531
* interfaces and links, so it would be natural to use the
2532
* default interface as the default link.
2533
*/
2534
scope6_setdefault(V_nd6_defifp);
2535
}
2536
2537
return (0);
2538
}
2539
2540
bool
2541
nd6_defrouter_list_empty(void)
2542
{
2543
2544
return (TAILQ_EMPTY(&V_nd6_defrouter));
2545
}
2546
2547
void
2548
nd6_defrouter_timer(void)
2549
{
2550
struct nd_defrouter *dr, *ndr;
2551
struct nd6_drhead drq;
2552
2553
TAILQ_INIT(&drq);
2554
2555
ND6_WLOCK();
2556
TAILQ_FOREACH_SAFE(dr, &V_nd6_defrouter, dr_entry, ndr)
2557
if (dr->expire && dr->expire < time_uptime)
2558
defrouter_unlink(dr, &drq);
2559
ND6_WUNLOCK();
2560
2561
while ((dr = TAILQ_FIRST(&drq)) != NULL) {
2562
TAILQ_REMOVE(&drq, dr, dr_entry);
2563
defrouter_del(dr);
2564
}
2565
}
2566
2567
/*
2568
* Nuke default router list entries toward ifp.
2569
* We defer removal of default router list entries that is installed in the
2570
* routing table, in order to keep additional side effects as small as possible.
2571
*/
2572
void
2573
nd6_defrouter_purge(struct ifnet *ifp)
2574
{
2575
struct nd_defrouter *dr, *ndr;
2576
struct nd6_drhead drq;
2577
2578
TAILQ_INIT(&drq);
2579
2580
ND6_WLOCK();
2581
TAILQ_FOREACH_SAFE(dr, &V_nd6_defrouter, dr_entry, ndr) {
2582
if (dr->installed)
2583
continue;
2584
if (dr->ifp == ifp)
2585
defrouter_unlink(dr, &drq);
2586
}
2587
TAILQ_FOREACH_SAFE(dr, &V_nd6_defrouter, dr_entry, ndr) {
2588
if (!dr->installed)
2589
continue;
2590
if (dr->ifp == ifp)
2591
defrouter_unlink(dr, &drq);
2592
}
2593
ND6_WUNLOCK();
2594
2595
/* Delete the unlinked router objects. */
2596
while ((dr = TAILQ_FIRST(&drq)) != NULL) {
2597
TAILQ_REMOVE(&drq, dr, dr_entry);
2598
defrouter_del(dr);
2599
}
2600
}
2601
2602
void
2603
nd6_defrouter_flush_all(void)
2604
{
2605
struct nd_defrouter *dr;
2606
struct nd6_drhead drq;
2607
2608
TAILQ_INIT(&drq);
2609
2610
ND6_WLOCK();
2611
while ((dr = TAILQ_FIRST(&V_nd6_defrouter)) != NULL)
2612
defrouter_unlink(dr, &drq);
2613
ND6_WUNLOCK();
2614
2615
while ((dr = TAILQ_FIRST(&drq)) != NULL) {
2616
TAILQ_REMOVE(&drq, dr, dr_entry);
2617
defrouter_del(dr);
2618
}
2619
}
2620
2621
void
2622
nd6_defrouter_init(void)
2623
{
2624
2625
TAILQ_INIT(&V_nd6_defrouter);
2626
}
2627
2628
static int
2629
nd6_sysctl_drlist(SYSCTL_HANDLER_ARGS)
2630
{
2631
struct in6_defrouter d;
2632
struct nd_defrouter *dr;
2633
int error;
2634
2635
if (req->newptr != NULL)
2636
return (EPERM);
2637
2638
error = sysctl_wire_old_buffer(req, 0);
2639
if (error != 0)
2640
return (error);
2641
2642
bzero(&d, sizeof(d));
2643
d.rtaddr.sin6_family = AF_INET6;
2644
d.rtaddr.sin6_len = sizeof(d.rtaddr);
2645
2646
ND6_RLOCK();
2647
TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) {
2648
d.rtaddr.sin6_addr = dr->rtaddr;
2649
error = sa6_recoverscope(&d.rtaddr);
2650
if (error != 0)
2651
break;
2652
d.flags = dr->raflags;
2653
d.rtlifetime = dr->rtlifetime;
2654
d.expire = dr->expire + (time_second - time_uptime);
2655
d.if_index = dr->ifp->if_index;
2656
error = SYSCTL_OUT(req, &d, sizeof(d));
2657
if (error != 0)
2658
break;
2659
}
2660
ND6_RUNLOCK();
2661
return (error);
2662
}
2663
SYSCTL_PROC(_net_inet6_icmp6, ICMPV6CTL_ND6_DRLIST, nd6_drlist,
2664
CTLTYPE_OPAQUE | CTLFLAG_RD | CTLFLAG_MPSAFE,
2665
NULL, 0, nd6_sysctl_drlist, "S,in6_defrouter",
2666
"NDP default router list");
2667
2668