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
, unsigned int *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 #ifdef HAVE_STRUCT_SOCKADDR_DL
299 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
301 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
303 /* Option length should be rounded up to next octet if
304 the link address does not end on an octet boundary. */
305 buf
[len
++] = (sdl
->sdl_alen
+ 9) >> 3;
307 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
308 len
+= sdl
->sdl_alen
;
310 /* Pad option to end on an octet boundary. */
311 memset (buf
+ len
, 0, -(sdl
->sdl_alen
+ 2) & 0x7);
312 len
+= -(sdl
->sdl_alen
+ 2) & 0x7;
315 if (ifp
->hw_addr_len
!= 0)
317 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
319 /* Option length should be rounded up to next octet if
320 the link address does not end on an octet boundary. */
321 buf
[len
++] = (ifp
->hw_addr_len
+ 9) >> 3;
323 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
324 len
+= ifp
->hw_addr_len
;
326 /* Pad option to end on an octet boundary. */
327 memset (buf
+ len
, 0, -(ifp
->hw_addr_len
+ 2) & 0x7);
328 len
+= -(ifp
->hw_addr_len
+ 2) & 0x7;
330 #endif /* HAVE_STRUCT_SOCKADDR_DL */
333 if (zif
->rtadv
.AdvLinkMTU
)
335 struct nd_opt_mtu
* opt
= (struct nd_opt_mtu
*) (buf
+ len
);
336 opt
->nd_opt_mtu_type
= ND_OPT_MTU
;
337 opt
->nd_opt_mtu_len
= 1;
338 opt
->nd_opt_mtu_reserved
= 0;
339 opt
->nd_opt_mtu_mtu
= htonl (zif
->rtadv
.AdvLinkMTU
);
340 len
+= sizeof (struct nd_opt_mtu
);
343 msg
.msg_name
= (void *) &addr
;
344 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
347 msg
.msg_control
= (void *) adata
;
348 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
353 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
354 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
355 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
356 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
358 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
359 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
360 pkt
->ipi6_ifindex
= ifp
->ifindex
;
362 ret
= sendmsg (sock
, &msg
, 0);
365 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
366 errno
, safe_strerror(errno
));
371 rtadv_timer (struct thread
*thread
)
373 struct zebra_vrf
*zvrf
= THREAD_ARG (thread
);
374 struct listnode
*node
, *nnode
;
375 struct interface
*ifp
;
376 struct zebra_if
*zif
;
379 zvrf
->rtadv
.ra_timer
= NULL
;
380 if (zvrf
->rtadv
.adv_msec_if_count
== 0)
382 period
= 1000; /* 1 s */
383 rtadv_event (zvrf
, RTADV_TIMER
, 1 /* 1 s */);
387 period
= 10; /* 10 ms */
388 rtadv_event (zvrf
, RTADV_TIMER_MSEC
, 10 /* 10 ms */);
391 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf
->vrf_id
), node
, nnode
, ifp
))
393 if (if_is_loopback (ifp
) || ! if_is_operative (ifp
))
398 if (zif
->rtadv
.AdvSendAdvertisements
)
400 zif
->rtadv
.AdvIntervalTimer
-= period
;
401 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
403 /* FIXME: using MaxRtrAdvInterval each time isn't what section
404 6.2.4 of RFC4861 tells to do. */
405 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
406 rtadv_send_packet (zvrf
->rtadv
.sock
, ifp
);
414 rtadv_process_solicit (struct interface
*ifp
)
416 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
418 zlog_info ("Router solicitation received on %s vrf %u", ifp
->name
, zvrf
->vrf_id
);
420 rtadv_send_packet (zvrf
->rtadv
.sock
, ifp
);
424 rtadv_process_advert (u_char
*msg
, unsigned int len
, struct interface
*ifp
,
425 struct sockaddr_in6
*addr
)
427 struct nd_router_advert
*radvert
;
428 char addr_str
[INET6_ADDRSTRLEN
];
429 struct zebra_if
*zif
;
433 inet_ntop (AF_INET6
, &addr
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
435 if (IS_ZEBRA_DEBUG_PACKET
)
436 zlog_debug ("Router advertisement received on %s from : %s", ifp
->name
, addr_str
);
438 if (len
< sizeof(struct nd_router_advert
)) {
439 zlog_warn("received icmpv6 RA packet with invalid length (%d) from %s",
443 if (!IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) {
444 zlog_warn("received icmpv6 RA packet with non-linklocal source address from %s",
449 radvert
= (struct nd_router_advert
*) msg
;
451 if ((radvert
->nd_ra_curhoplimit
&& zif
->rtadv
.AdvCurHopLimit
) &&
452 (radvert
->nd_ra_curhoplimit
!= zif
->rtadv
.AdvCurHopLimit
))
454 zlog_warn("our AdvCurHopLimit on %s doesn't agree with %s",
455 ifp
->name
, addr_str
);
458 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_MANAGED
) &&
459 !zif
->rtadv
.AdvManagedFlag
)
461 zlog_warn("our AdvManagedFlag on %s doesn't agree with %s",
462 ifp
->name
, addr_str
);
465 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_OTHER
) &&
466 !zif
->rtadv
.AdvOtherConfigFlag
)
468 zlog_warn("our AdvOtherConfigFlag on %s doesn't agree with %s",
469 ifp
->name
, addr_str
);
472 if ((radvert
->nd_ra_reachable
&& zif
->rtadv
.AdvReachableTime
) &&
473 (ntohl(radvert
->nd_ra_reachable
) != zif
->rtadv
.AdvReachableTime
))
475 zlog_warn("our AdvReachableTime on %s doesn't agree with %s",
476 ifp
->name
, addr_str
);
479 if ((radvert
->nd_ra_retransmit
&& zif
->rtadv
.AdvRetransTimer
) &&
480 (ntohl(radvert
->nd_ra_retransmit
) != (unsigned int)zif
->rtadv
.AdvRetransTimer
))
482 zlog_warn("our AdvRetransTimer on %s doesn't agree with %s",
483 ifp
->name
, addr_str
);
486 /* Currently supporting only P2P links, so any new RA source address is
487 considered as the replacement of the previously learnt Link-Local address.
488 As per the RFC, lifetime zero is to be considered a delete */
489 if (ntohs(radvert
->nd_ra_router_lifetime
))
490 nbr_connected_replacement_add_ipv6(ifp
, &addr
->sin6_addr
, 128);
492 nbr_connected_delete_ipv6(ifp
, &addr
->sin6_addr
, 128);
499 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
,
500 struct sockaddr_in6
*from
, vrf_id_t vrf_id
)
502 struct icmp6_hdr
*icmph
;
503 struct interface
*ifp
;
504 struct zebra_if
*zif
;
506 /* Interface search. */
507 ifp
= if_lookup_by_index_vrf (ifindex
, vrf_id
);
510 zlog_warn ("Unknown interface index: %d, vrf %u", ifindex
, vrf_id
);
514 if (if_is_loopback (ifp
))
517 /* Check interface configuration. */
519 if (! zif
->rtadv
.AdvSendAdvertisements
)
522 /* ICMP message length check. */
523 if (len
< sizeof (struct icmp6_hdr
))
525 zlog_warn ("Invalid ICMPV6 packet length: %d", len
);
529 icmph
= (struct icmp6_hdr
*) buf
;
531 /* ICMP message type check. */
532 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
533 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
535 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph
->icmp6_type
);
539 /* Hoplimit check. */
540 if (hoplimit
>= 0 && hoplimit
!= 255)
542 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
547 /* Check ICMP message type. */
548 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
549 rtadv_process_solicit (ifp
);
550 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
551 rtadv_process_advert (buf
, len
, ifp
, from
);
557 rtadv_read (struct thread
*thread
)
561 u_char buf
[RTADV_MSG_SIZE
];
562 struct sockaddr_in6 from
;
563 unsigned int ifindex
= 0;
565 struct zebra_vrf
*zvrf
= THREAD_ARG (thread
);
567 sock
= THREAD_FD (thread
);
568 zvrf
->rtadv
.ra_read
= NULL
;
570 /* Register myself. */
571 rtadv_event (zvrf
, RTADV_READ
, sock
);
573 len
= rtadv_recv_packet (sock
, buf
, BUFSIZ
, &from
, &ifindex
, &hoplimit
);
577 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno
));
581 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
, &from
, zvrf
->vrf_id
);
587 rtadv_make_socket (vrf_id_t vrf_id
)
591 struct icmp6_filter filter
;
593 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
594 zlog_err ("rtadv_make_socket: could not raise privs, %s",
595 safe_strerror (errno
) );
597 sock
= vrf_socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
, vrf_id
);
599 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
600 zlog_err ("rtadv_make_socket: could not lower privs, %s",
601 safe_strerror (errno
) );
603 /* When we can't make ICMPV6 socket simply back. Router
604 advertisement feature will not be supported. */
608 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
611 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
614 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
617 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
620 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
624 ICMP6_FILTER_SETBLOCKALL(&filter
);
625 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
626 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
628 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
629 sizeof (struct icmp6_filter
));
632 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
639 static struct rtadv_prefix
*
640 rtadv_prefix_new (void)
642 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
646 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
648 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
651 static struct rtadv_prefix
*
652 rtadv_prefix_lookup (struct list
*rplist
, struct prefix_ipv6
*p
)
654 struct listnode
*node
;
655 struct rtadv_prefix
*rprefix
;
657 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
658 if (prefix_same ((struct prefix
*) &rprefix
->prefix
, (struct prefix
*) p
))
663 static struct rtadv_prefix
*
664 rtadv_prefix_get (struct list
*rplist
, struct prefix_ipv6
*p
)
666 struct rtadv_prefix
*rprefix
;
668 rprefix
= rtadv_prefix_lookup (rplist
, p
);
672 rprefix
= rtadv_prefix_new ();
673 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix_ipv6
));
674 listnode_add (rplist
, rprefix
);
680 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
682 struct rtadv_prefix
*rprefix
;
684 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
686 /* Set parameters. */
687 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
688 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
689 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
690 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
691 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
695 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
697 struct rtadv_prefix
*rprefix
;
699 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
702 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
703 rtadv_prefix_free (rprefix
);
710 DEFUN (ipv6_nd_suppress_ra
,
711 ipv6_nd_suppress_ra_cmd
,
712 "ipv6 nd suppress-ra",
713 "Interface IPv6 config commands\n"
714 "Neighbor discovery\n"
715 "Suppress Router Advertisement\n")
717 struct interface
*ifp
;
718 struct zebra_if
*zif
;
719 struct zebra_vrf
*zvrf
;
723 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
725 if (if_is_loopback (ifp
))
727 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
731 if (zif
->rtadv
.AdvSendAdvertisements
)
733 zif
->rtadv
.AdvSendAdvertisements
= 0;
734 zif
->rtadv
.AdvIntervalTimer
= 0;
735 zvrf
->rtadv
.adv_if_count
--;
737 if_leave_all_router (zvrf
->rtadv
.sock
, ifp
);
739 if (zvrf
->rtadv
.adv_if_count
== 0)
740 rtadv_event (zvrf
, RTADV_STOP
, 0);
746 DEFUN (no_ipv6_nd_suppress_ra
,
747 no_ipv6_nd_suppress_ra_cmd
,
748 "no ipv6 nd suppress-ra",
750 "Interface IPv6 config commands\n"
751 "Neighbor discovery\n"
752 "Suppress Router Advertisement\n")
754 struct interface
*ifp
;
755 struct zebra_if
*zif
;
756 struct zebra_vrf
*zvrf
;
760 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
762 if (if_is_loopback (ifp
))
764 vty_out (vty
, "Invalid interface%s", VTY_NEWLINE
);
768 if (! zif
->rtadv
.AdvSendAdvertisements
)
770 zif
->rtadv
.AdvSendAdvertisements
= 1;
771 zif
->rtadv
.AdvIntervalTimer
= 0;
772 zvrf
->rtadv
.adv_if_count
++;
774 if_join_all_router (zvrf
->rtadv
.sock
, ifp
);
776 if (zvrf
->rtadv
.adv_if_count
== 1)
777 rtadv_event (zvrf
, RTADV_START
, zvrf
->rtadv
.sock
);
783 DEFUN (ipv6_nd_ra_interval_msec
,
784 ipv6_nd_ra_interval_msec_cmd
,
785 "ipv6 nd ra-interval msec <70-1800000>",
786 "Interface IPv6 config commands\n"
787 "Neighbor discovery\n"
788 "Router Advertisement interval\n"
789 "Router Advertisement interval in milliseconds\n")
792 struct interface
*ifp
= (struct interface
*) vty
->index
;
793 struct zebra_if
*zif
= ifp
->info
;
794 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
796 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 70, 1800000);
797 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
* 1000))
799 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
803 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
804 zvrf
->rtadv
.adv_msec_if_count
--;
807 zvrf
->rtadv
.adv_msec_if_count
++;
809 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
810 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
811 zif
->rtadv
.AdvIntervalTimer
= 0;
816 DEFUN (ipv6_nd_ra_interval
,
817 ipv6_nd_ra_interval_cmd
,
818 "ipv6 nd ra-interval <1-1800>",
819 "Interface IPv6 config commands\n"
820 "Neighbor discovery\n"
821 "Router Advertisement interval\n"
822 "Router Advertisement interval in seconds\n")
825 struct interface
*ifp
= (struct interface
*) vty
->index
;
826 struct zebra_if
*zif
= ifp
->info
;
827 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
829 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 1, 1800);
830 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
))
832 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
836 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
837 zvrf
->rtadv
.adv_msec_if_count
--;
839 /* convert to milliseconds */
840 interval
= interval
* 1000;
842 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
843 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
844 zif
->rtadv
.AdvIntervalTimer
= 0;
849 DEFUN (no_ipv6_nd_ra_interval
,
850 no_ipv6_nd_ra_interval_cmd
,
851 "no ipv6 nd ra-interval",
853 "Interface IPv6 config commands\n"
854 "Neighbor discovery\n"
855 "Router Advertisement interval\n")
857 struct interface
*ifp
;
858 struct zebra_if
*zif
;
859 struct zebra_vrf
*zvrf
;
861 ifp
= (struct interface
*) vty
->index
;
863 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
865 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
866 zvrf
->rtadv
.adv_msec_if_count
--;
868 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
869 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
870 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
875 ALIAS (no_ipv6_nd_ra_interval
,
876 no_ipv6_nd_ra_interval_val_cmd
,
877 "no ipv6 nd ra-interval <1-1800>",
879 "Interface IPv6 config commands\n"
880 "Neighbor discovery\n"
881 "Router Advertisement interval\n")
883 ALIAS (no_ipv6_nd_ra_interval
,
884 no_ipv6_nd_ra_interval_msec_val_cmd
,
885 "no ipv6 nd ra-interval msec <1-1800000>",
887 "Interface IPv6 config commands\n"
888 "Neighbor discovery\n"
889 "Router Advertisement interval\n"
890 "Router Advertisement interval in milliseconds\n")
892 DEFUN (ipv6_nd_ra_lifetime
,
893 ipv6_nd_ra_lifetime_cmd
,
894 "ipv6 nd ra-lifetime <0-9000>",
895 "Interface IPv6 config commands\n"
896 "Neighbor discovery\n"
898 "Router lifetime in seconds (0 stands for a non-default gw)\n")
901 struct interface
*ifp
;
902 struct zebra_if
*zif
;
904 ifp
= (struct interface
*) vty
->index
;
907 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime
, argv
[0], 0, 9000);
909 /* The value to be placed in the Router Lifetime field
910 * of Router Advertisements sent from the interface,
911 * in seconds. MUST be either zero or between
912 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
913 if ((lifetime
!= 0 && lifetime
* 1000 < zif
->rtadv
.MaxRtrAdvInterval
))
915 vty_out (vty
, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE
);
919 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
924 DEFUN (no_ipv6_nd_ra_lifetime
,
925 no_ipv6_nd_ra_lifetime_cmd
,
926 "no ipv6 nd ra-lifetime",
928 "Interface IPv6 config commands\n"
929 "Neighbor discovery\n"
932 struct interface
*ifp
;
933 struct zebra_if
*zif
;
935 ifp
= (struct interface
*) vty
->index
;
938 zif
->rtadv
.AdvDefaultLifetime
= -1;
943 ALIAS (no_ipv6_nd_ra_lifetime
,
944 no_ipv6_nd_ra_lifetime_val_cmd
,
945 "no ipv6 nd ra-lifetime <0-9000>",
947 "Interface IPv6 config commands\n"
948 "Neighbor discovery\n"
950 "Router lifetime in seconds (0 stands for a non-default gw)\n")
952 DEFUN (ipv6_nd_reachable_time
,
953 ipv6_nd_reachable_time_cmd
,
954 "ipv6 nd reachable-time <1-3600000>",
955 "Interface IPv6 config commands\n"
956 "Neighbor discovery\n"
958 "Reachable time in milliseconds\n")
960 struct interface
*ifp
= (struct interface
*) vty
->index
;
961 struct zebra_if
*zif
= ifp
->info
;
962 VTY_GET_INTEGER_RANGE ("reachable time", zif
->rtadv
.AdvReachableTime
, argv
[0], 1, RTADV_MAX_REACHABLE_TIME
);
966 DEFUN (no_ipv6_nd_reachable_time
,
967 no_ipv6_nd_reachable_time_cmd
,
968 "no ipv6 nd reachable-time",
970 "Interface IPv6 config commands\n"
971 "Neighbor discovery\n"
974 struct interface
*ifp
;
975 struct zebra_if
*zif
;
977 ifp
= (struct interface
*) vty
->index
;
980 zif
->rtadv
.AdvReachableTime
= 0;
985 ALIAS (no_ipv6_nd_reachable_time
,
986 no_ipv6_nd_reachable_time_val_cmd
,
987 "no ipv6 nd reachable-time <1-3600000>",
989 "Interface IPv6 config commands\n"
990 "Neighbor discovery\n"
992 "Reachable time in milliseconds\n")
994 DEFUN (ipv6_nd_homeagent_preference
,
995 ipv6_nd_homeagent_preference_cmd
,
996 "ipv6 nd home-agent-preference <0-65535>",
997 "Interface IPv6 config commands\n"
998 "Neighbor discovery\n"
999 "Home Agent preference\n"
1000 "preference value (default is 0, least preferred)\n")
1002 struct interface
*ifp
= (struct interface
*) vty
->index
;
1003 struct zebra_if
*zif
= ifp
->info
;
1004 VTY_GET_INTEGER_RANGE ("home agent preference", zif
->rtadv
.HomeAgentPreference
, argv
[0], 0, 65535);
1008 DEFUN (no_ipv6_nd_homeagent_preference
,
1009 no_ipv6_nd_homeagent_preference_cmd
,
1010 "no ipv6 nd home-agent-preference",
1012 "Interface IPv6 config commands\n"
1013 "Neighbor discovery\n"
1014 "Home Agent preference\n")
1016 struct interface
*ifp
;
1017 struct zebra_if
*zif
;
1019 ifp
= (struct interface
*) vty
->index
;
1022 zif
->rtadv
.HomeAgentPreference
= 0;
1027 ALIAS (no_ipv6_nd_homeagent_preference
,
1028 no_ipv6_nd_homeagent_preference_val_cmd
,
1029 "no ipv6 nd home-agent-preference <0-65535>",
1031 "Interface IPv6 config commands\n"
1032 "Neighbor discovery\n"
1033 "Home Agent preference\n"
1034 "preference value (default is 0, least preferred)\n")
1036 DEFUN (ipv6_nd_homeagent_lifetime
,
1037 ipv6_nd_homeagent_lifetime_cmd
,
1038 "ipv6 nd home-agent-lifetime <0-65520>",
1039 "Interface IPv6 config commands\n"
1040 "Neighbor discovery\n"
1041 "Home Agent lifetime\n"
1042 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1044 struct interface
*ifp
= (struct interface
*) vty
->index
;
1045 struct zebra_if
*zif
= ifp
->info
;
1046 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif
->rtadv
.HomeAgentLifetime
, argv
[0], 0, RTADV_MAX_HALIFETIME
);
1050 DEFUN (no_ipv6_nd_homeagent_lifetime
,
1051 no_ipv6_nd_homeagent_lifetime_cmd
,
1052 "no ipv6 nd home-agent-lifetime",
1054 "Interface IPv6 config commands\n"
1055 "Neighbor discovery\n"
1056 "Home Agent lifetime\n")
1058 struct interface
*ifp
;
1059 struct zebra_if
*zif
;
1061 ifp
= (struct interface
*) vty
->index
;
1064 zif
->rtadv
.HomeAgentLifetime
= -1;
1069 ALIAS (no_ipv6_nd_homeagent_lifetime
,
1070 no_ipv6_nd_homeagent_lifetime_val_cmd
,
1071 "no ipv6 nd home-agent-lifetime <0-65520>",
1073 "Interface IPv6 config commands\n"
1074 "Neighbor discovery\n"
1075 "Home Agent lifetime\n"
1076 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1078 DEFUN (ipv6_nd_managed_config_flag
,
1079 ipv6_nd_managed_config_flag_cmd
,
1080 "ipv6 nd managed-config-flag",
1081 "Interface IPv6 config commands\n"
1082 "Neighbor discovery\n"
1083 "Managed address configuration flag\n")
1085 struct interface
*ifp
;
1086 struct zebra_if
*zif
;
1088 ifp
= (struct interface
*) vty
->index
;
1091 zif
->rtadv
.AdvManagedFlag
= 1;
1096 DEFUN (no_ipv6_nd_managed_config_flag
,
1097 no_ipv6_nd_managed_config_flag_cmd
,
1098 "no ipv6 nd managed-config-flag",
1100 "Interface IPv6 config commands\n"
1101 "Neighbor discovery\n"
1102 "Managed address configuration flag\n")
1104 struct interface
*ifp
;
1105 struct zebra_if
*zif
;
1107 ifp
= (struct interface
*) vty
->index
;
1110 zif
->rtadv
.AdvManagedFlag
= 0;
1115 DEFUN (ipv6_nd_homeagent_config_flag
,
1116 ipv6_nd_homeagent_config_flag_cmd
,
1117 "ipv6 nd home-agent-config-flag",
1118 "Interface IPv6 config commands\n"
1119 "Neighbor discovery\n"
1120 "Home Agent configuration flag\n")
1122 struct interface
*ifp
;
1123 struct zebra_if
*zif
;
1125 ifp
= (struct interface
*) vty
->index
;
1128 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1133 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1134 no_ipv6_nd_homeagent_config_flag_cmd
,
1135 "no ipv6 nd home-agent-config-flag",
1137 "Interface IPv6 config commands\n"
1138 "Neighbor discovery\n"
1139 "Home Agent configuration flag\n")
1141 struct interface
*ifp
;
1142 struct zebra_if
*zif
;
1144 ifp
= (struct interface
*) vty
->index
;
1147 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1152 DEFUN (ipv6_nd_adv_interval_config_option
,
1153 ipv6_nd_adv_interval_config_option_cmd
,
1154 "ipv6 nd adv-interval-option",
1155 "Interface IPv6 config commands\n"
1156 "Neighbor discovery\n"
1157 "Advertisement Interval Option\n")
1159 struct interface
*ifp
;
1160 struct zebra_if
*zif
;
1162 ifp
= (struct interface
*) vty
->index
;
1165 zif
->rtadv
.AdvIntervalOption
= 1;
1170 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1171 no_ipv6_nd_adv_interval_config_option_cmd
,
1172 "no ipv6 nd adv-interval-option",
1174 "Interface IPv6 config commands\n"
1175 "Neighbor discovery\n"
1176 "Advertisement Interval Option\n")
1178 struct interface
*ifp
;
1179 struct zebra_if
*zif
;
1181 ifp
= (struct interface
*) vty
->index
;
1184 zif
->rtadv
.AdvIntervalOption
= 0;
1189 DEFUN (ipv6_nd_other_config_flag
,
1190 ipv6_nd_other_config_flag_cmd
,
1191 "ipv6 nd other-config-flag",
1192 "Interface IPv6 config commands\n"
1193 "Neighbor discovery\n"
1194 "Other statefull configuration flag\n")
1196 struct interface
*ifp
;
1197 struct zebra_if
*zif
;
1199 ifp
= (struct interface
*) vty
->index
;
1202 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1207 DEFUN (no_ipv6_nd_other_config_flag
,
1208 no_ipv6_nd_other_config_flag_cmd
,
1209 "no ipv6 nd other-config-flag",
1211 "Interface IPv6 config commands\n"
1212 "Neighbor discovery\n"
1213 "Other statefull configuration flag\n")
1215 struct interface
*ifp
;
1216 struct zebra_if
*zif
;
1218 ifp
= (struct interface
*) vty
->index
;
1221 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1226 DEFUN (ipv6_nd_prefix
,
1228 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1229 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1230 "Interface IPv6 config commands\n"
1231 "Neighbor discovery\n"
1232 "Prefix information\n"
1234 "Valid lifetime in seconds\n"
1235 "Infinite valid lifetime\n"
1236 "Preferred lifetime in seconds\n"
1237 "Infinite preferred lifetime\n"
1238 "Do not use prefix for onlink determination\n"
1239 "Do not use prefix for autoconfiguration\n"
1240 "Set Router Address flag\n")
1245 struct interface
*ifp
;
1246 struct zebra_if
*zebra_if
;
1247 struct rtadv_prefix rp
;
1249 ifp
= (struct interface
*) vty
->index
;
1250 zebra_if
= ifp
->info
;
1252 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1255 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1258 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1259 rp
.AdvOnLinkFlag
= 1;
1260 rp
.AdvAutonomousFlag
= 1;
1261 rp
.AdvRouterAddressFlag
= 0;
1262 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1263 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1267 if ((isdigit(argv
[1][0])) || strncmp (argv
[1], "i", 1) == 0)
1269 if ( strncmp (argv
[1], "i", 1) == 0)
1270 rp
.AdvValidLifetime
= UINT32_MAX
;
1272 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1275 if ( strncmp (argv
[2], "i", 1) == 0)
1276 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1278 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1281 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1283 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1286 cursor
= cursor
+ 2;
1290 for (i
= cursor
; i
< argc
; i
++)
1292 if (strncmp (argv
[i
], "of", 2) == 0)
1293 rp
.AdvOnLinkFlag
= 0;
1294 if (strncmp (argv
[i
], "no", 2) == 0)
1295 rp
.AdvAutonomousFlag
= 0;
1296 if (strncmp (argv
[i
], "ro", 2) == 0)
1297 rp
.AdvRouterAddressFlag
= 1;
1302 rtadv_prefix_set (zebra_if
, &rp
);
1307 ALIAS (ipv6_nd_prefix
,
1308 ipv6_nd_prefix_val_nortaddr_cmd
,
1309 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1310 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1311 "Interface IPv6 config commands\n"
1312 "Neighbor discovery\n"
1313 "Prefix information\n"
1315 "Valid lifetime in seconds\n"
1316 "Infinite valid lifetime\n"
1317 "Preferred lifetime in seconds\n"
1318 "Infinite preferred lifetime\n"
1319 "Do not use prefix for onlink determination\n"
1320 "Do not use prefix for autoconfiguration\n")
1322 ALIAS (ipv6_nd_prefix
,
1323 ipv6_nd_prefix_val_rev_cmd
,
1324 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1325 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1326 "Interface IPv6 config commands\n"
1327 "Neighbor discovery\n"
1328 "Prefix information\n"
1330 "Valid lifetime in seconds\n"
1331 "Infinite valid lifetime\n"
1332 "Preferred lifetime in seconds\n"
1333 "Infinite preferred lifetime\n"
1334 "Do not use prefix for autoconfiguration\n"
1335 "Do not use prefix for onlink determination\n")
1337 ALIAS (ipv6_nd_prefix
,
1338 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1339 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1340 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1341 "Interface IPv6 config commands\n"
1342 "Neighbor discovery\n"
1343 "Prefix information\n"
1345 "Valid lifetime in seconds\n"
1346 "Infinite valid lifetime\n"
1347 "Preferred lifetime in seconds\n"
1348 "Infinite preferred lifetime\n"
1349 "Do not use prefix for autoconfiguration\n"
1350 "Do not use prefix for onlink determination\n"
1351 "Set Router Address flag\n")
1353 ALIAS (ipv6_nd_prefix
,
1354 ipv6_nd_prefix_val_noauto_cmd
,
1355 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1356 "(<0-4294967295>|infinite) (no-autoconfig|)",
1357 "Interface IPv6 config commands\n"
1358 "Neighbor discovery\n"
1359 "Prefix information\n"
1361 "Valid lifetime in seconds\n"
1362 "Infinite valid lifetime\n"
1363 "Preferred lifetime in seconds\n"
1364 "Infinite preferred lifetime\n"
1365 "Do not use prefix for autoconfiguration")
1367 ALIAS (ipv6_nd_prefix
,
1368 ipv6_nd_prefix_val_offlink_cmd
,
1369 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1370 "(<0-4294967295>|infinite) (off-link|)",
1371 "Interface IPv6 config commands\n"
1372 "Neighbor discovery\n"
1373 "Prefix information\n"
1375 "Valid lifetime in seconds\n"
1376 "Infinite valid lifetime\n"
1377 "Preferred lifetime in seconds\n"
1378 "Infinite preferred lifetime\n"
1379 "Do not use prefix for onlink determination\n")
1381 ALIAS (ipv6_nd_prefix
,
1382 ipv6_nd_prefix_val_rtaddr_cmd
,
1383 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1384 "(<0-4294967295>|infinite) (router-address|)",
1385 "Interface IPv6 config commands\n"
1386 "Neighbor discovery\n"
1387 "Prefix information\n"
1389 "Valid lifetime in seconds\n"
1390 "Infinite valid lifetime\n"
1391 "Preferred lifetime in seconds\n"
1392 "Infinite preferred lifetime\n"
1393 "Set Router Address flag\n")
1395 ALIAS (ipv6_nd_prefix
,
1396 ipv6_nd_prefix_val_cmd
,
1397 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1398 "(<0-4294967295>|infinite)",
1399 "Interface IPv6 config commands\n"
1400 "Neighbor discovery\n"
1401 "Prefix information\n"
1403 "Valid lifetime in seconds\n"
1404 "Infinite valid lifetime\n"
1405 "Preferred lifetime in seconds\n"
1406 "Infinite preferred lifetime\n")
1408 ALIAS (ipv6_nd_prefix
,
1409 ipv6_nd_prefix_noval_cmd
,
1410 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1411 "Interface IPv6 config commands\n"
1412 "Neighbor discovery\n"
1413 "Prefix information\n"
1415 "Do not use prefix for autoconfiguration\n"
1416 "Do not use prefix for onlink determination\n")
1418 ALIAS (ipv6_nd_prefix
,
1419 ipv6_nd_prefix_noval_rev_cmd
,
1420 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1421 "Interface IPv6 config commands\n"
1422 "Neighbor discovery\n"
1423 "Prefix information\n"
1425 "Do not use prefix for onlink determination\n"
1426 "Do not use prefix for autoconfiguration\n")
1428 ALIAS (ipv6_nd_prefix
,
1429 ipv6_nd_prefix_noval_noauto_cmd
,
1430 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1431 "Interface IPv6 config commands\n"
1432 "Neighbor discovery\n"
1433 "Prefix information\n"
1435 "Do not use prefix for autoconfiguration\n")
1437 ALIAS (ipv6_nd_prefix
,
1438 ipv6_nd_prefix_noval_offlink_cmd
,
1439 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1440 "Interface IPv6 config commands\n"
1441 "Neighbor discovery\n"
1442 "Prefix information\n"
1444 "Do not use prefix for onlink determination\n")
1446 ALIAS (ipv6_nd_prefix
,
1447 ipv6_nd_prefix_noval_rtaddr_cmd
,
1448 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1449 "Interface IPv6 config commands\n"
1450 "Neighbor discovery\n"
1451 "Prefix information\n"
1453 "Set Router Address flag\n")
1455 ALIAS (ipv6_nd_prefix
,
1456 ipv6_nd_prefix_prefix_cmd
,
1457 "ipv6 nd prefix X:X::X:X/M",
1458 "Interface IPv6 config commands\n"
1459 "Neighbor discovery\n"
1460 "Prefix information\n"
1463 DEFUN (no_ipv6_nd_prefix
,
1464 no_ipv6_nd_prefix_cmd
,
1465 "no ipv6 nd prefix IPV6PREFIX",
1467 "Interface IPv6 config commands\n"
1468 "Neighbor discovery\n"
1469 "Prefix information\n"
1473 struct interface
*ifp
;
1474 struct zebra_if
*zebra_if
;
1475 struct rtadv_prefix rp
;
1477 ifp
= (struct interface
*) vty
->index
;
1478 zebra_if
= ifp
->info
;
1480 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1483 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1486 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1488 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1491 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1498 ALIAS (no_ipv6_nd_prefix
,
1499 no_ipv6_nd_prefix_val_nortaddr_cmd
,
1500 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1502 "Interface IPv6 config commands\n"
1503 "Neighbor discovery\n"
1504 "Prefix information\n"
1506 "Valid lifetime in seconds\n"
1507 "Infinite valid lifetime\n"
1508 "Preferred lifetime in seconds\n"
1509 "Infinite preferred lifetime\n"
1510 "Do not use prefix for onlink determination\n"
1511 "Do not use prefix for autoconfiguration\n"
1512 "Set Router Address flag\n")
1514 ALIAS (no_ipv6_nd_prefix
,
1515 no_ipv6_nd_prefix_val_rev_cmd
,
1516 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1518 "Interface IPv6 config commands\n"
1519 "Neighbor discovery\n"
1520 "Prefix information\n"
1522 "Valid lifetime in seconds\n"
1523 "Infinite valid lifetime\n"
1524 "Preferred lifetime in seconds\n"
1525 "Infinite preferred lifetime\n"
1526 "Do not use prefix for autoconfiguration\n"
1527 "Do not use prefix for onlink determination\n")
1529 ALIAS (no_ipv6_nd_prefix
,
1530 no_ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1531 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1533 "Interface IPv6 config commands\n"
1534 "Neighbor discovery\n"
1535 "Prefix information\n"
1537 "Valid lifetime in seconds\n"
1538 "Infinite valid lifetime\n"
1539 "Preferred lifetime in seconds\n"
1540 "Infinite preferred lifetime\n"
1541 "Do not use prefix for autoconfiguration\n"
1542 "Do not use prefix for onlink determination\n"
1543 "Set Router Address flag\n")
1545 ALIAS (no_ipv6_nd_prefix
,
1546 no_ipv6_nd_prefix_val_noauto_cmd
,
1547 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1549 "Interface IPv6 config commands\n"
1550 "Neighbor discovery\n"
1551 "Prefix information\n"
1553 "Valid lifetime in seconds\n"
1554 "Infinite valid lifetime\n"
1555 "Preferred lifetime in seconds\n"
1556 "Infinite preferred lifetime\n"
1557 "Do not use prefix for autoconfiguration")
1559 ALIAS (no_ipv6_nd_prefix
,
1560 no_ipv6_nd_prefix_val_offlink_cmd
,
1561 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1563 "Interface IPv6 config commands\n"
1564 "Neighbor discovery\n"
1565 "Prefix information\n"
1567 "Valid lifetime in seconds\n"
1568 "Infinite valid lifetime\n"
1569 "Preferred lifetime in seconds\n"
1570 "Infinite preferred lifetime\n"
1571 "Do not use prefix for onlink determination\n")
1573 ALIAS (no_ipv6_nd_prefix
,
1574 no_ipv6_nd_prefix_val_rtaddr_cmd
,
1575 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1577 "Interface IPv6 config commands\n"
1578 "Neighbor discovery\n"
1579 "Prefix information\n"
1581 "Valid lifetime in seconds\n"
1582 "Infinite valid lifetime\n"
1583 "Preferred lifetime in seconds\n"
1584 "Infinite preferred lifetime\n"
1585 "Set Router Address flag\n")
1587 ALIAS (no_ipv6_nd_prefix
,
1588 no_ipv6_nd_prefix_val_cmd
,
1589 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1591 "Interface IPv6 config commands\n"
1592 "Neighbor discovery\n"
1593 "Prefix information\n"
1595 "Valid lifetime in seconds\n"
1596 "Infinite valid lifetime\n"
1597 "Preferred lifetime in seconds\n"
1598 "Infinite preferred lifetime\n")
1600 ALIAS (no_ipv6_nd_prefix
,
1601 no_ipv6_nd_prefix_noval_cmd
,
1602 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1604 "Interface IPv6 config commands\n"
1605 "Neighbor discovery\n"
1606 "Prefix information\n"
1608 "Do not use prefix for autoconfiguration\n"
1609 "Do not use prefix for onlink determination\n")
1611 ALIAS (no_ipv6_nd_prefix
,
1612 no_ipv6_nd_prefix_noval_rev_cmd
,
1613 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1615 "Interface IPv6 config commands\n"
1616 "Neighbor discovery\n"
1617 "Prefix information\n"
1619 "Do not use prefix for onlink determination\n"
1620 "Do not use prefix for autoconfiguration\n")
1622 ALIAS (no_ipv6_nd_prefix
,
1623 no_ipv6_nd_prefix_noval_noauto_cmd
,
1624 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1626 "Interface IPv6 config commands\n"
1627 "Neighbor discovery\n"
1628 "Prefix information\n"
1630 "Do not use prefix for autoconfiguration\n")
1632 ALIAS (no_ipv6_nd_prefix
,
1633 no_ipv6_nd_prefix_noval_offlink_cmd
,
1634 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1636 "Interface IPv6 config commands\n"
1637 "Neighbor discovery\n"
1638 "Prefix information\n"
1640 "Do not use prefix for onlink determination\n")
1642 ALIAS (no_ipv6_nd_prefix
,
1643 no_ipv6_nd_prefix_noval_rtaddr_cmd
,
1644 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1646 "Interface IPv6 config commands\n"
1647 "Neighbor discovery\n"
1648 "Prefix information\n"
1650 "Set Router Address flag\n")
1652 DEFUN (ipv6_nd_router_preference
,
1653 ipv6_nd_router_preference_cmd
,
1654 "ipv6 nd router-preference (high|medium|low)",
1655 "Interface IPv6 config commands\n"
1656 "Neighbor discovery\n"
1657 "Default router preference\n"
1658 "High default router preference\n"
1659 "Low default router preference\n"
1660 "Medium default router preference (default)\n")
1662 struct interface
*ifp
;
1663 struct zebra_if
*zif
;
1666 ifp
= (struct interface
*) vty
->index
;
1669 while (0 != rtadv_pref_strs
[i
])
1671 if (strncmp (argv
[0], rtadv_pref_strs
[i
], 1) == 0)
1673 zif
->rtadv
.DefaultPreference
= i
;
1679 return CMD_ERR_NO_MATCH
;
1682 DEFUN (no_ipv6_nd_router_preference
,
1683 no_ipv6_nd_router_preference_cmd
,
1684 "no ipv6 nd router-preference",
1686 "Interface IPv6 config commands\n"
1687 "Neighbor discovery\n"
1688 "Default router preference\n")
1690 struct interface
*ifp
;
1691 struct zebra_if
*zif
;
1693 ifp
= (struct interface
*) vty
->index
;
1696 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1701 ALIAS (no_ipv6_nd_router_preference
,
1702 no_ipv6_nd_router_preference_val_cmd
,
1703 "no ipv6 nd router-preference (high|medium|low)",
1705 "Interface IPv6 config commands\n"
1706 "Neighbor discovery\n"
1707 "Default router preference\n"
1708 "High default router preference\n"
1709 "Low default router preference\n"
1710 "Medium default router preference (default)\n")
1714 "ipv6 nd mtu <1-65535>",
1715 "Interface IPv6 config commands\n"
1716 "Neighbor discovery\n"
1720 struct interface
*ifp
= (struct interface
*) vty
->index
;
1721 struct zebra_if
*zif
= ifp
->info
;
1722 VTY_GET_INTEGER_RANGE ("MTU", zif
->rtadv
.AdvLinkMTU
, argv
[0], 1, 65535);
1726 DEFUN (no_ipv6_nd_mtu
,
1730 "Interface IPv6 config commands\n"
1731 "Neighbor discovery\n"
1734 struct interface
*ifp
= (struct interface
*) vty
->index
;
1735 struct zebra_if
*zif
= ifp
->info
;
1736 zif
->rtadv
.AdvLinkMTU
= 0;
1740 ALIAS (no_ipv6_nd_mtu
,
1741 no_ipv6_nd_mtu_val_cmd
,
1742 "no ipv6 nd mtu <1-65535>",
1744 "Interface IPv6 config commands\n"
1745 "Neighbor discovery\n"
1749 /* Write configuration about router advertisement. */
1751 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1753 struct zebra_if
*zif
;
1754 struct listnode
*node
;
1755 struct rtadv_prefix
*rprefix
;
1756 u_char buf
[INET6_ADDRSTRLEN
];
1761 if (! if_is_loopback (ifp
))
1763 if (zif
->rtadv
.AdvSendAdvertisements
)
1764 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1768 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1769 if (interval
% 1000)
1770 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1773 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1774 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1777 if (zif
->rtadv
.AdvIntervalOption
)
1778 vty_out (vty
, " ipv6 nd adv-interval-option%s", VTY_NEWLINE
);
1780 if (zif
->rtadv
.AdvDefaultLifetime
!= -1)
1781 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1784 if (zif
->rtadv
.HomeAgentPreference
)
1785 vty_out (vty
, " ipv6 nd home-agent-preference %u%s",
1786 zif
->rtadv
.HomeAgentPreference
, VTY_NEWLINE
);
1788 if (zif
->rtadv
.HomeAgentLifetime
!= -1)
1789 vty_out (vty
, " ipv6 nd home-agent-lifetime %u%s",
1790 zif
->rtadv
.HomeAgentLifetime
, VTY_NEWLINE
);
1792 if (zif
->rtadv
.AdvHomeAgentFlag
)
1793 vty_out (vty
, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE
);
1795 if (zif
->rtadv
.AdvReachableTime
)
1796 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1799 if (zif
->rtadv
.AdvManagedFlag
)
1800 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1802 if (zif
->rtadv
.AdvOtherConfigFlag
)
1803 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1805 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1806 vty_out (vty
, " ipv6 nd router-preference %s%s",
1807 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1810 if (zif
->rtadv
.AdvLinkMTU
)
1811 vty_out (vty
, " ipv6 nd mtu %d%s", zif
->rtadv
.AdvLinkMTU
, VTY_NEWLINE
);
1813 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1815 vty_out (vty
, " ipv6 nd prefix %s/%d",
1816 inet_ntop (AF_INET6
, &rprefix
->prefix
.prefix
,
1817 (char *) buf
, INET6_ADDRSTRLEN
),
1818 rprefix
->prefix
.prefixlen
);
1819 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1820 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1822 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1823 vty_out (vty
, " infinite");
1825 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1826 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1827 vty_out (vty
, " infinite");
1829 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1831 if (!rprefix
->AdvOnLinkFlag
)
1832 vty_out (vty
, " off-link");
1833 if (!rprefix
->AdvAutonomousFlag
)
1834 vty_out (vty
, " no-autoconfig");
1835 if (rprefix
->AdvRouterAddressFlag
)
1836 vty_out (vty
, " router-address");
1837 vty_out (vty
, "%s", VTY_NEWLINE
);
1843 rtadv_event (struct zebra_vrf
*zvrf
, enum rtadv_event event
, int val
)
1845 struct rtadv
*rtadv
= &zvrf
->rtadv
;
1850 if (! rtadv
->ra_read
)
1851 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zvrf
, val
);
1852 if (! rtadv
->ra_timer
)
1853 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
1857 if (rtadv
->ra_timer
)
1859 thread_cancel (rtadv
->ra_timer
);
1860 rtadv
->ra_timer
= NULL
;
1864 thread_cancel (rtadv
->ra_read
);
1865 rtadv
->ra_read
= NULL
;
1869 if (! rtadv
->ra_timer
)
1870 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, zvrf
,
1873 case RTADV_TIMER_MSEC
:
1874 if (! rtadv
->ra_timer
)
1875 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
1879 if (! rtadv
->ra_read
)
1880 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zvrf
, val
);
1889 rtadv_init (struct zebra_vrf
*zvrf
)
1891 zvrf
->rtadv
.sock
= rtadv_make_socket (zvrf
->vrf_id
);
1895 rtadv_terminate (struct zebra_vrf
*zvrf
)
1897 rtadv_event (zvrf
, RTADV_STOP
, 0);
1899 if (zvrf
->rtadv
.sock
>= 0)
1901 close (zvrf
->rtadv
.sock
);
1902 zvrf
->rtadv
.sock
= -1;
1905 zvrf
->rtadv
.adv_if_count
= 0;
1906 zvrf
->rtadv
.adv_msec_if_count
= 0;
1910 rtadv_cmd_init (void)
1912 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
1913 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
1914 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
1915 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
1916 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
1917 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_val_cmd
);
1918 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_msec_val_cmd
);
1919 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
1920 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
1921 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_val_cmd
);
1922 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
1923 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
1924 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_val_cmd
);
1925 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
1926 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
1927 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
1928 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
1929 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
1930 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
1931 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
1932 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
1933 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_val_cmd
);
1934 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
1935 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
1936 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_val_cmd
);
1937 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
1938 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
1939 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
1940 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1941 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
1942 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
1943 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
1944 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
1945 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
1946 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
1947 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
1948 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
1949 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
1950 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
1951 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
1952 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
1953 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
1954 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd
);
1955 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_nortaddr_cmd
);
1956 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_cmd
);
1957 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_noauto_cmd
);
1958 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_offlink_cmd
);
1959 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rtaddr_cmd
);
1960 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_cmd
);
1961 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_cmd
);
1962 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rev_cmd
);
1963 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_noauto_cmd
);
1964 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_offlink_cmd
);
1965 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rtaddr_cmd
);
1966 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
1967 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
1968 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_val_cmd
);
1969 install_element (INTERFACE_NODE
, &ipv6_nd_mtu_cmd
);
1970 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_cmd
);
1971 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_val_cmd
);
1975 if_join_all_router (int sock
, struct interface
*ifp
)
1979 struct ipv6_mreq mreq
;
1981 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
1982 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
1983 mreq
.ipv6mr_interface
= ifp
->ifindex
;
1985 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
1986 (char *) &mreq
, sizeof mreq
);
1988 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno
));
1990 zlog_info ("rtadv: %s join to all-routers multicast group", ifp
->name
);
1996 if_leave_all_router (int sock
, struct interface
*ifp
)
2000 struct ipv6_mreq mreq
;
2002 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2003 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2004 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2006 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
2007 (char *) &mreq
, sizeof mreq
);
2009 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno
));
2011 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp
->name
);
2018 rtadv_init (struct zebra_vrf
*zvrf
)
2023 rtadv_terminate (struct zebra_vrf
*zvrf
)
2028 rtadv_cmd_init (void)
2032 #endif /* HAVE_RTADV && HAVE_IPV6 */