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