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
37 #include "zebra/interface.h"
38 #include "zebra/rtadv.h"
39 #include "zebra/debug.h"
40 #include "zebra/rib.h"
41 #include "zebra/zserv.h"
42 #include "zebra/zebra_ns.h"
43 #include "zebra/zebra_vrf.h"
45 extern struct zebra_privs_t zserv_privs
;
47 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
50 #include <netinet/icmp6.h>
53 /* If RFC2133 definition is used. */
54 #ifndef IPV6_JOIN_GROUP
55 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
57 #ifndef IPV6_LEAVE_GROUP
58 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
61 #define ALLNODE "ff02::1"
62 #define ALLROUTER "ff02::2"
64 enum rtadv_event
{RTADV_START
, RTADV_STOP
, RTADV_TIMER
,
65 RTADV_TIMER_MSEC
, RTADV_READ
};
67 static void rtadv_event (struct zebra_ns
*, enum rtadv_event
, int);
69 static int if_join_all_router (int, struct interface
*);
70 static int if_leave_all_router (int, struct interface
*);
73 rtadv_increment_received(struct zebra_ns
*zns
, unsigned int *ifindex
)
76 struct interface
*iface
;
79 iface
= if_lookup_by_index_per_ns (zns
, *ifindex
);
80 if (iface
&& iface
->info
)
90 rtadv_recv_packet (struct zebra_ns
*zns
, int sock
, u_char
*buf
, int buflen
,
91 struct sockaddr_in6
*from
, unsigned int *ifindex
,
97 struct cmsghdr
*cmsgptr
;
102 /* Fill in message and iovec. */
103 msg
.msg_name
= (void *) from
;
104 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
107 msg
.msg_control
= (void *) adata
;
108 msg
.msg_controllen
= sizeof adata
;
110 iov
.iov_len
= buflen
;
112 /* If recvmsg fail return minus value. */
113 ret
= recvmsg (sock
, &msg
, 0);
117 for (cmsgptr
= ZCMSG_FIRSTHDR(&msg
); cmsgptr
!= NULL
;
118 cmsgptr
= CMSG_NXTHDR(&msg
, cmsgptr
))
120 /* I want interface index which this packet comes from. */
121 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
122 cmsgptr
->cmsg_type
== IPV6_PKTINFO
)
124 struct in6_pktinfo
*ptr
;
126 ptr
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
127 *ifindex
= ptr
->ipi6_ifindex
;
128 memcpy(&dst
, &ptr
->ipi6_addr
, sizeof(ptr
->ipi6_addr
));
131 /* Incoming packet's hop limit. */
132 if (cmsgptr
->cmsg_level
== IPPROTO_IPV6
&&
133 cmsgptr
->cmsg_type
== IPV6_HOPLIMIT
)
135 int *hoptr
= (int *) CMSG_DATA (cmsgptr
);
140 rtadv_increment_received(zns
, ifindex
);
144 #define RTADV_MSG_SIZE 4096
146 /* Send router advertisement packet. */
148 rtadv_send_packet (int sock
, struct interface
*ifp
)
152 struct cmsghdr
*cmsgptr
;
153 struct in6_pktinfo
*pkt
;
154 struct sockaddr_in6 addr
;
155 #ifdef HAVE_STRUCT_SOCKADDR_DL
156 struct sockaddr_dl
*sdl
;
157 #endif /* HAVE_STRUCT_SOCKADDR_DL */
158 static void *adata
= NULL
;
159 unsigned char buf
[RTADV_MSG_SIZE
];
160 struct nd_router_advert
*rtadv
;
163 struct zebra_if
*zif
;
164 struct rtadv_prefix
*rprefix
;
165 u_char all_nodes_addr
[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
166 struct listnode
*node
;
167 u_int16_t pkt_RouterLifetime
;
170 * Allocate control message bufffer. This is dynamic because
171 * CMSG_SPACE is not guaranteed not to call a function. Note that
172 * the size will be different on different architectures due to
173 * differing alignment rules.
177 /* XXX Free on shutdown. */
178 adata
= malloc(CMSG_SPACE(sizeof(struct in6_pktinfo
)));
181 zlog_err("rtadv_send_packet: can't malloc control data");
184 /* Logging of packet. */
185 if (IS_ZEBRA_DEBUG_PACKET
)
186 zlog_debug ("%s(%u): Tx RA, socket %u",
187 ifp
->name
, ifp
->ifindex
, sock
);
189 /* Fill in sockaddr_in6. */
190 memset (&addr
, 0, sizeof (struct sockaddr_in6
));
191 addr
.sin6_family
= AF_INET6
;
193 addr
.sin6_len
= sizeof (struct sockaddr_in6
);
194 #endif /* SIN6_LEN */
195 addr
.sin6_port
= htons (IPPROTO_ICMPV6
);
196 IPV6_ADDR_COPY (&addr
.sin6_addr
, all_nodes_addr
);
198 /* Fetch interface information. */
201 /* Make router advertisement message. */
202 rtadv
= (struct nd_router_advert
*) buf
;
204 rtadv
->nd_ra_type
= ND_ROUTER_ADVERT
;
205 rtadv
->nd_ra_code
= 0;
206 rtadv
->nd_ra_cksum
= 0;
208 rtadv
->nd_ra_curhoplimit
= 64;
210 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
211 rtadv
->nd_ra_flags_reserved
=
212 zif
->rtadv
.AdvDefaultLifetime
== 0 ? 0 : zif
->rtadv
.DefaultPreference
;
213 rtadv
->nd_ra_flags_reserved
<<= 3;
215 if (zif
->rtadv
.AdvManagedFlag
)
216 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_MANAGED
;
217 if (zif
->rtadv
.AdvOtherConfigFlag
)
218 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_OTHER
;
219 if (zif
->rtadv
.AdvHomeAgentFlag
)
220 rtadv
->nd_ra_flags_reserved
|= ND_RA_FLAG_HOME_AGENT
;
221 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
222 * AdvDefaultLifetime is by default based on the value of
223 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
224 * field of Router Advertisements. Given that this field is expressed
225 * in seconds, a small MaxRtrAdvInterval value can result in a zero
226 * value for this field. To prevent this, routers SHOULD keep
227 * AdvDefaultLifetime in at least one second, even if the use of
228 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
229 pkt_RouterLifetime
= zif
->rtadv
.AdvDefaultLifetime
!= -1 ?
230 zif
->rtadv
.AdvDefaultLifetime
:
231 MAX (1, 0.003 * zif
->rtadv
.MaxRtrAdvInterval
);
232 rtadv
->nd_ra_router_lifetime
= htons (pkt_RouterLifetime
);
233 rtadv
->nd_ra_reachable
= htonl (zif
->rtadv
.AdvReachableTime
);
234 rtadv
->nd_ra_retransmit
= htonl (0);
236 len
= sizeof (struct nd_router_advert
);
238 /* If both the Home Agent Preference and Home Agent Lifetime are set to
239 * their default values specified above, this option SHOULD NOT be
240 * included in the Router Advertisement messages sent by this home
241 * agent. -- RFC6275, 7.4 */
244 zif
->rtadv
.AdvHomeAgentFlag
&&
245 (zif
->rtadv
.HomeAgentPreference
|| zif
->rtadv
.HomeAgentLifetime
!= -1)
248 struct nd_opt_homeagent_info
*ndopt_hai
=
249 (struct nd_opt_homeagent_info
*)(buf
+ len
);
250 ndopt_hai
->nd_opt_hai_type
= ND_OPT_HA_INFORMATION
;
251 ndopt_hai
->nd_opt_hai_len
= 1;
252 ndopt_hai
->nd_opt_hai_reserved
= 0;
253 ndopt_hai
->nd_opt_hai_preference
= htons(zif
->rtadv
.HomeAgentPreference
);
254 /* 16-bit unsigned integer. The lifetime associated with the home
255 * agent in units of seconds. The default value is the same as the
256 * Router Lifetime, as specified in the main body of the Router
257 * Advertisement. The maximum value corresponds to 18.2 hours. A
258 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
259 ndopt_hai
->nd_opt_hai_lifetime
= htons
261 zif
->rtadv
.HomeAgentLifetime
!= -1 ?
262 zif
->rtadv
.HomeAgentLifetime
:
263 MAX (1, pkt_RouterLifetime
) /* 0 is OK for RL, but not for HAL*/
265 len
+= sizeof(struct nd_opt_homeagent_info
);
268 if (zif
->rtadv
.AdvIntervalOption
)
270 struct nd_opt_adv_interval
*ndopt_adv
=
271 (struct nd_opt_adv_interval
*)(buf
+ len
);
272 ndopt_adv
->nd_opt_ai_type
= ND_OPT_ADV_INTERVAL
;
273 ndopt_adv
->nd_opt_ai_len
= 1;
274 ndopt_adv
->nd_opt_ai_reserved
= 0;
275 ndopt_adv
->nd_opt_ai_interval
= htonl(zif
->rtadv
.MaxRtrAdvInterval
);
276 len
+= sizeof(struct nd_opt_adv_interval
);
279 /* Fill in prefix. */
280 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
282 struct nd_opt_prefix_info
*pinfo
;
284 pinfo
= (struct nd_opt_prefix_info
*) (buf
+ len
);
286 pinfo
->nd_opt_pi_type
= ND_OPT_PREFIX_INFORMATION
;
287 pinfo
->nd_opt_pi_len
= 4;
288 pinfo
->nd_opt_pi_prefix_len
= rprefix
->prefix
.prefixlen
;
290 pinfo
->nd_opt_pi_flags_reserved
= 0;
291 if (rprefix
->AdvOnLinkFlag
)
292 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_ONLINK
;
293 if (rprefix
->AdvAutonomousFlag
)
294 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_AUTO
;
295 if (rprefix
->AdvRouterAddressFlag
)
296 pinfo
->nd_opt_pi_flags_reserved
|= ND_OPT_PI_FLAG_RADDR
;
298 pinfo
->nd_opt_pi_valid_time
= htonl (rprefix
->AdvValidLifetime
);
299 pinfo
->nd_opt_pi_preferred_time
= htonl (rprefix
->AdvPreferredLifetime
);
300 pinfo
->nd_opt_pi_reserved2
= 0;
302 IPV6_ADDR_COPY (&pinfo
->nd_opt_pi_prefix
, &rprefix
->prefix
.prefix
);
306 u_char buf
[INET6_ADDRSTRLEN
];
308 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6
, &pinfo
->nd_opt_pi_prefix
,
309 buf
, INET6_ADDRSTRLEN
));
314 len
+= sizeof (struct nd_opt_prefix_info
);
317 /* Hardware address. */
318 #ifdef HAVE_STRUCT_SOCKADDR_DL
320 if (sdl
!= NULL
&& sdl
->sdl_alen
!= 0)
322 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
324 /* Option length should be rounded up to next octet if
325 the link address does not end on an octet boundary. */
326 buf
[len
++] = (sdl
->sdl_alen
+ 9) >> 3;
328 memcpy (buf
+ len
, LLADDR (sdl
), sdl
->sdl_alen
);
329 len
+= sdl
->sdl_alen
;
331 /* Pad option to end on an octet boundary. */
332 memset (buf
+ len
, 0, -(sdl
->sdl_alen
+ 2) & 0x7);
333 len
+= -(sdl
->sdl_alen
+ 2) & 0x7;
336 if (ifp
->hw_addr_len
!= 0)
338 buf
[len
++] = ND_OPT_SOURCE_LINKADDR
;
340 /* Option length should be rounded up to next octet if
341 the link address does not end on an octet boundary. */
342 buf
[len
++] = (ifp
->hw_addr_len
+ 9) >> 3;
344 memcpy (buf
+ len
, ifp
->hw_addr
, ifp
->hw_addr_len
);
345 len
+= ifp
->hw_addr_len
;
347 /* Pad option to end on an octet boundary. */
348 memset (buf
+ len
, 0, -(ifp
->hw_addr_len
+ 2) & 0x7);
349 len
+= -(ifp
->hw_addr_len
+ 2) & 0x7;
351 #endif /* HAVE_STRUCT_SOCKADDR_DL */
354 if (zif
->rtadv
.AdvLinkMTU
)
356 struct nd_opt_mtu
* opt
= (struct nd_opt_mtu
*) (buf
+ len
);
357 opt
->nd_opt_mtu_type
= ND_OPT_MTU
;
358 opt
->nd_opt_mtu_len
= 1;
359 opt
->nd_opt_mtu_reserved
= 0;
360 opt
->nd_opt_mtu_mtu
= htonl (zif
->rtadv
.AdvLinkMTU
);
361 len
+= sizeof (struct nd_opt_mtu
);
364 msg
.msg_name
= (void *) &addr
;
365 msg
.msg_namelen
= sizeof (struct sockaddr_in6
);
368 msg
.msg_control
= (void *) adata
;
369 msg
.msg_controllen
= CMSG_SPACE(sizeof(struct in6_pktinfo
));
374 cmsgptr
= ZCMSG_FIRSTHDR(&msg
);
375 cmsgptr
->cmsg_len
= CMSG_LEN(sizeof(struct in6_pktinfo
));
376 cmsgptr
->cmsg_level
= IPPROTO_IPV6
;
377 cmsgptr
->cmsg_type
= IPV6_PKTINFO
;
379 pkt
= (struct in6_pktinfo
*) CMSG_DATA (cmsgptr
);
380 memset (&pkt
->ipi6_addr
, 0, sizeof (struct in6_addr
));
381 pkt
->ipi6_ifindex
= ifp
->ifindex
;
383 ret
= sendmsg (sock
, &msg
, 0);
386 zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
387 ifp
->name
, ifp
->ifindex
, sock
, errno
, safe_strerror(errno
));
394 rtadv_timer (struct thread
*thread
)
396 struct zebra_ns
*zns
= THREAD_ARG (thread
);
398 struct listnode
*node
, *nnode
;
399 struct interface
*ifp
;
400 struct zebra_if
*zif
;
403 zns
->rtadv
.ra_timer
= NULL
;
404 if (zns
->rtadv
.adv_msec_if_count
== 0)
406 period
= 1000; /* 1 s */
407 rtadv_event (zns
, RTADV_TIMER
, 1 /* 1 s */);
411 period
= 10; /* 10 ms */
412 rtadv_event (zns
, RTADV_TIMER_MSEC
, 10 /* 10 ms */);
415 for (iter
= vrf_first (); iter
!= VRF_ITER_INVALID
; iter
= vrf_next (iter
))
416 for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter
), node
, nnode
, ifp
))
418 if (if_is_loopback (ifp
) ||
419 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
) ||
420 ! if_is_operative (ifp
))
425 if (zif
->rtadv
.AdvSendAdvertisements
)
427 if (zif
->rtadv
.inFastRexmit
)
429 /* We assume we fast rexmit every sec so no additional vars */
430 if (--zif
->rtadv
.NumFastReXmitsRemain
<= 0)
431 zif
->rtadv
.inFastRexmit
= 0;
433 if (IS_ZEBRA_DEBUG_SEND
)
434 zlog_debug("Fast RA Rexmit on interface %s", ifp
->name
);
436 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
440 zif
->rtadv
.AdvIntervalTimer
-= period
;
441 if (zif
->rtadv
.AdvIntervalTimer
<= 0)
443 /* FIXME: using MaxRtrAdvInterval each time isn't what section
444 6.2.4 of RFC4861 tells to do. */
445 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
446 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
456 rtadv_process_solicit (struct interface
*ifp
)
458 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
459 struct zebra_ns
*zns
= zvrf
->zns
;
462 rtadv_send_packet (zns
->rtadv
.sock
, ifp
);
466 rtadv_process_advert (u_char
*msg
, unsigned int len
, struct interface
*ifp
,
467 struct sockaddr_in6
*addr
)
469 struct nd_router_advert
*radvert
;
470 char addr_str
[INET6_ADDRSTRLEN
];
471 struct zebra_if
*zif
;
476 inet_ntop (AF_INET6
, &addr
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
478 if (len
< sizeof(struct nd_router_advert
)) {
479 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
480 ifp
->name
, ifp
->ifindex
, len
, addr_str
);
483 if (!IN6_IS_ADDR_LINKLOCAL(&addr
->sin6_addr
)) {
484 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
485 ifp
->name
, ifp
->ifindex
, addr_str
);
489 radvert
= (struct nd_router_advert
*) msg
;
491 if ((radvert
->nd_ra_curhoplimit
&& zif
->rtadv
.AdvCurHopLimit
) &&
492 (radvert
->nd_ra_curhoplimit
!= zif
->rtadv
.AdvCurHopLimit
))
494 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
495 ifp
->name
, ifp
->ifindex
, addr_str
);
498 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_MANAGED
) &&
499 !zif
->rtadv
.AdvManagedFlag
)
501 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
502 ifp
->name
, ifp
->ifindex
, addr_str
);
505 if ((radvert
->nd_ra_flags_reserved
& ND_RA_FLAG_OTHER
) &&
506 !zif
->rtadv
.AdvOtherConfigFlag
)
508 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
509 ifp
->name
, ifp
->ifindex
, addr_str
);
512 if ((radvert
->nd_ra_reachable
&& zif
->rtadv
.AdvReachableTime
) &&
513 (ntohl(radvert
->nd_ra_reachable
) != zif
->rtadv
.AdvReachableTime
))
515 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
516 ifp
->name
, ifp
->ifindex
, addr_str
);
519 if ((radvert
->nd_ra_retransmit
&& zif
->rtadv
.AdvRetransTimer
) &&
520 (ntohl(radvert
->nd_ra_retransmit
) != (unsigned int)zif
->rtadv
.AdvRetransTimer
))
522 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
523 ifp
->name
, ifp
->ifindex
, addr_str
);
526 /* Create entry for neighbor if not known. */
528 IPV6_ADDR_COPY (&p
.u
.prefix
, &addr
->sin6_addr
);
529 p
.prefixlen
= IPV6_MAX_PREFIXLEN
;
531 if (!nbr_connected_check(ifp
, &p
))
532 nbr_connected_add_ipv6 (ifp
, &addr
->sin6_addr
);
537 rtadv_process_packet (u_char
*buf
, unsigned int len
, unsigned int ifindex
, int hoplimit
,
538 struct sockaddr_in6
*from
, struct zebra_ns
*zns
)
540 struct icmp6_hdr
*icmph
;
541 struct interface
*ifp
;
542 struct zebra_if
*zif
;
543 char addr_str
[INET6_ADDRSTRLEN
];
545 inet_ntop (AF_INET6
, &from
->sin6_addr
, addr_str
, INET6_ADDRSTRLEN
);
547 /* Interface search. */
548 ifp
= if_lookup_by_index_per_ns (zns
, ifindex
);
551 zlog_warn ("RA/RS received on unknown IF %u from %s",
556 if (IS_ZEBRA_DEBUG_PACKET
)
557 zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
558 ifp
->name
, ifp
->ifindex
, len
, addr_str
);
560 if (if_is_loopback (ifp
) ||
561 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
))
564 /* Check interface configuration. */
566 if (! zif
->rtadv
.AdvSendAdvertisements
)
569 /* ICMP message length check. */
570 if (len
< sizeof (struct icmp6_hdr
))
572 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
573 ifp
->name
, ifp
->ifindex
, len
);
577 icmph
= (struct icmp6_hdr
*) buf
;
579 /* ICMP message type check. */
580 if (icmph
->icmp6_type
!= ND_ROUTER_SOLICIT
&&
581 icmph
->icmp6_type
!= ND_ROUTER_ADVERT
)
583 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
584 ifp
->name
, ifp
->ifindex
, icmph
->icmp6_type
);
588 /* Hoplimit check. */
589 if (hoplimit
>= 0 && hoplimit
!= 255)
591 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
592 ifp
->name
, ifp
->ifindex
, hoplimit
);
596 /* Check ICMP message type. */
597 if (icmph
->icmp6_type
== ND_ROUTER_SOLICIT
)
598 rtadv_process_solicit (ifp
);
599 else if (icmph
->icmp6_type
== ND_ROUTER_ADVERT
)
600 rtadv_process_advert (buf
, len
, ifp
, from
);
606 rtadv_read (struct thread
*thread
)
610 u_char buf
[RTADV_MSG_SIZE
];
611 struct sockaddr_in6 from
;
612 unsigned int ifindex
= 0;
614 struct zebra_ns
*zns
= THREAD_ARG (thread
);
616 sock
= THREAD_FD (thread
);
617 zns
->rtadv
.ra_read
= NULL
;
619 /* Register myself. */
620 rtadv_event (zns
, RTADV_READ
, sock
);
622 len
= rtadv_recv_packet (zns
, sock
, buf
, sizeof (buf
), &from
, &ifindex
, &hoplimit
);
626 zlog_warn ("RA/RS recv failed, socket %u error %s",
627 sock
, safe_strerror (errno
));
631 rtadv_process_packet (buf
, (unsigned)len
, ifindex
, hoplimit
, &from
, zns
);
637 rtadv_make_socket (void)
641 struct icmp6_filter filter
;
643 if ( zserv_privs
.change (ZPRIVS_RAISE
) )
644 zlog_err ("rtadv_make_socket: could not raise privs, %s",
645 safe_strerror (errno
) );
647 sock
= socket (AF_INET6
, SOCK_RAW
, IPPROTO_ICMPV6
);
649 if ( zserv_privs
.change (ZPRIVS_LOWER
) )
650 zlog_err ("rtadv_make_socket: could not lower privs, %s",
651 safe_strerror (errno
) );
659 ret
= setsockopt_ipv6_pktinfo (sock
, 1);
665 ret
= setsockopt_ipv6_multicast_loop (sock
, 0);
671 ret
= setsockopt_ipv6_unicast_hops (sock
, 255);
677 ret
= setsockopt_ipv6_multicast_hops (sock
, 255);
683 ret
= setsockopt_ipv6_hoplimit (sock
, 1);
690 ICMP6_FILTER_SETBLOCKALL(&filter
);
691 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT
, &filter
);
692 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT
, &filter
);
694 ret
= setsockopt (sock
, IPPROTO_ICMPV6
, ICMP6_FILTER
, &filter
,
695 sizeof (struct icmp6_filter
));
698 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno
));
705 static struct rtadv_prefix
*
706 rtadv_prefix_new (void)
708 return XCALLOC (MTYPE_RTADV_PREFIX
, sizeof (struct rtadv_prefix
));
712 rtadv_prefix_free (struct rtadv_prefix
*rtadv_prefix
)
714 XFREE (MTYPE_RTADV_PREFIX
, rtadv_prefix
);
717 static struct rtadv_prefix
*
718 rtadv_prefix_lookup (struct list
*rplist
, struct prefix_ipv6
*p
)
720 struct listnode
*node
;
721 struct rtadv_prefix
*rprefix
;
723 for (ALL_LIST_ELEMENTS_RO (rplist
, node
, rprefix
))
724 if (prefix_same ((struct prefix
*) &rprefix
->prefix
, (struct prefix
*) p
))
729 static struct rtadv_prefix
*
730 rtadv_prefix_get (struct list
*rplist
, struct prefix_ipv6
*p
)
732 struct rtadv_prefix
*rprefix
;
734 rprefix
= rtadv_prefix_lookup (rplist
, p
);
738 rprefix
= rtadv_prefix_new ();
739 memcpy (&rprefix
->prefix
, p
, sizeof (struct prefix_ipv6
));
740 listnode_add (rplist
, rprefix
);
746 rtadv_prefix_set (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
748 struct rtadv_prefix
*rprefix
;
750 rprefix
= rtadv_prefix_get (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
752 /* Set parameters. */
753 rprefix
->AdvValidLifetime
= rp
->AdvValidLifetime
;
754 rprefix
->AdvPreferredLifetime
= rp
->AdvPreferredLifetime
;
755 rprefix
->AdvOnLinkFlag
= rp
->AdvOnLinkFlag
;
756 rprefix
->AdvAutonomousFlag
= rp
->AdvAutonomousFlag
;
757 rprefix
->AdvRouterAddressFlag
= rp
->AdvRouterAddressFlag
;
761 rtadv_prefix_reset (struct zebra_if
*zif
, struct rtadv_prefix
*rp
)
763 struct rtadv_prefix
*rprefix
;
765 rprefix
= rtadv_prefix_lookup (zif
->rtadv
.AdvPrefixList
, &rp
->prefix
);
768 listnode_delete (zif
->rtadv
.AdvPrefixList
, (void *) rprefix
);
769 rtadv_prefix_free (rprefix
);
777 ipv6_nd_suppress_ra_set (struct interface
*ifp
, ipv6_nd_suppress_ra_status status
)
779 struct zebra_if
*zif
;
780 struct zebra_vrf
*zvrf
;
781 struct zebra_ns
*zns
;
784 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
787 if (status
== RA_SUPPRESS
)
789 /* RA is currently enabled */
790 if (zif
->rtadv
.AdvSendAdvertisements
)
792 zif
->rtadv
.AdvSendAdvertisements
= 0;
793 zif
->rtadv
.AdvIntervalTimer
= 0;
794 zns
->rtadv
.adv_if_count
--;
796 if_leave_all_router (zns
->rtadv
.sock
, ifp
);
798 if (zns
->rtadv
.adv_if_count
== 0)
799 rtadv_event (zns
, RTADV_STOP
, 0);
804 if (! zif
->rtadv
.AdvSendAdvertisements
)
806 zif
->rtadv
.AdvSendAdvertisements
= 1;
807 zif
->rtadv
.AdvIntervalTimer
= 0;
808 zns
->rtadv
.adv_if_count
++;
810 if (zif
->rtadv
.MaxRtrAdvInterval
>= 1000)
812 /* Enable Fast RA only when RA interval is in secs */
813 zif
->rtadv
.inFastRexmit
= 1;
814 zif
->rtadv
.NumFastReXmitsRemain
= RTADV_NUM_FAST_REXMITS
;
817 if_join_all_router (zns
->rtadv
.sock
, ifp
);
819 if (zns
->rtadv
.adv_if_count
== 1)
820 rtadv_event (zns
, RTADV_START
, zns
->rtadv
.sock
);
826 * Handle client (BGP) message to enable or disable IPv6 RA on an interface.
827 * Note that while the client could request RA on an interface on which the
828 * operator has not enabled RA, RA won't be disabled upon client request
829 * if the operator has explicitly enabled RA. The enable request can also
830 * specify a RA interval (in seconds).
833 zebra_interface_radv_set (struct zserv
*client
, int sock
, u_short length
,
834 struct zebra_vrf
*zvrf
, int enable
)
837 unsigned int ifindex
;
838 struct interface
*ifp
;
839 struct zebra_if
*zif
;
844 /* Get interface index and RA interval. */
845 ifindex
= stream_getl (s
);
846 ra_interval
= stream_getl (s
);
848 if (IS_ZEBRA_DEBUG_EVENT
)
849 zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
850 zvrf
->vrf_id
, ifindex
, enable
? "enable" : "disable",
851 zebra_route_string(client
->proto
), ra_interval
);
853 /* Locate interface and check VRF match. */
854 ifp
= if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT
), ifindex
);
857 zlog_warn("%u: IF %u RA %s client %s - interface unknown",
858 zvrf
->vrf_id
, ifindex
, enable
? "enable" : "disable",
859 zebra_route_string(client
->proto
));
862 if (ifp
->vrf_id
!= zvrf
->vrf_id
)
864 zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
865 zvrf
->vrf_id
, ifindex
, enable
? "enable" : "disable",
866 zebra_route_string(client
->proto
), ifp
->vrf_id
);
873 ipv6_nd_suppress_ra_set (ifp
, RA_ENABLE
);
875 (ra_interval
* 1000) < zif
->rtadv
.MaxRtrAdvInterval
)
876 zif
->rtadv
.MaxRtrAdvInterval
= ra_interval
* 1000;
880 if (!zif
->rtadv
.configured
)
882 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
883 ipv6_nd_suppress_ra_set (ifp
, RA_SUPPRESS
);
888 DEFUN (ipv6_nd_suppress_ra
,
889 ipv6_nd_suppress_ra_cmd
,
890 "ipv6 nd suppress-ra",
891 "Interface IPv6 config commands\n"
892 "Neighbor discovery\n"
893 "Suppress Router Advertisement\n")
895 struct interface
*ifp
;
896 struct zebra_if
*zif
;
900 if (if_is_loopback (ifp
) ||
901 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
))
903 vty_out (vty
, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE
);
907 ipv6_nd_suppress_ra_set (ifp
, RA_SUPPRESS
);
909 zif
->rtadv
.configured
= 0;
913 DEFUN (no_ipv6_nd_suppress_ra
,
914 no_ipv6_nd_suppress_ra_cmd
,
915 "no ipv6 nd suppress-ra",
917 "Interface IPv6 config commands\n"
918 "Neighbor discovery\n"
919 "Suppress Router Advertisement\n")
921 struct interface
*ifp
;
922 struct zebra_if
*zif
;
926 if (if_is_loopback (ifp
) ||
927 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
))
929 vty_out (vty
, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE
);
933 ipv6_nd_suppress_ra_set (ifp
, RA_ENABLE
);
935 zif
->rtadv
.configured
= 1;
939 DEFUN (ipv6_nd_ra_interval_msec
,
940 ipv6_nd_ra_interval_msec_cmd
,
941 "ipv6 nd ra-interval msec <70-1800000>",
942 "Interface IPv6 config commands\n"
943 "Neighbor discovery\n"
944 "Router Advertisement interval\n"
945 "Router Advertisement interval in milliseconds\n")
948 struct interface
*ifp
= (struct interface
*) vty
->index
;
949 struct zebra_if
*zif
= ifp
->info
;
950 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
951 struct zebra_ns
*zns
;
954 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 70, 1800000);
955 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
* 1000))
957 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
961 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
962 zns
->rtadv
.adv_msec_if_count
--;
965 zns
->rtadv
.adv_msec_if_count
++;
967 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
968 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
969 zif
->rtadv
.AdvIntervalTimer
= 0;
974 DEFUN (ipv6_nd_ra_interval
,
975 ipv6_nd_ra_interval_cmd
,
976 "ipv6 nd ra-interval <1-1800>",
977 "Interface IPv6 config commands\n"
978 "Neighbor discovery\n"
979 "Router Advertisement interval\n"
980 "Router Advertisement interval in seconds\n")
983 struct interface
*ifp
= (struct interface
*) vty
->index
;
984 struct zebra_if
*zif
= ifp
->info
;
985 struct zebra_vrf
*zvrf
= vrf_info_lookup (ifp
->vrf_id
);
986 struct zebra_ns
*zns
;
989 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval
, argv
[0], 1, 1800);
990 if ((zif
->rtadv
.AdvDefaultLifetime
!= -1 && interval
> (unsigned)zif
->rtadv
.AdvDefaultLifetime
))
992 vty_out (vty
, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE
);
996 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
997 zns
->rtadv
.adv_msec_if_count
--;
999 /* convert to milliseconds */
1000 interval
= interval
* 1000;
1002 zif
->rtadv
.MaxRtrAdvInterval
= interval
;
1003 zif
->rtadv
.MinRtrAdvInterval
= 0.33 * interval
;
1004 zif
->rtadv
.AdvIntervalTimer
= 0;
1009 DEFUN (no_ipv6_nd_ra_interval
,
1010 no_ipv6_nd_ra_interval_cmd
,
1011 "no ipv6 nd ra-interval",
1013 "Interface IPv6 config commands\n"
1014 "Neighbor discovery\n"
1015 "Router Advertisement interval\n")
1017 struct interface
*ifp
;
1018 struct zebra_if
*zif
;
1019 struct zebra_vrf
*zvrf
;
1020 struct zebra_ns
*zns
;
1022 ifp
= (struct interface
*) vty
->index
;
1024 zvrf
= vrf_info_lookup (ifp
->vrf_id
);
1027 if (zif
->rtadv
.MaxRtrAdvInterval
% 1000)
1028 zns
->rtadv
.adv_msec_if_count
--;
1030 zif
->rtadv
.MaxRtrAdvInterval
= RTADV_MAX_RTR_ADV_INTERVAL
;
1031 zif
->rtadv
.MinRtrAdvInterval
= RTADV_MIN_RTR_ADV_INTERVAL
;
1032 zif
->rtadv
.AdvIntervalTimer
= zif
->rtadv
.MaxRtrAdvInterval
;
1037 ALIAS (no_ipv6_nd_ra_interval
,
1038 no_ipv6_nd_ra_interval_val_cmd
,
1039 "no ipv6 nd ra-interval <1-1800>",
1041 "Interface IPv6 config commands\n"
1042 "Neighbor discovery\n"
1043 "Router Advertisement interval\n")
1045 ALIAS (no_ipv6_nd_ra_interval
,
1046 no_ipv6_nd_ra_interval_msec_val_cmd
,
1047 "no ipv6 nd ra-interval msec <1-1800000>",
1049 "Interface IPv6 config commands\n"
1050 "Neighbor discovery\n"
1051 "Router Advertisement interval\n"
1052 "Router Advertisement interval in milliseconds\n")
1054 DEFUN (ipv6_nd_ra_lifetime
,
1055 ipv6_nd_ra_lifetime_cmd
,
1056 "ipv6 nd ra-lifetime <0-9000>",
1057 "Interface IPv6 config commands\n"
1058 "Neighbor discovery\n"
1060 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1063 struct interface
*ifp
;
1064 struct zebra_if
*zif
;
1066 ifp
= (struct interface
*) vty
->index
;
1069 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime
, argv
[0], 0, 9000);
1071 /* The value to be placed in the Router Lifetime field
1072 * of Router Advertisements sent from the interface,
1073 * in seconds. MUST be either zero or between
1074 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
1075 if ((lifetime
!= 0 && lifetime
* 1000 < zif
->rtadv
.MaxRtrAdvInterval
))
1077 vty_out (vty
, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE
);
1081 zif
->rtadv
.AdvDefaultLifetime
= lifetime
;
1086 DEFUN (no_ipv6_nd_ra_lifetime
,
1087 no_ipv6_nd_ra_lifetime_cmd
,
1088 "no ipv6 nd ra-lifetime",
1090 "Interface IPv6 config commands\n"
1091 "Neighbor discovery\n"
1092 "Router lifetime\n")
1094 struct interface
*ifp
;
1095 struct zebra_if
*zif
;
1097 ifp
= (struct interface
*) vty
->index
;
1100 zif
->rtadv
.AdvDefaultLifetime
= -1;
1105 ALIAS (no_ipv6_nd_ra_lifetime
,
1106 no_ipv6_nd_ra_lifetime_val_cmd
,
1107 "no ipv6 nd ra-lifetime <0-9000>",
1109 "Interface IPv6 config commands\n"
1110 "Neighbor discovery\n"
1112 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1114 DEFUN (ipv6_nd_reachable_time
,
1115 ipv6_nd_reachable_time_cmd
,
1116 "ipv6 nd reachable-time <1-3600000>",
1117 "Interface IPv6 config commands\n"
1118 "Neighbor discovery\n"
1120 "Reachable time in milliseconds\n")
1122 struct interface
*ifp
= (struct interface
*) vty
->index
;
1123 struct zebra_if
*zif
= ifp
->info
;
1124 VTY_GET_INTEGER_RANGE ("reachable time", zif
->rtadv
.AdvReachableTime
, argv
[0], 1, RTADV_MAX_REACHABLE_TIME
);
1128 DEFUN (no_ipv6_nd_reachable_time
,
1129 no_ipv6_nd_reachable_time_cmd
,
1130 "no ipv6 nd reachable-time",
1132 "Interface IPv6 config commands\n"
1133 "Neighbor discovery\n"
1136 struct interface
*ifp
;
1137 struct zebra_if
*zif
;
1139 ifp
= (struct interface
*) vty
->index
;
1142 zif
->rtadv
.AdvReachableTime
= 0;
1147 ALIAS (no_ipv6_nd_reachable_time
,
1148 no_ipv6_nd_reachable_time_val_cmd
,
1149 "no ipv6 nd reachable-time <1-3600000>",
1151 "Interface IPv6 config commands\n"
1152 "Neighbor discovery\n"
1154 "Reachable time in milliseconds\n")
1156 DEFUN (ipv6_nd_homeagent_preference
,
1157 ipv6_nd_homeagent_preference_cmd
,
1158 "ipv6 nd home-agent-preference <0-65535>",
1159 "Interface IPv6 config commands\n"
1160 "Neighbor discovery\n"
1161 "Home Agent preference\n"
1162 "preference value (default is 0, least preferred)\n")
1164 struct interface
*ifp
= (struct interface
*) vty
->index
;
1165 struct zebra_if
*zif
= ifp
->info
;
1166 VTY_GET_INTEGER_RANGE ("home agent preference", zif
->rtadv
.HomeAgentPreference
, argv
[0], 0, 65535);
1170 DEFUN (no_ipv6_nd_homeagent_preference
,
1171 no_ipv6_nd_homeagent_preference_cmd
,
1172 "no ipv6 nd home-agent-preference",
1174 "Interface IPv6 config commands\n"
1175 "Neighbor discovery\n"
1176 "Home Agent preference\n")
1178 struct interface
*ifp
;
1179 struct zebra_if
*zif
;
1181 ifp
= (struct interface
*) vty
->index
;
1184 zif
->rtadv
.HomeAgentPreference
= 0;
1189 ALIAS (no_ipv6_nd_homeagent_preference
,
1190 no_ipv6_nd_homeagent_preference_val_cmd
,
1191 "no ipv6 nd home-agent-preference <0-65535>",
1193 "Interface IPv6 config commands\n"
1194 "Neighbor discovery\n"
1195 "Home Agent preference\n"
1196 "preference value (default is 0, least preferred)\n")
1198 DEFUN (ipv6_nd_homeagent_lifetime
,
1199 ipv6_nd_homeagent_lifetime_cmd
,
1200 "ipv6 nd home-agent-lifetime <0-65520>",
1201 "Interface IPv6 config commands\n"
1202 "Neighbor discovery\n"
1203 "Home Agent lifetime\n"
1204 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1206 struct interface
*ifp
= (struct interface
*) vty
->index
;
1207 struct zebra_if
*zif
= ifp
->info
;
1208 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif
->rtadv
.HomeAgentLifetime
, argv
[0], 0, RTADV_MAX_HALIFETIME
);
1212 DEFUN (no_ipv6_nd_homeagent_lifetime
,
1213 no_ipv6_nd_homeagent_lifetime_cmd
,
1214 "no ipv6 nd home-agent-lifetime",
1216 "Interface IPv6 config commands\n"
1217 "Neighbor discovery\n"
1218 "Home Agent lifetime\n")
1220 struct interface
*ifp
;
1221 struct zebra_if
*zif
;
1223 ifp
= (struct interface
*) vty
->index
;
1226 zif
->rtadv
.HomeAgentLifetime
= -1;
1231 ALIAS (no_ipv6_nd_homeagent_lifetime
,
1232 no_ipv6_nd_homeagent_lifetime_val_cmd
,
1233 "no ipv6 nd home-agent-lifetime <0-65520>",
1235 "Interface IPv6 config commands\n"
1236 "Neighbor discovery\n"
1237 "Home Agent lifetime\n"
1238 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1240 DEFUN (ipv6_nd_managed_config_flag
,
1241 ipv6_nd_managed_config_flag_cmd
,
1242 "ipv6 nd managed-config-flag",
1243 "Interface IPv6 config commands\n"
1244 "Neighbor discovery\n"
1245 "Managed address configuration flag\n")
1247 struct interface
*ifp
;
1248 struct zebra_if
*zif
;
1250 ifp
= (struct interface
*) vty
->index
;
1253 zif
->rtadv
.AdvManagedFlag
= 1;
1258 DEFUN (no_ipv6_nd_managed_config_flag
,
1259 no_ipv6_nd_managed_config_flag_cmd
,
1260 "no ipv6 nd managed-config-flag",
1262 "Interface IPv6 config commands\n"
1263 "Neighbor discovery\n"
1264 "Managed address configuration flag\n")
1266 struct interface
*ifp
;
1267 struct zebra_if
*zif
;
1269 ifp
= (struct interface
*) vty
->index
;
1272 zif
->rtadv
.AdvManagedFlag
= 0;
1277 DEFUN (ipv6_nd_homeagent_config_flag
,
1278 ipv6_nd_homeagent_config_flag_cmd
,
1279 "ipv6 nd home-agent-config-flag",
1280 "Interface IPv6 config commands\n"
1281 "Neighbor discovery\n"
1282 "Home Agent configuration flag\n")
1284 struct interface
*ifp
;
1285 struct zebra_if
*zif
;
1287 ifp
= (struct interface
*) vty
->index
;
1290 zif
->rtadv
.AdvHomeAgentFlag
= 1;
1295 DEFUN (no_ipv6_nd_homeagent_config_flag
,
1296 no_ipv6_nd_homeagent_config_flag_cmd
,
1297 "no ipv6 nd home-agent-config-flag",
1299 "Interface IPv6 config commands\n"
1300 "Neighbor discovery\n"
1301 "Home Agent configuration flag\n")
1303 struct interface
*ifp
;
1304 struct zebra_if
*zif
;
1306 ifp
= (struct interface
*) vty
->index
;
1309 zif
->rtadv
.AdvHomeAgentFlag
= 0;
1314 DEFUN (ipv6_nd_adv_interval_config_option
,
1315 ipv6_nd_adv_interval_config_option_cmd
,
1316 "ipv6 nd adv-interval-option",
1317 "Interface IPv6 config commands\n"
1318 "Neighbor discovery\n"
1319 "Advertisement Interval Option\n")
1321 struct interface
*ifp
;
1322 struct zebra_if
*zif
;
1324 ifp
= (struct interface
*) vty
->index
;
1327 zif
->rtadv
.AdvIntervalOption
= 1;
1332 DEFUN (no_ipv6_nd_adv_interval_config_option
,
1333 no_ipv6_nd_adv_interval_config_option_cmd
,
1334 "no ipv6 nd adv-interval-option",
1336 "Interface IPv6 config commands\n"
1337 "Neighbor discovery\n"
1338 "Advertisement Interval Option\n")
1340 struct interface
*ifp
;
1341 struct zebra_if
*zif
;
1343 ifp
= (struct interface
*) vty
->index
;
1346 zif
->rtadv
.AdvIntervalOption
= 0;
1351 DEFUN (ipv6_nd_other_config_flag
,
1352 ipv6_nd_other_config_flag_cmd
,
1353 "ipv6 nd other-config-flag",
1354 "Interface IPv6 config commands\n"
1355 "Neighbor discovery\n"
1356 "Other statefull configuration flag\n")
1358 struct interface
*ifp
;
1359 struct zebra_if
*zif
;
1361 ifp
= (struct interface
*) vty
->index
;
1364 zif
->rtadv
.AdvOtherConfigFlag
= 1;
1369 DEFUN (no_ipv6_nd_other_config_flag
,
1370 no_ipv6_nd_other_config_flag_cmd
,
1371 "no ipv6 nd other-config-flag",
1373 "Interface IPv6 config commands\n"
1374 "Neighbor discovery\n"
1375 "Other statefull configuration flag\n")
1377 struct interface
*ifp
;
1378 struct zebra_if
*zif
;
1380 ifp
= (struct interface
*) vty
->index
;
1383 zif
->rtadv
.AdvOtherConfigFlag
= 0;
1388 DEFUN (ipv6_nd_prefix
,
1390 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1391 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1392 "Interface IPv6 config commands\n"
1393 "Neighbor discovery\n"
1394 "Prefix information\n"
1396 "Valid lifetime in seconds\n"
1397 "Infinite valid lifetime\n"
1398 "Preferred lifetime in seconds\n"
1399 "Infinite preferred lifetime\n"
1400 "Do not use prefix for onlink determination\n"
1401 "Do not use prefix for autoconfiguration\n"
1402 "Set Router Address flag\n")
1407 struct interface
*ifp
;
1408 struct zebra_if
*zebra_if
;
1409 struct rtadv_prefix rp
;
1411 ifp
= (struct interface
*) vty
->index
;
1412 zebra_if
= ifp
->info
;
1414 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1417 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1420 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1421 rp
.AdvOnLinkFlag
= 1;
1422 rp
.AdvAutonomousFlag
= 1;
1423 rp
.AdvRouterAddressFlag
= 0;
1424 rp
.AdvValidLifetime
= RTADV_VALID_LIFETIME
;
1425 rp
.AdvPreferredLifetime
= RTADV_PREFERRED_LIFETIME
;
1429 if ((isdigit((unsigned char)argv
[1][0]))
1430 || strncmp (argv
[1], "i", 1) == 0)
1432 if ( strncmp (argv
[1], "i", 1) == 0)
1433 rp
.AdvValidLifetime
= UINT32_MAX
;
1435 rp
.AdvValidLifetime
= (u_int32_t
) strtoll (argv
[1],
1438 if ( strncmp (argv
[2], "i", 1) == 0)
1439 rp
.AdvPreferredLifetime
= UINT32_MAX
;
1441 rp
.AdvPreferredLifetime
= (u_int32_t
) strtoll (argv
[2],
1444 if (rp
.AdvPreferredLifetime
> rp
.AdvValidLifetime
)
1446 vty_out (vty
, "Invalid preferred lifetime%s", VTY_NEWLINE
);
1449 cursor
= cursor
+ 2;
1453 for (i
= cursor
; i
< argc
; i
++)
1455 if (strncmp (argv
[i
], "of", 2) == 0)
1456 rp
.AdvOnLinkFlag
= 0;
1457 if (strncmp (argv
[i
], "no", 2) == 0)
1458 rp
.AdvAutonomousFlag
= 0;
1459 if (strncmp (argv
[i
], "ro", 2) == 0)
1460 rp
.AdvRouterAddressFlag
= 1;
1465 rtadv_prefix_set (zebra_if
, &rp
);
1470 ALIAS (ipv6_nd_prefix
,
1471 ipv6_nd_prefix_val_nortaddr_cmd
,
1472 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1473 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1474 "Interface IPv6 config commands\n"
1475 "Neighbor discovery\n"
1476 "Prefix information\n"
1478 "Valid lifetime in seconds\n"
1479 "Infinite valid lifetime\n"
1480 "Preferred lifetime in seconds\n"
1481 "Infinite preferred lifetime\n"
1482 "Do not use prefix for onlink determination\n"
1483 "Do not use prefix for autoconfiguration\n")
1485 ALIAS (ipv6_nd_prefix
,
1486 ipv6_nd_prefix_val_rev_cmd
,
1487 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1488 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1489 "Interface IPv6 config commands\n"
1490 "Neighbor discovery\n"
1491 "Prefix information\n"
1493 "Valid lifetime in seconds\n"
1494 "Infinite valid lifetime\n"
1495 "Preferred lifetime in seconds\n"
1496 "Infinite preferred lifetime\n"
1497 "Do not use prefix for autoconfiguration\n"
1498 "Do not use prefix for onlink determination\n")
1500 ALIAS (ipv6_nd_prefix
,
1501 ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1502 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1503 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1504 "Interface IPv6 config commands\n"
1505 "Neighbor discovery\n"
1506 "Prefix information\n"
1508 "Valid lifetime in seconds\n"
1509 "Infinite valid lifetime\n"
1510 "Preferred lifetime in seconds\n"
1511 "Infinite preferred lifetime\n"
1512 "Do not use prefix for autoconfiguration\n"
1513 "Do not use prefix for onlink determination\n"
1514 "Set Router Address flag\n")
1516 ALIAS (ipv6_nd_prefix
,
1517 ipv6_nd_prefix_val_noauto_cmd
,
1518 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1519 "(<0-4294967295>|infinite) (no-autoconfig|)",
1520 "Interface IPv6 config commands\n"
1521 "Neighbor discovery\n"
1522 "Prefix information\n"
1524 "Valid lifetime in seconds\n"
1525 "Infinite valid lifetime\n"
1526 "Preferred lifetime in seconds\n"
1527 "Infinite preferred lifetime\n"
1528 "Do not use prefix for autoconfiguration")
1530 ALIAS (ipv6_nd_prefix
,
1531 ipv6_nd_prefix_val_offlink_cmd
,
1532 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1533 "(<0-4294967295>|infinite) (off-link|)",
1534 "Interface IPv6 config commands\n"
1535 "Neighbor discovery\n"
1536 "Prefix information\n"
1538 "Valid lifetime in seconds\n"
1539 "Infinite valid lifetime\n"
1540 "Preferred lifetime in seconds\n"
1541 "Infinite preferred lifetime\n"
1542 "Do not use prefix for onlink determination\n")
1544 ALIAS (ipv6_nd_prefix
,
1545 ipv6_nd_prefix_val_rtaddr_cmd
,
1546 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1547 "(<0-4294967295>|infinite) (router-address|)",
1548 "Interface IPv6 config commands\n"
1549 "Neighbor discovery\n"
1550 "Prefix information\n"
1552 "Valid lifetime in seconds\n"
1553 "Infinite valid lifetime\n"
1554 "Preferred lifetime in seconds\n"
1555 "Infinite preferred lifetime\n"
1556 "Set Router Address flag\n")
1558 ALIAS (ipv6_nd_prefix
,
1559 ipv6_nd_prefix_val_cmd
,
1560 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1561 "(<0-4294967295>|infinite)",
1562 "Interface IPv6 config commands\n"
1563 "Neighbor discovery\n"
1564 "Prefix information\n"
1566 "Valid lifetime in seconds\n"
1567 "Infinite valid lifetime\n"
1568 "Preferred lifetime in seconds\n"
1569 "Infinite preferred lifetime\n")
1571 ALIAS (ipv6_nd_prefix
,
1572 ipv6_nd_prefix_noval_cmd
,
1573 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1574 "Interface IPv6 config commands\n"
1575 "Neighbor discovery\n"
1576 "Prefix information\n"
1578 "Do not use prefix for autoconfiguration\n"
1579 "Do not use prefix for onlink determination\n")
1581 ALIAS (ipv6_nd_prefix
,
1582 ipv6_nd_prefix_noval_rev_cmd
,
1583 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1584 "Interface IPv6 config commands\n"
1585 "Neighbor discovery\n"
1586 "Prefix information\n"
1588 "Do not use prefix for onlink determination\n"
1589 "Do not use prefix for autoconfiguration\n")
1591 ALIAS (ipv6_nd_prefix
,
1592 ipv6_nd_prefix_noval_noauto_cmd
,
1593 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1594 "Interface IPv6 config commands\n"
1595 "Neighbor discovery\n"
1596 "Prefix information\n"
1598 "Do not use prefix for autoconfiguration\n")
1600 ALIAS (ipv6_nd_prefix
,
1601 ipv6_nd_prefix_noval_offlink_cmd
,
1602 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1603 "Interface IPv6 config commands\n"
1604 "Neighbor discovery\n"
1605 "Prefix information\n"
1607 "Do not use prefix for onlink determination\n")
1609 ALIAS (ipv6_nd_prefix
,
1610 ipv6_nd_prefix_noval_rtaddr_cmd
,
1611 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1612 "Interface IPv6 config commands\n"
1613 "Neighbor discovery\n"
1614 "Prefix information\n"
1616 "Set Router Address flag\n")
1618 ALIAS (ipv6_nd_prefix
,
1619 ipv6_nd_prefix_prefix_cmd
,
1620 "ipv6 nd prefix X:X::X:X/M",
1621 "Interface IPv6 config commands\n"
1622 "Neighbor discovery\n"
1623 "Prefix information\n"
1626 DEFUN (no_ipv6_nd_prefix
,
1627 no_ipv6_nd_prefix_cmd
,
1628 "no ipv6 nd prefix IPV6PREFIX",
1630 "Interface IPv6 config commands\n"
1631 "Neighbor discovery\n"
1632 "Prefix information\n"
1636 struct interface
*ifp
;
1637 struct zebra_if
*zebra_if
;
1638 struct rtadv_prefix rp
;
1640 ifp
= (struct interface
*) vty
->index
;
1641 zebra_if
= ifp
->info
;
1643 ret
= str2prefix_ipv6 (argv
[0], &rp
.prefix
);
1646 vty_out (vty
, "Malformed IPv6 prefix%s", VTY_NEWLINE
);
1649 apply_mask_ipv6 (&rp
.prefix
); /* RFC4861 4.6.2 */
1651 ret
= rtadv_prefix_reset (zebra_if
, &rp
);
1654 vty_out (vty
, "Non-exist IPv6 prefix%s", VTY_NEWLINE
);
1661 ALIAS (no_ipv6_nd_prefix
,
1662 no_ipv6_nd_prefix_val_nortaddr_cmd
,
1663 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1665 "Interface IPv6 config commands\n"
1666 "Neighbor discovery\n"
1667 "Prefix information\n"
1669 "Valid lifetime in seconds\n"
1670 "Infinite valid lifetime\n"
1671 "Preferred lifetime in seconds\n"
1672 "Infinite preferred lifetime\n"
1673 "Do not use prefix for onlink determination\n"
1674 "Do not use prefix for autoconfiguration\n"
1675 "Set Router Address flag\n")
1677 ALIAS (no_ipv6_nd_prefix
,
1678 no_ipv6_nd_prefix_val_rev_cmd
,
1679 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1681 "Interface IPv6 config commands\n"
1682 "Neighbor discovery\n"
1683 "Prefix information\n"
1685 "Valid lifetime in seconds\n"
1686 "Infinite valid lifetime\n"
1687 "Preferred lifetime in seconds\n"
1688 "Infinite preferred lifetime\n"
1689 "Do not use prefix for autoconfiguration\n"
1690 "Do not use prefix for onlink determination\n")
1692 ALIAS (no_ipv6_nd_prefix
,
1693 no_ipv6_nd_prefix_val_rev_rtaddr_cmd
,
1694 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1696 "Interface IPv6 config commands\n"
1697 "Neighbor discovery\n"
1698 "Prefix information\n"
1700 "Valid lifetime in seconds\n"
1701 "Infinite valid lifetime\n"
1702 "Preferred lifetime in seconds\n"
1703 "Infinite preferred lifetime\n"
1704 "Do not use prefix for autoconfiguration\n"
1705 "Do not use prefix for onlink determination\n"
1706 "Set Router Address flag\n")
1708 ALIAS (no_ipv6_nd_prefix
,
1709 no_ipv6_nd_prefix_val_noauto_cmd
,
1710 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1712 "Interface IPv6 config commands\n"
1713 "Neighbor discovery\n"
1714 "Prefix information\n"
1716 "Valid lifetime in seconds\n"
1717 "Infinite valid lifetime\n"
1718 "Preferred lifetime in seconds\n"
1719 "Infinite preferred lifetime\n"
1720 "Do not use prefix for autoconfiguration")
1722 ALIAS (no_ipv6_nd_prefix
,
1723 no_ipv6_nd_prefix_val_offlink_cmd
,
1724 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1726 "Interface IPv6 config commands\n"
1727 "Neighbor discovery\n"
1728 "Prefix information\n"
1730 "Valid lifetime in seconds\n"
1731 "Infinite valid lifetime\n"
1732 "Preferred lifetime in seconds\n"
1733 "Infinite preferred lifetime\n"
1734 "Do not use prefix for onlink determination\n")
1736 ALIAS (no_ipv6_nd_prefix
,
1737 no_ipv6_nd_prefix_val_rtaddr_cmd
,
1738 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1740 "Interface IPv6 config commands\n"
1741 "Neighbor discovery\n"
1742 "Prefix information\n"
1744 "Valid lifetime in seconds\n"
1745 "Infinite valid lifetime\n"
1746 "Preferred lifetime in seconds\n"
1747 "Infinite preferred lifetime\n"
1748 "Set Router Address flag\n")
1750 ALIAS (no_ipv6_nd_prefix
,
1751 no_ipv6_nd_prefix_val_cmd
,
1752 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1754 "Interface IPv6 config commands\n"
1755 "Neighbor discovery\n"
1756 "Prefix information\n"
1758 "Valid lifetime in seconds\n"
1759 "Infinite valid lifetime\n"
1760 "Preferred lifetime in seconds\n"
1761 "Infinite preferred lifetime\n")
1763 ALIAS (no_ipv6_nd_prefix
,
1764 no_ipv6_nd_prefix_noval_cmd
,
1765 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1767 "Interface IPv6 config commands\n"
1768 "Neighbor discovery\n"
1769 "Prefix information\n"
1771 "Do not use prefix for autoconfiguration\n"
1772 "Do not use prefix for onlink determination\n")
1774 ALIAS (no_ipv6_nd_prefix
,
1775 no_ipv6_nd_prefix_noval_rev_cmd
,
1776 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1778 "Interface IPv6 config commands\n"
1779 "Neighbor discovery\n"
1780 "Prefix information\n"
1782 "Do not use prefix for onlink determination\n"
1783 "Do not use prefix for autoconfiguration\n")
1785 ALIAS (no_ipv6_nd_prefix
,
1786 no_ipv6_nd_prefix_noval_noauto_cmd
,
1787 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1789 "Interface IPv6 config commands\n"
1790 "Neighbor discovery\n"
1791 "Prefix information\n"
1793 "Do not use prefix for autoconfiguration\n")
1795 ALIAS (no_ipv6_nd_prefix
,
1796 no_ipv6_nd_prefix_noval_offlink_cmd
,
1797 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1799 "Interface IPv6 config commands\n"
1800 "Neighbor discovery\n"
1801 "Prefix information\n"
1803 "Do not use prefix for onlink determination\n")
1805 ALIAS (no_ipv6_nd_prefix
,
1806 no_ipv6_nd_prefix_noval_rtaddr_cmd
,
1807 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1809 "Interface IPv6 config commands\n"
1810 "Neighbor discovery\n"
1811 "Prefix information\n"
1813 "Set Router Address flag\n")
1815 DEFUN (ipv6_nd_router_preference
,
1816 ipv6_nd_router_preference_cmd
,
1817 "ipv6 nd router-preference (high|medium|low)",
1818 "Interface IPv6 config commands\n"
1819 "Neighbor discovery\n"
1820 "Default router preference\n"
1821 "High default router preference\n"
1822 "Low default router preference\n"
1823 "Medium default router preference (default)\n")
1825 struct interface
*ifp
;
1826 struct zebra_if
*zif
;
1829 ifp
= (struct interface
*) vty
->index
;
1832 while (0 != rtadv_pref_strs
[i
])
1834 if (strncmp (argv
[0], rtadv_pref_strs
[i
], 1) == 0)
1836 zif
->rtadv
.DefaultPreference
= i
;
1842 return CMD_ERR_NO_MATCH
;
1845 DEFUN (no_ipv6_nd_router_preference
,
1846 no_ipv6_nd_router_preference_cmd
,
1847 "no ipv6 nd router-preference",
1849 "Interface IPv6 config commands\n"
1850 "Neighbor discovery\n"
1851 "Default router preference\n")
1853 struct interface
*ifp
;
1854 struct zebra_if
*zif
;
1856 ifp
= (struct interface
*) vty
->index
;
1859 zif
->rtadv
.DefaultPreference
= RTADV_PREF_MEDIUM
; /* Default per RFC4191. */
1864 ALIAS (no_ipv6_nd_router_preference
,
1865 no_ipv6_nd_router_preference_val_cmd
,
1866 "no ipv6 nd router-preference (high|medium|low)",
1868 "Interface IPv6 config commands\n"
1869 "Neighbor discovery\n"
1870 "Default router preference\n"
1871 "High default router preference\n"
1872 "Low default router preference\n"
1873 "Medium default router preference (default)\n")
1877 "ipv6 nd mtu <1-65535>",
1878 "Interface IPv6 config commands\n"
1879 "Neighbor discovery\n"
1883 struct interface
*ifp
= (struct interface
*) vty
->index
;
1884 struct zebra_if
*zif
= ifp
->info
;
1885 VTY_GET_INTEGER_RANGE ("MTU", zif
->rtadv
.AdvLinkMTU
, argv
[0], 1, 65535);
1889 DEFUN (no_ipv6_nd_mtu
,
1893 "Interface IPv6 config commands\n"
1894 "Neighbor discovery\n"
1897 struct interface
*ifp
= (struct interface
*) vty
->index
;
1898 struct zebra_if
*zif
= ifp
->info
;
1899 zif
->rtadv
.AdvLinkMTU
= 0;
1903 ALIAS (no_ipv6_nd_mtu
,
1904 no_ipv6_nd_mtu_val_cmd
,
1905 "no ipv6 nd mtu <1-65535>",
1907 "Interface IPv6 config commands\n"
1908 "Neighbor discovery\n"
1912 /* Write configuration about router advertisement. */
1914 rtadv_config_write (struct vty
*vty
, struct interface
*ifp
)
1916 struct zebra_if
*zif
;
1917 struct listnode
*node
;
1918 struct rtadv_prefix
*rprefix
;
1919 char buf
[PREFIX_STRLEN
];
1924 if (!(if_is_loopback (ifp
) ||
1925 CHECK_FLAG(ifp
->status
, ZEBRA_INTERFACE_VRF_LOOPBACK
)))
1927 if (zif
->rtadv
.AdvSendAdvertisements
)
1928 vty_out (vty
, " no ipv6 nd suppress-ra%s", VTY_NEWLINE
);
1931 interval
= zif
->rtadv
.MaxRtrAdvInterval
;
1932 if (interval
% 1000)
1933 vty_out (vty
, " ipv6 nd ra-interval msec %d%s", interval
,
1936 if (interval
!= RTADV_MAX_RTR_ADV_INTERVAL
)
1937 vty_out (vty
, " ipv6 nd ra-interval %d%s", interval
/ 1000,
1940 if (zif
->rtadv
.AdvIntervalOption
)
1941 vty_out (vty
, " ipv6 nd adv-interval-option%s", VTY_NEWLINE
);
1943 if (zif
->rtadv
.AdvDefaultLifetime
!= -1)
1944 vty_out (vty
, " ipv6 nd ra-lifetime %d%s", zif
->rtadv
.AdvDefaultLifetime
,
1947 if (zif
->rtadv
.HomeAgentPreference
)
1948 vty_out (vty
, " ipv6 nd home-agent-preference %u%s",
1949 zif
->rtadv
.HomeAgentPreference
, VTY_NEWLINE
);
1951 if (zif
->rtadv
.HomeAgentLifetime
!= -1)
1952 vty_out (vty
, " ipv6 nd home-agent-lifetime %u%s",
1953 zif
->rtadv
.HomeAgentLifetime
, VTY_NEWLINE
);
1955 if (zif
->rtadv
.AdvHomeAgentFlag
)
1956 vty_out (vty
, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE
);
1958 if (zif
->rtadv
.AdvReachableTime
)
1959 vty_out (vty
, " ipv6 nd reachable-time %d%s", zif
->rtadv
.AdvReachableTime
,
1962 if (zif
->rtadv
.AdvManagedFlag
)
1963 vty_out (vty
, " ipv6 nd managed-config-flag%s", VTY_NEWLINE
);
1965 if (zif
->rtadv
.AdvOtherConfigFlag
)
1966 vty_out (vty
, " ipv6 nd other-config-flag%s", VTY_NEWLINE
);
1968 if (zif
->rtadv
.DefaultPreference
!= RTADV_PREF_MEDIUM
)
1969 vty_out (vty
, " ipv6 nd router-preference %s%s",
1970 rtadv_pref_strs
[zif
->rtadv
.DefaultPreference
],
1973 if (zif
->rtadv
.AdvLinkMTU
)
1974 vty_out (vty
, " ipv6 nd mtu %d%s", zif
->rtadv
.AdvLinkMTU
, VTY_NEWLINE
);
1976 for (ALL_LIST_ELEMENTS_RO (zif
->rtadv
.AdvPrefixList
, node
, rprefix
))
1978 vty_out (vty
, " ipv6 nd prefix %s",
1979 prefix2str (&rprefix
->prefix
, buf
, sizeof(buf
)));
1980 if ((rprefix
->AdvValidLifetime
!= RTADV_VALID_LIFETIME
) ||
1981 (rprefix
->AdvPreferredLifetime
!= RTADV_PREFERRED_LIFETIME
))
1983 if (rprefix
->AdvValidLifetime
== UINT32_MAX
)
1984 vty_out (vty
, " infinite");
1986 vty_out (vty
, " %u", rprefix
->AdvValidLifetime
);
1987 if (rprefix
->AdvPreferredLifetime
== UINT32_MAX
)
1988 vty_out (vty
, " infinite");
1990 vty_out (vty
, " %u", rprefix
->AdvPreferredLifetime
);
1992 if (!rprefix
->AdvOnLinkFlag
)
1993 vty_out (vty
, " off-link");
1994 if (!rprefix
->AdvAutonomousFlag
)
1995 vty_out (vty
, " no-autoconfig");
1996 if (rprefix
->AdvRouterAddressFlag
)
1997 vty_out (vty
, " router-address");
1998 vty_out (vty
, "%s", VTY_NEWLINE
);
2004 rtadv_event (struct zebra_ns
*zns
, enum rtadv_event event
, int val
)
2006 struct rtadv
*rtadv
= &zns
->rtadv
;
2011 if (! rtadv
->ra_read
)
2012 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zns
, val
);
2013 if (! rtadv
->ra_timer
)
2014 rtadv
->ra_timer
= thread_add_event (zebrad
.master
, rtadv_timer
,
2018 if (rtadv
->ra_timer
)
2020 thread_cancel (rtadv
->ra_timer
);
2021 rtadv
->ra_timer
= NULL
;
2025 thread_cancel (rtadv
->ra_read
);
2026 rtadv
->ra_read
= NULL
;
2030 if (! rtadv
->ra_timer
)
2031 rtadv
->ra_timer
= thread_add_timer (zebrad
.master
, rtadv_timer
, zns
,
2034 case RTADV_TIMER_MSEC
:
2035 if (! rtadv
->ra_timer
)
2036 rtadv
->ra_timer
= thread_add_timer_msec (zebrad
.master
, rtadv_timer
,
2040 if (! rtadv
->ra_read
)
2041 rtadv
->ra_read
= thread_add_read (zebrad
.master
, rtadv_read
, zns
, val
);
2050 rtadv_init (struct zebra_ns
*zns
)
2052 zns
->rtadv
.sock
= rtadv_make_socket ();
2056 rtadv_terminate (struct zebra_ns
*zns
)
2058 rtadv_event (zns
, RTADV_STOP
, 0);
2059 if (zns
->rtadv
.sock
>= 0)
2061 close (zns
->rtadv
.sock
);
2062 zns
->rtadv
.sock
= -1;
2065 zns
->rtadv
.adv_if_count
= 0;
2066 zns
->rtadv
.adv_msec_if_count
= 0;
2070 rtadv_cmd_init (void)
2072 install_element (INTERFACE_NODE
, &ipv6_nd_suppress_ra_cmd
);
2073 install_element (INTERFACE_NODE
, &no_ipv6_nd_suppress_ra_cmd
);
2074 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_cmd
);
2075 install_element (INTERFACE_NODE
, &ipv6_nd_ra_interval_msec_cmd
);
2076 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_cmd
);
2077 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_val_cmd
);
2078 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_interval_msec_val_cmd
);
2079 install_element (INTERFACE_NODE
, &ipv6_nd_ra_lifetime_cmd
);
2080 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_cmd
);
2081 install_element (INTERFACE_NODE
, &no_ipv6_nd_ra_lifetime_val_cmd
);
2082 install_element (INTERFACE_NODE
, &ipv6_nd_reachable_time_cmd
);
2083 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_cmd
);
2084 install_element (INTERFACE_NODE
, &no_ipv6_nd_reachable_time_val_cmd
);
2085 install_element (INTERFACE_NODE
, &ipv6_nd_managed_config_flag_cmd
);
2086 install_element (INTERFACE_NODE
, &no_ipv6_nd_managed_config_flag_cmd
);
2087 install_element (INTERFACE_NODE
, &ipv6_nd_other_config_flag_cmd
);
2088 install_element (INTERFACE_NODE
, &no_ipv6_nd_other_config_flag_cmd
);
2089 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_config_flag_cmd
);
2090 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_config_flag_cmd
);
2091 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_preference_cmd
);
2092 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_cmd
);
2093 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_preference_val_cmd
);
2094 install_element (INTERFACE_NODE
, &ipv6_nd_homeagent_lifetime_cmd
);
2095 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_cmd
);
2096 install_element (INTERFACE_NODE
, &no_ipv6_nd_homeagent_lifetime_val_cmd
);
2097 install_element (INTERFACE_NODE
, &ipv6_nd_adv_interval_config_option_cmd
);
2098 install_element (INTERFACE_NODE
, &no_ipv6_nd_adv_interval_config_option_cmd
);
2099 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_cmd
);
2100 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_rtaddr_cmd
);
2101 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_nortaddr_cmd
);
2102 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rev_cmd
);
2103 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_noauto_cmd
);
2104 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_offlink_cmd
);
2105 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_rtaddr_cmd
);
2106 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_val_cmd
);
2107 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_cmd
);
2108 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rev_cmd
);
2109 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_noauto_cmd
);
2110 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_offlink_cmd
);
2111 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_noval_rtaddr_cmd
);
2112 install_element (INTERFACE_NODE
, &ipv6_nd_prefix_prefix_cmd
);
2113 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_cmd
);
2114 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd
);
2115 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_nortaddr_cmd
);
2116 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rev_cmd
);
2117 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_noauto_cmd
);
2118 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_offlink_cmd
);
2119 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_rtaddr_cmd
);
2120 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_val_cmd
);
2121 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_cmd
);
2122 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rev_cmd
);
2123 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_noauto_cmd
);
2124 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_offlink_cmd
);
2125 install_element (INTERFACE_NODE
, &no_ipv6_nd_prefix_noval_rtaddr_cmd
);
2126 install_element (INTERFACE_NODE
, &ipv6_nd_router_preference_cmd
);
2127 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_cmd
);
2128 install_element (INTERFACE_NODE
, &no_ipv6_nd_router_preference_val_cmd
);
2129 install_element (INTERFACE_NODE
, &ipv6_nd_mtu_cmd
);
2130 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_cmd
);
2131 install_element (INTERFACE_NODE
, &no_ipv6_nd_mtu_val_cmd
);
2135 if_join_all_router (int sock
, struct interface
*ifp
)
2139 struct ipv6_mreq mreq
;
2141 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2142 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2143 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2145 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_JOIN_GROUP
,
2146 (char *) &mreq
, sizeof mreq
);
2148 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2149 ifp
->name
, ifp
->ifindex
, sock
, safe_strerror (errno
));
2151 if (IS_ZEBRA_DEBUG_EVENT
)
2152 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2153 ifp
->name
, ifp
->ifindex
, sock
);
2159 if_leave_all_router (int sock
, struct interface
*ifp
)
2163 struct ipv6_mreq mreq
;
2165 memset (&mreq
, 0, sizeof (struct ipv6_mreq
));
2166 inet_pton (AF_INET6
, ALLROUTER
, &mreq
.ipv6mr_multiaddr
);
2167 mreq
.ipv6mr_interface
= ifp
->ifindex
;
2169 ret
= setsockopt (sock
, IPPROTO_IPV6
, IPV6_LEAVE_GROUP
,
2170 (char *) &mreq
, sizeof mreq
);
2172 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2173 ifp
->name
, ifp
->ifindex
, sock
,safe_strerror (errno
));
2175 if (IS_ZEBRA_DEBUG_EVENT
)
2176 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2177 ifp
->name
, ifp
->ifindex
, sock
);
2184 rtadv_init (struct zebra_ns
*zns
)
2189 rtadv_terminate (struct zebra_ns
*zns
)
2194 rtadv_cmd_init (void)
2198 #endif /* HAVE_RTADV && HAVE_IPV6 */