1 /* Router advertisement
2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
3 * Copyright (C) 1999 Kunihiro Ishiguro
5 * This file is part of GNU Zebra.
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
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.
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
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"
42 extern struct zebra_privs_t zserv_privs;
44 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
47 #include <netinet/icmp6.h>
50 /* If RFC2133 definition is used. */
51 #ifndef IPV6_JOIN_GROUP
52 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
54 #ifndef IPV6_LEAVE_GROUP
55 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
58 #define ALLNODE "ff02::1"
59 #define ALLROUTER "ff02::2"
61 extern struct zebra_t zebrad;
63 enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
64 RTADV_TIMER_MSEC, RTADV_READ};
66 static void rtadv_event (struct zebra_vrf *, enum rtadv_event, int);
68 static int if_join_all_router (int, struct interface *);
69 static int if_leave_all_router (int, struct interface *);
72 rtadv_recv_packet (int sock, u_char *buf, int buflen,
73 struct sockaddr_in6 *from, ifindex_t *ifindex,
79 struct cmsghdr *cmsgptr;
84 /* Fill in message and iovec. */
85 msg.msg_name = (void *) from;
86 msg.msg_namelen = sizeof (struct sockaddr_in6);
89 msg.msg_control = (void *) adata;
90 msg.msg_controllen = sizeof adata;
94 /* If recvmsg fail return minus value. */
95 ret = recvmsg (sock, &msg, 0);
99 for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
100 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
102 /* I want interface index which this packet comes from. */
103 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
104 cmsgptr->cmsg_type == IPV6_PKTINFO)
106 struct in6_pktinfo *ptr;
108 ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
109 *ifindex = ptr->ipi6_ifindex;
110 memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
113 /* Incoming packet's hop limit. */
114 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
115 cmsgptr->cmsg_type == IPV6_HOPLIMIT)
117 int *hoptr = (int *) CMSG_DATA (cmsgptr);
124 #define RTADV_MSG_SIZE 4096
126 /* Send router advertisement packet. */
128 rtadv_send_packet (int sock, struct interface *ifp)
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;
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;
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.
157 /* XXX Free on shutdown. */
158 adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
161 zlog_err("rtadv_send_packet: can't malloc control data\n");
164 /* Logging of packet. */
165 if (IS_ZEBRA_DEBUG_PACKET)
166 zlog_debug ("Router advertisement send to %s", ifp->name);
168 /* Fill in sockaddr_in6. */
169 memset (&addr, 0, sizeof (struct sockaddr_in6));
170 addr.sin6_family = AF_INET6;
172 addr.sin6_len = sizeof (struct sockaddr_in6);
173 #endif /* SIN6_LEN */
174 addr.sin6_port = htons (IPPROTO_ICMPV6);
175 IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
177 /* Fetch interface information. */
180 /* Make router advertisement message. */
181 rtadv = (struct nd_router_advert *) buf;
183 rtadv->nd_ra_type = ND_ROUTER_ADVERT;
184 rtadv->nd_ra_code = 0;
185 rtadv->nd_ra_cksum = 0;
187 rtadv->nd_ra_curhoplimit = 64;
189 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
190 rtadv->nd_ra_flags_reserved =
191 zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
192 rtadv->nd_ra_flags_reserved <<= 3;
194 if (zif->rtadv.AdvManagedFlag)
195 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
196 if (zif->rtadv.AdvOtherConfigFlag)
197 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
198 if (zif->rtadv.AdvHomeAgentFlag)
199 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
200 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
201 * AdvDefaultLifetime is by default based on the value of
202 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
203 * field of Router Advertisements. Given that this field is expressed
204 * in seconds, a small MaxRtrAdvInterval value can result in a zero
205 * value for this field. To prevent this, routers SHOULD keep
206 * AdvDefaultLifetime in at least one second, even if the use of
207 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
208 pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ?
209 zif->rtadv.AdvDefaultLifetime :
210 MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
211 rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime);
212 rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
213 rtadv->nd_ra_retransmit = htonl (0);
215 len = sizeof (struct nd_router_advert);
217 /* If both the Home Agent Preference and Home Agent Lifetime are set to
218 * their default values specified above, this option SHOULD NOT be
219 * included in the Router Advertisement messages sent by this home
220 * agent. -- RFC6275, 7.4 */
223 zif->rtadv.AdvHomeAgentFlag &&
224 (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
227 struct nd_opt_homeagent_info *ndopt_hai =
228 (struct nd_opt_homeagent_info *)(buf + len);
229 ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
230 ndopt_hai->nd_opt_hai_len = 1;
231 ndopt_hai->nd_opt_hai_reserved = 0;
232 ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
233 /* 16-bit unsigned integer. The lifetime associated with the home
234 * agent in units of seconds. The default value is the same as the
235 * Router Lifetime, as specified in the main body of the Router
236 * Advertisement. The maximum value corresponds to 18.2 hours. A
237 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
238 ndopt_hai->nd_opt_hai_lifetime = htons
240 zif->rtadv.HomeAgentLifetime != -1 ?
241 zif->rtadv.HomeAgentLifetime :
242 MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
244 len += sizeof(struct nd_opt_homeagent_info);
247 if (zif->rtadv.AdvIntervalOption)
249 struct nd_opt_adv_interval *ndopt_adv =
250 (struct nd_opt_adv_interval *)(buf + len);
251 ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
252 ndopt_adv->nd_opt_ai_len = 1;
253 ndopt_adv->nd_opt_ai_reserved = 0;
254 ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
255 len += sizeof(struct nd_opt_adv_interval);
258 /* Fill in prefix. */
259 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
261 struct nd_opt_prefix_info *pinfo;
263 pinfo = (struct nd_opt_prefix_info *) (buf + len);
265 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
266 pinfo->nd_opt_pi_len = 4;
267 pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
269 pinfo->nd_opt_pi_flags_reserved = 0;
270 if (rprefix->AdvOnLinkFlag)
271 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
272 if (rprefix->AdvAutonomousFlag)
273 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
274 if (rprefix->AdvRouterAddressFlag)
275 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
277 pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
278 pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
279 pinfo->nd_opt_pi_reserved2 = 0;
281 IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
285 u_char buf[INET6_ADDRSTRLEN];
287 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
288 buf, INET6_ADDRSTRLEN));
293 len += sizeof (struct nd_opt_prefix_info);
296 /* Hardware address. */
297 if (ifp->hw_addr_len != 0)
299 buf[len++] = ND_OPT_SOURCE_LINKADDR;
301 /* Option length should be rounded up to next octet if
302 the link address does not end on an octet boundary. */
303 buf[len++] = (ifp->hw_addr_len + 9) >> 3;
305 memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
306 len += ifp->hw_addr_len;
308 /* Pad option to end on an octet boundary. */
309 memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
310 len += -(ifp->hw_addr_len + 2) & 0x7;
314 if (zif->rtadv.AdvLinkMTU)
316 struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
317 opt->nd_opt_mtu_type = ND_OPT_MTU;
318 opt->nd_opt_mtu_len = 1;
319 opt->nd_opt_mtu_reserved = 0;
320 opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
321 len += sizeof (struct nd_opt_mtu);
324 msg.msg_name = (void *) &addr;
325 msg.msg_namelen = sizeof (struct sockaddr_in6);
328 msg.msg_control = (void *) adata;
329 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
334 cmsgptr = ZCMSG_FIRSTHDR(&msg);
335 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
336 cmsgptr->cmsg_level = IPPROTO_IPV6;
337 cmsgptr->cmsg_type = IPV6_PKTINFO;
339 pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
340 memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
341 pkt->ipi6_ifindex = ifp->ifindex;
343 ret = sendmsg (sock, &msg, 0);
346 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
347 errno, safe_strerror(errno));
352 rtadv_timer (struct thread *thread)
354 struct zebra_vrf *zvrf = THREAD_ARG (thread);
355 struct listnode *node, *nnode;
356 struct interface *ifp;
357 struct zebra_if *zif;
360 zvrf->rtadv.ra_timer = NULL;
361 if (zvrf->rtadv.adv_msec_if_count == 0)
363 period = 1000; /* 1 s */
364 rtadv_event (zvrf, RTADV_TIMER, 1 /* 1 s */);
368 period = 10; /* 10 ms */
369 rtadv_event (zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
372 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf->vrf_id), node, nnode, ifp))
374 if (if_is_loopback (ifp) || ! if_is_operative (ifp))
379 if (zif->rtadv.AdvSendAdvertisements)
381 zif->rtadv.AdvIntervalTimer -= period;
382 if (zif->rtadv.AdvIntervalTimer <= 0)
384 /* FIXME: using MaxRtrAdvInterval each time isn't what section
385 6.2.4 of RFC4861 tells to do. */
386 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
387 rtadv_send_packet (zvrf->rtadv.sock, ifp);
395 rtadv_process_solicit (struct interface *ifp)
397 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
399 zlog_info ("Router solicitation received on %s vrf %u", ifp->name, zvrf->vrf_id);
401 rtadv_send_packet (zvrf->rtadv.sock, ifp);
405 rtadv_process_advert (void)
407 zlog_info ("Router advertisement received");
411 rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex,
412 int hoplimit, vrf_id_t vrf_id)
414 struct icmp6_hdr *icmph;
415 struct interface *ifp;
416 struct zebra_if *zif;
418 /* Interface search. */
419 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
422 zlog_warn ("Unknown interface index: %d, vrf %u", ifindex, vrf_id);
426 if (if_is_loopback (ifp))
429 /* Check interface configuration. */
431 if (! zif->rtadv.AdvSendAdvertisements)
434 /* ICMP message length check. */
435 if (len < sizeof (struct icmp6_hdr))
437 zlog_warn ("Invalid ICMPV6 packet length: %d", len);
441 icmph = (struct icmp6_hdr *) buf;
443 /* ICMP message type check. */
444 if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
445 icmph->icmp6_type != ND_ROUTER_ADVERT)
447 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph->icmp6_type);
451 /* Hoplimit check. */
452 if (hoplimit >= 0 && hoplimit != 255)
454 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
459 /* Check ICMP message type. */
460 if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
461 rtadv_process_solicit (ifp);
462 else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
463 rtadv_process_advert ();
469 rtadv_read (struct thread *thread)
473 u_char buf[RTADV_MSG_SIZE];
474 struct sockaddr_in6 from;
475 ifindex_t ifindex = 0;
477 struct zebra_vrf *zvrf = THREAD_ARG (thread);
479 sock = THREAD_FD (thread);
480 zvrf->rtadv.ra_read = NULL;
482 /* Register myself. */
483 rtadv_event (zvrf, RTADV_READ, sock);
485 len = rtadv_recv_packet (sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
489 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno));
493 rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, zvrf->vrf_id);
499 rtadv_make_socket (vrf_id_t vrf_id)
503 struct icmp6_filter filter;
505 if ( zserv_privs.change (ZPRIVS_RAISE) )
506 zlog_err ("rtadv_make_socket: could not raise privs, %s",
507 safe_strerror (errno) );
509 sock = vrf_socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, vrf_id);
511 if ( zserv_privs.change (ZPRIVS_LOWER) )
512 zlog_err ("rtadv_make_socket: could not lower privs, %s",
513 safe_strerror (errno) );
515 /* When we can't make ICMPV6 socket simply back. Router
516 advertisement feature will not be supported. */
523 ret = setsockopt_ipv6_pktinfo (sock, 1);
529 ret = setsockopt_ipv6_multicast_loop (sock, 0);
535 ret = setsockopt_ipv6_unicast_hops (sock, 255);
541 ret = setsockopt_ipv6_multicast_hops (sock, 255);
547 ret = setsockopt_ipv6_hoplimit (sock, 1);
554 ICMP6_FILTER_SETBLOCKALL(&filter);
555 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
556 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
558 ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
559 sizeof (struct icmp6_filter));
562 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
569 static struct rtadv_prefix *
570 rtadv_prefix_new (void)
572 return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
576 rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
578 XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
581 static struct rtadv_prefix *
582 rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
584 struct listnode *node;
585 struct rtadv_prefix *rprefix;
587 for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
588 if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
593 static struct rtadv_prefix *
594 rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
596 struct rtadv_prefix *rprefix;
598 rprefix = rtadv_prefix_lookup (rplist, p);
602 rprefix = rtadv_prefix_new ();
603 memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
604 listnode_add (rplist, rprefix);
610 rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
612 struct rtadv_prefix *rprefix;
614 rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
616 /* Set parameters. */
617 rprefix->AdvValidLifetime = rp->AdvValidLifetime;
618 rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
619 rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
620 rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
621 rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
625 rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
627 struct rtadv_prefix *rprefix;
629 rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
632 listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
633 rtadv_prefix_free (rprefix);
640 DEFUN (ipv6_nd_suppress_ra,
641 ipv6_nd_suppress_ra_cmd,
642 "ipv6 nd suppress-ra",
643 "Interface IPv6 config commands\n"
644 "Neighbor discovery\n"
645 "Suppress Router Advertisement\n")
647 struct interface *ifp;
648 struct zebra_if *zif;
649 struct zebra_vrf *zvrf;
653 zvrf = vrf_info_lookup (ifp->vrf_id);
655 if (if_is_loopback (ifp))
657 vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
661 if (zif->rtadv.AdvSendAdvertisements)
663 zif->rtadv.AdvSendAdvertisements = 0;
664 zif->rtadv.AdvIntervalTimer = 0;
665 zvrf->rtadv.adv_if_count--;
667 if_leave_all_router (zvrf->rtadv.sock, ifp);
669 if (zvrf->rtadv.adv_if_count == 0)
670 rtadv_event (zvrf, RTADV_STOP, 0);
676 DEFUN (no_ipv6_nd_suppress_ra,
677 no_ipv6_nd_suppress_ra_cmd,
678 "no ipv6 nd suppress-ra",
680 "Interface IPv6 config commands\n"
681 "Neighbor discovery\n"
682 "Suppress Router Advertisement\n")
684 struct interface *ifp;
685 struct zebra_if *zif;
686 struct zebra_vrf *zvrf;
690 zvrf = vrf_info_lookup (ifp->vrf_id);
692 if (if_is_loopback (ifp))
694 vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
698 if (! zif->rtadv.AdvSendAdvertisements)
700 zif->rtadv.AdvSendAdvertisements = 1;
701 zif->rtadv.AdvIntervalTimer = 0;
702 zvrf->rtadv.adv_if_count++;
704 if_join_all_router (zvrf->rtadv.sock, ifp);
706 if (zvrf->rtadv.adv_if_count == 1)
707 rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock);
713 DEFUN (ipv6_nd_ra_interval_msec,
714 ipv6_nd_ra_interval_msec_cmd,
715 "ipv6 nd ra-interval msec <70-1800000>",
716 "Interface IPv6 config commands\n"
717 "Neighbor discovery\n"
718 "Router Advertisement interval\n"
719 "Router Advertisement interval in milliseconds\n")
722 struct interface *ifp = (struct interface *) vty->index;
723 struct zebra_if *zif = ifp->info;
724 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
726 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
727 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
729 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
733 if (zif->rtadv.MaxRtrAdvInterval % 1000)
734 zvrf->rtadv.adv_msec_if_count--;
737 zvrf->rtadv.adv_msec_if_count++;
739 zif->rtadv.MaxRtrAdvInterval = interval;
740 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
741 zif->rtadv.AdvIntervalTimer = 0;
746 DEFUN (ipv6_nd_ra_interval,
747 ipv6_nd_ra_interval_cmd,
748 "ipv6 nd ra-interval <1-1800>",
749 "Interface IPv6 config commands\n"
750 "Neighbor discovery\n"
751 "Router Advertisement interval\n"
752 "Router Advertisement interval in seconds\n")
755 struct interface *ifp = (struct interface *) vty->index;
756 struct zebra_if *zif = ifp->info;
757 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
759 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
760 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
762 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
766 if (zif->rtadv.MaxRtrAdvInterval % 1000)
767 zvrf->rtadv.adv_msec_if_count--;
769 /* convert to milliseconds */
770 interval = interval * 1000;
772 zif->rtadv.MaxRtrAdvInterval = interval;
773 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
774 zif->rtadv.AdvIntervalTimer = 0;
779 DEFUN (no_ipv6_nd_ra_interval,
780 no_ipv6_nd_ra_interval_cmd,
781 "no ipv6 nd ra-interval",
783 "Interface IPv6 config commands\n"
784 "Neighbor discovery\n"
785 "Router Advertisement interval\n")
787 struct interface *ifp;
788 struct zebra_if *zif;
789 struct zebra_vrf *zvrf;
791 ifp = (struct interface *) vty->index;
793 zvrf = vrf_info_lookup (ifp->vrf_id);
795 if (zif->rtadv.MaxRtrAdvInterval % 1000)
796 zvrf->rtadv.adv_msec_if_count--;
798 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
799 zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
800 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
805 ALIAS (no_ipv6_nd_ra_interval,
806 no_ipv6_nd_ra_interval_val_cmd,
807 "no ipv6 nd ra-interval <1-1800>",
809 "Interface IPv6 config commands\n"
810 "Neighbor discovery\n"
811 "Router Advertisement interval\n")
813 ALIAS (no_ipv6_nd_ra_interval,
814 no_ipv6_nd_ra_interval_msec_val_cmd,
815 "no ipv6 nd ra-interval msec <1-1800000>",
817 "Interface IPv6 config commands\n"
818 "Neighbor discovery\n"
819 "Router Advertisement interval\n"
820 "Router Advertisement interval in milliseconds\n")
822 DEFUN (ipv6_nd_ra_lifetime,
823 ipv6_nd_ra_lifetime_cmd,
824 "ipv6 nd ra-lifetime <0-9000>",
825 "Interface IPv6 config commands\n"
826 "Neighbor discovery\n"
828 "Router lifetime in seconds (0 stands for a non-default gw)\n")
831 struct interface *ifp;
832 struct zebra_if *zif;
834 ifp = (struct interface *) vty->index;
837 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
839 /* The value to be placed in the Router Lifetime field
840 * of Router Advertisements sent from the interface,
841 * in seconds. MUST be either zero or between
842 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
843 if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
845 vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
849 zif->rtadv.AdvDefaultLifetime = lifetime;
854 DEFUN (no_ipv6_nd_ra_lifetime,
855 no_ipv6_nd_ra_lifetime_cmd,
856 "no ipv6 nd ra-lifetime",
858 "Interface IPv6 config commands\n"
859 "Neighbor discovery\n"
862 struct interface *ifp;
863 struct zebra_if *zif;
865 ifp = (struct interface *) vty->index;
868 zif->rtadv.AdvDefaultLifetime = -1;
873 ALIAS (no_ipv6_nd_ra_lifetime,
874 no_ipv6_nd_ra_lifetime_val_cmd,
875 "no ipv6 nd ra-lifetime <0-9000>",
877 "Interface IPv6 config commands\n"
878 "Neighbor discovery\n"
880 "Router lifetime in seconds (0 stands for a non-default gw)\n")
882 DEFUN (ipv6_nd_reachable_time,
883 ipv6_nd_reachable_time_cmd,
884 "ipv6 nd reachable-time <1-3600000>",
885 "Interface IPv6 config commands\n"
886 "Neighbor discovery\n"
888 "Reachable time in milliseconds\n")
890 struct interface *ifp = (struct interface *) vty->index;
891 struct zebra_if *zif = ifp->info;
892 VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
896 DEFUN (no_ipv6_nd_reachable_time,
897 no_ipv6_nd_reachable_time_cmd,
898 "no ipv6 nd reachable-time",
900 "Interface IPv6 config commands\n"
901 "Neighbor discovery\n"
904 struct interface *ifp;
905 struct zebra_if *zif;
907 ifp = (struct interface *) vty->index;
910 zif->rtadv.AdvReachableTime = 0;
915 ALIAS (no_ipv6_nd_reachable_time,
916 no_ipv6_nd_reachable_time_val_cmd,
917 "no ipv6 nd reachable-time <1-3600000>",
919 "Interface IPv6 config commands\n"
920 "Neighbor discovery\n"
922 "Reachable time in milliseconds\n")
924 DEFUN (ipv6_nd_homeagent_preference,
925 ipv6_nd_homeagent_preference_cmd,
926 "ipv6 nd home-agent-preference <0-65535>",
927 "Interface IPv6 config commands\n"
928 "Neighbor discovery\n"
929 "Home Agent preference\n"
930 "preference value (default is 0, least preferred)\n")
932 struct interface *ifp = (struct interface *) vty->index;
933 struct zebra_if *zif = ifp->info;
934 VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
938 DEFUN (no_ipv6_nd_homeagent_preference,
939 no_ipv6_nd_homeagent_preference_cmd,
940 "no ipv6 nd home-agent-preference",
942 "Interface IPv6 config commands\n"
943 "Neighbor discovery\n"
944 "Home Agent preference\n")
946 struct interface *ifp;
947 struct zebra_if *zif;
949 ifp = (struct interface *) vty->index;
952 zif->rtadv.HomeAgentPreference = 0;
957 ALIAS (no_ipv6_nd_homeagent_preference,
958 no_ipv6_nd_homeagent_preference_val_cmd,
959 "no ipv6 nd home-agent-preference <0-65535>",
961 "Interface IPv6 config commands\n"
962 "Neighbor discovery\n"
963 "Home Agent preference\n"
964 "preference value (default is 0, least preferred)\n")
966 DEFUN (ipv6_nd_homeagent_lifetime,
967 ipv6_nd_homeagent_lifetime_cmd,
968 "ipv6 nd home-agent-lifetime <0-65520>",
969 "Interface IPv6 config commands\n"
970 "Neighbor discovery\n"
971 "Home Agent lifetime\n"
972 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
974 struct interface *ifp = (struct interface *) vty->index;
975 struct zebra_if *zif = ifp->info;
976 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
980 DEFUN (no_ipv6_nd_homeagent_lifetime,
981 no_ipv6_nd_homeagent_lifetime_cmd,
982 "no ipv6 nd home-agent-lifetime",
984 "Interface IPv6 config commands\n"
985 "Neighbor discovery\n"
986 "Home Agent lifetime\n")
988 struct interface *ifp;
989 struct zebra_if *zif;
991 ifp = (struct interface *) vty->index;
994 zif->rtadv.HomeAgentLifetime = -1;
999 ALIAS (no_ipv6_nd_homeagent_lifetime,
1000 no_ipv6_nd_homeagent_lifetime_val_cmd,
1001 "no ipv6 nd home-agent-lifetime <0-65520>",
1003 "Interface IPv6 config commands\n"
1004 "Neighbor discovery\n"
1005 "Home Agent lifetime\n"
1006 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1008 DEFUN (ipv6_nd_managed_config_flag,
1009 ipv6_nd_managed_config_flag_cmd,
1010 "ipv6 nd managed-config-flag",
1011 "Interface IPv6 config commands\n"
1012 "Neighbor discovery\n"
1013 "Managed address configuration flag\n")
1015 struct interface *ifp;
1016 struct zebra_if *zif;
1018 ifp = (struct interface *) vty->index;
1021 zif->rtadv.AdvManagedFlag = 1;
1026 DEFUN (no_ipv6_nd_managed_config_flag,
1027 no_ipv6_nd_managed_config_flag_cmd,
1028 "no ipv6 nd managed-config-flag",
1030 "Interface IPv6 config commands\n"
1031 "Neighbor discovery\n"
1032 "Managed address configuration flag\n")
1034 struct interface *ifp;
1035 struct zebra_if *zif;
1037 ifp = (struct interface *) vty->index;
1040 zif->rtadv.AdvManagedFlag = 0;
1045 DEFUN (ipv6_nd_homeagent_config_flag,
1046 ipv6_nd_homeagent_config_flag_cmd,
1047 "ipv6 nd home-agent-config-flag",
1048 "Interface IPv6 config commands\n"
1049 "Neighbor discovery\n"
1050 "Home Agent configuration flag\n")
1052 struct interface *ifp;
1053 struct zebra_if *zif;
1055 ifp = (struct interface *) vty->index;
1058 zif->rtadv.AdvHomeAgentFlag = 1;
1063 DEFUN (no_ipv6_nd_homeagent_config_flag,
1064 no_ipv6_nd_homeagent_config_flag_cmd,
1065 "no ipv6 nd home-agent-config-flag",
1067 "Interface IPv6 config commands\n"
1068 "Neighbor discovery\n"
1069 "Home Agent configuration flag\n")
1071 struct interface *ifp;
1072 struct zebra_if *zif;
1074 ifp = (struct interface *) vty->index;
1077 zif->rtadv.AdvHomeAgentFlag = 0;
1082 DEFUN (ipv6_nd_adv_interval_config_option,
1083 ipv6_nd_adv_interval_config_option_cmd,
1084 "ipv6 nd adv-interval-option",
1085 "Interface IPv6 config commands\n"
1086 "Neighbor discovery\n"
1087 "Advertisement Interval Option\n")
1089 struct interface *ifp;
1090 struct zebra_if *zif;
1092 ifp = (struct interface *) vty->index;
1095 zif->rtadv.AdvIntervalOption = 1;
1100 DEFUN (no_ipv6_nd_adv_interval_config_option,
1101 no_ipv6_nd_adv_interval_config_option_cmd,
1102 "no ipv6 nd adv-interval-option",
1104 "Interface IPv6 config commands\n"
1105 "Neighbor discovery\n"
1106 "Advertisement Interval Option\n")
1108 struct interface *ifp;
1109 struct zebra_if *zif;
1111 ifp = (struct interface *) vty->index;
1114 zif->rtadv.AdvIntervalOption = 0;
1119 DEFUN (ipv6_nd_other_config_flag,
1120 ipv6_nd_other_config_flag_cmd,
1121 "ipv6 nd other-config-flag",
1122 "Interface IPv6 config commands\n"
1123 "Neighbor discovery\n"
1124 "Other statefull configuration flag\n")
1126 struct interface *ifp;
1127 struct zebra_if *zif;
1129 ifp = (struct interface *) vty->index;
1132 zif->rtadv.AdvOtherConfigFlag = 1;
1137 DEFUN (no_ipv6_nd_other_config_flag,
1138 no_ipv6_nd_other_config_flag_cmd,
1139 "no ipv6 nd other-config-flag",
1141 "Interface IPv6 config commands\n"
1142 "Neighbor discovery\n"
1143 "Other statefull configuration flag\n")
1145 struct interface *ifp;
1146 struct zebra_if *zif;
1148 ifp = (struct interface *) vty->index;
1151 zif->rtadv.AdvOtherConfigFlag = 0;
1156 DEFUN (ipv6_nd_prefix,
1158 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1159 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1160 "Interface IPv6 config commands\n"
1161 "Neighbor discovery\n"
1162 "Prefix information\n"
1164 "Valid lifetime in seconds\n"
1165 "Infinite valid lifetime\n"
1166 "Preferred lifetime in seconds\n"
1167 "Infinite preferred lifetime\n"
1168 "Do not use prefix for onlink determination\n"
1169 "Do not use prefix for autoconfiguration\n"
1170 "Set Router Address flag\n")
1175 struct interface *ifp;
1176 struct zebra_if *zebra_if;
1177 struct rtadv_prefix rp;
1179 ifp = (struct interface *) vty->index;
1180 zebra_if = ifp->info;
1182 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1185 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1188 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1189 rp.AdvOnLinkFlag = 1;
1190 rp.AdvAutonomousFlag = 1;
1191 rp.AdvRouterAddressFlag = 0;
1192 rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
1193 rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
1197 if ((isdigit((unsigned char)argv[1][0]))
1198 || strncmp (argv[1], "i", 1) == 0)
1200 if ( strncmp (argv[1], "i", 1) == 0)
1201 rp.AdvValidLifetime = UINT32_MAX;
1203 rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
1206 if ( strncmp (argv[2], "i", 1) == 0)
1207 rp.AdvPreferredLifetime = UINT32_MAX;
1209 rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
1212 if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
1214 vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
1217 cursor = cursor + 2;
1221 for (i = cursor; i < argc; i++)
1223 if (strncmp (argv[i], "of", 2) == 0)
1224 rp.AdvOnLinkFlag = 0;
1225 if (strncmp (argv[i], "no", 2) == 0)
1226 rp.AdvAutonomousFlag = 0;
1227 if (strncmp (argv[i], "ro", 2) == 0)
1228 rp.AdvRouterAddressFlag = 1;
1233 rtadv_prefix_set (zebra_if, &rp);
1238 ALIAS (ipv6_nd_prefix,
1239 ipv6_nd_prefix_val_nortaddr_cmd,
1240 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1241 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1242 "Interface IPv6 config commands\n"
1243 "Neighbor discovery\n"
1244 "Prefix information\n"
1246 "Valid lifetime in seconds\n"
1247 "Infinite valid lifetime\n"
1248 "Preferred lifetime in seconds\n"
1249 "Infinite preferred lifetime\n"
1250 "Do not use prefix for onlink determination\n"
1251 "Do not use prefix for autoconfiguration\n")
1253 ALIAS (ipv6_nd_prefix,
1254 ipv6_nd_prefix_val_rev_cmd,
1255 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1256 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1257 "Interface IPv6 config commands\n"
1258 "Neighbor discovery\n"
1259 "Prefix information\n"
1261 "Valid lifetime in seconds\n"
1262 "Infinite valid lifetime\n"
1263 "Preferred lifetime in seconds\n"
1264 "Infinite preferred lifetime\n"
1265 "Do not use prefix for autoconfiguration\n"
1266 "Do not use prefix for onlink determination\n")
1268 ALIAS (ipv6_nd_prefix,
1269 ipv6_nd_prefix_val_rev_rtaddr_cmd,
1270 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1271 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1272 "Interface IPv6 config commands\n"
1273 "Neighbor discovery\n"
1274 "Prefix information\n"
1276 "Valid lifetime in seconds\n"
1277 "Infinite valid lifetime\n"
1278 "Preferred lifetime in seconds\n"
1279 "Infinite preferred lifetime\n"
1280 "Do not use prefix for autoconfiguration\n"
1281 "Do not use prefix for onlink determination\n"
1282 "Set Router Address flag\n")
1284 ALIAS (ipv6_nd_prefix,
1285 ipv6_nd_prefix_val_noauto_cmd,
1286 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1287 "(<0-4294967295>|infinite) (no-autoconfig|)",
1288 "Interface IPv6 config commands\n"
1289 "Neighbor discovery\n"
1290 "Prefix information\n"
1292 "Valid lifetime in seconds\n"
1293 "Infinite valid lifetime\n"
1294 "Preferred lifetime in seconds\n"
1295 "Infinite preferred lifetime\n"
1296 "Do not use prefix for autoconfiguration")
1298 ALIAS (ipv6_nd_prefix,
1299 ipv6_nd_prefix_val_offlink_cmd,
1300 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1301 "(<0-4294967295>|infinite) (off-link|)",
1302 "Interface IPv6 config commands\n"
1303 "Neighbor discovery\n"
1304 "Prefix information\n"
1306 "Valid lifetime in seconds\n"
1307 "Infinite valid lifetime\n"
1308 "Preferred lifetime in seconds\n"
1309 "Infinite preferred lifetime\n"
1310 "Do not use prefix for onlink determination\n")
1312 ALIAS (ipv6_nd_prefix,
1313 ipv6_nd_prefix_val_rtaddr_cmd,
1314 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1315 "(<0-4294967295>|infinite) (router-address|)",
1316 "Interface IPv6 config commands\n"
1317 "Neighbor discovery\n"
1318 "Prefix information\n"
1320 "Valid lifetime in seconds\n"
1321 "Infinite valid lifetime\n"
1322 "Preferred lifetime in seconds\n"
1323 "Infinite preferred lifetime\n"
1324 "Set Router Address flag\n")
1326 ALIAS (ipv6_nd_prefix,
1327 ipv6_nd_prefix_val_cmd,
1328 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1329 "(<0-4294967295>|infinite)",
1330 "Interface IPv6 config commands\n"
1331 "Neighbor discovery\n"
1332 "Prefix information\n"
1334 "Valid lifetime in seconds\n"
1335 "Infinite valid lifetime\n"
1336 "Preferred lifetime in seconds\n"
1337 "Infinite preferred lifetime\n")
1339 ALIAS (ipv6_nd_prefix,
1340 ipv6_nd_prefix_noval_cmd,
1341 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1342 "Interface IPv6 config commands\n"
1343 "Neighbor discovery\n"
1344 "Prefix information\n"
1346 "Do not use prefix for autoconfiguration\n"
1347 "Do not use prefix for onlink determination\n")
1349 ALIAS (ipv6_nd_prefix,
1350 ipv6_nd_prefix_noval_rev_cmd,
1351 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1352 "Interface IPv6 config commands\n"
1353 "Neighbor discovery\n"
1354 "Prefix information\n"
1356 "Do not use prefix for onlink determination\n"
1357 "Do not use prefix for autoconfiguration\n")
1359 ALIAS (ipv6_nd_prefix,
1360 ipv6_nd_prefix_noval_noauto_cmd,
1361 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1362 "Interface IPv6 config commands\n"
1363 "Neighbor discovery\n"
1364 "Prefix information\n"
1366 "Do not use prefix for autoconfiguration\n")
1368 ALIAS (ipv6_nd_prefix,
1369 ipv6_nd_prefix_noval_offlink_cmd,
1370 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1371 "Interface IPv6 config commands\n"
1372 "Neighbor discovery\n"
1373 "Prefix information\n"
1375 "Do not use prefix for onlink determination\n")
1377 ALIAS (ipv6_nd_prefix,
1378 ipv6_nd_prefix_noval_rtaddr_cmd,
1379 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1380 "Interface IPv6 config commands\n"
1381 "Neighbor discovery\n"
1382 "Prefix information\n"
1384 "Set Router Address flag\n")
1386 ALIAS (ipv6_nd_prefix,
1387 ipv6_nd_prefix_prefix_cmd,
1388 "ipv6 nd prefix X:X::X:X/M",
1389 "Interface IPv6 config commands\n"
1390 "Neighbor discovery\n"
1391 "Prefix information\n"
1394 DEFUN (no_ipv6_nd_prefix,
1395 no_ipv6_nd_prefix_cmd,
1396 "no ipv6 nd prefix IPV6PREFIX",
1398 "Interface IPv6 config commands\n"
1399 "Neighbor discovery\n"
1400 "Prefix information\n"
1404 struct interface *ifp;
1405 struct zebra_if *zebra_if;
1406 struct rtadv_prefix rp;
1408 ifp = (struct interface *) vty->index;
1409 zebra_if = ifp->info;
1411 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1414 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1417 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1419 ret = rtadv_prefix_reset (zebra_if, &rp);
1422 vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
1429 DEFUN (ipv6_nd_router_preference,
1430 ipv6_nd_router_preference_cmd,
1431 "ipv6 nd router-preference (high|medium|low)",
1432 "Interface IPv6 config commands\n"
1433 "Neighbor discovery\n"
1434 "Default router preference\n"
1435 "High default router preference\n"
1436 "Low default router preference\n"
1437 "Medium default router preference (default)\n")
1439 struct interface *ifp;
1440 struct zebra_if *zif;
1443 ifp = (struct interface *) vty->index;
1446 while (0 != rtadv_pref_strs[i])
1448 if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
1450 zif->rtadv.DefaultPreference = i;
1456 return CMD_ERR_NO_MATCH;
1459 DEFUN (no_ipv6_nd_router_preference,
1460 no_ipv6_nd_router_preference_cmd,
1461 "no ipv6 nd router-preference",
1463 "Interface IPv6 config commands\n"
1464 "Neighbor discovery\n"
1465 "Default router preference\n")
1467 struct interface *ifp;
1468 struct zebra_if *zif;
1470 ifp = (struct interface *) vty->index;
1473 zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
1478 ALIAS (no_ipv6_nd_router_preference,
1479 no_ipv6_nd_router_preference_val_cmd,
1480 "no ipv6 nd router-preference (high|medium|low)",
1482 "Interface IPv6 config commands\n"
1483 "Neighbor discovery\n"
1484 "Default router preference\n"
1485 "High default router preference\n"
1486 "Low default router preference\n"
1487 "Medium default router preference (default)\n")
1491 "ipv6 nd mtu <1-65535>",
1492 "Interface IPv6 config commands\n"
1493 "Neighbor discovery\n"
1497 struct interface *ifp = (struct interface *) vty->index;
1498 struct zebra_if *zif = ifp->info;
1499 VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
1503 DEFUN (no_ipv6_nd_mtu,
1507 "Interface IPv6 config commands\n"
1508 "Neighbor discovery\n"
1511 struct interface *ifp = (struct interface *) vty->index;
1512 struct zebra_if *zif = ifp->info;
1513 zif->rtadv.AdvLinkMTU = 0;
1517 ALIAS (no_ipv6_nd_mtu,
1518 no_ipv6_nd_mtu_val_cmd,
1519 "no ipv6 nd mtu <1-65535>",
1521 "Interface IPv6 config commands\n"
1522 "Neighbor discovery\n"
1526 /* Write configuration about router advertisement. */
1528 rtadv_config_write (struct vty *vty, struct interface *ifp)
1530 struct zebra_if *zif;
1531 struct listnode *node;
1532 struct rtadv_prefix *rprefix;
1533 char buf[PREFIX_STRLEN];
1538 if (! if_is_loopback (ifp))
1540 if (zif->rtadv.AdvSendAdvertisements)
1541 vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
1545 interval = zif->rtadv.MaxRtrAdvInterval;
1546 if (interval % 1000)
1547 vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
1550 if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
1551 vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
1554 if (zif->rtadv.AdvIntervalOption)
1555 vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1557 if (zif->rtadv.AdvDefaultLifetime != -1)
1558 vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1561 if (zif->rtadv.HomeAgentPreference)
1562 vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1563 zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1565 if (zif->rtadv.HomeAgentLifetime != -1)
1566 vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
1567 zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
1569 if (zif->rtadv.AdvHomeAgentFlag)
1570 vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
1572 if (zif->rtadv.AdvReachableTime)
1573 vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
1576 if (zif->rtadv.AdvManagedFlag)
1577 vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
1579 if (zif->rtadv.AdvOtherConfigFlag)
1580 vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
1582 if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
1583 vty_out (vty, " ipv6 nd router-preference %s%s",
1584 rtadv_pref_strs[zif->rtadv.DefaultPreference],
1587 if (zif->rtadv.AdvLinkMTU)
1588 vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1590 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
1592 vty_out (vty, " ipv6 nd prefix %s",
1593 prefix2str (&rprefix->prefix, buf, sizeof(buf)));
1594 if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
1595 (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
1597 if (rprefix->AdvValidLifetime == UINT32_MAX)
1598 vty_out (vty, " infinite");
1600 vty_out (vty, " %u", rprefix->AdvValidLifetime);
1601 if (rprefix->AdvPreferredLifetime == UINT32_MAX)
1602 vty_out (vty, " infinite");
1604 vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
1606 if (!rprefix->AdvOnLinkFlag)
1607 vty_out (vty, " off-link");
1608 if (!rprefix->AdvAutonomousFlag)
1609 vty_out (vty, " no-autoconfig");
1610 if (rprefix->AdvRouterAddressFlag)
1611 vty_out (vty, " router-address");
1612 vty_out (vty, "%s", VTY_NEWLINE);
1618 rtadv_event (struct zebra_vrf *zvrf, enum rtadv_event event, int val)
1620 struct rtadv *rtadv = &zvrf->rtadv;
1625 if (! rtadv->ra_read)
1626 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
1627 if (! rtadv->ra_timer)
1628 rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
1632 if (rtadv->ra_timer)
1634 thread_cancel (rtadv->ra_timer);
1635 rtadv->ra_timer = NULL;
1639 thread_cancel (rtadv->ra_read);
1640 rtadv->ra_read = NULL;
1644 if (! rtadv->ra_timer)
1645 rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zvrf,
1648 case RTADV_TIMER_MSEC:
1649 if (! rtadv->ra_timer)
1650 rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
1654 if (! rtadv->ra_read)
1655 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
1664 rtadv_init (struct zebra_vrf *zvrf)
1666 zvrf->rtadv.sock = rtadv_make_socket (zvrf->vrf_id);
1670 rtadv_terminate (struct zebra_vrf *zvrf)
1672 rtadv_event (zvrf, RTADV_STOP, 0);
1674 if (zvrf->rtadv.sock >= 0)
1676 close (zvrf->rtadv.sock);
1677 zvrf->rtadv.sock = -1;
1680 zvrf->rtadv.adv_if_count = 0;
1681 zvrf->rtadv.adv_msec_if_count = 0;
1685 rtadv_cmd_init (void)
1687 install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
1688 install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
1689 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
1690 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
1691 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
1692 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
1693 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
1694 install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
1695 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
1696 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
1697 install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
1698 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
1699 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
1700 install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
1701 install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
1702 install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
1703 install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
1704 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
1705 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
1706 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
1707 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
1708 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
1709 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
1710 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
1711 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
1712 install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
1713 install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
1714 install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
1715 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
1716 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
1717 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
1718 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
1719 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
1720 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
1721 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
1722 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
1723 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
1724 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
1725 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
1726 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
1727 install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
1728 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
1729 install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
1730 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
1731 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
1732 install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
1733 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
1734 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
1738 if_join_all_router (int sock, struct interface *ifp)
1742 struct ipv6_mreq mreq;
1744 memset (&mreq, 0, sizeof (struct ipv6_mreq));
1745 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
1746 mreq.ipv6mr_interface = ifp->ifindex;
1748 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1749 (char *) &mreq, sizeof mreq);
1751 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno));
1753 zlog_info ("rtadv: %s join to all-routers multicast group", ifp->name);
1759 if_leave_all_router (int sock, struct interface *ifp)
1763 struct ipv6_mreq mreq;
1765 memset (&mreq, 0, sizeof (struct ipv6_mreq));
1766 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
1767 mreq.ipv6mr_interface = ifp->ifindex;
1769 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
1770 (char *) &mreq, sizeof mreq);
1772 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno));
1774 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp->name);
1781 rtadv_init (struct zebra_vrf *zvrf)
1786 rtadv_terminate (struct zebra_vrf *zvrf)
1791 rtadv_cmd_init (void)
1795 #endif /* HAVE_RTADV && HAVE_IPV6 */