]> git.proxmox.com Git - mirror_frr.git/blob - zebra/rtadv.c
Merge pull request #11175 from louis-6wind/ip-vrf-exec
[mirror_frr.git] / zebra / rtadv.c
1 /* Router advertisement
2 * Copyright (C) 2016 Cumulus Networks
3 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
4 * Copyright (C) 1999 Kunihiro Ishiguro
5 *
6 * This file is part of GNU Zebra.
7 *
8 * GNU Zebra is free software; you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation; either version 2, or (at your option) any
11 * later version.
12 *
13 * GNU Zebra is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; see the file COPYING; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23 #include <zebra.h>
24
25 #include "memory.h"
26 #include "sockopt.h"
27 #include "thread.h"
28 #include "if.h"
29 #include "stream.h"
30 #include "log.h"
31 #include "prefix.h"
32 #include "linklist.h"
33 #include "command.h"
34 #include "privs.h"
35 #include "vrf.h"
36 #include "ns.h"
37 #include "lib_errors.h"
38
39 #include "zebra/interface.h"
40 #include "zebra/rtadv.h"
41 #include "zebra/debug.h"
42 #include "zebra/rib.h"
43 #include "zebra/zapi_msg.h"
44 #include "zebra/zebra_vrf.h"
45 #include "zebra/zebra_errors.h"
46 #include "zebra/zebra_router.h"
47
48 extern struct zebra_privs_t zserv_privs;
49
50 static uint32_t interfaces_configured_for_ra_from_bgp;
51
52 #if defined(HAVE_RTADV)
53
54 #ifndef VTYSH_EXTRACT_PL
55 #include "zebra/rtadv_clippy.c"
56 #endif
57
58 DEFINE_MTYPE_STATIC(ZEBRA, RTADV_PREFIX, "Router Advertisement Prefix");
59 DEFINE_MTYPE_STATIC(ZEBRA, ADV_IF, "Advertised Interface");
60
61 #ifdef OPEN_BSD
62 #include <netinet/icmp6.h>
63 #endif
64
65 /* If RFC2133 definition is used. */
66 #ifndef IPV6_JOIN_GROUP
67 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
68 #endif
69 #ifndef IPV6_LEAVE_GROUP
70 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
71 #endif
72
73 #define ALLNODE "ff02::1"
74 #define ALLROUTER "ff02::2"
75
76 /* adv list node */
77 struct adv_if {
78 char name[INTERFACE_NAMSIZ];
79 struct adv_if_list_item list_item;
80 };
81
82 static int adv_if_cmp(const struct adv_if *a, const struct adv_if *b)
83 {
84 return if_cmp_name_func(a->name, b->name);
85 }
86
87 DECLARE_SORTLIST_UNIQ(adv_if_list, struct adv_if, list_item, adv_if_cmp);
88
89 static int rtadv_prefix_cmp(const struct rtadv_prefix *a,
90 const struct rtadv_prefix *b)
91 {
92 return prefix_cmp(&a->prefix, &b->prefix);
93 }
94
95 DECLARE_RBTREE_UNIQ(rtadv_prefixes, struct rtadv_prefix, item,
96 rtadv_prefix_cmp);
97
98 DEFINE_MTYPE_STATIC(ZEBRA, RTADV_RDNSS, "Router Advertisement RDNSS");
99 DEFINE_MTYPE_STATIC(ZEBRA, RTADV_DNSSL, "Router Advertisement DNSSL");
100
101 /* Order is intentional. Matches RFC4191. This array is also used for
102 command matching, so only modify with care. */
103 static const char *const rtadv_pref_strs[] = {
104 "medium", "high", "INVALID", "low", 0
105 };
106
107 enum rtadv_event {
108 RTADV_START,
109 RTADV_STOP,
110 RTADV_TIMER,
111 RTADV_TIMER_MSEC,
112 RTADV_READ
113 };
114
115 static void rtadv_event(struct zebra_vrf *, enum rtadv_event, int);
116
117 static int if_join_all_router(int, struct interface *);
118 static int if_leave_all_router(int, struct interface *);
119
120 static struct zebra_vrf *rtadv_interface_get_zvrf(const struct interface *ifp)
121 {
122 /* We use the default vrf for rtadv handling except in netns */
123 if (!vrf_is_backend_netns())
124 return vrf_info_lookup(VRF_DEFAULT);
125
126 return ifp->vrf->info;
127 }
128
129 static int rtadv_increment_received(struct zebra_vrf *zvrf, ifindex_t *ifindex)
130 {
131 int ret = -1;
132 struct interface *iface;
133 struct zebra_if *zif;
134
135 iface = if_lookup_by_index(*ifindex, zvrf->vrf->vrf_id);
136 if (iface && iface->info) {
137 zif = iface->info;
138 zif->ra_rcvd++;
139 ret = 0;
140 }
141 return ret;
142 }
143
144 static int rtadv_recv_packet(struct zebra_vrf *zvrf, int sock, uint8_t *buf,
145 int buflen, struct sockaddr_in6 *from,
146 ifindex_t *ifindex, int *hoplimit)
147 {
148 int ret;
149 struct msghdr msg;
150 struct iovec iov;
151 struct cmsghdr *cmsgptr;
152 struct in6_addr dst;
153
154 char adata[1024];
155
156 /* Fill in message and iovec. */
157 memset(&msg, 0, sizeof(msg));
158 msg.msg_name = (void *)from;
159 msg.msg_namelen = sizeof(struct sockaddr_in6);
160 msg.msg_iov = &iov;
161 msg.msg_iovlen = 1;
162 msg.msg_control = (void *)adata;
163 msg.msg_controllen = sizeof(adata);
164 iov.iov_base = buf;
165 iov.iov_len = buflen;
166
167 /* If recvmsg fail return minus value. */
168 ret = recvmsg(sock, &msg, 0);
169 if (ret < 0)
170 return ret;
171
172 for (cmsgptr = CMSG_FIRSTHDR(&msg); cmsgptr != NULL;
173 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr)) {
174 /* I want interface index which this packet comes from. */
175 if (cmsgptr->cmsg_level == IPPROTO_IPV6
176 && cmsgptr->cmsg_type == IPV6_PKTINFO) {
177 struct in6_pktinfo *ptr;
178
179 ptr = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
180 *ifindex = ptr->ipi6_ifindex;
181 memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
182 }
183
184 /* Incoming packet's hop limit. */
185 if (cmsgptr->cmsg_level == IPPROTO_IPV6
186 && cmsgptr->cmsg_type == IPV6_HOPLIMIT) {
187 int *hoptr = (int *)CMSG_DATA(cmsgptr);
188 *hoplimit = *hoptr;
189 }
190 }
191
192 rtadv_increment_received(zvrf, ifindex);
193 return ret;
194 }
195
196 #define RTADV_MSG_SIZE 4096
197
198 /* Send router advertisement packet. */
199 static void rtadv_send_packet(int sock, struct interface *ifp,
200 enum ipv6_nd_suppress_ra_status stop)
201 {
202 struct msghdr msg;
203 struct iovec iov;
204 struct cmsghdr *cmsgptr;
205 struct in6_pktinfo *pkt;
206 struct sockaddr_in6 addr;
207 static void *adata = NULL;
208 unsigned char buf[RTADV_MSG_SIZE];
209 struct nd_router_advert *rtadv;
210 int ret;
211 int len = 0;
212 struct zebra_if *zif;
213 struct rtadv_prefix *rprefix;
214 uint8_t all_nodes_addr[] = {0xff, 0x02, 0, 0, 0, 0, 0, 0,
215 0, 0, 0, 0, 0, 0, 0, 1};
216 struct listnode *node;
217 uint16_t pkt_RouterLifetime;
218
219 /*
220 * Allocate control message bufffer. This is dynamic because
221 * CMSG_SPACE is not guaranteed not to call a function. Note that
222 * the size will be different on different architectures due to
223 * differing alignment rules.
224 */
225 if (adata == NULL) {
226 /* XXX Free on shutdown. */
227 adata = calloc(1, CMSG_SPACE(sizeof(struct in6_pktinfo)));
228
229 if (adata == NULL) {
230 zlog_debug(
231 "rtadv_send_packet: can't malloc control data");
232 exit(-1);
233 }
234 }
235
236 /* Logging of packet. */
237 if (IS_ZEBRA_DEBUG_PACKET)
238 zlog_debug("%s(%s:%u): Tx RA, socket %u", ifp->name,
239 ifp->vrf->name, ifp->ifindex, sock);
240
241 /* Fill in sockaddr_in6. */
242 memset(&addr, 0, sizeof(struct sockaddr_in6));
243 addr.sin6_family = AF_INET6;
244 #ifdef SIN6_LEN
245 addr.sin6_len = sizeof(struct sockaddr_in6);
246 #endif /* SIN6_LEN */
247 addr.sin6_port = htons(IPPROTO_ICMPV6);
248 IPV6_ADDR_COPY(&addr.sin6_addr, all_nodes_addr);
249
250 /* Fetch interface information. */
251 zif = ifp->info;
252
253 /* Make router advertisement message. */
254 rtadv = (struct nd_router_advert *)buf;
255
256 rtadv->nd_ra_type = ND_ROUTER_ADVERT;
257 rtadv->nd_ra_code = 0;
258 rtadv->nd_ra_cksum = 0;
259
260 rtadv->nd_ra_curhoplimit = zif->rtadv.AdvCurHopLimit;
261
262 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
263 rtadv->nd_ra_flags_reserved = zif->rtadv.AdvDefaultLifetime == 0
264 ? 0
265 : zif->rtadv.DefaultPreference;
266 rtadv->nd_ra_flags_reserved <<= 3;
267
268 if (zif->rtadv.AdvManagedFlag)
269 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
270 if (zif->rtadv.AdvOtherConfigFlag)
271 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
272 if (zif->rtadv.AdvHomeAgentFlag)
273 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
274 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
275 * AdvDefaultLifetime is by default based on the value of
276 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
277 * field of Router Advertisements. Given that this field is expressed
278 * in seconds, a small MaxRtrAdvInterval value can result in a zero
279 * value for this field. To prevent this, routers SHOULD keep
280 * AdvDefaultLifetime in at least one second, even if the use of
281 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
282 pkt_RouterLifetime =
283 zif->rtadv.AdvDefaultLifetime != -1
284 ? zif->rtadv.AdvDefaultLifetime
285 : MAX(1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
286
287 /* send RA lifetime of 0 before stopping. rfc4861/6.2.5 */
288 rtadv->nd_ra_router_lifetime =
289 (stop == RA_SUPPRESS) ? htons(0) : htons(pkt_RouterLifetime);
290 rtadv->nd_ra_reachable = htonl(zif->rtadv.AdvReachableTime);
291 rtadv->nd_ra_retransmit = htonl(zif->rtadv.AdvRetransTimer);
292
293 len = sizeof(struct nd_router_advert);
294
295 /* If both the Home Agent Preference and Home Agent Lifetime are set to
296 * their default values specified above, this option SHOULD NOT be
297 * included in the Router Advertisement messages sent by this home
298 * agent. -- RFC6275, 7.4 */
299 if (zif->rtadv.AdvHomeAgentFlag
300 && (zif->rtadv.HomeAgentPreference
301 || zif->rtadv.HomeAgentLifetime != -1)) {
302 struct nd_opt_homeagent_info *ndopt_hai =
303 (struct nd_opt_homeagent_info *)(buf + len);
304 ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
305 ndopt_hai->nd_opt_hai_len = 1;
306 ndopt_hai->nd_opt_hai_reserved = 0;
307 ndopt_hai->nd_opt_hai_preference =
308 htons(zif->rtadv.HomeAgentPreference);
309 /* 16-bit unsigned integer. The lifetime associated with the
310 * home
311 * agent in units of seconds. The default value is the same as
312 * the
313 * Router Lifetime, as specified in the main body of the Router
314 * Advertisement. The maximum value corresponds to 18.2 hours.
315 * A
316 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
317 ndopt_hai->nd_opt_hai_lifetime =
318 htons(zif->rtadv.HomeAgentLifetime != -1
319 ? zif->rtadv.HomeAgentLifetime
320 : MAX(1, pkt_RouterLifetime) /* 0 is OK
321 for RL,
322 but not
323 for HAL*/
324 );
325 len += sizeof(struct nd_opt_homeagent_info);
326 }
327
328 if (zif->rtadv.AdvIntervalOption) {
329 struct nd_opt_adv_interval *ndopt_adv =
330 (struct nd_opt_adv_interval *)(buf + len);
331 ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
332 ndopt_adv->nd_opt_ai_len = 1;
333 ndopt_adv->nd_opt_ai_reserved = 0;
334 ndopt_adv->nd_opt_ai_interval =
335 htonl(zif->rtadv.MaxRtrAdvInterval);
336 len += sizeof(struct nd_opt_adv_interval);
337 }
338
339 /* Fill in prefix. */
340 frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) {
341 struct nd_opt_prefix_info *pinfo;
342
343 pinfo = (struct nd_opt_prefix_info *)(buf + len);
344
345 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
346 pinfo->nd_opt_pi_len = 4;
347 pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
348
349 pinfo->nd_opt_pi_flags_reserved = 0;
350 if (rprefix->AdvOnLinkFlag)
351 pinfo->nd_opt_pi_flags_reserved |=
352 ND_OPT_PI_FLAG_ONLINK;
353 if (rprefix->AdvAutonomousFlag)
354 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
355 if (rprefix->AdvRouterAddressFlag)
356 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
357
358 pinfo->nd_opt_pi_valid_time = htonl(rprefix->AdvValidLifetime);
359 pinfo->nd_opt_pi_preferred_time =
360 htonl(rprefix->AdvPreferredLifetime);
361 pinfo->nd_opt_pi_reserved2 = 0;
362
363 IPV6_ADDR_COPY(&pinfo->nd_opt_pi_prefix,
364 &rprefix->prefix.prefix);
365
366 len += sizeof(struct nd_opt_prefix_info);
367 }
368
369 /* Hardware address. */
370 if (ifp->hw_addr_len != 0) {
371 buf[len++] = ND_OPT_SOURCE_LINKADDR;
372
373 /* Option length should be rounded up to next octet if
374 the link address does not end on an octet boundary. */
375 buf[len++] = (ifp->hw_addr_len + 9) >> 3;
376
377 memcpy(buf + len, ifp->hw_addr, ifp->hw_addr_len);
378 len += ifp->hw_addr_len;
379
380 /* Pad option to end on an octet boundary. */
381 memset(buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
382 len += -(ifp->hw_addr_len + 2) & 0x7;
383 }
384
385 /* MTU */
386 if (zif->rtadv.AdvLinkMTU) {
387 struct nd_opt_mtu *opt = (struct nd_opt_mtu *)(buf + len);
388 opt->nd_opt_mtu_type = ND_OPT_MTU;
389 opt->nd_opt_mtu_len = 1;
390 opt->nd_opt_mtu_reserved = 0;
391 opt->nd_opt_mtu_mtu = htonl(zif->rtadv.AdvLinkMTU);
392 len += sizeof(struct nd_opt_mtu);
393 }
394
395 /*
396 * There is no limit on the number of configurable recursive DNS
397 * servers or search list entries. We don't want the RA message
398 * to exceed the link's MTU (risking fragmentation) or even
399 * blow the stack buffer allocated for it.
400 */
401 size_t max_len = MIN(ifp->mtu6 - 40, sizeof(buf));
402
403 /* Recursive DNS servers */
404 struct rtadv_rdnss *rdnss;
405
406 for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvRDNSSList, node, rdnss)) {
407 size_t opt_len =
408 sizeof(struct nd_opt_rdnss) + sizeof(struct in6_addr);
409
410 if (len + opt_len > max_len) {
411 zlog_warn(
412 "%s(%s:%u): Tx RA: RDNSS option would exceed MTU, omitting it",
413 ifp->name, ifp->vrf->name, ifp->ifindex);
414 goto no_more_opts;
415 }
416 struct nd_opt_rdnss *opt = (struct nd_opt_rdnss *)(buf + len);
417
418 opt->nd_opt_rdnss_type = ND_OPT_RDNSS;
419 opt->nd_opt_rdnss_len = opt_len / 8;
420 opt->nd_opt_rdnss_reserved = 0;
421 opt->nd_opt_rdnss_lifetime = htonl(
422 rdnss->lifetime_set
423 ? rdnss->lifetime
424 : MAX(1, 0.003 * zif->rtadv.MaxRtrAdvInterval));
425
426 len += sizeof(struct nd_opt_rdnss);
427
428 IPV6_ADDR_COPY(buf + len, &rdnss->addr);
429 len += sizeof(struct in6_addr);
430 }
431
432 /* DNS search list */
433 struct rtadv_dnssl *dnssl;
434
435 for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvDNSSLList, node, dnssl)) {
436 size_t opt_len = sizeof(struct nd_opt_dnssl)
437 + ((dnssl->encoded_len + 7) & ~7);
438
439 if (len + opt_len > max_len) {
440 zlog_warn(
441 "%s(%u): Tx RA: DNSSL option would exceed MTU, omitting it",
442 ifp->name, ifp->ifindex);
443 goto no_more_opts;
444 }
445 struct nd_opt_dnssl *opt = (struct nd_opt_dnssl *)(buf + len);
446
447 opt->nd_opt_dnssl_type = ND_OPT_DNSSL;
448 opt->nd_opt_dnssl_len = opt_len / 8;
449 opt->nd_opt_dnssl_reserved = 0;
450 opt->nd_opt_dnssl_lifetime = htonl(
451 dnssl->lifetime_set
452 ? dnssl->lifetime
453 : MAX(1, 0.003 * zif->rtadv.MaxRtrAdvInterval));
454
455 len += sizeof(struct nd_opt_dnssl);
456
457 memcpy(buf + len, dnssl->encoded_name, dnssl->encoded_len);
458 len += dnssl->encoded_len;
459
460 /* Zero-pad to 8-octet boundary */
461 while (len % 8)
462 buf[len++] = '\0';
463 }
464
465 no_more_opts:
466
467 msg.msg_name = (void *)&addr;
468 msg.msg_namelen = sizeof(struct sockaddr_in6);
469 msg.msg_iov = &iov;
470 msg.msg_iovlen = 1;
471 msg.msg_control = (void *)adata;
472 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
473 msg.msg_flags = 0;
474 iov.iov_base = buf;
475 iov.iov_len = len;
476
477 cmsgptr = CMSG_FIRSTHDR(&msg);
478 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
479 cmsgptr->cmsg_level = IPPROTO_IPV6;
480 cmsgptr->cmsg_type = IPV6_PKTINFO;
481
482 pkt = (struct in6_pktinfo *)CMSG_DATA(cmsgptr);
483 memset(&pkt->ipi6_addr, 0, sizeof(struct in6_addr));
484 pkt->ipi6_ifindex = ifp->ifindex;
485
486 ret = sendmsg(sock, &msg, 0);
487 if (ret < 0) {
488 flog_err_sys(EC_LIB_SOCKET,
489 "%s(%u): Tx RA failed, socket %u error %d (%s)",
490 ifp->name, ifp->ifindex, sock, errno,
491 safe_strerror(errno));
492 } else
493 zif->ra_sent++;
494 }
495
496 static void rtadv_timer(struct thread *thread)
497 {
498 struct zebra_vrf *zvrf = THREAD_ARG(thread);
499 struct vrf *vrf;
500 struct interface *ifp;
501 struct zebra_if *zif;
502 int period;
503
504 zvrf->rtadv.ra_timer = NULL;
505 if (adv_if_list_count(&zvrf->rtadv.adv_msec_if) == 0) {
506 period = 1000; /* 1 s */
507 rtadv_event(zvrf, RTADV_TIMER, 1 /* 1 s */);
508 } else {
509 period = 10; /* 10 ms */
510 rtadv_event(zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
511 }
512
513 RB_FOREACH (vrf, vrf_id_head, &vrfs_by_id)
514 FOR_ALL_INTERFACES (vrf, ifp) {
515 if (if_is_loopback(ifp) || !if_is_operative(ifp) ||
516 IS_ZEBRA_IF_BRIDGE_SLAVE(ifp) ||
517 !connected_get_linklocal(ifp) ||
518 (vrf_is_backend_netns() &&
519 ifp->vrf->vrf_id != zvrf->vrf->vrf_id))
520 continue;
521
522 zif = ifp->info;
523
524 if (zif->rtadv.AdvSendAdvertisements) {
525 if (zif->rtadv.inFastRexmit
526 && zif->rtadv.UseFastRexmit) {
527 /* We assume we fast rexmit every sec so
528 * no
529 * additional vars */
530 if (--zif->rtadv.NumFastReXmitsRemain
531 <= 0)
532 zif->rtadv.inFastRexmit = 0;
533
534 if (IS_ZEBRA_DEBUG_SEND)
535 zlog_debug(
536 "Fast RA Rexmit on interface %s(%s:%u)",
537 ifp->name,
538 ifp->vrf->name,
539 ifp->ifindex);
540
541 rtadv_send_packet(zvrf->rtadv.sock, ifp,
542 RA_ENABLE);
543 } else {
544 zif->rtadv.AdvIntervalTimer -= period;
545 if (zif->rtadv.AdvIntervalTimer <= 0) {
546 /* FIXME: using
547 MaxRtrAdvInterval each
548 time isn't what section
549 6.2.4 of RFC4861 tells to do.
550 */
551 zif->rtadv.AdvIntervalTimer =
552 zif->rtadv
553 .MaxRtrAdvInterval;
554 rtadv_send_packet(
555 zvrf->rtadv.sock, ifp,
556 RA_ENABLE);
557 }
558 }
559 }
560 }
561 }
562
563 static void rtadv_process_solicit(struct interface *ifp)
564 {
565 struct zebra_vrf *zvrf;
566 struct zebra_if *zif;
567
568 zvrf = rtadv_interface_get_zvrf(ifp);
569 assert(zvrf);
570 zif = ifp->info;
571
572 /*
573 * If FastRetransmit is enabled, send the RA immediately.
574 * If not enabled but it has been more than MIN_DELAY_BETWEEN_RAS
575 * (3 seconds) since the last RA was sent, send it now and reset
576 * the timer to start at the max (configured) again.
577 * If not enabled and it is less than 3 seconds since the last
578 * RA packet was sent, set the timer for 3 seconds so the next
579 * one will be sent with a minimum of 3 seconds between RAs.
580 * RFC4861 sec 6.2.6
581 */
582 if ((zif->rtadv.UseFastRexmit)
583 || (zif->rtadv.AdvIntervalTimer <=
584 (zif->rtadv.MaxRtrAdvInterval - MIN_DELAY_BETWEEN_RAS))) {
585 rtadv_send_packet(zvrf->rtadv.sock, ifp, RA_ENABLE);
586 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
587 } else
588 zif->rtadv.AdvIntervalTimer = MIN_DELAY_BETWEEN_RAS;
589 }
590
591 /*
592 * This function processes optional attributes off of
593 * end of a RA packet received. At this point in
594 * time we only care about this in one situation
595 * which is when a interface does not have a LL
596 * v6 address. We still need to be able to install
597 * the mac address for v4 to v6 resolution
598 */
599 static void rtadv_process_optional(uint8_t *optional, unsigned int len,
600 struct interface *ifp,
601 struct sockaddr_in6 *addr)
602 {
603 char *mac;
604
605 while (len > 0) {
606 struct nd_opt_hdr *opt_hdr = (struct nd_opt_hdr *)optional;
607
608 switch(opt_hdr->nd_opt_type) {
609 case ND_OPT_SOURCE_LINKADDR:
610 mac = (char *)(optional+2);
611 if_nbr_mac_to_ipv4ll_neigh_update(ifp, mac,
612 &addr->sin6_addr, 1);
613 break;
614 default:
615 break;
616 }
617
618 len -= 8 * opt_hdr->nd_opt_len;
619 optional += 8 * opt_hdr->nd_opt_len;
620 }
621 }
622
623 static void rtadv_process_advert(uint8_t *msg, unsigned int len,
624 struct interface *ifp,
625 struct sockaddr_in6 *addr)
626 {
627 struct nd_router_advert *radvert;
628 char addr_str[INET6_ADDRSTRLEN];
629 struct zebra_if *zif;
630 struct prefix p;
631
632 zif = ifp->info;
633
634 inet_ntop(AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
635
636 if (len < sizeof(struct nd_router_advert)) {
637 if (IS_ZEBRA_DEBUG_PACKET)
638 zlog_debug(
639 "%s(%s:%u): Rx RA with invalid length %d from %s",
640 ifp->name, ifp->vrf->name, ifp->ifindex, len,
641 addr_str);
642 return;
643 }
644
645 if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
646 rtadv_process_optional(msg + sizeof(struct nd_router_advert),
647 len - sizeof(struct nd_router_advert),
648 ifp, addr);
649 if (IS_ZEBRA_DEBUG_PACKET)
650 zlog_debug(
651 "%s(%s:%u): Rx RA with non-linklocal source address from %s",
652 ifp->name, ifp->vrf->name, ifp->ifindex,
653 addr_str);
654 return;
655 }
656
657 radvert = (struct nd_router_advert *)msg;
658
659 #define SIXHOUR2USEC (int64_t)6 * 60 * 60 * 1000000
660
661 if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
662 (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit) &&
663 (monotime_since(&zif->rtadv.lastadvcurhoplimit, NULL) >
664 SIXHOUR2USEC ||
665 zif->rtadv.lastadvcurhoplimit.tv_sec == 0)) {
666 flog_warn(
667 EC_ZEBRA_RA_PARAM_MISMATCH,
668 "%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
669 ifp->name, ifp->ifindex, addr_str);
670 monotime(&zif->rtadv.lastadvcurhoplimit);
671 }
672
673 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
674 !zif->rtadv.AdvManagedFlag &&
675 (monotime_since(&zif->rtadv.lastadvmanagedflag, NULL) >
676 SIXHOUR2USEC ||
677 zif->rtadv.lastadvmanagedflag.tv_sec == 0)) {
678 flog_warn(
679 EC_ZEBRA_RA_PARAM_MISMATCH,
680 "%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
681 ifp->name, ifp->ifindex, addr_str);
682 monotime(&zif->rtadv.lastadvmanagedflag);
683 }
684
685 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
686 !zif->rtadv.AdvOtherConfigFlag &&
687 (monotime_since(&zif->rtadv.lastadvotherconfigflag, NULL) >
688 SIXHOUR2USEC ||
689 zif->rtadv.lastadvotherconfigflag.tv_sec == 0)) {
690 flog_warn(
691 EC_ZEBRA_RA_PARAM_MISMATCH,
692 "%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
693 ifp->name, ifp->ifindex, addr_str);
694 monotime(&zif->rtadv.lastadvotherconfigflag);
695 }
696
697 if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
698 (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime) &&
699 (monotime_since(&zif->rtadv.lastadvreachabletime, NULL) >
700 SIXHOUR2USEC ||
701 zif->rtadv.lastadvreachabletime.tv_sec == 0)) {
702 flog_warn(
703 EC_ZEBRA_RA_PARAM_MISMATCH,
704 "%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
705 ifp->name, ifp->ifindex, addr_str);
706 monotime(&zif->rtadv.lastadvreachabletime);
707 }
708
709 if ((ntohl(radvert->nd_ra_retransmit) !=
710 (unsigned int)zif->rtadv.AdvRetransTimer) &&
711 (monotime_since(&zif->rtadv.lastadvretranstimer, NULL) >
712 SIXHOUR2USEC ||
713 zif->rtadv.lastadvretranstimer.tv_sec == 0)) {
714 flog_warn(
715 EC_ZEBRA_RA_PARAM_MISMATCH,
716 "%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
717 ifp->name, ifp->ifindex, addr_str);
718 monotime(&zif->rtadv.lastadvretranstimer);
719 }
720
721 /* Create entry for neighbor if not known. */
722 p.family = AF_INET6;
723 IPV6_ADDR_COPY(&p.u.prefix6, &addr->sin6_addr);
724 p.prefixlen = IPV6_MAX_BITLEN;
725
726 if (!nbr_connected_check(ifp, &p))
727 nbr_connected_add_ipv6(ifp, &addr->sin6_addr);
728 }
729
730
731 static void rtadv_process_packet(uint8_t *buf, unsigned int len,
732 ifindex_t ifindex, int hoplimit,
733 struct sockaddr_in6 *from,
734 struct zebra_vrf *zvrf)
735 {
736 struct icmp6_hdr *icmph;
737 struct interface *ifp;
738 struct zebra_if *zif;
739 char addr_str[INET6_ADDRSTRLEN];
740
741 inet_ntop(AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
742
743 /* Interface search. */
744 ifp = if_lookup_by_index(ifindex, zvrf->vrf->vrf_id);
745 if (ifp == NULL) {
746 flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
747 "RA/RS received on unknown IF %u from %s", ifindex,
748 addr_str);
749 return;
750 }
751
752 if (IS_ZEBRA_DEBUG_PACKET)
753 zlog_debug("%s(%s:%u): Rx RA/RS len %d from %s", ifp->name,
754 ifp->vrf->name, ifp->ifindex, len, addr_str);
755
756 if (if_is_loopback(ifp))
757 return;
758
759 /* Check interface configuration. */
760 zif = ifp->info;
761 if (!zif->rtadv.AdvSendAdvertisements)
762 return;
763
764 /* ICMP message length check. */
765 if (len < sizeof(struct icmp6_hdr)) {
766 zlog_debug(
767 "%s(%s:%u): Rx RA with Invalid ICMPV6 packet length %d",
768 ifp->name, ifp->vrf->name, ifp->ifindex, len);
769 return;
770 }
771
772 icmph = (struct icmp6_hdr *)buf;
773
774 /* ICMP message type check. */
775 if (icmph->icmp6_type != ND_ROUTER_SOLICIT
776 && icmph->icmp6_type != ND_ROUTER_ADVERT) {
777 zlog_debug("%s(%s:%u): Rx RA - Unwanted ICMPV6 message type %d",
778 ifp->name, ifp->vrf->name, ifp->ifindex,
779 icmph->icmp6_type);
780 return;
781 }
782
783 /* Hoplimit check. */
784 if (hoplimit >= 0 && hoplimit != 255) {
785 zlog_debug("%s(%s:%u): Rx RA - Invalid hoplimit %d", ifp->name,
786 ifp->vrf->name, ifp->ifindex, hoplimit);
787 return;
788 }
789
790 /* Check ICMP message type. */
791 if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
792 rtadv_process_solicit(ifp);
793 else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
794 rtadv_process_advert(buf, len, ifp, from);
795
796 return;
797 }
798
799 static void rtadv_read(struct thread *thread)
800 {
801 int sock;
802 int len;
803 uint8_t buf[RTADV_MSG_SIZE];
804 struct sockaddr_in6 from;
805 ifindex_t ifindex = 0;
806 int hoplimit = -1;
807 struct zebra_vrf *zvrf = THREAD_ARG(thread);
808
809 sock = THREAD_FD(thread);
810 zvrf->rtadv.ra_read = NULL;
811
812 /* Register myself. */
813 rtadv_event(zvrf, RTADV_READ, 0);
814
815 len = rtadv_recv_packet(zvrf, sock, buf, sizeof(buf), &from, &ifindex,
816 &hoplimit);
817
818 if (len < 0) {
819 flog_err_sys(EC_LIB_SOCKET,
820 "RA/RS recv failed, socket %u error %s", sock,
821 safe_strerror(errno));
822 return;
823 }
824
825 rtadv_process_packet(buf, (unsigned)len, ifindex, hoplimit, &from, zvrf);
826 }
827
828 static int rtadv_make_socket(ns_id_t ns_id)
829 {
830 int sock = -1;
831 int ret = 0;
832 struct icmp6_filter filter;
833
834 frr_with_privs(&zserv_privs) {
835
836 sock = ns_socket(AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, ns_id);
837
838 }
839
840 if (sock < 0) {
841 return -1;
842 }
843
844 ret = setsockopt_ipv6_pktinfo(sock, 1);
845 if (ret < 0) {
846 close(sock);
847 return ret;
848 }
849 ret = setsockopt_ipv6_multicast_loop(sock, 0);
850 if (ret < 0) {
851 close(sock);
852 return ret;
853 }
854 ret = setsockopt_ipv6_unicast_hops(sock, 255);
855 if (ret < 0) {
856 close(sock);
857 return ret;
858 }
859 ret = setsockopt_ipv6_multicast_hops(sock, 255);
860 if (ret < 0) {
861 close(sock);
862 return ret;
863 }
864 ret = setsockopt_ipv6_hoplimit(sock, 1);
865 if (ret < 0) {
866 close(sock);
867 return ret;
868 }
869
870 ICMP6_FILTER_SETBLOCKALL(&filter);
871 ICMP6_FILTER_SETPASS(ND_ROUTER_SOLICIT, &filter);
872 ICMP6_FILTER_SETPASS(ND_ROUTER_ADVERT, &filter);
873
874 ret = setsockopt(sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
875 sizeof(struct icmp6_filter));
876 if (ret < 0) {
877 zlog_info("ICMP6_FILTER set fail: %s", safe_strerror(errno));
878 close(sock);
879 return ret;
880 }
881
882 return sock;
883 }
884
885 static struct adv_if *adv_if_new(const char *name)
886 {
887 struct adv_if *new;
888
889 new = XCALLOC(MTYPE_ADV_IF, sizeof(struct adv_if));
890
891 strlcpy(new->name, name, sizeof(new->name));
892
893 return new;
894 }
895
896 static void adv_if_free(struct adv_if *adv_if)
897 {
898 XFREE(MTYPE_ADV_IF, adv_if);
899 }
900
901 static bool adv_if_is_empty_internal(const struct adv_if_list_head *adv_if_head)
902 {
903 return adv_if_list_count(adv_if_head) ? false : true;
904 }
905
906 static struct adv_if *adv_if_add_internal(struct adv_if_list_head *adv_if_head,
907 const char *name)
908 {
909 struct adv_if adv_if_lookup = {};
910 struct adv_if *adv_if = NULL;
911
912 strlcpy(adv_if_lookup.name, name, sizeof(adv_if_lookup.name));
913 adv_if = adv_if_list_find(adv_if_head, &adv_if_lookup);
914
915 if (adv_if != NULL)
916 return adv_if;
917
918 adv_if = adv_if_new(adv_if_lookup.name);
919 adv_if_list_add(adv_if_head, adv_if);
920
921 return NULL;
922 }
923
924 static struct adv_if *adv_if_del_internal(struct adv_if_list_head *adv_if_head,
925 const char *name)
926 {
927 struct adv_if adv_if_lookup = {};
928 struct adv_if *adv_if = NULL;
929
930 strlcpy(adv_if_lookup.name, name, sizeof(adv_if_lookup.name));
931 adv_if = adv_if_list_find(adv_if_head, &adv_if_lookup);
932
933 if (adv_if == NULL)
934 return NULL;
935
936 adv_if_list_del(adv_if_head, adv_if);
937
938 return adv_if;
939 }
940
941 static void adv_if_clean_internal(struct adv_if_list_head *adv_if_head)
942 {
943 struct adv_if *node = NULL;
944
945 if (!adv_if_is_empty_internal(adv_if_head)) {
946 frr_each_safe (adv_if_list, adv_if_head, node) {
947 adv_if_list_del(adv_if_head, node);
948 adv_if_free(node);
949 }
950 }
951
952 adv_if_list_fini(adv_if_head);
953 }
954
955
956 /*
957 * Add to list. On Success, return NULL, otherwise return already existing
958 * adv_if.
959 */
960 static struct adv_if *adv_if_add(struct zebra_vrf *zvrf, const char *name)
961 {
962 struct adv_if *adv_if = NULL;
963
964 adv_if = adv_if_add_internal(&zvrf->rtadv.adv_if, name);
965
966 if (adv_if != NULL)
967 return adv_if;
968
969 if (IS_ZEBRA_DEBUG_EVENT) {
970 struct vrf *vrf = zvrf->vrf;
971
972 zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
973 VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
974 adv_if_list_count(&zvrf->rtadv.adv_if));
975 }
976
977 return NULL;
978 }
979
980 /*
981 * Del from list. On Success, return the adv_if, otherwise return NULL. Caller
982 * frees.
983 */
984 static struct adv_if *adv_if_del(struct zebra_vrf *zvrf, const char *name)
985 {
986 struct adv_if *adv_if = NULL;
987
988 adv_if = adv_if_del_internal(&zvrf->rtadv.adv_if, name);
989
990 if (adv_if == NULL)
991 return NULL;
992
993 if (IS_ZEBRA_DEBUG_EVENT) {
994 struct vrf *vrf = zvrf->vrf;
995
996 zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
997 VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
998 adv_if_list_count(&zvrf->rtadv.adv_if));
999 }
1000
1001 return adv_if;
1002 }
1003
1004 /*
1005 * Add to list. On Success, return NULL, otherwise return already existing
1006 * adv_if.
1007 */
1008 static struct adv_if *adv_msec_if_add(struct zebra_vrf *zvrf, const char *name)
1009 {
1010 struct adv_if *adv_if = NULL;
1011
1012 adv_if = adv_if_add_internal(&zvrf->rtadv.adv_msec_if, name);
1013
1014 if (adv_if != NULL)
1015 return adv_if;
1016
1017 if (IS_ZEBRA_DEBUG_EVENT) {
1018 struct vrf *vrf = zvrf->vrf;
1019
1020 zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
1021 VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
1022 adv_if_list_count(&zvrf->rtadv.adv_msec_if));
1023 }
1024
1025 return NULL;
1026 }
1027
1028 /*
1029 * Del from list. On Success, return the adv_if, otherwise return NULL. Caller
1030 * frees.
1031 */
1032 static struct adv_if *adv_msec_if_del(struct zebra_vrf *zvrf, const char *name)
1033 {
1034 struct adv_if *adv_if = NULL;
1035
1036 adv_if = adv_if_del_internal(&zvrf->rtadv.adv_msec_if, name);
1037
1038 if (adv_if == NULL)
1039 return NULL;
1040
1041 if (IS_ZEBRA_DEBUG_EVENT) {
1042 struct vrf *vrf = zvrf->vrf;
1043
1044 zlog_debug("%s: %s:%u IF %s count: %zu", __func__,
1045 VRF_LOGNAME(vrf), zvrf_id(zvrf), name,
1046 adv_if_list_count(&zvrf->rtadv.adv_msec_if));
1047 }
1048
1049 return adv_if;
1050 }
1051
1052 /* Clean adv_if list, called on vrf terminate */
1053 static void adv_if_clean(struct zebra_vrf *zvrf)
1054 {
1055 if (IS_ZEBRA_DEBUG_EVENT) {
1056 struct vrf *vrf = zvrf->vrf;
1057
1058 zlog_debug("%s: %s:%u count: %zu -> 0", __func__,
1059 VRF_LOGNAME(vrf), zvrf_id(zvrf),
1060 adv_if_list_count(&zvrf->rtadv.adv_if));
1061 }
1062
1063 adv_if_clean_internal(&zvrf->rtadv.adv_if);
1064 }
1065
1066 /* Clean adv_msec_if list, called on vrf terminate */
1067 static void adv_msec_if_clean(struct zebra_vrf *zvrf)
1068 {
1069 if (IS_ZEBRA_DEBUG_EVENT) {
1070 struct vrf *vrf = zvrf->vrf;
1071
1072 zlog_debug("%s: %s:%u count: %zu -> 0", __func__,
1073 VRF_LOGNAME(vrf), zvrf_id(zvrf),
1074 adv_if_list_count(&zvrf->rtadv.adv_msec_if));
1075 }
1076
1077 adv_if_clean_internal(&zvrf->rtadv.adv_msec_if);
1078 }
1079
1080 static struct rtadv_prefix *rtadv_prefix_new(void)
1081 {
1082 return XCALLOC(MTYPE_RTADV_PREFIX, sizeof(struct rtadv_prefix));
1083 }
1084
1085 static void rtadv_prefix_free(struct rtadv_prefix *rtadv_prefix)
1086 {
1087 XFREE(MTYPE_RTADV_PREFIX, rtadv_prefix);
1088 }
1089
1090 static struct rtadv_prefix *rtadv_prefix_get(struct rtadv_prefixes_head *list,
1091 struct prefix_ipv6 *p)
1092 {
1093 struct rtadv_prefix *rprefix, ref;
1094
1095 ref.prefix = *p;
1096
1097 rprefix = rtadv_prefixes_find(list, &ref);
1098 if (rprefix)
1099 return rprefix;
1100
1101 rprefix = rtadv_prefix_new();
1102 memcpy(&rprefix->prefix, p, sizeof(struct prefix_ipv6));
1103 rtadv_prefixes_add(list, rprefix);
1104
1105 return rprefix;
1106 }
1107
1108 static void rtadv_prefix_set_defaults(struct rtadv_prefix *rp)
1109 {
1110 rp->AdvAutonomousFlag = 1;
1111 rp->AdvOnLinkFlag = 1;
1112 rp->AdvRouterAddressFlag = 0;
1113 rp->AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
1114 rp->AdvValidLifetime = RTADV_VALID_LIFETIME;
1115 }
1116
1117 static void rtadv_prefix_set(struct zebra_if *zif, struct rtadv_prefix *rp)
1118 {
1119 struct rtadv_prefix *rprefix;
1120
1121 rprefix = rtadv_prefix_get(zif->rtadv.prefixes, &rp->prefix);
1122
1123 /*
1124 * Set parameters based on where the prefix is created.
1125 * If auto-created based on kernel address addition, set the
1126 * default values. If created from a manual "ipv6 nd prefix"
1127 * command, take the parameters from the manual command. Note
1128 * that if the manual command exists, the default values will
1129 * not overwrite the manual values.
1130 */
1131 if (rp->AdvPrefixCreate == PREFIX_SRC_MANUAL) {
1132 if (rprefix->AdvPrefixCreate == PREFIX_SRC_AUTO)
1133 rprefix->AdvPrefixCreate = PREFIX_SRC_BOTH;
1134 else
1135 rprefix->AdvPrefixCreate = PREFIX_SRC_MANUAL;
1136
1137 rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
1138 rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
1139 rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
1140 rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
1141 rprefix->AdvValidLifetime = rp->AdvValidLifetime;
1142 } else if (rp->AdvPrefixCreate == PREFIX_SRC_AUTO) {
1143 if (rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL)
1144 rprefix->AdvPrefixCreate = PREFIX_SRC_BOTH;
1145 else {
1146 rprefix->AdvPrefixCreate = PREFIX_SRC_AUTO;
1147 rtadv_prefix_set_defaults(rprefix);
1148 }
1149 }
1150 }
1151
1152 static int rtadv_prefix_reset(struct zebra_if *zif, struct rtadv_prefix *rp)
1153 {
1154 struct rtadv_prefix *rprefix;
1155
1156 rprefix = rtadv_prefixes_find(zif->rtadv.prefixes, rp);
1157 if (rprefix != NULL) {
1158
1159 /*
1160 * When deleting an address from the list, need to take care
1161 * it wasn't defined both automatically via kernel
1162 * address addition as well as manually by vtysh cli. If both,
1163 * we don't actually delete but may change the parameters
1164 * back to default if a manually defined entry is deleted.
1165 */
1166 if (rp->AdvPrefixCreate == PREFIX_SRC_MANUAL) {
1167 if (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH) {
1168 rprefix->AdvPrefixCreate = PREFIX_SRC_AUTO;
1169 rtadv_prefix_set_defaults(rprefix);
1170 return 1;
1171 }
1172 } else if (rp->AdvPrefixCreate == PREFIX_SRC_AUTO) {
1173 if (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH) {
1174 rprefix->AdvPrefixCreate = PREFIX_SRC_MANUAL;
1175 return 1;
1176 }
1177 }
1178
1179 rtadv_prefixes_del(zif->rtadv.prefixes, rprefix);
1180 rtadv_prefix_free(rprefix);
1181 return 1;
1182 } else
1183 return 0;
1184 }
1185
1186 /* Add IPv6 prefixes learned from the kernel to the RA prefix list */
1187 void rtadv_add_prefix(struct zebra_if *zif, const struct prefix_ipv6 *p)
1188 {
1189 struct rtadv_prefix rp;
1190
1191 rp.prefix = *p;
1192 apply_mask_ipv6(&rp.prefix);
1193 rp.AdvPrefixCreate = PREFIX_SRC_AUTO;
1194 rtadv_prefix_set(zif, &rp);
1195 }
1196
1197 /* Delete IPv6 prefixes removed by the kernel from the RA prefix list */
1198 void rtadv_delete_prefix(struct zebra_if *zif, const struct prefix *p)
1199 {
1200 struct rtadv_prefix rp;
1201
1202 rp.prefix = *((struct prefix_ipv6 *)p);
1203 apply_mask_ipv6(&rp.prefix);
1204 rp.AdvPrefixCreate = PREFIX_SRC_AUTO;
1205 rtadv_prefix_reset(zif, &rp);
1206 }
1207
1208 static void ipv6_nd_suppress_ra_set(struct interface *ifp,
1209 enum ipv6_nd_suppress_ra_status status)
1210 {
1211 struct zebra_if *zif;
1212 struct zebra_vrf *zvrf;
1213 struct adv_if *adv_if = NULL;
1214
1215 zif = ifp->info;
1216
1217 zvrf = rtadv_interface_get_zvrf(ifp);
1218
1219 if (status == RA_SUPPRESS) {
1220 /* RA is currently enabled */
1221 if (zif->rtadv.AdvSendAdvertisements) {
1222 rtadv_send_packet(zvrf->rtadv.sock, ifp, RA_SUPPRESS);
1223 zif->rtadv.AdvSendAdvertisements = 0;
1224 zif->rtadv.AdvIntervalTimer = 0;
1225
1226 adv_if = adv_if_del(zvrf, ifp->name);
1227 if (adv_if == NULL)
1228 return; /* Nothing to delete */
1229
1230 adv_if_free(adv_if);
1231
1232 if_leave_all_router(zvrf->rtadv.sock, ifp);
1233
1234 if (adv_if_list_count(&zvrf->rtadv.adv_if) == 0)
1235 rtadv_event(zvrf, RTADV_STOP, 0);
1236 }
1237 } else {
1238 if (!zif->rtadv.AdvSendAdvertisements) {
1239 zif->rtadv.AdvSendAdvertisements = 1;
1240 zif->rtadv.AdvIntervalTimer = 0;
1241 if ((zif->rtadv.MaxRtrAdvInterval >= 1000)
1242 && zif->rtadv.UseFastRexmit) {
1243 /*
1244 * Enable Fast RA only when RA interval is in
1245 * secs and Fast RA retransmit is enabled
1246 */
1247 zif->rtadv.inFastRexmit = 1;
1248 zif->rtadv.NumFastReXmitsRemain =
1249 RTADV_NUM_FAST_REXMITS;
1250 }
1251
1252 adv_if = adv_if_add(zvrf, ifp->name);
1253 if (adv_if != NULL)
1254 return; /* Alread added */
1255
1256 if_join_all_router(zvrf->rtadv.sock, ifp);
1257
1258 if (adv_if_list_count(&zvrf->rtadv.adv_if) == 1)
1259 rtadv_event(zvrf, RTADV_START, 0);
1260 }
1261 }
1262 }
1263
1264 /*
1265 * Handle client (BGP) message to enable or disable IPv6 RA on an interface.
1266 * Note that while the client could request RA on an interface on which the
1267 * operator has not enabled RA, RA won't be disabled upon client request
1268 * if the operator has explicitly enabled RA. The enable request can also
1269 * specify a RA interval (in seconds).
1270 */
1271 static void zebra_interface_radv_set(ZAPI_HANDLER_ARGS, int enable)
1272 {
1273 struct stream *s;
1274 ifindex_t ifindex;
1275 struct interface *ifp;
1276 struct zebra_if *zif;
1277 uint32_t ra_interval;
1278
1279 s = msg;
1280
1281 /* Get interface index and RA interval. */
1282 STREAM_GETL(s, ifindex);
1283 STREAM_GETL(s, ra_interval);
1284
1285 if (IS_ZEBRA_DEBUG_EVENT) {
1286 struct vrf *vrf = zvrf->vrf;
1287
1288 zlog_debug("%s:%u: IF %u RA %s from client %s, interval %ums",
1289 VRF_LOGNAME(vrf), zvrf_id(zvrf), ifindex,
1290 enable ? "enable" : "disable",
1291 zebra_route_string(client->proto), ra_interval);
1292 }
1293
1294 /* Locate interface and check VRF match. */
1295 ifp = if_lookup_by_index(ifindex, zvrf->vrf->vrf_id);
1296 if (!ifp) {
1297 struct vrf *vrf = zvrf->vrf;
1298
1299 flog_warn(EC_ZEBRA_UNKNOWN_INTERFACE,
1300 "%s:%u: IF %u RA %s client %s - interface unknown",
1301 VRF_LOGNAME(vrf), zvrf_id(zvrf), ifindex,
1302 enable ? "enable" : "disable",
1303 zebra_route_string(client->proto));
1304 return;
1305 }
1306 if (vrf_is_backend_netns() && ifp->vrf->vrf_id != zvrf_id(zvrf)) {
1307 zlog_debug(
1308 "%s:%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
1309 ifp->vrf->name, zvrf_id(zvrf), ifindex,
1310 enable ? "enable" : "disable",
1311 zebra_route_string(client->proto), ifp->vrf->vrf_id);
1312 return;
1313 }
1314
1315 zif = ifp->info;
1316 if (enable) {
1317 if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
1318 interfaces_configured_for_ra_from_bgp++;
1319
1320 SET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
1321 ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
1322 if (ra_interval
1323 && (ra_interval * 1000) < (unsigned int) zif->rtadv.MaxRtrAdvInterval
1324 && !CHECK_FLAG(zif->rtadv.ra_configured,
1325 VTY_RA_INTERVAL_CONFIGURED))
1326 zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
1327 } else {
1328 if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
1329 interfaces_configured_for_ra_from_bgp--;
1330
1331 UNSET_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED);
1332 if (!CHECK_FLAG(zif->rtadv.ra_configured,
1333 VTY_RA_INTERVAL_CONFIGURED))
1334 zif->rtadv.MaxRtrAdvInterval =
1335 RTADV_MAX_RTR_ADV_INTERVAL;
1336 if (!CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED))
1337 ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
1338 }
1339 stream_failure:
1340 return;
1341 }
1342
1343 /*
1344 * send router lifetime value of zero in RAs on this interface since we're
1345 * ceasing to advertise and want to let our neighbors know.
1346 * RFC 4861 secion 6.2.5
1347 */
1348 void rtadv_stop_ra(struct interface *ifp)
1349 {
1350 struct zebra_if *zif;
1351 struct zebra_vrf *zvrf;
1352
1353 zif = ifp->info;
1354 zvrf = rtadv_interface_get_zvrf(ifp);
1355
1356 if (zif->rtadv.AdvSendAdvertisements)
1357 rtadv_send_packet(zvrf->rtadv.sock, ifp, RA_SUPPRESS);
1358 }
1359
1360 /*
1361 * Send router lifetime value of zero in RAs on all interfaces since we're
1362 * ceasing to advertise globally and want to let all of our neighbors know
1363 * RFC 4861 secion 6.2.5
1364 *
1365 * Delete all ipv6 global prefixes added to the router advertisement prefix
1366 * lists prior to ceasing.
1367 */
1368 void rtadv_stop_ra_all(void)
1369 {
1370 struct vrf *vrf;
1371 struct interface *ifp;
1372 struct zebra_if *zif;
1373 struct rtadv_prefix *rprefix;
1374
1375 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name)
1376 FOR_ALL_INTERFACES (vrf, ifp) {
1377 zif = ifp->info;
1378
1379 frr_each_safe (rtadv_prefixes, zif->rtadv.prefixes,
1380 rprefix)
1381 rtadv_prefix_reset(zif, rprefix);
1382
1383 rtadv_stop_ra(ifp);
1384 }
1385 }
1386
1387 void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS)
1388 {
1389 zebra_interface_radv_set(client, hdr, msg, zvrf, 0);
1390 }
1391 void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS)
1392 {
1393 zebra_interface_radv_set(client, hdr, msg, zvrf, 1);
1394 }
1395
1396 static void show_zvrf_rtadv_adv_if_helper(struct vty *vty,
1397 struct adv_if_list_head *adv_if_head)
1398 {
1399 struct adv_if *node = NULL;
1400
1401 if (!adv_if_is_empty_internal(adv_if_head)) {
1402 frr_each (adv_if_list, adv_if_head, node) {
1403 vty_out(vty, " %s\n", node->name);
1404 }
1405 }
1406
1407 vty_out(vty, "\n");
1408 }
1409
1410 static void show_zvrf_rtadv_helper(struct vty *vty, struct zebra_vrf *zvrf)
1411 {
1412 vty_out(vty, "VRF: %s\n", zvrf_name(zvrf));
1413 vty_out(vty, " Interfaces:\n");
1414 show_zvrf_rtadv_adv_if_helper(vty, &zvrf->rtadv.adv_if);
1415
1416 vty_out(vty, " Interfaces(msec):\n");
1417 show_zvrf_rtadv_adv_if_helper(vty, &zvrf->rtadv.adv_msec_if);
1418 }
1419
1420 DEFPY(show_ipv6_nd_ra_if, show_ipv6_nd_ra_if_cmd,
1421 "show ipv6 nd ra-interfaces [vrf<NAME$vrf_name|all$vrf_all>]",
1422 SHOW_STR IP6_STR
1423 "Neighbor discovery\n"
1424 "Route Advertisement Interfaces\n" VRF_FULL_CMD_HELP_STR)
1425 {
1426 struct zebra_vrf *zvrf = NULL;
1427
1428 if (!vrf_is_backend_netns() && (vrf_name || vrf_all)) {
1429 vty_out(vty,
1430 "%% VRF subcommand only applicable for netns-based vrfs.\n");
1431 return CMD_WARNING;
1432 }
1433
1434 if (vrf_all) {
1435 struct vrf *vrf;
1436
1437 RB_FOREACH (vrf, vrf_name_head, &vrfs_by_name) {
1438 struct zebra_vrf *zvrf;
1439
1440 zvrf = vrf->info;
1441 if (!zvrf)
1442 continue;
1443
1444 show_zvrf_rtadv_helper(vty, zvrf);
1445 }
1446
1447 return CMD_SUCCESS;
1448 }
1449
1450 if (vrf_name)
1451 zvrf = zebra_vrf_lookup_by_name(vrf_name);
1452 else
1453 zvrf = zebra_vrf_lookup_by_name(VRF_DEFAULT_NAME);
1454
1455 if (!zvrf) {
1456 vty_out(vty, "%% VRF '%s' specified does not exist\n",
1457 vrf_name);
1458 return CMD_WARNING;
1459 }
1460
1461 show_zvrf_rtadv_helper(vty, zvrf);
1462
1463 return CMD_SUCCESS;
1464 }
1465
1466 DEFUN (ipv6_nd_ra_fast_retrans,
1467 ipv6_nd_ra_fast_retrans_cmd,
1468 "ipv6 nd ra-fast-retrans",
1469 "Interface IPv6 config commands\n"
1470 "Neighbor discovery\n"
1471 "Fast retransmit of RA packets\n")
1472 {
1473 VTY_DECLVAR_CONTEXT(interface, ifp);
1474 struct zebra_if *zif = ifp->info;
1475
1476 if (if_is_loopback(ifp)) {
1477 vty_out(vty,
1478 "Cannot configure IPv6 Router Advertisements on this interface\n");
1479 return CMD_WARNING_CONFIG_FAILED;
1480 }
1481
1482 zif->rtadv.UseFastRexmit = true;
1483
1484 return CMD_SUCCESS;
1485 }
1486
1487 DEFUN (no_ipv6_nd_ra_fast_retrans,
1488 no_ipv6_nd_ra_fast_retrans_cmd,
1489 "no ipv6 nd ra-fast-retrans",
1490 NO_STR
1491 "Interface IPv6 config commands\n"
1492 "Neighbor discovery\n"
1493 "Fast retransmit of RA packets\n")
1494 {
1495 VTY_DECLVAR_CONTEXT(interface, ifp);
1496 struct zebra_if *zif = ifp->info;
1497
1498 if (if_is_loopback(ifp)) {
1499 vty_out(vty,
1500 "Cannot configure IPv6 Router Advertisements on this interface\n");
1501 return CMD_WARNING_CONFIG_FAILED;
1502 }
1503
1504 zif->rtadv.UseFastRexmit = false;
1505
1506 return CMD_SUCCESS;
1507 }
1508
1509 DEFPY (ipv6_nd_ra_hop_limit,
1510 ipv6_nd_ra_hop_limit_cmd,
1511 "ipv6 nd ra-hop-limit (0-255)$hopcount",
1512 "Interface IPv6 config commands\n"
1513 "Neighbor discovery\n"
1514 "Advertisement Hop Limit\n"
1515 "Advertisement Hop Limit in hops (default:64)\n")
1516 {
1517 VTY_DECLVAR_CONTEXT(interface, ifp);
1518 struct zebra_if *zif = ifp->info;
1519
1520 if (if_is_loopback(ifp)) {
1521 vty_out(vty,
1522 "Cannot configure IPv6 Router Advertisements on this interface\n");
1523 return CMD_WARNING_CONFIG_FAILED;
1524 }
1525
1526 zif->rtadv.AdvCurHopLimit = hopcount;
1527
1528 return CMD_SUCCESS;
1529 }
1530
1531 DEFPY (no_ipv6_nd_ra_hop_limit,
1532 no_ipv6_nd_ra_hop_limit_cmd,
1533 "no ipv6 nd ra-hop-limit [(0-255)]",
1534 NO_STR
1535 "Interface IPv6 config commands\n"
1536 "Neighbor discovery\n"
1537 "Advertisement Hop Limit\n"
1538 "Advertisement Hop Limit in hops\n")
1539 {
1540 VTY_DECLVAR_CONTEXT(interface, ifp);
1541 struct zebra_if *zif = ifp->info;
1542
1543 if (if_is_loopback(ifp)) {
1544 vty_out(vty,
1545 "Cannot configure IPv6 Router Advertisements on this interface\n");
1546 return CMD_WARNING_CONFIG_FAILED;
1547 }
1548
1549 zif->rtadv.AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
1550
1551 return CMD_SUCCESS;
1552 }
1553
1554 DEFPY (ipv6_nd_ra_retrans_interval,
1555 ipv6_nd_ra_retrans_interval_cmd,
1556 "ipv6 nd ra-retrans-interval (0-4294967295)$interval",
1557 "Interface IPv6 config commands\n"
1558 "Neighbor discovery\n"
1559 "Advertisement Retransmit Interval\n"
1560 "Advertisement Retransmit Interval in msec\n")
1561 {
1562 VTY_DECLVAR_CONTEXT(interface, ifp);
1563 struct zebra_if *zif = ifp->info;
1564
1565 if (if_is_loopback(ifp)) {
1566 vty_out(vty,
1567 "Cannot configure IPv6 Router Advertisements on loopback interface\n");
1568 return CMD_WARNING_CONFIG_FAILED;
1569 }
1570
1571 zif->rtadv.AdvRetransTimer = interval;
1572
1573 return CMD_SUCCESS;
1574 }
1575
1576 DEFPY (no_ipv6_nd_ra_retrans_interval,
1577 no_ipv6_nd_ra_retrans_interval_cmd,
1578 "no ipv6 nd ra-retrans-interval [(0-4294967295)]",
1579 NO_STR
1580 "Interface IPv6 config commands\n"
1581 "Neighbor discovery\n"
1582 "Advertisement Retransmit Interval\n"
1583 "Advertisement Retransmit Interval in msec\n")
1584 {
1585 VTY_DECLVAR_CONTEXT(interface, ifp);
1586 struct zebra_if *zif = ifp->info;
1587
1588 if (if_is_loopback(ifp)) {
1589 vty_out(vty,
1590 "Cannot remove IPv6 Router Advertisements on loopback interface\n");
1591 return CMD_WARNING_CONFIG_FAILED;
1592 }
1593
1594 zif->rtadv.AdvRetransTimer = 0;
1595
1596 return CMD_SUCCESS;
1597 }
1598
1599 DEFUN (ipv6_nd_suppress_ra,
1600 ipv6_nd_suppress_ra_cmd,
1601 "ipv6 nd suppress-ra",
1602 "Interface IPv6 config commands\n"
1603 "Neighbor discovery\n"
1604 "Suppress Router Advertisement\n")
1605 {
1606 VTY_DECLVAR_CONTEXT(interface, ifp);
1607 struct zebra_if *zif = ifp->info;
1608
1609 if (if_is_loopback(ifp)) {
1610 vty_out(vty,
1611 "Cannot configure IPv6 Router Advertisements on this interface\n");
1612 return CMD_WARNING_CONFIG_FAILED;
1613 }
1614
1615 if (!CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
1616 ipv6_nd_suppress_ra_set(ifp, RA_SUPPRESS);
1617
1618 UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
1619 return CMD_SUCCESS;
1620 }
1621
1622 DEFUN (no_ipv6_nd_suppress_ra,
1623 no_ipv6_nd_suppress_ra_cmd,
1624 "no ipv6 nd suppress-ra",
1625 NO_STR
1626 "Interface IPv6 config commands\n"
1627 "Neighbor discovery\n"
1628 "Suppress Router Advertisement\n")
1629 {
1630 VTY_DECLVAR_CONTEXT(interface, ifp);
1631 struct zebra_if *zif = ifp->info;
1632
1633 if (if_is_loopback(ifp)) {
1634 vty_out(vty,
1635 "Cannot configure IPv6 Router Advertisements on this interface\n");
1636 return CMD_WARNING_CONFIG_FAILED;
1637 }
1638
1639 ipv6_nd_suppress_ra_set(ifp, RA_ENABLE);
1640 SET_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED);
1641 return CMD_SUCCESS;
1642 }
1643
1644 DEFUN (ipv6_nd_ra_interval_msec,
1645 ipv6_nd_ra_interval_msec_cmd,
1646 "ipv6 nd ra-interval msec (70-1800000)",
1647 "Interface IPv6 config commands\n"
1648 "Neighbor discovery\n"
1649 "Router Advertisement interval\n"
1650 "Router Advertisement interval in milliseconds\n"
1651 "Router Advertisement interval in milliseconds\n")
1652 {
1653 int idx_number = 4;
1654 VTY_DECLVAR_CONTEXT(interface, ifp);
1655 unsigned interval;
1656 struct zebra_if *zif = ifp->info;
1657 struct zebra_vrf *zvrf;
1658 struct adv_if *adv_if;
1659
1660 zvrf = rtadv_interface_get_zvrf(ifp);
1661
1662 interval = strtoul(argv[idx_number]->arg, NULL, 10);
1663 if ((zif->rtadv.AdvDefaultLifetime != -1
1664 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000)) {
1665 vty_out(vty,
1666 "This ra-interval would conflict with configured ra-lifetime!\n");
1667 return CMD_WARNING_CONFIG_FAILED;
1668 }
1669
1670 if (zif->rtadv.MaxRtrAdvInterval % 1000) {
1671 adv_if = adv_msec_if_del(zvrf, ifp->name);
1672 if (adv_if != NULL)
1673 adv_if_free(adv_if);
1674 }
1675
1676 if (interval % 1000)
1677 (void)adv_msec_if_add(zvrf, ifp->name);
1678
1679 SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
1680 zif->rtadv.MaxRtrAdvInterval = interval;
1681 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
1682 zif->rtadv.AdvIntervalTimer = 0;
1683
1684 return CMD_SUCCESS;
1685 }
1686
1687 DEFUN (ipv6_nd_ra_interval,
1688 ipv6_nd_ra_interval_cmd,
1689 "ipv6 nd ra-interval (1-1800)",
1690 "Interface IPv6 config commands\n"
1691 "Neighbor discovery\n"
1692 "Router Advertisement interval\n"
1693 "Router Advertisement interval in seconds\n")
1694 {
1695 int idx_number = 3;
1696 VTY_DECLVAR_CONTEXT(interface, ifp);
1697 unsigned interval;
1698 struct zebra_if *zif = ifp->info;
1699 struct zebra_vrf *zvrf;
1700 struct adv_if *adv_if;
1701
1702 zvrf = rtadv_interface_get_zvrf(ifp);
1703
1704 interval = strtoul(argv[idx_number]->arg, NULL, 10);
1705 if ((zif->rtadv.AdvDefaultLifetime != -1
1706 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime)) {
1707 vty_out(vty,
1708 "This ra-interval would conflict with configured ra-lifetime!\n");
1709 return CMD_WARNING_CONFIG_FAILED;
1710 }
1711
1712 if (zif->rtadv.MaxRtrAdvInterval % 1000) {
1713 adv_if = adv_msec_if_del(zvrf, ifp->name);
1714 if (adv_if != NULL)
1715 adv_if_free(adv_if);
1716 }
1717
1718 /* convert to milliseconds */
1719 interval = interval * 1000;
1720
1721 SET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
1722 zif->rtadv.MaxRtrAdvInterval = interval;
1723 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
1724 zif->rtadv.AdvIntervalTimer = 0;
1725
1726 return CMD_SUCCESS;
1727 }
1728
1729 DEFUN (no_ipv6_nd_ra_interval,
1730 no_ipv6_nd_ra_interval_cmd,
1731 "no ipv6 nd ra-interval [<(1-1800)|msec (1-1800000)>]",
1732 NO_STR
1733 "Interface IPv6 config commands\n"
1734 "Neighbor discovery\n"
1735 "Router Advertisement interval\n"
1736 "Router Advertisement interval in seconds\n"
1737 "Specify millisecond router advertisement interval\n"
1738 "Router Advertisement interval in milliseconds\n")
1739 {
1740 VTY_DECLVAR_CONTEXT(interface, ifp);
1741 struct zebra_if *zif = ifp->info;
1742 struct zebra_vrf *zvrf = NULL;
1743 struct adv_if *adv_if;
1744
1745 zvrf = rtadv_interface_get_zvrf(ifp);
1746
1747 if (zif->rtadv.MaxRtrAdvInterval % 1000) {
1748 adv_if = adv_msec_if_del(zvrf, ifp->name);
1749 if (adv_if != NULL)
1750 adv_if_free(adv_if);
1751 }
1752
1753 UNSET_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED);
1754
1755 if (CHECK_FLAG(zif->rtadv.ra_configured, BGP_RA_CONFIGURED))
1756 zif->rtadv.MaxRtrAdvInterval = 10000;
1757 else
1758 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
1759
1760 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
1761 zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
1762
1763 return CMD_SUCCESS;
1764 }
1765
1766 DEFUN (ipv6_nd_ra_lifetime,
1767 ipv6_nd_ra_lifetime_cmd,
1768 "ipv6 nd ra-lifetime (0-9000)",
1769 "Interface IPv6 config commands\n"
1770 "Neighbor discovery\n"
1771 "Router lifetime\n"
1772 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1773 {
1774 int idx_number = 3;
1775 VTY_DECLVAR_CONTEXT(interface, ifp);
1776 struct zebra_if *zif = ifp->info;
1777 int lifetime;
1778
1779 lifetime = strtoul(argv[idx_number]->arg, NULL, 10);
1780
1781 /* The value to be placed in the Router Lifetime field
1782 * of Router Advertisements sent from the interface,
1783 * in seconds. MUST be either zero or between
1784 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
1785 if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval)) {
1786 vty_out(vty,
1787 "This ra-lifetime would conflict with configured ra-interval\n");
1788 return CMD_WARNING_CONFIG_FAILED;
1789 }
1790
1791 zif->rtadv.AdvDefaultLifetime = lifetime;
1792
1793 return CMD_SUCCESS;
1794 }
1795
1796 DEFUN (no_ipv6_nd_ra_lifetime,
1797 no_ipv6_nd_ra_lifetime_cmd,
1798 "no ipv6 nd ra-lifetime [(0-9000)]",
1799 NO_STR
1800 "Interface IPv6 config commands\n"
1801 "Neighbor discovery\n"
1802 "Router lifetime\n"
1803 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1804 {
1805 VTY_DECLVAR_CONTEXT(interface, ifp);
1806 struct zebra_if *zif = ifp->info;
1807
1808 zif->rtadv.AdvDefaultLifetime = -1;
1809
1810 return CMD_SUCCESS;
1811 }
1812
1813 DEFUN (ipv6_nd_reachable_time,
1814 ipv6_nd_reachable_time_cmd,
1815 "ipv6 nd reachable-time (1-3600000)",
1816 "Interface IPv6 config commands\n"
1817 "Neighbor discovery\n"
1818 "Reachable time\n"
1819 "Reachable time in milliseconds\n")
1820 {
1821 int idx_number = 3;
1822 VTY_DECLVAR_CONTEXT(interface, ifp);
1823 struct zebra_if *zif = ifp->info;
1824 zif->rtadv.AdvReachableTime = strtoul(argv[idx_number]->arg, NULL, 10);
1825 return CMD_SUCCESS;
1826 }
1827
1828 DEFUN (no_ipv6_nd_reachable_time,
1829 no_ipv6_nd_reachable_time_cmd,
1830 "no ipv6 nd reachable-time [(1-3600000)]",
1831 NO_STR
1832 "Interface IPv6 config commands\n"
1833 "Neighbor discovery\n"
1834 "Reachable time\n"
1835 "Reachable time in milliseconds\n")
1836 {
1837 VTY_DECLVAR_CONTEXT(interface, ifp);
1838 struct zebra_if *zif = ifp->info;
1839
1840 zif->rtadv.AdvReachableTime = 0;
1841
1842 return CMD_SUCCESS;
1843 }
1844
1845 DEFUN (ipv6_nd_homeagent_preference,
1846 ipv6_nd_homeagent_preference_cmd,
1847 "ipv6 nd home-agent-preference (0-65535)",
1848 "Interface IPv6 config commands\n"
1849 "Neighbor discovery\n"
1850 "Home Agent preference\n"
1851 "preference value (default is 0, least preferred)\n")
1852 {
1853 int idx_number = 3;
1854 VTY_DECLVAR_CONTEXT(interface, ifp);
1855 struct zebra_if *zif = ifp->info;
1856 zif->rtadv.HomeAgentPreference =
1857 strtoul(argv[idx_number]->arg, NULL, 10);
1858 return CMD_SUCCESS;
1859 }
1860
1861 DEFUN (no_ipv6_nd_homeagent_preference,
1862 no_ipv6_nd_homeagent_preference_cmd,
1863 "no ipv6 nd home-agent-preference [(0-65535)]",
1864 NO_STR
1865 "Interface IPv6 config commands\n"
1866 "Neighbor discovery\n"
1867 "Home Agent preference\n"
1868 "preference value (default is 0, least preferred)\n")
1869 {
1870 VTY_DECLVAR_CONTEXT(interface, ifp);
1871 struct zebra_if *zif = ifp->info;
1872
1873 zif->rtadv.HomeAgentPreference = 0;
1874
1875 return CMD_SUCCESS;
1876 }
1877
1878 DEFUN (ipv6_nd_homeagent_lifetime,
1879 ipv6_nd_homeagent_lifetime_cmd,
1880 "ipv6 nd home-agent-lifetime (0-65520)",
1881 "Interface IPv6 config commands\n"
1882 "Neighbor discovery\n"
1883 "Home Agent lifetime\n"
1884 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1885 {
1886 int idx_number = 3;
1887 VTY_DECLVAR_CONTEXT(interface, ifp);
1888 struct zebra_if *zif = ifp->info;
1889 zif->rtadv.HomeAgentLifetime = strtoul(argv[idx_number]->arg, NULL, 10);
1890 return CMD_SUCCESS;
1891 }
1892
1893 DEFUN (no_ipv6_nd_homeagent_lifetime,
1894 no_ipv6_nd_homeagent_lifetime_cmd,
1895 "no ipv6 nd home-agent-lifetime [(0-65520)]",
1896 NO_STR
1897 "Interface IPv6 config commands\n"
1898 "Neighbor discovery\n"
1899 "Home Agent lifetime\n"
1900 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1901 {
1902 VTY_DECLVAR_CONTEXT(interface, ifp);
1903 struct zebra_if *zif = ifp->info;
1904
1905 zif->rtadv.HomeAgentLifetime = -1;
1906
1907 return CMD_SUCCESS;
1908 }
1909
1910 DEFUN (ipv6_nd_managed_config_flag,
1911 ipv6_nd_managed_config_flag_cmd,
1912 "ipv6 nd managed-config-flag",
1913 "Interface IPv6 config commands\n"
1914 "Neighbor discovery\n"
1915 "Managed address configuration flag\n")
1916 {
1917 VTY_DECLVAR_CONTEXT(interface, ifp);
1918 struct zebra_if *zif = ifp->info;
1919
1920 zif->rtadv.AdvManagedFlag = 1;
1921
1922 return CMD_SUCCESS;
1923 }
1924
1925 DEFUN (no_ipv6_nd_managed_config_flag,
1926 no_ipv6_nd_managed_config_flag_cmd,
1927 "no ipv6 nd managed-config-flag",
1928 NO_STR
1929 "Interface IPv6 config commands\n"
1930 "Neighbor discovery\n"
1931 "Managed address configuration flag\n")
1932 {
1933 VTY_DECLVAR_CONTEXT(interface, ifp);
1934 struct zebra_if *zif = ifp->info;
1935
1936 zif->rtadv.AdvManagedFlag = 0;
1937
1938 return CMD_SUCCESS;
1939 }
1940
1941 DEFUN (ipv6_nd_homeagent_config_flag,
1942 ipv6_nd_homeagent_config_flag_cmd,
1943 "ipv6 nd home-agent-config-flag",
1944 "Interface IPv6 config commands\n"
1945 "Neighbor discovery\n"
1946 "Home Agent configuration flag\n")
1947 {
1948 VTY_DECLVAR_CONTEXT(interface, ifp);
1949 struct zebra_if *zif = ifp->info;
1950
1951 zif->rtadv.AdvHomeAgentFlag = 1;
1952
1953 return CMD_SUCCESS;
1954 }
1955
1956 DEFUN (no_ipv6_nd_homeagent_config_flag,
1957 no_ipv6_nd_homeagent_config_flag_cmd,
1958 "no ipv6 nd home-agent-config-flag",
1959 NO_STR
1960 "Interface IPv6 config commands\n"
1961 "Neighbor discovery\n"
1962 "Home Agent configuration flag\n")
1963 {
1964 VTY_DECLVAR_CONTEXT(interface, ifp);
1965 struct zebra_if *zif = ifp->info;
1966
1967 zif->rtadv.AdvHomeAgentFlag = 0;
1968
1969 return CMD_SUCCESS;
1970 }
1971
1972 DEFUN (ipv6_nd_adv_interval_config_option,
1973 ipv6_nd_adv_interval_config_option_cmd,
1974 "ipv6 nd adv-interval-option",
1975 "Interface IPv6 config commands\n"
1976 "Neighbor discovery\n"
1977 "Advertisement Interval Option\n")
1978 {
1979 VTY_DECLVAR_CONTEXT(interface, ifp);
1980 struct zebra_if *zif = ifp->info;
1981
1982 zif->rtadv.AdvIntervalOption = 1;
1983
1984 return CMD_SUCCESS;
1985 }
1986
1987 DEFUN (no_ipv6_nd_adv_interval_config_option,
1988 no_ipv6_nd_adv_interval_config_option_cmd,
1989 "no ipv6 nd adv-interval-option",
1990 NO_STR
1991 "Interface IPv6 config commands\n"
1992 "Neighbor discovery\n"
1993 "Advertisement Interval Option\n")
1994 {
1995 VTY_DECLVAR_CONTEXT(interface, ifp);
1996 struct zebra_if *zif = ifp->info;
1997
1998 zif->rtadv.AdvIntervalOption = 0;
1999
2000 return CMD_SUCCESS;
2001 }
2002
2003 DEFUN (ipv6_nd_other_config_flag,
2004 ipv6_nd_other_config_flag_cmd,
2005 "ipv6 nd other-config-flag",
2006 "Interface IPv6 config commands\n"
2007 "Neighbor discovery\n"
2008 "Other statefull configuration flag\n")
2009 {
2010 VTY_DECLVAR_CONTEXT(interface, ifp);
2011 struct zebra_if *zif = ifp->info;
2012
2013 zif->rtadv.AdvOtherConfigFlag = 1;
2014
2015 return CMD_SUCCESS;
2016 }
2017
2018 DEFUN (no_ipv6_nd_other_config_flag,
2019 no_ipv6_nd_other_config_flag_cmd,
2020 "no ipv6 nd other-config-flag",
2021 NO_STR
2022 "Interface IPv6 config commands\n"
2023 "Neighbor discovery\n"
2024 "Other statefull configuration flag\n")
2025 {
2026 VTY_DECLVAR_CONTEXT(interface, ifp);
2027 struct zebra_if *zif = ifp->info;
2028
2029 zif->rtadv.AdvOtherConfigFlag = 0;
2030
2031 return CMD_SUCCESS;
2032 }
2033
2034 DEFUN (ipv6_nd_prefix,
2035 ipv6_nd_prefix_cmd,
2036 "ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
2037 "Interface IPv6 config commands\n"
2038 "Neighbor discovery\n"
2039 "Prefix information\n"
2040 "IPv6 prefix\n"
2041 "Valid lifetime in seconds\n"
2042 "Infinite valid lifetime\n"
2043 "Preferred lifetime in seconds\n"
2044 "Infinite preferred lifetime\n"
2045 "Set Router Address flag\n"
2046 "Do not use prefix for onlink determination\n"
2047 "Do not use prefix for autoconfiguration\n"
2048 "Do not use prefix for autoconfiguration\n"
2049 "Do not use prefix for onlink determination\n")
2050 {
2051 /* prelude */
2052 char *prefix = argv[3]->arg;
2053 int lifetimes = (argc > 4) && (argv[4]->type == RANGE_TKN
2054 || strmatch(argv[4]->text, "infinite"));
2055 int routeropts = lifetimes ? argc > 6 : argc > 4;
2056
2057 int idx_routeropts = routeropts ? (lifetimes ? 6 : 4) : 0;
2058
2059 char *lifetime = NULL, *preflifetime = NULL;
2060 int routeraddr = 0, offlink = 0, noautoconf = 0;
2061 if (lifetimes) {
2062 lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg
2063 : argv[4]->text;
2064 preflifetime = argv[5]->type == RANGE_TKN ? argv[5]->arg
2065 : argv[5]->text;
2066 }
2067 if (routeropts) {
2068 routeraddr =
2069 strmatch(argv[idx_routeropts]->text, "router-address");
2070 if (!routeraddr) {
2071 offlink = (argc > idx_routeropts + 1
2072 || strmatch(argv[idx_routeropts]->text,
2073 "off-link"));
2074 noautoconf = (argc > idx_routeropts + 1
2075 || strmatch(argv[idx_routeropts]->text,
2076 "no-autoconfig"));
2077 }
2078 }
2079
2080 /* business */
2081 VTY_DECLVAR_CONTEXT(interface, ifp);
2082 struct zebra_if *zebra_if = ifp->info;
2083 int ret;
2084 struct rtadv_prefix rp;
2085
2086 ret = str2prefix_ipv6(prefix, &rp.prefix);
2087 if (!ret) {
2088 vty_out(vty, "Malformed IPv6 prefix\n");
2089 return CMD_WARNING_CONFIG_FAILED;
2090 }
2091 apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */
2092 rp.AdvOnLinkFlag = !offlink;
2093 rp.AdvAutonomousFlag = !noautoconf;
2094 rp.AdvRouterAddressFlag = routeraddr;
2095 rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
2096 rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
2097 rp.AdvPrefixCreate = PREFIX_SRC_MANUAL;
2098
2099 if (lifetimes) {
2100 rp.AdvValidLifetime = strmatch(lifetime, "infinite")
2101 ? UINT32_MAX
2102 : strtoll(lifetime, NULL, 10);
2103 rp.AdvPreferredLifetime =
2104 strmatch(preflifetime, "infinite")
2105 ? UINT32_MAX
2106 : strtoll(preflifetime, NULL, 10);
2107 if (rp.AdvPreferredLifetime > rp.AdvValidLifetime) {
2108 vty_out(vty, "Invalid preferred lifetime\n");
2109 return CMD_WARNING_CONFIG_FAILED;
2110 }
2111 }
2112
2113 rtadv_prefix_set(zebra_if, &rp);
2114
2115 return CMD_SUCCESS;
2116 }
2117
2118 DEFUN (no_ipv6_nd_prefix,
2119 no_ipv6_nd_prefix_cmd,
2120 "no ipv6 nd prefix X:X::X:X/M [<(0-4294967295)|infinite> <(0-4294967295)|infinite>] [<router-address|off-link [no-autoconfig]|no-autoconfig [off-link]>]",
2121 NO_STR
2122 "Interface IPv6 config commands\n"
2123 "Neighbor discovery\n"
2124 "Prefix information\n"
2125 "IPv6 prefix\n"
2126 "Valid lifetime in seconds\n"
2127 "Infinite valid lifetime\n"
2128 "Preferred lifetime in seconds\n"
2129 "Infinite preferred lifetime\n"
2130 "Set Router Address flag\n"
2131 "Do not use prefix for onlink determination\n"
2132 "Do not use prefix for autoconfiguration\n"
2133 "Do not use prefix for autoconfiguration\n"
2134 "Do not use prefix for onlink determination\n")
2135 {
2136 VTY_DECLVAR_CONTEXT(interface, ifp);
2137 struct zebra_if *zebra_if = ifp->info;
2138 int ret;
2139 struct rtadv_prefix rp;
2140 char *prefix = argv[4]->arg;
2141
2142 ret = str2prefix_ipv6(prefix, &rp.prefix);
2143 if (!ret) {
2144 vty_out(vty, "Malformed IPv6 prefix\n");
2145 return CMD_WARNING_CONFIG_FAILED;
2146 }
2147 apply_mask_ipv6(&rp.prefix); /* RFC4861 4.6.2 */
2148 rp.AdvPrefixCreate = PREFIX_SRC_MANUAL;
2149
2150 ret = rtadv_prefix_reset(zebra_if, &rp);
2151 if (!ret) {
2152 vty_out(vty, "Non-existant IPv6 prefix\n");
2153 return CMD_WARNING_CONFIG_FAILED;
2154 }
2155
2156 return CMD_SUCCESS;
2157 }
2158
2159 DEFUN (ipv6_nd_router_preference,
2160 ipv6_nd_router_preference_cmd,
2161 "ipv6 nd router-preference <high|medium|low>",
2162 "Interface IPv6 config commands\n"
2163 "Neighbor discovery\n"
2164 "Default router preference\n"
2165 "High default router preference\n"
2166 "Medium default router preference (default)\n"
2167 "Low default router preference\n")
2168 {
2169 int idx_high_medium_low = 3;
2170 VTY_DECLVAR_CONTEXT(interface, ifp);
2171 struct zebra_if *zif = ifp->info;
2172 int i = 0;
2173
2174 while (0 != rtadv_pref_strs[i]) {
2175 if (strncmp(argv[idx_high_medium_low]->arg, rtadv_pref_strs[i],
2176 1)
2177 == 0) {
2178 zif->rtadv.DefaultPreference = i;
2179 return CMD_SUCCESS;
2180 }
2181 i++;
2182 }
2183
2184 return CMD_ERR_NO_MATCH;
2185 }
2186
2187 DEFUN (no_ipv6_nd_router_preference,
2188 no_ipv6_nd_router_preference_cmd,
2189 "no ipv6 nd router-preference [<high|medium|low>]",
2190 NO_STR
2191 "Interface IPv6 config commands\n"
2192 "Neighbor discovery\n"
2193 "Default router preference\n"
2194 "High default router preference\n"
2195 "Medium default router preference (default)\n"
2196 "Low default router preference\n")
2197 {
2198 VTY_DECLVAR_CONTEXT(interface, ifp);
2199 struct zebra_if *zif = ifp->info;
2200
2201 zif->rtadv.DefaultPreference =
2202 RTADV_PREF_MEDIUM; /* Default per RFC4191. */
2203
2204 return CMD_SUCCESS;
2205 }
2206
2207 DEFUN (ipv6_nd_mtu,
2208 ipv6_nd_mtu_cmd,
2209 "ipv6 nd mtu (1-65535)",
2210 "Interface IPv6 config commands\n"
2211 "Neighbor discovery\n"
2212 "Advertised MTU\n"
2213 "MTU in bytes\n")
2214 {
2215 int idx_number = 3;
2216 VTY_DECLVAR_CONTEXT(interface, ifp);
2217 struct zebra_if *zif = ifp->info;
2218 zif->rtadv.AdvLinkMTU = strtoul(argv[idx_number]->arg, NULL, 10);
2219 return CMD_SUCCESS;
2220 }
2221
2222 DEFUN (no_ipv6_nd_mtu,
2223 no_ipv6_nd_mtu_cmd,
2224 "no ipv6 nd mtu [(1-65535)]",
2225 NO_STR
2226 "Interface IPv6 config commands\n"
2227 "Neighbor discovery\n"
2228 "Advertised MTU\n"
2229 "MTU in bytes\n")
2230 {
2231 VTY_DECLVAR_CONTEXT(interface, ifp);
2232 struct zebra_if *zif = ifp->info;
2233 zif->rtadv.AdvLinkMTU = 0;
2234 return CMD_SUCCESS;
2235 }
2236
2237 static struct rtadv_rdnss *rtadv_rdnss_new(void)
2238 {
2239 return XCALLOC(MTYPE_RTADV_RDNSS, sizeof(struct rtadv_rdnss));
2240 }
2241
2242 static void rtadv_rdnss_free(struct rtadv_rdnss *rdnss)
2243 {
2244 XFREE(MTYPE_RTADV_RDNSS, rdnss);
2245 }
2246
2247 static struct rtadv_rdnss *rtadv_rdnss_lookup(struct list *list,
2248 struct rtadv_rdnss *rdnss)
2249 {
2250 struct listnode *node;
2251 struct rtadv_rdnss *p;
2252
2253 for (ALL_LIST_ELEMENTS_RO(list, node, p))
2254 if (IPV6_ADDR_SAME(&p->addr, &rdnss->addr))
2255 return p;
2256 return NULL;
2257 }
2258
2259 static struct rtadv_rdnss *rtadv_rdnss_get(struct list *list,
2260 struct rtadv_rdnss *rdnss)
2261 {
2262 struct rtadv_rdnss *p;
2263
2264 p = rtadv_rdnss_lookup(list, rdnss);
2265 if (p)
2266 return p;
2267
2268 p = rtadv_rdnss_new();
2269 memcpy(p, rdnss, sizeof(struct rtadv_rdnss));
2270 listnode_add(list, p);
2271
2272 return p;
2273 }
2274
2275 static void rtadv_rdnss_set(struct zebra_if *zif, struct rtadv_rdnss *rdnss)
2276 {
2277 struct rtadv_rdnss *p;
2278
2279 p = rtadv_rdnss_get(zif->rtadv.AdvRDNSSList, rdnss);
2280 p->lifetime = rdnss->lifetime;
2281 p->lifetime_set = rdnss->lifetime_set;
2282 }
2283
2284 static int rtadv_rdnss_reset(struct zebra_if *zif, struct rtadv_rdnss *rdnss)
2285 {
2286 struct rtadv_rdnss *p;
2287
2288 p = rtadv_rdnss_lookup(zif->rtadv.AdvRDNSSList, rdnss);
2289 if (p) {
2290 listnode_delete(zif->rtadv.AdvRDNSSList, p);
2291 rtadv_rdnss_free(p);
2292 return 1;
2293 }
2294
2295 return 0;
2296 }
2297
2298 static struct rtadv_dnssl *rtadv_dnssl_new(void)
2299 {
2300 return XCALLOC(MTYPE_RTADV_DNSSL, sizeof(struct rtadv_dnssl));
2301 }
2302
2303 static void rtadv_dnssl_free(struct rtadv_dnssl *dnssl)
2304 {
2305 XFREE(MTYPE_RTADV_DNSSL, dnssl);
2306 }
2307
2308 static struct rtadv_dnssl *rtadv_dnssl_lookup(struct list *list,
2309 struct rtadv_dnssl *dnssl)
2310 {
2311 struct listnode *node;
2312 struct rtadv_dnssl *p;
2313
2314 for (ALL_LIST_ELEMENTS_RO(list, node, p))
2315 if (!strcasecmp(p->name, dnssl->name))
2316 return p;
2317 return NULL;
2318 }
2319
2320 static struct rtadv_dnssl *rtadv_dnssl_get(struct list *list,
2321 struct rtadv_dnssl *dnssl)
2322 {
2323 struct rtadv_dnssl *p;
2324
2325 p = rtadv_dnssl_lookup(list, dnssl);
2326 if (p)
2327 return p;
2328
2329 p = rtadv_dnssl_new();
2330 memcpy(p, dnssl, sizeof(struct rtadv_dnssl));
2331 listnode_add(list, p);
2332
2333 return p;
2334 }
2335
2336 static void rtadv_dnssl_set(struct zebra_if *zif, struct rtadv_dnssl *dnssl)
2337 {
2338 struct rtadv_dnssl *p;
2339
2340 p = rtadv_dnssl_get(zif->rtadv.AdvDNSSLList, dnssl);
2341 memcpy(p, dnssl, sizeof(struct rtadv_dnssl));
2342 }
2343
2344 static int rtadv_dnssl_reset(struct zebra_if *zif, struct rtadv_dnssl *dnssl)
2345 {
2346 struct rtadv_dnssl *p;
2347
2348 p = rtadv_dnssl_lookup(zif->rtadv.AdvDNSSLList, dnssl);
2349 if (p) {
2350 listnode_delete(zif->rtadv.AdvDNSSLList, p);
2351 rtadv_dnssl_free(p);
2352 return 1;
2353 }
2354
2355 return 0;
2356 }
2357
2358 /*
2359 * Convert dotted domain name (with or without trailing root zone dot) to
2360 * sequence of length-prefixed labels, as described in [RFC1035 3.1]. Write up
2361 * to strlen(in) + 2 octets to out.
2362 *
2363 * Returns the number of octets written to out or -1 if in does not constitute
2364 * a valid domain name.
2365 */
2366 static int rtadv_dnssl_encode(uint8_t *out, const char *in)
2367 {
2368 const char *label_start, *label_end;
2369 size_t outp;
2370
2371 outp = 0;
2372 label_start = in;
2373
2374 while (*label_start) {
2375 size_t label_len;
2376
2377 label_end = strchr(label_start, '.');
2378 if (label_end == NULL)
2379 label_end = label_start + strlen(label_start);
2380
2381 label_len = label_end - label_start;
2382 if (label_len >= 64)
2383 return -1; /* labels must be 63 octets or less */
2384
2385 out[outp++] = (uint8_t)label_len;
2386 memcpy(out + outp, label_start, label_len);
2387 outp += label_len;
2388 label_start += label_len;
2389 if (*label_start == '.')
2390 label_start++;
2391 }
2392
2393 out[outp++] = '\0';
2394 return outp;
2395 }
2396
2397 DEFUN(ipv6_nd_rdnss,
2398 ipv6_nd_rdnss_cmd,
2399 "ipv6 nd rdnss X:X::X:X [<(0-4294967295)|infinite>]",
2400 "Interface IPv6 config commands\n"
2401 "Neighbor discovery\n"
2402 "Recursive DNS server information\n"
2403 "IPv6 address\n"
2404 "Valid lifetime in seconds\n"
2405 "Infinite valid lifetime\n")
2406 {
2407 VTY_DECLVAR_CONTEXT(interface, ifp);
2408 struct zebra_if *zif = ifp->info;
2409 struct rtadv_rdnss rdnss = {};
2410
2411 if (inet_pton(AF_INET6, argv[3]->arg, &rdnss.addr) != 1) {
2412 vty_out(vty, "Malformed IPv6 address\n");
2413 return CMD_WARNING_CONFIG_FAILED;
2414 }
2415 if (argc > 4) {
2416 char *lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg
2417 : argv[4]->text;
2418 rdnss.lifetime = strmatch(lifetime, "infinite")
2419 ? UINT32_MAX
2420 : strtoll(lifetime, NULL, 10);
2421 rdnss.lifetime_set = 1;
2422 }
2423
2424 rtadv_rdnss_set(zif, &rdnss);
2425
2426 return CMD_SUCCESS;
2427 }
2428
2429 DEFUN(no_ipv6_nd_rdnss,
2430 no_ipv6_nd_rdnss_cmd,
2431 "no ipv6 nd rdnss X:X::X:X [<(0-4294967295)|infinite>]",
2432 NO_STR
2433 "Interface IPv6 config commands\n"
2434 "Neighbor discovery\n"
2435 "Recursive DNS server information\n"
2436 "IPv6 address\n"
2437 "Valid lifetime in seconds\n"
2438 "Infinite valid lifetime\n")
2439 {
2440 VTY_DECLVAR_CONTEXT(interface, ifp);
2441 struct zebra_if *zif = ifp->info;
2442 struct rtadv_rdnss rdnss = {};
2443
2444 if (inet_pton(AF_INET6, argv[4]->arg, &rdnss.addr) != 1) {
2445 vty_out(vty, "Malformed IPv6 address\n");
2446 return CMD_WARNING_CONFIG_FAILED;
2447 }
2448 if (rtadv_rdnss_reset(zif, &rdnss) != 1) {
2449 vty_out(vty, "Non-existant RDNSS address\n");
2450 return CMD_WARNING_CONFIG_FAILED;
2451 }
2452
2453 return CMD_SUCCESS;
2454 }
2455
2456 DEFUN(ipv6_nd_dnssl,
2457 ipv6_nd_dnssl_cmd,
2458 "ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]",
2459 "Interface IPv6 config commands\n"
2460 "Neighbor discovery\n"
2461 "DNS search list information\n"
2462 "Domain name suffix\n"
2463 "Valid lifetime in seconds\n"
2464 "Infinite valid lifetime\n")
2465 {
2466 VTY_DECLVAR_CONTEXT(interface, ifp);
2467 struct zebra_if *zif = ifp->info;
2468 struct rtadv_dnssl dnssl = {};
2469 size_t len;
2470 int ret;
2471
2472 len = strlcpy(dnssl.name, argv[3]->arg, sizeof(dnssl.name));
2473 if (len == 0 || len >= sizeof(dnssl.name)) {
2474 vty_out(vty, "Malformed DNS search domain\n");
2475 return CMD_WARNING_CONFIG_FAILED;
2476 }
2477 if (dnssl.name[len - 1] == '.') {
2478 /*
2479 * Allow, but don't require, a trailing dot signifying the root
2480 * zone. Canonicalize by cutting it off if present.
2481 */
2482 dnssl.name[len - 1] = '\0';
2483 len--;
2484 }
2485 if (argc > 4) {
2486 char *lifetime = argv[4]->type == RANGE_TKN ? argv[4]->arg
2487 : argv[4]->text;
2488 dnssl.lifetime = strmatch(lifetime, "infinite")
2489 ? UINT32_MAX
2490 : strtoll(lifetime, NULL, 10);
2491 dnssl.lifetime_set = 1;
2492 }
2493
2494 ret = rtadv_dnssl_encode(dnssl.encoded_name, dnssl.name);
2495 if (ret < 0) {
2496 vty_out(vty, "Malformed DNS search domain\n");
2497 return CMD_WARNING_CONFIG_FAILED;
2498 }
2499 dnssl.encoded_len = ret;
2500 rtadv_dnssl_set(zif, &dnssl);
2501
2502 return CMD_SUCCESS;
2503 }
2504
2505 DEFUN(no_ipv6_nd_dnssl,
2506 no_ipv6_nd_dnssl_cmd,
2507 "no ipv6 nd dnssl SUFFIX [<(0-4294967295)|infinite>]",
2508 NO_STR
2509 "Interface IPv6 config commands\n"
2510 "Neighbor discovery\n"
2511 "DNS search list information\n"
2512 "Domain name suffix\n"
2513 "Valid lifetime in seconds\n"
2514 "Infinite valid lifetime\n")
2515 {
2516 VTY_DECLVAR_CONTEXT(interface, ifp);
2517 struct zebra_if *zif = ifp->info;
2518 struct rtadv_dnssl dnssl = {};
2519 size_t len;
2520
2521 len = strlcpy(dnssl.name, argv[4]->arg, sizeof(dnssl.name));
2522 if (len == 0 || len >= sizeof(dnssl.name)) {
2523 vty_out(vty, "Malformed DNS search domain\n");
2524 return CMD_WARNING_CONFIG_FAILED;
2525 }
2526 if (dnssl.name[len - 1] == '.') {
2527 dnssl.name[len - 1] = '\0';
2528 len--;
2529 }
2530 if (rtadv_dnssl_reset(zif, &dnssl) != 1) {
2531 vty_out(vty, "Non-existant DNS search domain\n");
2532 return CMD_WARNING_CONFIG_FAILED;
2533 }
2534
2535 return CMD_SUCCESS;
2536 }
2537
2538
2539 /* Dump interface ND information to vty. */
2540 static int nd_dump_vty(struct vty *vty, struct interface *ifp)
2541 {
2542 struct zebra_if *zif;
2543 struct rtadvconf *rtadv;
2544 int interval;
2545
2546 zif = (struct zebra_if *)ifp->info;
2547 rtadv = &zif->rtadv;
2548
2549 if (rtadv->AdvSendAdvertisements) {
2550 vty_out(vty,
2551 " ND advertised reachable time is %d milliseconds\n",
2552 rtadv->AdvReachableTime);
2553 vty_out(vty,
2554 " ND advertised retransmit interval is %u milliseconds\n",
2555 rtadv->AdvRetransTimer);
2556 vty_out(vty, " ND advertised hop-count limit is %d hops\n",
2557 rtadv->AdvCurHopLimit);
2558 vty_out(vty, " ND router advertisements sent: %d rcvd: %d\n",
2559 zif->ra_sent, zif->ra_rcvd);
2560 interval = rtadv->MaxRtrAdvInterval;
2561 if (interval % 1000)
2562 vty_out(vty,
2563 " ND router advertisements are sent every %d milliseconds\n",
2564 interval);
2565 else
2566 vty_out(vty,
2567 " ND router advertisements are sent every %d seconds\n",
2568 interval / 1000);
2569 if (!rtadv->UseFastRexmit)
2570 vty_out(vty,
2571 " ND router advertisements do not use fast retransmit\n");
2572
2573 if (rtadv->AdvDefaultLifetime != -1)
2574 vty_out(vty,
2575 " ND router advertisements live for %d seconds\n",
2576 rtadv->AdvDefaultLifetime);
2577 else
2578 vty_out(vty,
2579 " ND router advertisements lifetime tracks ra-interval\n");
2580 vty_out(vty,
2581 " ND router advertisement default router preference is %s\n",
2582 rtadv_pref_strs[rtadv->DefaultPreference]);
2583 if (rtadv->AdvManagedFlag)
2584 vty_out(vty,
2585 " Hosts use DHCP to obtain routable addresses.\n");
2586 else
2587 vty_out(vty,
2588 " Hosts use stateless autoconfig for addresses.\n");
2589 if (rtadv->AdvHomeAgentFlag) {
2590 vty_out(vty,
2591 " ND router advertisements with Home Agent flag bit set.\n");
2592 if (rtadv->HomeAgentLifetime != -1)
2593 vty_out(vty,
2594 " Home Agent lifetime is %u seconds\n",
2595 rtadv->HomeAgentLifetime);
2596 else
2597 vty_out(vty,
2598 " Home Agent lifetime tracks ra-lifetime\n");
2599 vty_out(vty, " Home Agent preference is %u\n",
2600 rtadv->HomeAgentPreference);
2601 }
2602 if (rtadv->AdvIntervalOption)
2603 vty_out(vty,
2604 " ND router advertisements with Adv. Interval option.\n");
2605 }
2606 return 0;
2607 }
2608
2609
2610 /* Write configuration about router advertisement. */
2611 static int rtadv_config_write(struct vty *vty, struct interface *ifp)
2612 {
2613 struct zebra_if *zif;
2614 struct listnode *node;
2615 struct rtadv_prefix *rprefix;
2616 struct rtadv_rdnss *rdnss;
2617 struct rtadv_dnssl *dnssl;
2618 int interval;
2619
2620 zif = ifp->info;
2621
2622 if (!if_is_loopback(ifp)) {
2623 if (zif->rtadv.AdvSendAdvertisements
2624 && CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_CONFIGURED))
2625 vty_out(vty, " no ipv6 nd suppress-ra\n");
2626 }
2627
2628 interval = zif->rtadv.MaxRtrAdvInterval;
2629 if (CHECK_FLAG(zif->rtadv.ra_configured, VTY_RA_INTERVAL_CONFIGURED)) {
2630 if (interval % 1000)
2631 vty_out(vty, " ipv6 nd ra-interval msec %d\n",
2632 interval);
2633 else if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
2634 vty_out(vty, " ipv6 nd ra-interval %d\n",
2635 interval / 1000);
2636 }
2637
2638 if (zif->rtadv.AdvIntervalOption)
2639 vty_out(vty, " ipv6 nd adv-interval-option\n");
2640
2641 if (!zif->rtadv.UseFastRexmit)
2642 vty_out(vty, " no ipv6 nd ra-fast-retrans\n");
2643
2644 if (zif->rtadv.AdvRetransTimer != 0)
2645 vty_out(vty, " ipv6 nd ra-retrans-interval %u\n",
2646 zif->rtadv.AdvRetransTimer);
2647
2648 if (zif->rtadv.AdvCurHopLimit != RTADV_DEFAULT_HOPLIMIT)
2649 vty_out(vty, " ipv6 nd ra-hop-limit %d\n",
2650 zif->rtadv.AdvCurHopLimit);
2651
2652 if (zif->rtadv.AdvDefaultLifetime != -1)
2653 vty_out(vty, " ipv6 nd ra-lifetime %d\n",
2654 zif->rtadv.AdvDefaultLifetime);
2655
2656 if (zif->rtadv.HomeAgentPreference)
2657 vty_out(vty, " ipv6 nd home-agent-preference %u\n",
2658 zif->rtadv.HomeAgentPreference);
2659
2660 if (zif->rtadv.HomeAgentLifetime != -1)
2661 vty_out(vty, " ipv6 nd home-agent-lifetime %u\n",
2662 zif->rtadv.HomeAgentLifetime);
2663
2664 if (zif->rtadv.AdvHomeAgentFlag)
2665 vty_out(vty, " ipv6 nd home-agent-config-flag\n");
2666
2667 if (zif->rtadv.AdvReachableTime)
2668 vty_out(vty, " ipv6 nd reachable-time %d\n",
2669 zif->rtadv.AdvReachableTime);
2670
2671 if (zif->rtadv.AdvManagedFlag)
2672 vty_out(vty, " ipv6 nd managed-config-flag\n");
2673
2674 if (zif->rtadv.AdvOtherConfigFlag)
2675 vty_out(vty, " ipv6 nd other-config-flag\n");
2676
2677 if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
2678 vty_out(vty, " ipv6 nd router-preference %s\n",
2679 rtadv_pref_strs[zif->rtadv.DefaultPreference]);
2680
2681 if (zif->rtadv.AdvLinkMTU)
2682 vty_out(vty, " ipv6 nd mtu %d\n", zif->rtadv.AdvLinkMTU);
2683
2684 frr_each (rtadv_prefixes, zif->rtadv.prefixes, rprefix) {
2685 if ((rprefix->AdvPrefixCreate == PREFIX_SRC_MANUAL)
2686 || (rprefix->AdvPrefixCreate == PREFIX_SRC_BOTH)) {
2687 vty_out(vty, " ipv6 nd prefix %pFX", &rprefix->prefix);
2688 if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME)
2689 || (rprefix->AdvPreferredLifetime
2690 != RTADV_PREFERRED_LIFETIME)) {
2691 if (rprefix->AdvValidLifetime == UINT32_MAX)
2692 vty_out(vty, " infinite");
2693 else
2694 vty_out(vty, " %u",
2695 rprefix->AdvValidLifetime);
2696 if (rprefix->AdvPreferredLifetime == UINT32_MAX)
2697 vty_out(vty, " infinite");
2698 else
2699 vty_out(vty, " %u",
2700 rprefix->AdvPreferredLifetime);
2701 }
2702 if (!rprefix->AdvOnLinkFlag)
2703 vty_out(vty, " off-link");
2704 if (!rprefix->AdvAutonomousFlag)
2705 vty_out(vty, " no-autoconfig");
2706 if (rprefix->AdvRouterAddressFlag)
2707 vty_out(vty, " router-address");
2708 vty_out(vty, "\n");
2709 }
2710 }
2711
2712 for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvRDNSSList, node, rdnss)) {
2713 char buf[INET6_ADDRSTRLEN];
2714
2715 vty_out(vty, " ipv6 nd rdnss %s",
2716 inet_ntop(AF_INET6, &rdnss->addr, buf, sizeof(buf)));
2717 if (rdnss->lifetime_set) {
2718 if (rdnss->lifetime == UINT32_MAX)
2719 vty_out(vty, " infinite");
2720 else
2721 vty_out(vty, " %u", rdnss->lifetime);
2722 }
2723 vty_out(vty, "\n");
2724 }
2725 for (ALL_LIST_ELEMENTS_RO(zif->rtadv.AdvDNSSLList, node, dnssl)) {
2726 vty_out(vty, " ipv6 nd dnssl %s", dnssl->name);
2727 if (dnssl->lifetime_set) {
2728 if (dnssl->lifetime == UINT32_MAX)
2729 vty_out(vty, " infinite");
2730 else
2731 vty_out(vty, " %u", dnssl->lifetime);
2732 }
2733 vty_out(vty, "\n");
2734 }
2735 return 0;
2736 }
2737
2738
2739 static void rtadv_event(struct zebra_vrf *zvrf, enum rtadv_event event, int val)
2740 {
2741 struct rtadv *rtadv;
2742
2743 if (IS_ZEBRA_DEBUG_EVENT) {
2744 struct vrf *vrf = zvrf->vrf;
2745
2746 zlog_debug("%s(%s) with event: %d and val: %d", __func__,
2747 VRF_LOGNAME(vrf), event, val);
2748 }
2749
2750 rtadv = &zvrf->rtadv;
2751
2752 switch (event) {
2753 case RTADV_START:
2754 thread_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
2755 &rtadv->ra_read);
2756 thread_add_event(zrouter.master, rtadv_timer, zvrf, 0,
2757 &rtadv->ra_timer);
2758 break;
2759 case RTADV_STOP:
2760 THREAD_OFF(rtadv->ra_timer);
2761 THREAD_OFF(rtadv->ra_read);
2762 break;
2763 case RTADV_TIMER:
2764 thread_add_timer(zrouter.master, rtadv_timer, zvrf, val,
2765 &rtadv->ra_timer);
2766 break;
2767 case RTADV_TIMER_MSEC:
2768 thread_add_timer_msec(zrouter.master, rtadv_timer, zvrf, val,
2769 &rtadv->ra_timer);
2770 break;
2771 case RTADV_READ:
2772 thread_add_read(zrouter.master, rtadv_read, zvrf, rtadv->sock,
2773 &rtadv->ra_read);
2774 break;
2775 default:
2776 break;
2777 }
2778 return;
2779 }
2780
2781 void rtadv_if_up(struct zebra_if *zif)
2782 {
2783 /* Enable fast tx of RA if enabled && RA interval is not in msecs */
2784 if (zif->rtadv.AdvSendAdvertisements &&
2785 (zif->rtadv.MaxRtrAdvInterval >= 1000) &&
2786 zif->rtadv.UseFastRexmit) {
2787 zif->rtadv.inFastRexmit = 1;
2788 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
2789 }
2790 }
2791
2792 void rtadv_if_init(struct zebra_if *zif)
2793 {
2794 /* Set default router advertise values. */
2795 struct rtadvconf *rtadv;
2796
2797 rtadv = &zif->rtadv;
2798
2799 rtadv->AdvSendAdvertisements = 0;
2800 rtadv->MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
2801 rtadv->MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
2802 rtadv->AdvIntervalTimer = 0;
2803 rtadv->AdvManagedFlag = 0;
2804 rtadv->AdvOtherConfigFlag = 0;
2805 rtadv->AdvHomeAgentFlag = 0;
2806 rtadv->AdvLinkMTU = 0;
2807 rtadv->AdvReachableTime = 0;
2808 rtadv->AdvRetransTimer = 0;
2809 rtadv->AdvCurHopLimit = RTADV_DEFAULT_HOPLIMIT;
2810 memset(&rtadv->lastadvcurhoplimit, 0,
2811 sizeof(rtadv->lastadvcurhoplimit));
2812 memset(&rtadv->lastadvmanagedflag, 0,
2813 sizeof(rtadv->lastadvmanagedflag));
2814 memset(&rtadv->lastadvotherconfigflag, 0,
2815 sizeof(rtadv->lastadvotherconfigflag));
2816 memset(&rtadv->lastadvreachabletime, 0,
2817 sizeof(rtadv->lastadvreachabletime));
2818 memset(&rtadv->lastadvretranstimer, 0,
2819 sizeof(rtadv->lastadvretranstimer));
2820 rtadv->AdvDefaultLifetime = -1; /* derive from MaxRtrAdvInterval */
2821 rtadv->HomeAgentPreference = 0;
2822 rtadv->HomeAgentLifetime = -1; /* derive from AdvDefaultLifetime */
2823 rtadv->AdvIntervalOption = 0;
2824 rtadv->UseFastRexmit = true;
2825 rtadv->DefaultPreference = RTADV_PREF_MEDIUM;
2826
2827 rtadv_prefixes_init(rtadv->prefixes);
2828
2829 rtadv->AdvRDNSSList = list_new();
2830 rtadv->AdvDNSSLList = list_new();
2831 }
2832
2833 void rtadv_if_fini(struct zebra_if *zif)
2834 {
2835 struct rtadvconf *rtadv;
2836 struct rtadv_prefix *rp;
2837
2838 rtadv = &zif->rtadv;
2839
2840 while ((rp = rtadv_prefixes_pop(rtadv->prefixes)))
2841 rtadv_prefix_free(rp);
2842
2843 list_delete(&rtadv->AdvRDNSSList);
2844 list_delete(&rtadv->AdvDNSSLList);
2845 }
2846
2847 void rtadv_vrf_init(struct zebra_vrf *zvrf)
2848 {
2849 if (!vrf_is_backend_netns() && (zvrf_id(zvrf) != VRF_DEFAULT))
2850 return;
2851
2852 zvrf->rtadv.sock = rtadv_make_socket(zvrf->zns->ns_id);
2853 }
2854
2855 void rtadv_vrf_terminate(struct zebra_vrf *zvrf)
2856 {
2857 if (!vrf_is_backend_netns() && (zvrf_id(zvrf) != VRF_DEFAULT))
2858 return;
2859
2860 rtadv_event(zvrf, RTADV_STOP, 0);
2861 if (zvrf->rtadv.sock >= 0) {
2862 close(zvrf->rtadv.sock);
2863 zvrf->rtadv.sock = -1;
2864 }
2865
2866 adv_if_clean(zvrf);
2867 adv_msec_if_clean(zvrf);
2868 }
2869
2870 void rtadv_cmd_init(void)
2871 {
2872 interfaces_configured_for_ra_from_bgp = 0;
2873
2874 hook_register(zebra_if_extra_info, nd_dump_vty);
2875 hook_register(zebra_if_config_wr, rtadv_config_write);
2876
2877 install_element(VIEW_NODE, &show_ipv6_nd_ra_if_cmd);
2878
2879 install_element(INTERFACE_NODE, &ipv6_nd_ra_fast_retrans_cmd);
2880 install_element(INTERFACE_NODE, &no_ipv6_nd_ra_fast_retrans_cmd);
2881 install_element(INTERFACE_NODE, &ipv6_nd_ra_retrans_interval_cmd);
2882 install_element(INTERFACE_NODE, &no_ipv6_nd_ra_retrans_interval_cmd);
2883 install_element(INTERFACE_NODE, &ipv6_nd_ra_hop_limit_cmd);
2884 install_element(INTERFACE_NODE, &no_ipv6_nd_ra_hop_limit_cmd);
2885 install_element(INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
2886 install_element(INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
2887 install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
2888 install_element(INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
2889 install_element(INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
2890 install_element(INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
2891 install_element(INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
2892 install_element(INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
2893 install_element(INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
2894 install_element(INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
2895 install_element(INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
2896 install_element(INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
2897 install_element(INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
2898 install_element(INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
2899 install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
2900 install_element(INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
2901 install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
2902 install_element(INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
2903 install_element(INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
2904 install_element(INTERFACE_NODE,
2905 &ipv6_nd_adv_interval_config_option_cmd);
2906 install_element(INTERFACE_NODE,
2907 &no_ipv6_nd_adv_interval_config_option_cmd);
2908 install_element(INTERFACE_NODE, &ipv6_nd_prefix_cmd);
2909 install_element(INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
2910 install_element(INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
2911 install_element(INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
2912 install_element(INTERFACE_NODE, &ipv6_nd_mtu_cmd);
2913 install_element(INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
2914 install_element(INTERFACE_NODE, &ipv6_nd_rdnss_cmd);
2915 install_element(INTERFACE_NODE, &no_ipv6_nd_rdnss_cmd);
2916 install_element(INTERFACE_NODE, &ipv6_nd_dnssl_cmd);
2917 install_element(INTERFACE_NODE, &no_ipv6_nd_dnssl_cmd);
2918 }
2919
2920 static int if_join_all_router(int sock, struct interface *ifp)
2921 {
2922 int ret;
2923
2924 struct ipv6_mreq mreq;
2925
2926 memset(&mreq, 0, sizeof(mreq));
2927 inet_pton(AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2928 mreq.ipv6mr_interface = ifp->ifindex;
2929
2930 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_JOIN_GROUP, (char *)&mreq,
2931 sizeof(mreq));
2932 if (ret < 0)
2933 flog_err_sys(EC_LIB_SOCKET,
2934 "%s(%u): Failed to join group, socket %u error %s",
2935 ifp->name, ifp->ifindex, sock,
2936 safe_strerror(errno));
2937
2938 if (IS_ZEBRA_DEBUG_EVENT)
2939 zlog_debug(
2940 "%s(%s:%u): Join All-Routers multicast group, socket %u",
2941 ifp->name, ifp->vrf->name, ifp->ifindex, sock);
2942
2943 return 0;
2944 }
2945
2946 static int if_leave_all_router(int sock, struct interface *ifp)
2947 {
2948 int ret;
2949
2950 struct ipv6_mreq mreq;
2951
2952 memset(&mreq, 0, sizeof(mreq));
2953 inet_pton(AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2954 mreq.ipv6mr_interface = ifp->ifindex;
2955
2956 ret = setsockopt(sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP, (char *)&mreq,
2957 sizeof(mreq));
2958 if (ret < 0)
2959 flog_err_sys(
2960 EC_LIB_SOCKET,
2961 "%s(%s:%u): Failed to leave group, socket %u error %s",
2962 ifp->name, ifp->vrf->name, ifp->ifindex, sock,
2963 safe_strerror(errno));
2964
2965 if (IS_ZEBRA_DEBUG_EVENT)
2966 zlog_debug(
2967 "%s(%s:%u): Leave All-Routers multicast group, socket %u",
2968 ifp->name, ifp->vrf->name, ifp->ifindex, sock);
2969
2970 return 0;
2971 }
2972
2973 bool rtadv_compiled_in(void)
2974 {
2975 return true;
2976 }
2977
2978 #else /* !HAVE_RTADV */
2979 /*
2980 * If the end user does not have RADV enabled we should
2981 * handle this better
2982 */
2983 void zebra_interface_radv_disable(ZAPI_HANDLER_ARGS)
2984 {
2985 if (IS_ZEBRA_DEBUG_PACKET)
2986 zlog_debug(
2987 "Received %s command, but ZEBRA is not compiled with Router Advertisements on",
2988 zserv_command_string(hdr->command));
2989
2990 return;
2991 }
2992
2993 void zebra_interface_radv_enable(ZAPI_HANDLER_ARGS)
2994 {
2995 if (IS_ZEBRA_DEBUG_PACKET)
2996 zlog_debug(
2997 "Received %s command, but ZEBRA is not compiled with Router Advertisements on",
2998 zserv_command_string(hdr->command));
2999
3000 return;
3001 }
3002
3003 bool rtadv_compiled_in(void)
3004 {
3005 return false;
3006 }
3007
3008 #endif /* HAVE_RTADV */
3009
3010 uint32_t rtadv_get_interfaces_configured_from_bgp(void)
3011 {
3012 return interfaces_configured_for_ra_from_bgp;
3013 }