]> git.proxmox.com Git - mirror_frr.git/blob - zebra/rtadv.c
Zebra: Cleanup registered nexthops upon client exit
[mirror_frr.git] / zebra / rtadv.c
1 /* Router advertisement
2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
3 * Copyright (C) 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, 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 "log.h"
30 #include "prefix.h"
31 #include "linklist.h"
32 #include "command.h"
33 #include "privs.h"
34 #include "vrf.h"
35
36 #include "zebra/interface.h"
37 #include "zebra/rtadv.h"
38 #include "zebra/debug.h"
39 #include "zebra/rib.h"
40 #include "zebra/zserv.h"
41
42 extern struct zebra_privs_t zserv_privs;
43
44 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
45
46 #ifdef OPEN_BSD
47 #include <netinet/icmp6.h>
48 #endif
49
50 /* If RFC2133 definition is used. */
51 #ifndef IPV6_JOIN_GROUP
52 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
53 #endif
54 #ifndef IPV6_LEAVE_GROUP
55 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
56 #endif
57
58 #define ALLNODE "ff02::1"
59 #define ALLROUTER "ff02::2"
60
61 extern struct zebra_t zebrad;
62
63 enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
64 RTADV_TIMER_MSEC, RTADV_READ};
65
66 static void rtadv_event (struct zebra_ns *, enum rtadv_event, int);
67
68 static int if_join_all_router (int, struct interface *);
69 static int if_leave_all_router (int, struct interface *);
70
71 static int
72 rtadv_recv_packet (int sock, u_char *buf, int buflen,
73 struct sockaddr_in6 *from, unsigned int *ifindex,
74 int *hoplimit)
75 {
76 int ret;
77 struct msghdr msg;
78 struct iovec iov;
79 struct cmsghdr *cmsgptr;
80 struct in6_addr dst;
81
82 char adata[1024];
83
84 /* Fill in message and iovec. */
85 msg.msg_name = (void *) from;
86 msg.msg_namelen = sizeof (struct sockaddr_in6);
87 msg.msg_iov = &iov;
88 msg.msg_iovlen = 1;
89 msg.msg_control = (void *) adata;
90 msg.msg_controllen = sizeof adata;
91 iov.iov_base = buf;
92 iov.iov_len = buflen;
93
94 /* If recvmsg fail return minus value. */
95 ret = recvmsg (sock, &msg, 0);
96 if (ret < 0)
97 return ret;
98
99 for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
100 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
101 {
102 /* I want interface index which this packet comes from. */
103 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
104 cmsgptr->cmsg_type == IPV6_PKTINFO)
105 {
106 struct in6_pktinfo *ptr;
107
108 ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
109 *ifindex = ptr->ipi6_ifindex;
110 memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
111 }
112
113 /* Incoming packet's hop limit. */
114 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
115 cmsgptr->cmsg_type == IPV6_HOPLIMIT)
116 {
117 int *hoptr = (int *) CMSG_DATA (cmsgptr);
118 *hoplimit = *hoptr;
119 }
120 }
121 return ret;
122 }
123
124 #define RTADV_MSG_SIZE 4096
125
126 /* Send router advertisement packet. */
127 static void
128 rtadv_send_packet (int sock, struct interface *ifp)
129 {
130 struct msghdr msg;
131 struct iovec iov;
132 struct cmsghdr *cmsgptr;
133 struct in6_pktinfo *pkt;
134 struct sockaddr_in6 addr;
135 #ifdef HAVE_STRUCT_SOCKADDR_DL
136 struct sockaddr_dl *sdl;
137 #endif /* HAVE_STRUCT_SOCKADDR_DL */
138 static void *adata = NULL;
139 unsigned char buf[RTADV_MSG_SIZE];
140 struct nd_router_advert *rtadv;
141 int ret;
142 int len = 0;
143 struct zebra_if *zif;
144 struct rtadv_prefix *rprefix;
145 u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
146 struct listnode *node;
147 u_int16_t pkt_RouterLifetime;
148
149 /*
150 * Allocate control message bufffer. This is dynamic because
151 * CMSG_SPACE is not guaranteed not to call a function. Note that
152 * the size will be different on different architectures due to
153 * differing alignment rules.
154 */
155 if (adata == NULL)
156 {
157 /* XXX Free on shutdown. */
158 adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
159
160 if (adata == NULL)
161 zlog_err("rtadv_send_packet: can't malloc control data");
162 }
163
164 /* Logging of packet. */
165 if (IS_ZEBRA_DEBUG_PACKET)
166 zlog_debug ("%s(%u): Tx RA, socket %u",
167 ifp->name, ifp->ifindex, sock);
168
169 /* Fill in sockaddr_in6. */
170 memset (&addr, 0, sizeof (struct sockaddr_in6));
171 addr.sin6_family = AF_INET6;
172 #ifdef SIN6_LEN
173 addr.sin6_len = sizeof (struct sockaddr_in6);
174 #endif /* SIN6_LEN */
175 addr.sin6_port = htons (IPPROTO_ICMPV6);
176 IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
177
178 /* Fetch interface information. */
179 zif = ifp->info;
180
181 /* Make router advertisement message. */
182 rtadv = (struct nd_router_advert *) buf;
183
184 rtadv->nd_ra_type = ND_ROUTER_ADVERT;
185 rtadv->nd_ra_code = 0;
186 rtadv->nd_ra_cksum = 0;
187
188 rtadv->nd_ra_curhoplimit = 64;
189
190 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
191 rtadv->nd_ra_flags_reserved =
192 zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
193 rtadv->nd_ra_flags_reserved <<= 3;
194
195 if (zif->rtadv.AdvManagedFlag)
196 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
197 if (zif->rtadv.AdvOtherConfigFlag)
198 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
199 if (zif->rtadv.AdvHomeAgentFlag)
200 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
201 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
202 * AdvDefaultLifetime is by default based on the value of
203 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
204 * field of Router Advertisements. Given that this field is expressed
205 * in seconds, a small MaxRtrAdvInterval value can result in a zero
206 * value for this field. To prevent this, routers SHOULD keep
207 * AdvDefaultLifetime in at least one second, even if the use of
208 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
209 pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ?
210 zif->rtadv.AdvDefaultLifetime :
211 MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
212 rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime);
213 rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
214 rtadv->nd_ra_retransmit = htonl (0);
215
216 len = sizeof (struct nd_router_advert);
217
218 /* If both the Home Agent Preference and Home Agent Lifetime are set to
219 * their default values specified above, this option SHOULD NOT be
220 * included in the Router Advertisement messages sent by this home
221 * agent. -- RFC6275, 7.4 */
222 if
223 (
224 zif->rtadv.AdvHomeAgentFlag &&
225 (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
226 )
227 {
228 struct nd_opt_homeagent_info *ndopt_hai =
229 (struct nd_opt_homeagent_info *)(buf + len);
230 ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
231 ndopt_hai->nd_opt_hai_len = 1;
232 ndopt_hai->nd_opt_hai_reserved = 0;
233 ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
234 /* 16-bit unsigned integer. The lifetime associated with the home
235 * agent in units of seconds. The default value is the same as the
236 * Router Lifetime, as specified in the main body of the Router
237 * Advertisement. The maximum value corresponds to 18.2 hours. A
238 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
239 ndopt_hai->nd_opt_hai_lifetime = htons
240 (
241 zif->rtadv.HomeAgentLifetime != -1 ?
242 zif->rtadv.HomeAgentLifetime :
243 MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
244 );
245 len += sizeof(struct nd_opt_homeagent_info);
246 }
247
248 if (zif->rtadv.AdvIntervalOption)
249 {
250 struct nd_opt_adv_interval *ndopt_adv =
251 (struct nd_opt_adv_interval *)(buf + len);
252 ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
253 ndopt_adv->nd_opt_ai_len = 1;
254 ndopt_adv->nd_opt_ai_reserved = 0;
255 ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
256 len += sizeof(struct nd_opt_adv_interval);
257 }
258
259 /* Fill in prefix. */
260 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
261 {
262 struct nd_opt_prefix_info *pinfo;
263
264 pinfo = (struct nd_opt_prefix_info *) (buf + len);
265
266 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
267 pinfo->nd_opt_pi_len = 4;
268 pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
269
270 pinfo->nd_opt_pi_flags_reserved = 0;
271 if (rprefix->AdvOnLinkFlag)
272 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
273 if (rprefix->AdvAutonomousFlag)
274 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
275 if (rprefix->AdvRouterAddressFlag)
276 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
277
278 pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
279 pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
280 pinfo->nd_opt_pi_reserved2 = 0;
281
282 IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
283
284 #ifdef DEBUG
285 {
286 u_char buf[INET6_ADDRSTRLEN];
287
288 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
289 buf, INET6_ADDRSTRLEN));
290
291 }
292 #endif /* DEBUG */
293
294 len += sizeof (struct nd_opt_prefix_info);
295 }
296
297 /* Hardware address. */
298 #ifdef HAVE_STRUCT_SOCKADDR_DL
299 sdl = &ifp->sdl;
300 if (sdl != NULL && sdl->sdl_alen != 0)
301 {
302 buf[len++] = ND_OPT_SOURCE_LINKADDR;
303
304 /* Option length should be rounded up to next octet if
305 the link address does not end on an octet boundary. */
306 buf[len++] = (sdl->sdl_alen + 9) >> 3;
307
308 memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
309 len += sdl->sdl_alen;
310
311 /* Pad option to end on an octet boundary. */
312 memset (buf + len, 0, -(sdl->sdl_alen + 2) & 0x7);
313 len += -(sdl->sdl_alen + 2) & 0x7;
314 }
315 #else
316 if (ifp->hw_addr_len != 0)
317 {
318 buf[len++] = ND_OPT_SOURCE_LINKADDR;
319
320 /* Option length should be rounded up to next octet if
321 the link address does not end on an octet boundary. */
322 buf[len++] = (ifp->hw_addr_len + 9) >> 3;
323
324 memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
325 len += ifp->hw_addr_len;
326
327 /* Pad option to end on an octet boundary. */
328 memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
329 len += -(ifp->hw_addr_len + 2) & 0x7;
330 }
331 #endif /* HAVE_STRUCT_SOCKADDR_DL */
332
333 /* MTU */
334 if (zif->rtadv.AdvLinkMTU)
335 {
336 struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
337 opt->nd_opt_mtu_type = ND_OPT_MTU;
338 opt->nd_opt_mtu_len = 1;
339 opt->nd_opt_mtu_reserved = 0;
340 opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
341 len += sizeof (struct nd_opt_mtu);
342 }
343
344 msg.msg_name = (void *) &addr;
345 msg.msg_namelen = sizeof (struct sockaddr_in6);
346 msg.msg_iov = &iov;
347 msg.msg_iovlen = 1;
348 msg.msg_control = (void *) adata;
349 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
350 msg.msg_flags = 0;
351 iov.iov_base = buf;
352 iov.iov_len = len;
353
354 cmsgptr = ZCMSG_FIRSTHDR(&msg);
355 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
356 cmsgptr->cmsg_level = IPPROTO_IPV6;
357 cmsgptr->cmsg_type = IPV6_PKTINFO;
358
359 pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
360 memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
361 pkt->ipi6_ifindex = ifp->ifindex;
362
363 ret = sendmsg (sock, &msg, 0);
364 if (ret < 0)
365 {
366 zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
367 ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno));
368 }
369 }
370
371 static int
372 rtadv_timer (struct thread *thread)
373 {
374 struct zebra_ns *zns = THREAD_ARG (thread);
375 vrf_iter_t iter;
376 struct listnode *node, *nnode;
377 struct interface *ifp;
378 struct zebra_if *zif;
379 int period;
380
381 zns->rtadv.ra_timer = NULL;
382 if (zns->rtadv.adv_msec_if_count == 0)
383 {
384 period = 1000; /* 1 s */
385 rtadv_event (zns, RTADV_TIMER, 1 /* 1 s */);
386 }
387 else
388 {
389 period = 10; /* 10 ms */
390 rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
391 }
392
393 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
394 for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
395 {
396 if (if_is_loopback (ifp) || ! if_is_operative (ifp))
397 continue;
398
399 zif = ifp->info;
400
401 if (zif->rtadv.AdvSendAdvertisements)
402 {
403 zif->rtadv.AdvIntervalTimer -= period;
404 if (zif->rtadv.AdvIntervalTimer <= 0)
405 {
406 /* FIXME: using MaxRtrAdvInterval each time isn't what section
407 6.2.4 of RFC4861 tells to do. */
408 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
409 rtadv_send_packet (zns->rtadv.sock, ifp);
410 }
411 }
412 }
413
414 return 0;
415 }
416
417 static void
418 rtadv_process_solicit (struct interface *ifp)
419 {
420 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
421 struct zebra_ns *zns = zvrf->zns;
422
423 assert (zns);
424 rtadv_send_packet (zns->rtadv.sock, ifp);
425 }
426
427 static void
428 rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
429 struct sockaddr_in6 *addr)
430 {
431 struct nd_router_advert *radvert;
432 char addr_str[INET6_ADDRSTRLEN];
433 struct zebra_if *zif;
434
435 zif = ifp->info;
436
437 inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
438
439 if (len < sizeof(struct nd_router_advert)) {
440 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
441 ifp->name, ifp->ifindex, len, addr_str);
442 return;
443 }
444 if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
445 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
446 ifp->name, ifp->ifindex, addr_str);
447 return;
448 }
449
450 radvert = (struct nd_router_advert *) msg;
451
452 if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
453 (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit))
454 {
455 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
456 ifp->name, ifp->ifindex, addr_str);
457 }
458
459 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
460 !zif->rtadv.AdvManagedFlag)
461 {
462 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
463 ifp->name, ifp->ifindex, addr_str);
464 }
465
466 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
467 !zif->rtadv.AdvOtherConfigFlag)
468 {
469 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
470 ifp->name, ifp->ifindex, addr_str);
471 }
472
473 if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
474 (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime))
475 {
476 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
477 ifp->name, ifp->ifindex, addr_str);
478 }
479
480 if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
481 (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer))
482 {
483 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
484 ifp->name, ifp->ifindex, addr_str);
485 }
486
487 /* Currently supporting only P2P links, so any new RA source address is
488 considered as the replacement of the previously learnt Link-Local address.
489 As per the RFC, lifetime zero is to be considered a delete */
490 if (ntohs(radvert->nd_ra_router_lifetime))
491 nbr_connected_replacement_add_ipv6(ifp, &addr->sin6_addr, 128);
492 else
493 nbr_connected_delete_ipv6(ifp, &addr->sin6_addr, 128);
494
495 return;
496 }
497
498
499 static void
500 rtadv_process_packet (u_char *buf, unsigned int len, unsigned int ifindex, int hoplimit,
501 struct sockaddr_in6 *from, struct zebra_ns *zns)
502 {
503 struct icmp6_hdr *icmph;
504 struct interface *ifp;
505 struct zebra_if *zif;
506 char addr_str[INET6_ADDRSTRLEN];
507
508 inet_ntop (AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
509
510 /* Interface search. */
511 ifp = if_lookup_by_index_per_ns (zns, ifindex);
512 if (ifp == NULL)
513 {
514 zlog_warn ("RA/RS received on unknown IF %u from %s",
515 ifindex, addr_str);
516 return;
517 }
518
519 if (IS_ZEBRA_DEBUG_PACKET)
520 zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
521 ifp->name, ifp->ifindex, len, addr_str);
522
523 if (if_is_loopback (ifp))
524 return;
525
526 /* Check interface configuration. */
527 zif = ifp->info;
528 if (! zif->rtadv.AdvSendAdvertisements)
529 return;
530
531 /* ICMP message length check. */
532 if (len < sizeof (struct icmp6_hdr))
533 {
534 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
535 ifp->name, ifp->ifindex, len);
536 return;
537 }
538
539 icmph = (struct icmp6_hdr *) buf;
540
541 /* ICMP message type check. */
542 if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
543 icmph->icmp6_type != ND_ROUTER_ADVERT)
544 {
545 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
546 ifp->name, ifp->ifindex, icmph->icmp6_type);
547 return;
548 }
549
550 /* Hoplimit check. */
551 if (hoplimit >= 0 && hoplimit != 255)
552 {
553 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
554 ifp->name, ifp->ifindex, hoplimit);
555 return;
556 }
557
558 /* Check ICMP message type. */
559 if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
560 rtadv_process_solicit (ifp);
561 else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
562 rtadv_process_advert (buf, len, ifp, from);
563
564 return;
565 }
566
567 static int
568 rtadv_read (struct thread *thread)
569 {
570 int sock;
571 int len;
572 u_char buf[RTADV_MSG_SIZE];
573 struct sockaddr_in6 from;
574 unsigned int ifindex = 0;
575 int hoplimit = -1;
576 struct zebra_ns *zns = THREAD_ARG (thread);
577
578 sock = THREAD_FD (thread);
579 zns->rtadv.ra_read = NULL;
580
581 /* Register myself. */
582 rtadv_event (zns, RTADV_READ, sock);
583
584 len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
585
586 if (len < 0)
587 {
588 zlog_warn ("RA/RS recv failed, socket %u error %s",
589 sock, safe_strerror (errno));
590 return len;
591 }
592
593 rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zns);
594
595 return 0;
596 }
597
598 static int
599 rtadv_make_socket (void)
600 {
601 int sock;
602 int ret = 0;
603 struct icmp6_filter filter;
604
605 if ( zserv_privs.change (ZPRIVS_RAISE) )
606 zlog_err ("rtadv_make_socket: could not raise privs, %s",
607 safe_strerror (errno) );
608
609 sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
610
611 if ( zserv_privs.change (ZPRIVS_LOWER) )
612 zlog_err ("rtadv_make_socket: could not lower privs, %s",
613 safe_strerror (errno) );
614
615 if (sock < 0)
616 return -1;
617
618 ret = setsockopt_ipv6_pktinfo (sock, 1);
619 if (ret < 0)
620 return ret;
621 ret = setsockopt_ipv6_multicast_loop (sock, 0);
622 if (ret < 0)
623 return ret;
624 ret = setsockopt_ipv6_unicast_hops (sock, 255);
625 if (ret < 0)
626 return ret;
627 ret = setsockopt_ipv6_multicast_hops (sock, 255);
628 if (ret < 0)
629 return ret;
630 ret = setsockopt_ipv6_hoplimit (sock, 1);
631 if (ret < 0)
632 return ret;
633
634 ICMP6_FILTER_SETBLOCKALL(&filter);
635 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
636 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
637
638 ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
639 sizeof (struct icmp6_filter));
640 if (ret < 0)
641 {
642 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
643 return ret;
644 }
645
646 return sock;
647 }
648
649 static struct rtadv_prefix *
650 rtadv_prefix_new (void)
651 {
652 return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
653 }
654
655 static void
656 rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
657 {
658 XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
659 }
660
661 static struct rtadv_prefix *
662 rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
663 {
664 struct listnode *node;
665 struct rtadv_prefix *rprefix;
666
667 for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
668 if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
669 return rprefix;
670 return NULL;
671 }
672
673 static struct rtadv_prefix *
674 rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
675 {
676 struct rtadv_prefix *rprefix;
677
678 rprefix = rtadv_prefix_lookup (rplist, p);
679 if (rprefix)
680 return rprefix;
681
682 rprefix = rtadv_prefix_new ();
683 memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
684 listnode_add (rplist, rprefix);
685
686 return rprefix;
687 }
688
689 static void
690 rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
691 {
692 struct rtadv_prefix *rprefix;
693
694 rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
695
696 /* Set parameters. */
697 rprefix->AdvValidLifetime = rp->AdvValidLifetime;
698 rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
699 rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
700 rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
701 rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
702 }
703
704 static int
705 rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
706 {
707 struct rtadv_prefix *rprefix;
708
709 rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
710 if (rprefix != NULL)
711 {
712 listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
713 rtadv_prefix_free (rprefix);
714 return 1;
715 }
716 else
717 return 0;
718 }
719
720 void
721 ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
722 {
723 struct zebra_if *zif;
724 struct zebra_vrf *zvrf;
725 struct zebra_ns *zns;
726
727 zif = ifp->info;
728 zvrf = vrf_info_lookup (ifp->vrf_id);
729 zns = zvrf->zns;
730
731 if (status == RA_SUPPRESS)
732 {
733 /* RA is currently enabled */
734 if (zif->rtadv.AdvSendAdvertisements)
735 {
736 zif->rtadv.AdvSendAdvertisements = 0;
737 zif->rtadv.AdvIntervalTimer = 0;
738 zns->rtadv.adv_if_count--;
739
740 if_leave_all_router (zns->rtadv.sock, ifp);
741
742 if (zns->rtadv.adv_if_count == 0)
743 rtadv_event (zns, RTADV_STOP, 0);
744 }
745 }
746 else
747 {
748 if (! zif->rtadv.AdvSendAdvertisements)
749 {
750 zif->rtadv.AdvSendAdvertisements = 1;
751 zif->rtadv.AdvIntervalTimer = 0;
752 zns->rtadv.adv_if_count++;
753
754 if_join_all_router (zns->rtadv.sock, ifp);
755
756 if (zns->rtadv.adv_if_count == 1)
757 rtadv_event (zns, RTADV_START, zns->rtadv.sock);
758 }
759 }
760 }
761
762 DEFUN (ipv6_nd_suppress_ra,
763 ipv6_nd_suppress_ra_cmd,
764 "ipv6 nd suppress-ra",
765 "Interface IPv6 config commands\n"
766 "Neighbor discovery\n"
767 "Suppress Router Advertisement\n")
768 {
769 struct interface *ifp;
770
771 ifp = vty->index;
772
773 if (if_is_loopback (ifp))
774 {
775 vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
776 return CMD_WARNING;
777 }
778
779 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
780 return CMD_SUCCESS;
781 }
782
783 DEFUN (no_ipv6_nd_suppress_ra,
784 no_ipv6_nd_suppress_ra_cmd,
785 "no ipv6 nd suppress-ra",
786 NO_STR
787 "Interface IPv6 config commands\n"
788 "Neighbor discovery\n"
789 "Suppress Router Advertisement\n")
790 {
791 struct interface *ifp;
792
793 ifp = vty->index;
794
795 if (if_is_loopback (ifp))
796 {
797 vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
798 return CMD_WARNING;
799 }
800
801 ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
802 return CMD_SUCCESS;
803 }
804
805 DEFUN (ipv6_nd_ra_interval_msec,
806 ipv6_nd_ra_interval_msec_cmd,
807 "ipv6 nd ra-interval msec <70-1800000>",
808 "Interface IPv6 config commands\n"
809 "Neighbor discovery\n"
810 "Router Advertisement interval\n"
811 "Router Advertisement interval in milliseconds\n")
812 {
813 unsigned interval;
814 struct interface *ifp = (struct interface *) vty->index;
815 struct zebra_if *zif = ifp->info;
816 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
817 struct zebra_ns *zns;
818
819 zns = zvrf->zns;
820 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
821 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
822 {
823 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
824 return CMD_WARNING;
825 }
826
827 if (zif->rtadv.MaxRtrAdvInterval % 1000)
828 zns->rtadv.adv_msec_if_count--;
829
830 if (interval % 1000)
831 zns->rtadv.adv_msec_if_count++;
832
833 zif->rtadv.MaxRtrAdvInterval = interval;
834 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
835 zif->rtadv.AdvIntervalTimer = 0;
836
837 return CMD_SUCCESS;
838 }
839
840 DEFUN (ipv6_nd_ra_interval,
841 ipv6_nd_ra_interval_cmd,
842 "ipv6 nd ra-interval <1-1800>",
843 "Interface IPv6 config commands\n"
844 "Neighbor discovery\n"
845 "Router Advertisement interval\n"
846 "Router Advertisement interval in seconds\n")
847 {
848 unsigned interval;
849 struct interface *ifp = (struct interface *) vty->index;
850 struct zebra_if *zif = ifp->info;
851 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
852 struct zebra_ns *zns;
853
854 zns = zvrf->zns;
855 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
856 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
857 {
858 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
859 return CMD_WARNING;
860 }
861
862 if (zif->rtadv.MaxRtrAdvInterval % 1000)
863 zns->rtadv.adv_msec_if_count--;
864
865 /* convert to milliseconds */
866 interval = interval * 1000;
867
868 zif->rtadv.MaxRtrAdvInterval = interval;
869 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
870 zif->rtadv.AdvIntervalTimer = 0;
871
872 return CMD_SUCCESS;
873 }
874
875 DEFUN (no_ipv6_nd_ra_interval,
876 no_ipv6_nd_ra_interval_cmd,
877 "no ipv6 nd ra-interval",
878 NO_STR
879 "Interface IPv6 config commands\n"
880 "Neighbor discovery\n"
881 "Router Advertisement interval\n")
882 {
883 struct interface *ifp;
884 struct zebra_if *zif;
885 struct zebra_vrf *zvrf;
886 struct zebra_ns *zns;
887
888 ifp = (struct interface *) vty->index;
889 zif = ifp->info;
890 zvrf = vrf_info_lookup (ifp->vrf_id);
891 zns = zvrf->zns;
892
893 if (zif->rtadv.MaxRtrAdvInterval % 1000)
894 zns->rtadv.adv_msec_if_count--;
895
896 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
897 zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
898 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
899
900 return CMD_SUCCESS;
901 }
902
903 ALIAS (no_ipv6_nd_ra_interval,
904 no_ipv6_nd_ra_interval_val_cmd,
905 "no ipv6 nd ra-interval <1-1800>",
906 NO_STR
907 "Interface IPv6 config commands\n"
908 "Neighbor discovery\n"
909 "Router Advertisement interval\n")
910
911 ALIAS (no_ipv6_nd_ra_interval,
912 no_ipv6_nd_ra_interval_msec_val_cmd,
913 "no ipv6 nd ra-interval msec <1-1800000>",
914 NO_STR
915 "Interface IPv6 config commands\n"
916 "Neighbor discovery\n"
917 "Router Advertisement interval\n"
918 "Router Advertisement interval in milliseconds\n")
919
920 DEFUN (ipv6_nd_ra_lifetime,
921 ipv6_nd_ra_lifetime_cmd,
922 "ipv6 nd ra-lifetime <0-9000>",
923 "Interface IPv6 config commands\n"
924 "Neighbor discovery\n"
925 "Router lifetime\n"
926 "Router lifetime in seconds (0 stands for a non-default gw)\n")
927 {
928 int lifetime;
929 struct interface *ifp;
930 struct zebra_if *zif;
931
932 ifp = (struct interface *) vty->index;
933 zif = ifp->info;
934
935 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
936
937 /* The value to be placed in the Router Lifetime field
938 * of Router Advertisements sent from the interface,
939 * in seconds. MUST be either zero or between
940 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
941 if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
942 {
943 vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
944 return CMD_WARNING;
945 }
946
947 zif->rtadv.AdvDefaultLifetime = lifetime;
948
949 return CMD_SUCCESS;
950 }
951
952 DEFUN (no_ipv6_nd_ra_lifetime,
953 no_ipv6_nd_ra_lifetime_cmd,
954 "no ipv6 nd ra-lifetime",
955 NO_STR
956 "Interface IPv6 config commands\n"
957 "Neighbor discovery\n"
958 "Router lifetime\n")
959 {
960 struct interface *ifp;
961 struct zebra_if *zif;
962
963 ifp = (struct interface *) vty->index;
964 zif = ifp->info;
965
966 zif->rtadv.AdvDefaultLifetime = -1;
967
968 return CMD_SUCCESS;
969 }
970
971 ALIAS (no_ipv6_nd_ra_lifetime,
972 no_ipv6_nd_ra_lifetime_val_cmd,
973 "no ipv6 nd ra-lifetime <0-9000>",
974 NO_STR
975 "Interface IPv6 config commands\n"
976 "Neighbor discovery\n"
977 "Router lifetime\n"
978 "Router lifetime in seconds (0 stands for a non-default gw)\n")
979
980 DEFUN (ipv6_nd_reachable_time,
981 ipv6_nd_reachable_time_cmd,
982 "ipv6 nd reachable-time <1-3600000>",
983 "Interface IPv6 config commands\n"
984 "Neighbor discovery\n"
985 "Reachable time\n"
986 "Reachable time in milliseconds\n")
987 {
988 struct interface *ifp = (struct interface *) vty->index;
989 struct zebra_if *zif = ifp->info;
990 VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
991 return CMD_SUCCESS;
992 }
993
994 DEFUN (no_ipv6_nd_reachable_time,
995 no_ipv6_nd_reachable_time_cmd,
996 "no ipv6 nd reachable-time",
997 NO_STR
998 "Interface IPv6 config commands\n"
999 "Neighbor discovery\n"
1000 "Reachable time\n")
1001 {
1002 struct interface *ifp;
1003 struct zebra_if *zif;
1004
1005 ifp = (struct interface *) vty->index;
1006 zif = ifp->info;
1007
1008 zif->rtadv.AdvReachableTime = 0;
1009
1010 return CMD_SUCCESS;
1011 }
1012
1013 ALIAS (no_ipv6_nd_reachable_time,
1014 no_ipv6_nd_reachable_time_val_cmd,
1015 "no ipv6 nd reachable-time <1-3600000>",
1016 NO_STR
1017 "Interface IPv6 config commands\n"
1018 "Neighbor discovery\n"
1019 "Reachable time\n"
1020 "Reachable time in milliseconds\n")
1021
1022 DEFUN (ipv6_nd_homeagent_preference,
1023 ipv6_nd_homeagent_preference_cmd,
1024 "ipv6 nd home-agent-preference <0-65535>",
1025 "Interface IPv6 config commands\n"
1026 "Neighbor discovery\n"
1027 "Home Agent preference\n"
1028 "preference value (default is 0, least preferred)\n")
1029 {
1030 struct interface *ifp = (struct interface *) vty->index;
1031 struct zebra_if *zif = ifp->info;
1032 VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
1033 return CMD_SUCCESS;
1034 }
1035
1036 DEFUN (no_ipv6_nd_homeagent_preference,
1037 no_ipv6_nd_homeagent_preference_cmd,
1038 "no ipv6 nd home-agent-preference",
1039 NO_STR
1040 "Interface IPv6 config commands\n"
1041 "Neighbor discovery\n"
1042 "Home Agent preference\n")
1043 {
1044 struct interface *ifp;
1045 struct zebra_if *zif;
1046
1047 ifp = (struct interface *) vty->index;
1048 zif = ifp->info;
1049
1050 zif->rtadv.HomeAgentPreference = 0;
1051
1052 return CMD_SUCCESS;
1053 }
1054
1055 ALIAS (no_ipv6_nd_homeagent_preference,
1056 no_ipv6_nd_homeagent_preference_val_cmd,
1057 "no ipv6 nd home-agent-preference <0-65535>",
1058 NO_STR
1059 "Interface IPv6 config commands\n"
1060 "Neighbor discovery\n"
1061 "Home Agent preference\n"
1062 "preference value (default is 0, least preferred)\n")
1063
1064 DEFUN (ipv6_nd_homeagent_lifetime,
1065 ipv6_nd_homeagent_lifetime_cmd,
1066 "ipv6 nd home-agent-lifetime <0-65520>",
1067 "Interface IPv6 config commands\n"
1068 "Neighbor discovery\n"
1069 "Home Agent lifetime\n"
1070 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1071 {
1072 struct interface *ifp = (struct interface *) vty->index;
1073 struct zebra_if *zif = ifp->info;
1074 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
1075 return CMD_SUCCESS;
1076 }
1077
1078 DEFUN (no_ipv6_nd_homeagent_lifetime,
1079 no_ipv6_nd_homeagent_lifetime_cmd,
1080 "no ipv6 nd home-agent-lifetime",
1081 NO_STR
1082 "Interface IPv6 config commands\n"
1083 "Neighbor discovery\n"
1084 "Home Agent lifetime\n")
1085 {
1086 struct interface *ifp;
1087 struct zebra_if *zif;
1088
1089 ifp = (struct interface *) vty->index;
1090 zif = ifp->info;
1091
1092 zif->rtadv.HomeAgentLifetime = -1;
1093
1094 return CMD_SUCCESS;
1095 }
1096
1097 ALIAS (no_ipv6_nd_homeagent_lifetime,
1098 no_ipv6_nd_homeagent_lifetime_val_cmd,
1099 "no ipv6 nd home-agent-lifetime <0-65520>",
1100 NO_STR
1101 "Interface IPv6 config commands\n"
1102 "Neighbor discovery\n"
1103 "Home Agent lifetime\n"
1104 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1105
1106 DEFUN (ipv6_nd_managed_config_flag,
1107 ipv6_nd_managed_config_flag_cmd,
1108 "ipv6 nd managed-config-flag",
1109 "Interface IPv6 config commands\n"
1110 "Neighbor discovery\n"
1111 "Managed address configuration flag\n")
1112 {
1113 struct interface *ifp;
1114 struct zebra_if *zif;
1115
1116 ifp = (struct interface *) vty->index;
1117 zif = ifp->info;
1118
1119 zif->rtadv.AdvManagedFlag = 1;
1120
1121 return CMD_SUCCESS;
1122 }
1123
1124 DEFUN (no_ipv6_nd_managed_config_flag,
1125 no_ipv6_nd_managed_config_flag_cmd,
1126 "no ipv6 nd managed-config-flag",
1127 NO_STR
1128 "Interface IPv6 config commands\n"
1129 "Neighbor discovery\n"
1130 "Managed address configuration flag\n")
1131 {
1132 struct interface *ifp;
1133 struct zebra_if *zif;
1134
1135 ifp = (struct interface *) vty->index;
1136 zif = ifp->info;
1137
1138 zif->rtadv.AdvManagedFlag = 0;
1139
1140 return CMD_SUCCESS;
1141 }
1142
1143 DEFUN (ipv6_nd_homeagent_config_flag,
1144 ipv6_nd_homeagent_config_flag_cmd,
1145 "ipv6 nd home-agent-config-flag",
1146 "Interface IPv6 config commands\n"
1147 "Neighbor discovery\n"
1148 "Home Agent configuration flag\n")
1149 {
1150 struct interface *ifp;
1151 struct zebra_if *zif;
1152
1153 ifp = (struct interface *) vty->index;
1154 zif = ifp->info;
1155
1156 zif->rtadv.AdvHomeAgentFlag = 1;
1157
1158 return CMD_SUCCESS;
1159 }
1160
1161 DEFUN (no_ipv6_nd_homeagent_config_flag,
1162 no_ipv6_nd_homeagent_config_flag_cmd,
1163 "no ipv6 nd home-agent-config-flag",
1164 NO_STR
1165 "Interface IPv6 config commands\n"
1166 "Neighbor discovery\n"
1167 "Home Agent configuration flag\n")
1168 {
1169 struct interface *ifp;
1170 struct zebra_if *zif;
1171
1172 ifp = (struct interface *) vty->index;
1173 zif = ifp->info;
1174
1175 zif->rtadv.AdvHomeAgentFlag = 0;
1176
1177 return CMD_SUCCESS;
1178 }
1179
1180 DEFUN (ipv6_nd_adv_interval_config_option,
1181 ipv6_nd_adv_interval_config_option_cmd,
1182 "ipv6 nd adv-interval-option",
1183 "Interface IPv6 config commands\n"
1184 "Neighbor discovery\n"
1185 "Advertisement Interval Option\n")
1186 {
1187 struct interface *ifp;
1188 struct zebra_if *zif;
1189
1190 ifp = (struct interface *) vty->index;
1191 zif = ifp->info;
1192
1193 zif->rtadv.AdvIntervalOption = 1;
1194
1195 return CMD_SUCCESS;
1196 }
1197
1198 DEFUN (no_ipv6_nd_adv_interval_config_option,
1199 no_ipv6_nd_adv_interval_config_option_cmd,
1200 "no ipv6 nd adv-interval-option",
1201 NO_STR
1202 "Interface IPv6 config commands\n"
1203 "Neighbor discovery\n"
1204 "Advertisement Interval Option\n")
1205 {
1206 struct interface *ifp;
1207 struct zebra_if *zif;
1208
1209 ifp = (struct interface *) vty->index;
1210 zif = ifp->info;
1211
1212 zif->rtadv.AdvIntervalOption = 0;
1213
1214 return CMD_SUCCESS;
1215 }
1216
1217 DEFUN (ipv6_nd_other_config_flag,
1218 ipv6_nd_other_config_flag_cmd,
1219 "ipv6 nd other-config-flag",
1220 "Interface IPv6 config commands\n"
1221 "Neighbor discovery\n"
1222 "Other statefull configuration flag\n")
1223 {
1224 struct interface *ifp;
1225 struct zebra_if *zif;
1226
1227 ifp = (struct interface *) vty->index;
1228 zif = ifp->info;
1229
1230 zif->rtadv.AdvOtherConfigFlag = 1;
1231
1232 return CMD_SUCCESS;
1233 }
1234
1235 DEFUN (no_ipv6_nd_other_config_flag,
1236 no_ipv6_nd_other_config_flag_cmd,
1237 "no ipv6 nd other-config-flag",
1238 NO_STR
1239 "Interface IPv6 config commands\n"
1240 "Neighbor discovery\n"
1241 "Other statefull configuration flag\n")
1242 {
1243 struct interface *ifp;
1244 struct zebra_if *zif;
1245
1246 ifp = (struct interface *) vty->index;
1247 zif = ifp->info;
1248
1249 zif->rtadv.AdvOtherConfigFlag = 0;
1250
1251 return CMD_SUCCESS;
1252 }
1253
1254 DEFUN (ipv6_nd_prefix,
1255 ipv6_nd_prefix_cmd,
1256 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1257 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1258 "Interface IPv6 config commands\n"
1259 "Neighbor discovery\n"
1260 "Prefix information\n"
1261 "IPv6 prefix\n"
1262 "Valid lifetime in seconds\n"
1263 "Infinite valid lifetime\n"
1264 "Preferred lifetime in seconds\n"
1265 "Infinite preferred lifetime\n"
1266 "Do not use prefix for onlink determination\n"
1267 "Do not use prefix for autoconfiguration\n"
1268 "Set Router Address flag\n")
1269 {
1270 int i;
1271 int ret;
1272 int cursor = 1;
1273 struct interface *ifp;
1274 struct zebra_if *zebra_if;
1275 struct rtadv_prefix rp;
1276
1277 ifp = (struct interface *) vty->index;
1278 zebra_if = ifp->info;
1279
1280 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1281 if (!ret)
1282 {
1283 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1287 rp.AdvOnLinkFlag = 1;
1288 rp.AdvAutonomousFlag = 1;
1289 rp.AdvRouterAddressFlag = 0;
1290 rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
1291 rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
1292
1293 if (argc > 1)
1294 {
1295 if ((isdigit(argv[1][0])) || strncmp (argv[1], "i", 1) == 0)
1296 {
1297 if ( strncmp (argv[1], "i", 1) == 0)
1298 rp.AdvValidLifetime = UINT32_MAX;
1299 else
1300 rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
1301 (char **)NULL, 10);
1302
1303 if ( strncmp (argv[2], "i", 1) == 0)
1304 rp.AdvPreferredLifetime = UINT32_MAX;
1305 else
1306 rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
1307 (char **)NULL, 10);
1308
1309 if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
1310 {
1311 vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
1312 return CMD_WARNING;
1313 }
1314 cursor = cursor + 2;
1315 }
1316 if (argc > cursor)
1317 {
1318 for (i = cursor; i < argc; i++)
1319 {
1320 if (strncmp (argv[i], "of", 2) == 0)
1321 rp.AdvOnLinkFlag = 0;
1322 if (strncmp (argv[i], "no", 2) == 0)
1323 rp.AdvAutonomousFlag = 0;
1324 if (strncmp (argv[i], "ro", 2) == 0)
1325 rp.AdvRouterAddressFlag = 1;
1326 }
1327 }
1328 }
1329
1330 rtadv_prefix_set (zebra_if, &rp);
1331
1332 return CMD_SUCCESS;
1333 }
1334
1335 ALIAS (ipv6_nd_prefix,
1336 ipv6_nd_prefix_val_nortaddr_cmd,
1337 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1338 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1339 "Interface IPv6 config commands\n"
1340 "Neighbor discovery\n"
1341 "Prefix information\n"
1342 "IPv6 prefix\n"
1343 "Valid lifetime in seconds\n"
1344 "Infinite valid lifetime\n"
1345 "Preferred lifetime in seconds\n"
1346 "Infinite preferred lifetime\n"
1347 "Do not use prefix for onlink determination\n"
1348 "Do not use prefix for autoconfiguration\n")
1349
1350 ALIAS (ipv6_nd_prefix,
1351 ipv6_nd_prefix_val_rev_cmd,
1352 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1353 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1354 "Interface IPv6 config commands\n"
1355 "Neighbor discovery\n"
1356 "Prefix information\n"
1357 "IPv6 prefix\n"
1358 "Valid lifetime in seconds\n"
1359 "Infinite valid lifetime\n"
1360 "Preferred lifetime in seconds\n"
1361 "Infinite preferred lifetime\n"
1362 "Do not use prefix for autoconfiguration\n"
1363 "Do not use prefix for onlink determination\n")
1364
1365 ALIAS (ipv6_nd_prefix,
1366 ipv6_nd_prefix_val_rev_rtaddr_cmd,
1367 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1368 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1369 "Interface IPv6 config commands\n"
1370 "Neighbor discovery\n"
1371 "Prefix information\n"
1372 "IPv6 prefix\n"
1373 "Valid lifetime in seconds\n"
1374 "Infinite valid lifetime\n"
1375 "Preferred lifetime in seconds\n"
1376 "Infinite preferred lifetime\n"
1377 "Do not use prefix for autoconfiguration\n"
1378 "Do not use prefix for onlink determination\n"
1379 "Set Router Address flag\n")
1380
1381 ALIAS (ipv6_nd_prefix,
1382 ipv6_nd_prefix_val_noauto_cmd,
1383 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1384 "(<0-4294967295>|infinite) (no-autoconfig|)",
1385 "Interface IPv6 config commands\n"
1386 "Neighbor discovery\n"
1387 "Prefix information\n"
1388 "IPv6 prefix\n"
1389 "Valid lifetime in seconds\n"
1390 "Infinite valid lifetime\n"
1391 "Preferred lifetime in seconds\n"
1392 "Infinite preferred lifetime\n"
1393 "Do not use prefix for autoconfiguration")
1394
1395 ALIAS (ipv6_nd_prefix,
1396 ipv6_nd_prefix_val_offlink_cmd,
1397 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1398 "(<0-4294967295>|infinite) (off-link|)",
1399 "Interface IPv6 config commands\n"
1400 "Neighbor discovery\n"
1401 "Prefix information\n"
1402 "IPv6 prefix\n"
1403 "Valid lifetime in seconds\n"
1404 "Infinite valid lifetime\n"
1405 "Preferred lifetime in seconds\n"
1406 "Infinite preferred lifetime\n"
1407 "Do not use prefix for onlink determination\n")
1408
1409 ALIAS (ipv6_nd_prefix,
1410 ipv6_nd_prefix_val_rtaddr_cmd,
1411 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1412 "(<0-4294967295>|infinite) (router-address|)",
1413 "Interface IPv6 config commands\n"
1414 "Neighbor discovery\n"
1415 "Prefix information\n"
1416 "IPv6 prefix\n"
1417 "Valid lifetime in seconds\n"
1418 "Infinite valid lifetime\n"
1419 "Preferred lifetime in seconds\n"
1420 "Infinite preferred lifetime\n"
1421 "Set Router Address flag\n")
1422
1423 ALIAS (ipv6_nd_prefix,
1424 ipv6_nd_prefix_val_cmd,
1425 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1426 "(<0-4294967295>|infinite)",
1427 "Interface IPv6 config commands\n"
1428 "Neighbor discovery\n"
1429 "Prefix information\n"
1430 "IPv6 prefix\n"
1431 "Valid lifetime in seconds\n"
1432 "Infinite valid lifetime\n"
1433 "Preferred lifetime in seconds\n"
1434 "Infinite preferred lifetime\n")
1435
1436 ALIAS (ipv6_nd_prefix,
1437 ipv6_nd_prefix_noval_cmd,
1438 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1439 "Interface IPv6 config commands\n"
1440 "Neighbor discovery\n"
1441 "Prefix information\n"
1442 "IPv6 prefix\n"
1443 "Do not use prefix for autoconfiguration\n"
1444 "Do not use prefix for onlink determination\n")
1445
1446 ALIAS (ipv6_nd_prefix,
1447 ipv6_nd_prefix_noval_rev_cmd,
1448 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1449 "Interface IPv6 config commands\n"
1450 "Neighbor discovery\n"
1451 "Prefix information\n"
1452 "IPv6 prefix\n"
1453 "Do not use prefix for onlink determination\n"
1454 "Do not use prefix for autoconfiguration\n")
1455
1456 ALIAS (ipv6_nd_prefix,
1457 ipv6_nd_prefix_noval_noauto_cmd,
1458 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1459 "Interface IPv6 config commands\n"
1460 "Neighbor discovery\n"
1461 "Prefix information\n"
1462 "IPv6 prefix\n"
1463 "Do not use prefix for autoconfiguration\n")
1464
1465 ALIAS (ipv6_nd_prefix,
1466 ipv6_nd_prefix_noval_offlink_cmd,
1467 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1468 "Interface IPv6 config commands\n"
1469 "Neighbor discovery\n"
1470 "Prefix information\n"
1471 "IPv6 prefix\n"
1472 "Do not use prefix for onlink determination\n")
1473
1474 ALIAS (ipv6_nd_prefix,
1475 ipv6_nd_prefix_noval_rtaddr_cmd,
1476 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1477 "Interface IPv6 config commands\n"
1478 "Neighbor discovery\n"
1479 "Prefix information\n"
1480 "IPv6 prefix\n"
1481 "Set Router Address flag\n")
1482
1483 ALIAS (ipv6_nd_prefix,
1484 ipv6_nd_prefix_prefix_cmd,
1485 "ipv6 nd prefix X:X::X:X/M",
1486 "Interface IPv6 config commands\n"
1487 "Neighbor discovery\n"
1488 "Prefix information\n"
1489 "IPv6 prefix\n")
1490
1491 DEFUN (no_ipv6_nd_prefix,
1492 no_ipv6_nd_prefix_cmd,
1493 "no ipv6 nd prefix IPV6PREFIX",
1494 NO_STR
1495 "Interface IPv6 config commands\n"
1496 "Neighbor discovery\n"
1497 "Prefix information\n"
1498 "IPv6 prefix\n")
1499 {
1500 int ret;
1501 struct interface *ifp;
1502 struct zebra_if *zebra_if;
1503 struct rtadv_prefix rp;
1504
1505 ifp = (struct interface *) vty->index;
1506 zebra_if = ifp->info;
1507
1508 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1509 if (!ret)
1510 {
1511 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1512 return CMD_WARNING;
1513 }
1514 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1515
1516 ret = rtadv_prefix_reset (zebra_if, &rp);
1517 if (!ret)
1518 {
1519 vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
1520 return CMD_WARNING;
1521 }
1522
1523 return CMD_SUCCESS;
1524 }
1525
1526 ALIAS (no_ipv6_nd_prefix,
1527 no_ipv6_nd_prefix_val_nortaddr_cmd,
1528 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1529 NO_STR
1530 "Interface IPv6 config commands\n"
1531 "Neighbor discovery\n"
1532 "Prefix information\n"
1533 "IPv6 prefix\n"
1534 "Valid lifetime in seconds\n"
1535 "Infinite valid lifetime\n"
1536 "Preferred lifetime in seconds\n"
1537 "Infinite preferred lifetime\n"
1538 "Do not use prefix for onlink determination\n"
1539 "Do not use prefix for autoconfiguration\n"
1540 "Set Router Address flag\n")
1541
1542 ALIAS (no_ipv6_nd_prefix,
1543 no_ipv6_nd_prefix_val_rev_cmd,
1544 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1545 NO_STR
1546 "Interface IPv6 config commands\n"
1547 "Neighbor discovery\n"
1548 "Prefix information\n"
1549 "IPv6 prefix\n"
1550 "Valid lifetime in seconds\n"
1551 "Infinite valid lifetime\n"
1552 "Preferred lifetime in seconds\n"
1553 "Infinite preferred lifetime\n"
1554 "Do not use prefix for autoconfiguration\n"
1555 "Do not use prefix for onlink determination\n")
1556
1557 ALIAS (no_ipv6_nd_prefix,
1558 no_ipv6_nd_prefix_val_rev_rtaddr_cmd,
1559 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1560 NO_STR
1561 "Interface IPv6 config commands\n"
1562 "Neighbor discovery\n"
1563 "Prefix information\n"
1564 "IPv6 prefix\n"
1565 "Valid lifetime in seconds\n"
1566 "Infinite valid lifetime\n"
1567 "Preferred lifetime in seconds\n"
1568 "Infinite preferred lifetime\n"
1569 "Do not use prefix for autoconfiguration\n"
1570 "Do not use prefix for onlink determination\n"
1571 "Set Router Address flag\n")
1572
1573 ALIAS (no_ipv6_nd_prefix,
1574 no_ipv6_nd_prefix_val_noauto_cmd,
1575 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1576 NO_STR
1577 "Interface IPv6 config commands\n"
1578 "Neighbor discovery\n"
1579 "Prefix information\n"
1580 "IPv6 prefix\n"
1581 "Valid lifetime in seconds\n"
1582 "Infinite valid lifetime\n"
1583 "Preferred lifetime in seconds\n"
1584 "Infinite preferred lifetime\n"
1585 "Do not use prefix for autoconfiguration")
1586
1587 ALIAS (no_ipv6_nd_prefix,
1588 no_ipv6_nd_prefix_val_offlink_cmd,
1589 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1590 NO_STR
1591 "Interface IPv6 config commands\n"
1592 "Neighbor discovery\n"
1593 "Prefix information\n"
1594 "IPv6 prefix\n"
1595 "Valid lifetime in seconds\n"
1596 "Infinite valid lifetime\n"
1597 "Preferred lifetime in seconds\n"
1598 "Infinite preferred lifetime\n"
1599 "Do not use prefix for onlink determination\n")
1600
1601 ALIAS (no_ipv6_nd_prefix,
1602 no_ipv6_nd_prefix_val_rtaddr_cmd,
1603 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1604 NO_STR
1605 "Interface IPv6 config commands\n"
1606 "Neighbor discovery\n"
1607 "Prefix information\n"
1608 "IPv6 prefix\n"
1609 "Valid lifetime in seconds\n"
1610 "Infinite valid lifetime\n"
1611 "Preferred lifetime in seconds\n"
1612 "Infinite preferred lifetime\n"
1613 "Set Router Address flag\n")
1614
1615 ALIAS (no_ipv6_nd_prefix,
1616 no_ipv6_nd_prefix_val_cmd,
1617 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1618 NO_STR
1619 "Interface IPv6 config commands\n"
1620 "Neighbor discovery\n"
1621 "Prefix information\n"
1622 "IPv6 prefix\n"
1623 "Valid lifetime in seconds\n"
1624 "Infinite valid lifetime\n"
1625 "Preferred lifetime in seconds\n"
1626 "Infinite preferred lifetime\n")
1627
1628 ALIAS (no_ipv6_nd_prefix,
1629 no_ipv6_nd_prefix_noval_cmd,
1630 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1631 NO_STR
1632 "Interface IPv6 config commands\n"
1633 "Neighbor discovery\n"
1634 "Prefix information\n"
1635 "IPv6 prefix\n"
1636 "Do not use prefix for autoconfiguration\n"
1637 "Do not use prefix for onlink determination\n")
1638
1639 ALIAS (no_ipv6_nd_prefix,
1640 no_ipv6_nd_prefix_noval_rev_cmd,
1641 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1642 NO_STR
1643 "Interface IPv6 config commands\n"
1644 "Neighbor discovery\n"
1645 "Prefix information\n"
1646 "IPv6 prefix\n"
1647 "Do not use prefix for onlink determination\n"
1648 "Do not use prefix for autoconfiguration\n")
1649
1650 ALIAS (no_ipv6_nd_prefix,
1651 no_ipv6_nd_prefix_noval_noauto_cmd,
1652 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1653 NO_STR
1654 "Interface IPv6 config commands\n"
1655 "Neighbor discovery\n"
1656 "Prefix information\n"
1657 "IPv6 prefix\n"
1658 "Do not use prefix for autoconfiguration\n")
1659
1660 ALIAS (no_ipv6_nd_prefix,
1661 no_ipv6_nd_prefix_noval_offlink_cmd,
1662 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1663 NO_STR
1664 "Interface IPv6 config commands\n"
1665 "Neighbor discovery\n"
1666 "Prefix information\n"
1667 "IPv6 prefix\n"
1668 "Do not use prefix for onlink determination\n")
1669
1670 ALIAS (no_ipv6_nd_prefix,
1671 no_ipv6_nd_prefix_noval_rtaddr_cmd,
1672 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1673 NO_STR
1674 "Interface IPv6 config commands\n"
1675 "Neighbor discovery\n"
1676 "Prefix information\n"
1677 "IPv6 prefix\n"
1678 "Set Router Address flag\n")
1679
1680 DEFUN (ipv6_nd_router_preference,
1681 ipv6_nd_router_preference_cmd,
1682 "ipv6 nd router-preference (high|medium|low)",
1683 "Interface IPv6 config commands\n"
1684 "Neighbor discovery\n"
1685 "Default router preference\n"
1686 "High default router preference\n"
1687 "Low default router preference\n"
1688 "Medium default router preference (default)\n")
1689 {
1690 struct interface *ifp;
1691 struct zebra_if *zif;
1692 int i = 0;
1693
1694 ifp = (struct interface *) vty->index;
1695 zif = ifp->info;
1696
1697 while (0 != rtadv_pref_strs[i])
1698 {
1699 if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
1700 {
1701 zif->rtadv.DefaultPreference = i;
1702 return CMD_SUCCESS;
1703 }
1704 i++;
1705 }
1706
1707 return CMD_ERR_NO_MATCH;
1708 }
1709
1710 DEFUN (no_ipv6_nd_router_preference,
1711 no_ipv6_nd_router_preference_cmd,
1712 "no ipv6 nd router-preference",
1713 NO_STR
1714 "Interface IPv6 config commands\n"
1715 "Neighbor discovery\n"
1716 "Default router preference\n")
1717 {
1718 struct interface *ifp;
1719 struct zebra_if *zif;
1720
1721 ifp = (struct interface *) vty->index;
1722 zif = ifp->info;
1723
1724 zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
1725
1726 return CMD_SUCCESS;
1727 }
1728
1729 ALIAS (no_ipv6_nd_router_preference,
1730 no_ipv6_nd_router_preference_val_cmd,
1731 "no ipv6 nd router-preference (high|medium|low)",
1732 NO_STR
1733 "Interface IPv6 config commands\n"
1734 "Neighbor discovery\n"
1735 "Default router preference\n"
1736 "High default router preference\n"
1737 "Low default router preference\n"
1738 "Medium default router preference (default)\n")
1739
1740 DEFUN (ipv6_nd_mtu,
1741 ipv6_nd_mtu_cmd,
1742 "ipv6 nd mtu <1-65535>",
1743 "Interface IPv6 config commands\n"
1744 "Neighbor discovery\n"
1745 "Advertised MTU\n"
1746 "MTU in bytes\n")
1747 {
1748 struct interface *ifp = (struct interface *) vty->index;
1749 struct zebra_if *zif = ifp->info;
1750 VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
1751 return CMD_SUCCESS;
1752 }
1753
1754 DEFUN (no_ipv6_nd_mtu,
1755 no_ipv6_nd_mtu_cmd,
1756 "no ipv6 nd mtu",
1757 NO_STR
1758 "Interface IPv6 config commands\n"
1759 "Neighbor discovery\n"
1760 "Advertised MTU\n")
1761 {
1762 struct interface *ifp = (struct interface *) vty->index;
1763 struct zebra_if *zif = ifp->info;
1764 zif->rtadv.AdvLinkMTU = 0;
1765 return CMD_SUCCESS;
1766 }
1767
1768 ALIAS (no_ipv6_nd_mtu,
1769 no_ipv6_nd_mtu_val_cmd,
1770 "no ipv6 nd mtu <1-65535>",
1771 NO_STR
1772 "Interface IPv6 config commands\n"
1773 "Neighbor discovery\n"
1774 "Advertised MTU\n"
1775 "MTU in bytes\n")
1776
1777 /* Write configuration about router advertisement. */
1778 void
1779 rtadv_config_write (struct vty *vty, struct interface *ifp)
1780 {
1781 struct zebra_if *zif;
1782 struct listnode *node;
1783 struct rtadv_prefix *rprefix;
1784 u_char buf[INET6_ADDRSTRLEN];
1785 int interval;
1786
1787 zif = ifp->info;
1788
1789 if (! if_is_loopback (ifp))
1790 {
1791 if (ipv6_address_configured(ifp))
1792 {
1793 if (! zif->rtadv.AdvSendAdvertisements)
1794 vty_out (vty, " ipv6 nd suppress-ra%s", VTY_NEWLINE);
1795 }
1796 else
1797 {
1798 if (zif->rtadv.AdvSendAdvertisements)
1799 vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
1800 }
1801 }
1802
1803 interval = zif->rtadv.MaxRtrAdvInterval;
1804 if (interval % 1000)
1805 vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
1806 VTY_NEWLINE);
1807 else
1808 if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
1809 vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
1810 VTY_NEWLINE);
1811
1812 if (zif->rtadv.AdvIntervalOption)
1813 vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1814
1815 if (zif->rtadv.AdvDefaultLifetime != -1)
1816 vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1817 VTY_NEWLINE);
1818
1819 if (zif->rtadv.HomeAgentPreference)
1820 vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1821 zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1822
1823 if (zif->rtadv.HomeAgentLifetime != -1)
1824 vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
1825 zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
1826
1827 if (zif->rtadv.AdvHomeAgentFlag)
1828 vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
1829
1830 if (zif->rtadv.AdvReachableTime)
1831 vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
1832 VTY_NEWLINE);
1833
1834 if (zif->rtadv.AdvManagedFlag)
1835 vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
1836
1837 if (zif->rtadv.AdvOtherConfigFlag)
1838 vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
1839
1840 if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
1841 vty_out (vty, " ipv6 nd router-preference %s%s",
1842 rtadv_pref_strs[zif->rtadv.DefaultPreference],
1843 VTY_NEWLINE);
1844
1845 if (zif->rtadv.AdvLinkMTU)
1846 vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1847
1848 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
1849 {
1850 vty_out (vty, " ipv6 nd prefix %s/%d",
1851 inet_ntop (AF_INET6, &rprefix->prefix.prefix,
1852 (char *) buf, INET6_ADDRSTRLEN),
1853 rprefix->prefix.prefixlen);
1854 if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
1855 (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
1856 {
1857 if (rprefix->AdvValidLifetime == UINT32_MAX)
1858 vty_out (vty, " infinite");
1859 else
1860 vty_out (vty, " %u", rprefix->AdvValidLifetime);
1861 if (rprefix->AdvPreferredLifetime == UINT32_MAX)
1862 vty_out (vty, " infinite");
1863 else
1864 vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
1865 }
1866 if (!rprefix->AdvOnLinkFlag)
1867 vty_out (vty, " off-link");
1868 if (!rprefix->AdvAutonomousFlag)
1869 vty_out (vty, " no-autoconfig");
1870 if (rprefix->AdvRouterAddressFlag)
1871 vty_out (vty, " router-address");
1872 vty_out (vty, "%s", VTY_NEWLINE);
1873 }
1874 }
1875
1876
1877 static void
1878 rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
1879 {
1880 struct rtadv *rtadv = &zns->rtadv;
1881
1882 switch (event)
1883 {
1884 case RTADV_START:
1885 if (! rtadv->ra_read)
1886 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
1887 if (! rtadv->ra_timer)
1888 rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
1889 zns, 0);
1890 break;
1891 case RTADV_STOP:
1892 if (rtadv->ra_timer)
1893 {
1894 thread_cancel (rtadv->ra_timer);
1895 rtadv->ra_timer = NULL;
1896 }
1897 if (rtadv->ra_read)
1898 {
1899 thread_cancel (rtadv->ra_read);
1900 rtadv->ra_read = NULL;
1901 }
1902 break;
1903 case RTADV_TIMER:
1904 if (! rtadv->ra_timer)
1905 rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zns,
1906 val);
1907 break;
1908 case RTADV_TIMER_MSEC:
1909 if (! rtadv->ra_timer)
1910 rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
1911 zns, val);
1912 break;
1913 case RTADV_READ:
1914 if (! rtadv->ra_read)
1915 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
1916 break;
1917 default:
1918 break;
1919 }
1920 return;
1921 }
1922
1923 void
1924 rtadv_init (struct zebra_ns *zns)
1925 {
1926 zns->rtadv.sock = rtadv_make_socket ();
1927 }
1928
1929 void
1930 rtadv_terminate (struct zebra_ns *zns)
1931 {
1932 rtadv_event (zns, RTADV_STOP, 0);
1933 if (zns->rtadv.sock >= 0)
1934 {
1935 close (zns->rtadv.sock);
1936 zns->rtadv.sock = -1;
1937 }
1938
1939 zns->rtadv.adv_if_count = 0;
1940 zns->rtadv.adv_msec_if_count = 0;
1941 }
1942
1943 void
1944 rtadv_cmd_init (void)
1945 {
1946 install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
1947 install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
1948 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
1949 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
1950 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
1951 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
1952 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
1953 install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
1954 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
1955 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
1956 install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
1957 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
1958 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
1959 install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
1960 install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
1961 install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
1962 install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
1963 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
1964 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
1965 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
1966 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
1967 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
1968 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
1969 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
1970 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
1971 install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
1972 install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
1973 install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
1974 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
1975 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
1976 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
1977 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
1978 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
1979 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
1980 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
1981 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
1982 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
1983 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
1984 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
1985 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
1986 install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
1987 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
1988 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd);
1989 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_nortaddr_cmd);
1990 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_cmd);
1991 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_noauto_cmd);
1992 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_offlink_cmd);
1993 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rtaddr_cmd);
1994 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_cmd);
1995 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_cmd);
1996 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rev_cmd);
1997 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_noauto_cmd);
1998 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_offlink_cmd);
1999 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rtaddr_cmd);
2000 install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
2001 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
2002 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
2003 install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
2004 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
2005 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
2006 }
2007
2008 static int
2009 if_join_all_router (int sock, struct interface *ifp)
2010 {
2011 int ret;
2012
2013 struct ipv6_mreq mreq;
2014
2015 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2016 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2017 mreq.ipv6mr_interface = ifp->ifindex;
2018
2019 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
2020 (char *) &mreq, sizeof mreq);
2021 if (ret < 0)
2022 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2023 ifp->name, ifp->ifindex, sock, safe_strerror (errno));
2024
2025 if (IS_ZEBRA_DEBUG_EVENT)
2026 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2027 ifp->name, ifp->ifindex, sock);
2028
2029 return 0;
2030 }
2031
2032 static int
2033 if_leave_all_router (int sock, struct interface *ifp)
2034 {
2035 int ret;
2036
2037 struct ipv6_mreq mreq;
2038
2039 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2040 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2041 mreq.ipv6mr_interface = ifp->ifindex;
2042
2043 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
2044 (char *) &mreq, sizeof mreq);
2045 if (ret < 0)
2046 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2047 ifp->name, ifp->ifindex, sock,safe_strerror (errno));
2048
2049 if (IS_ZEBRA_DEBUG_EVENT)
2050 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2051 ifp->name, ifp->ifindex, sock);
2052
2053 return 0;
2054 }
2055
2056 #else
2057 void
2058 rtadv_init (struct zebra_ns *zns)
2059 {
2060 /* Empty.*/;
2061 }
2062 void
2063 rtadv_terminate (struct zebra_ns *zns)
2064 {
2065 /* Empty.*/;
2066 }
2067 void
2068 rtadv_cmd_init (void)
2069 {
2070 /* Empty.*/;
2071 }
2072 #endif /* HAVE_RTADV && HAVE_IPV6 */