]> git.proxmox.com Git - mirror_frr.git/blob - zebra/rtadv.c
Should be able to "no" the full text of any config line
[mirror_frr.git] / zebra / rtadv.c
1 /* Router advertisement
2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
3 * Copyright (C) 1999 Kunihiro Ishiguro
4 *
5 * This file is part of GNU Zebra.
6 *
7 * GNU Zebra is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the
9 * Free Software Foundation; either version 2, or (at your option) any
10 * later version.
11 *
12 * GNU Zebra is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with GNU Zebra; see the file COPYING. If not, write to the Free
19 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23 #include <zebra.h>
24
25 #include "memory.h"
26 #include "sockopt.h"
27 #include "thread.h"
28 #include "if.h"
29 #include "log.h"
30 #include "prefix.h"
31 #include "linklist.h"
32 #include "command.h"
33 #include "privs.h"
34 #include "vrf.h"
35
36 #include "zebra/interface.h"
37 #include "zebra/rtadv.h"
38 #include "zebra/debug.h"
39 #include "zebra/rib.h"
40 #include "zebra/zserv.h"
41
42 extern struct zebra_privs_t zserv_privs;
43
44 #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
45
46 #ifdef OPEN_BSD
47 #include <netinet/icmp6.h>
48 #endif
49
50 /* If RFC2133 definition is used. */
51 #ifndef IPV6_JOIN_GROUP
52 #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
53 #endif
54 #ifndef IPV6_LEAVE_GROUP
55 #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
56 #endif
57
58 #define ALLNODE "ff02::1"
59 #define ALLROUTER "ff02::2"
60
61 extern struct zebra_t zebrad;
62
63 enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
64 RTADV_TIMER_MSEC, RTADV_READ};
65
66 static void rtadv_event (struct zebra_vrf *, enum rtadv_event, int);
67
68 static int if_join_all_router (int, struct interface *);
69 static int if_leave_all_router (int, struct interface *);
70
71 static int
72 rtadv_recv_packet (int sock, u_char *buf, int buflen,
73 struct sockaddr_in6 *from, unsigned int *ifindex,
74 int *hoplimit)
75 {
76 int ret;
77 struct msghdr msg;
78 struct iovec iov;
79 struct cmsghdr *cmsgptr;
80 struct in6_addr dst;
81
82 char adata[1024];
83
84 /* Fill in message and iovec. */
85 msg.msg_name = (void *) from;
86 msg.msg_namelen = sizeof (struct sockaddr_in6);
87 msg.msg_iov = &iov;
88 msg.msg_iovlen = 1;
89 msg.msg_control = (void *) adata;
90 msg.msg_controllen = sizeof adata;
91 iov.iov_base = buf;
92 iov.iov_len = buflen;
93
94 /* If recvmsg fail return minus value. */
95 ret = recvmsg (sock, &msg, 0);
96 if (ret < 0)
97 return ret;
98
99 for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
100 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
101 {
102 /* I want interface index which this packet comes from. */
103 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
104 cmsgptr->cmsg_type == IPV6_PKTINFO)
105 {
106 struct in6_pktinfo *ptr;
107
108 ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
109 *ifindex = ptr->ipi6_ifindex;
110 memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
111 }
112
113 /* Incoming packet's hop limit. */
114 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
115 cmsgptr->cmsg_type == IPV6_HOPLIMIT)
116 {
117 int *hoptr = (int *) CMSG_DATA (cmsgptr);
118 *hoplimit = *hoptr;
119 }
120 }
121 return ret;
122 }
123
124 #define RTADV_MSG_SIZE 4096
125
126 /* Send router advertisement packet. */
127 static void
128 rtadv_send_packet (int sock, struct interface *ifp)
129 {
130 struct msghdr msg;
131 struct iovec iov;
132 struct cmsghdr *cmsgptr;
133 struct in6_pktinfo *pkt;
134 struct sockaddr_in6 addr;
135 #ifdef HAVE_STRUCT_SOCKADDR_DL
136 struct sockaddr_dl *sdl;
137 #endif /* HAVE_STRUCT_SOCKADDR_DL */
138 static void *adata = NULL;
139 unsigned char buf[RTADV_MSG_SIZE];
140 struct nd_router_advert *rtadv;
141 int ret;
142 int len = 0;
143 struct zebra_if *zif;
144 struct rtadv_prefix *rprefix;
145 u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
146 struct listnode *node;
147 u_int16_t pkt_RouterLifetime;
148
149 /*
150 * Allocate control message bufffer. This is dynamic because
151 * CMSG_SPACE is not guaranteed not to call a function. Note that
152 * the size will be different on different architectures due to
153 * differing alignment rules.
154 */
155 if (adata == NULL)
156 {
157 /* XXX Free on shutdown. */
158 adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
159
160 if (adata == NULL)
161 zlog_err("rtadv_send_packet: can't malloc control data\n");
162 }
163
164 /* Logging of packet. */
165 if (IS_ZEBRA_DEBUG_PACKET)
166 zlog_debug ("Router advertisement send to %s", ifp->name);
167
168 /* Fill in sockaddr_in6. */
169 memset (&addr, 0, sizeof (struct sockaddr_in6));
170 addr.sin6_family = AF_INET6;
171 #ifdef SIN6_LEN
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);
176
177 /* Fetch interface information. */
178 zif = ifp->info;
179
180 /* Make router advertisement message. */
181 rtadv = (struct nd_router_advert *) buf;
182
183 rtadv->nd_ra_type = ND_ROUTER_ADVERT;
184 rtadv->nd_ra_code = 0;
185 rtadv->nd_ra_cksum = 0;
186
187 rtadv->nd_ra_curhoplimit = 64;
188
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;
193
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);
214
215 len = sizeof (struct nd_router_advert);
216
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 */
221 if
222 (
223 zif->rtadv.AdvHomeAgentFlag &&
224 (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
225 )
226 {
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
239 (
240 zif->rtadv.HomeAgentLifetime != -1 ?
241 zif->rtadv.HomeAgentLifetime :
242 MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
243 );
244 len += sizeof(struct nd_opt_homeagent_info);
245 }
246
247 if (zif->rtadv.AdvIntervalOption)
248 {
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);
256 }
257
258 /* Fill in prefix. */
259 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
260 {
261 struct nd_opt_prefix_info *pinfo;
262
263 pinfo = (struct nd_opt_prefix_info *) (buf + len);
264
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;
268
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;
276
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;
280
281 IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
282
283 #ifdef DEBUG
284 {
285 u_char buf[INET6_ADDRSTRLEN];
286
287 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
288 buf, INET6_ADDRSTRLEN));
289
290 }
291 #endif /* DEBUG */
292
293 len += sizeof (struct nd_opt_prefix_info);
294 }
295
296 /* Hardware address. */
297 #ifdef HAVE_STRUCT_SOCKADDR_DL
298 sdl = &ifp->sdl;
299 if (sdl != NULL && sdl->sdl_alen != 0)
300 {
301 buf[len++] = ND_OPT_SOURCE_LINKADDR;
302
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;
306
307 memcpy (buf + len, LLADDR (sdl), sdl->sdl_alen);
308 len += sdl->sdl_alen;
309
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;
313 }
314 #else
315 if (ifp->hw_addr_len != 0)
316 {
317 buf[len++] = ND_OPT_SOURCE_LINKADDR;
318
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;
322
323 memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
324 len += ifp->hw_addr_len;
325
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;
329 }
330 #endif /* HAVE_STRUCT_SOCKADDR_DL */
331
332 /* MTU */
333 if (zif->rtadv.AdvLinkMTU)
334 {
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);
341 }
342
343 msg.msg_name = (void *) &addr;
344 msg.msg_namelen = sizeof (struct sockaddr_in6);
345 msg.msg_iov = &iov;
346 msg.msg_iovlen = 1;
347 msg.msg_control = (void *) adata;
348 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
349 msg.msg_flags = 0;
350 iov.iov_base = buf;
351 iov.iov_len = len;
352
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;
357
358 pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
359 memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
360 pkt->ipi6_ifindex = ifp->ifindex;
361
362 ret = sendmsg (sock, &msg, 0);
363 if (ret < 0)
364 {
365 zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
366 errno, safe_strerror(errno));
367 }
368 }
369
370 static int
371 rtadv_timer (struct thread *thread)
372 {
373 struct zebra_vrf *zvrf = THREAD_ARG (thread);
374 struct listnode *node, *nnode;
375 struct interface *ifp;
376 struct zebra_if *zif;
377 int period;
378
379 zvrf->rtadv.ra_timer = NULL;
380 if (zvrf->rtadv.adv_msec_if_count == 0)
381 {
382 period = 1000; /* 1 s */
383 rtadv_event (zvrf, RTADV_TIMER, 1 /* 1 s */);
384 }
385 else
386 {
387 period = 10; /* 10 ms */
388 rtadv_event (zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
389 }
390
391 for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf->vrf_id), node, nnode, ifp))
392 {
393 if (if_is_loopback (ifp) || ! if_is_operative (ifp))
394 continue;
395
396 zif = ifp->info;
397
398 if (zif->rtadv.AdvSendAdvertisements)
399 {
400 zif->rtadv.AdvIntervalTimer -= period;
401 if (zif->rtadv.AdvIntervalTimer <= 0)
402 {
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);
407 }
408 }
409 }
410 return 0;
411 }
412
413 static void
414 rtadv_process_solicit (struct interface *ifp)
415 {
416 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
417
418 zlog_info ("Router solicitation received on %s vrf %u", ifp->name, zvrf->vrf_id);
419
420 rtadv_send_packet (zvrf->rtadv.sock, ifp);
421 }
422
423 static void
424 rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
425 struct sockaddr_in6 *addr)
426 {
427 struct nd_router_advert *radvert;
428 char addr_str[INET6_ADDRSTRLEN];
429 struct zebra_if *zif;
430
431 zif = ifp->info;
432
433 inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
434
435 if (IS_ZEBRA_DEBUG_PACKET)
436 zlog_debug ("Router advertisement received on %s from : %s", ifp->name, addr_str);
437
438 if (len < sizeof(struct nd_router_advert)) {
439 zlog_warn("received icmpv6 RA packet with invalid length (%d) from %s",
440 len, addr_str);
441 return;
442 }
443 if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
444 zlog_warn("received icmpv6 RA packet with non-linklocal source address from %s",
445 addr_str);
446 return;
447 }
448
449 radvert = (struct nd_router_advert *) msg;
450
451 if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
452 (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit))
453 {
454 zlog_warn("our AdvCurHopLimit on %s doesn't agree with %s",
455 ifp->name, addr_str);
456 }
457
458 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
459 !zif->rtadv.AdvManagedFlag)
460 {
461 zlog_warn("our AdvManagedFlag on %s doesn't agree with %s",
462 ifp->name, addr_str);
463 }
464
465 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
466 !zif->rtadv.AdvOtherConfigFlag)
467 {
468 zlog_warn("our AdvOtherConfigFlag on %s doesn't agree with %s",
469 ifp->name, addr_str);
470 }
471
472 if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
473 (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime))
474 {
475 zlog_warn("our AdvReachableTime on %s doesn't agree with %s",
476 ifp->name, addr_str);
477 }
478
479 if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
480 (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer))
481 {
482 zlog_warn("our AdvRetransTimer on %s doesn't agree with %s",
483 ifp->name, addr_str);
484 }
485
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);
491 else
492 nbr_connected_delete_ipv6(ifp, &addr->sin6_addr, 128);
493
494 return;
495 }
496
497
498 static void
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)
501 {
502 struct icmp6_hdr *icmph;
503 struct interface *ifp;
504 struct zebra_if *zif;
505
506 /* Interface search. */
507 ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
508 if (ifp == NULL)
509 {
510 zlog_warn ("Unknown interface index: %d, vrf %u", ifindex, vrf_id);
511 return;
512 }
513
514 if (if_is_loopback (ifp))
515 return;
516
517 /* Check interface configuration. */
518 zif = ifp->info;
519 if (! zif->rtadv.AdvSendAdvertisements)
520 return;
521
522 /* ICMP message length check. */
523 if (len < sizeof (struct icmp6_hdr))
524 {
525 zlog_warn ("Invalid ICMPV6 packet length: %d", len);
526 return;
527 }
528
529 icmph = (struct icmp6_hdr *) buf;
530
531 /* ICMP message type check. */
532 if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
533 icmph->icmp6_type != ND_ROUTER_ADVERT)
534 {
535 zlog_warn ("Unwanted ICMPV6 message type: %d", icmph->icmp6_type);
536 return;
537 }
538
539 /* Hoplimit check. */
540 if (hoplimit >= 0 && hoplimit != 255)
541 {
542 zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
543 hoplimit);
544 return;
545 }
546
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);
552
553 return;
554 }
555
556 static int
557 rtadv_read (struct thread *thread)
558 {
559 int sock;
560 int len;
561 u_char buf[RTADV_MSG_SIZE];
562 struct sockaddr_in6 from;
563 unsigned int ifindex = 0;
564 int hoplimit = -1;
565 struct zebra_vrf *zvrf = THREAD_ARG (thread);
566
567 sock = THREAD_FD (thread);
568 zvrf->rtadv.ra_read = NULL;
569
570 /* Register myself. */
571 rtadv_event (zvrf, RTADV_READ, sock);
572
573 len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
574
575 if (len < 0)
576 {
577 zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno));
578 return len;
579 }
580
581 rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zvrf->vrf_id);
582
583 return 0;
584 }
585
586 static int
587 rtadv_make_socket (vrf_id_t vrf_id)
588 {
589 int sock;
590 int ret;
591 struct icmp6_filter filter;
592
593 if ( zserv_privs.change (ZPRIVS_RAISE) )
594 zlog_err ("rtadv_make_socket: could not raise privs, %s",
595 safe_strerror (errno) );
596
597 sock = vrf_socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, vrf_id);
598
599 if ( zserv_privs.change (ZPRIVS_LOWER) )
600 zlog_err ("rtadv_make_socket: could not lower privs, %s",
601 safe_strerror (errno) );
602
603 /* When we can't make ICMPV6 socket simply back. Router
604 advertisement feature will not be supported. */
605 if (sock < 0)
606 return -1;
607
608 ret = setsockopt_ipv6_pktinfo (sock, 1);
609 if (ret < 0)
610 return ret;
611 ret = setsockopt_ipv6_multicast_loop (sock, 0);
612 if (ret < 0)
613 return ret;
614 ret = setsockopt_ipv6_unicast_hops (sock, 255);
615 if (ret < 0)
616 return ret;
617 ret = setsockopt_ipv6_multicast_hops (sock, 255);
618 if (ret < 0)
619 return ret;
620 ret = setsockopt_ipv6_hoplimit (sock, 1);
621 if (ret < 0)
622 return ret;
623
624 ICMP6_FILTER_SETBLOCKALL(&filter);
625 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
626 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
627
628 ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
629 sizeof (struct icmp6_filter));
630 if (ret < 0)
631 {
632 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
633 return ret;
634 }
635
636 return sock;
637 }
638
639 static struct rtadv_prefix *
640 rtadv_prefix_new (void)
641 {
642 return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
643 }
644
645 static void
646 rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
647 {
648 XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
649 }
650
651 static struct rtadv_prefix *
652 rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
653 {
654 struct listnode *node;
655 struct rtadv_prefix *rprefix;
656
657 for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
658 if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
659 return rprefix;
660 return NULL;
661 }
662
663 static struct rtadv_prefix *
664 rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
665 {
666 struct rtadv_prefix *rprefix;
667
668 rprefix = rtadv_prefix_lookup (rplist, p);
669 if (rprefix)
670 return rprefix;
671
672 rprefix = rtadv_prefix_new ();
673 memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
674 listnode_add (rplist, rprefix);
675
676 return rprefix;
677 }
678
679 static void
680 rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
681 {
682 struct rtadv_prefix *rprefix;
683
684 rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
685
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;
692 }
693
694 static int
695 rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
696 {
697 struct rtadv_prefix *rprefix;
698
699 rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
700 if (rprefix != NULL)
701 {
702 listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
703 rtadv_prefix_free (rprefix);
704 return 1;
705 }
706 else
707 return 0;
708 }
709
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")
716 {
717 struct interface *ifp;
718 struct zebra_if *zif;
719 struct zebra_vrf *zvrf;
720
721 ifp = vty->index;
722 zif = ifp->info;
723 zvrf = vrf_info_lookup (ifp->vrf_id);
724
725 if (if_is_loopback (ifp))
726 {
727 vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
728 return CMD_WARNING;
729 }
730
731 if (zif->rtadv.AdvSendAdvertisements)
732 {
733 zif->rtadv.AdvSendAdvertisements = 0;
734 zif->rtadv.AdvIntervalTimer = 0;
735 zvrf->rtadv.adv_if_count--;
736
737 if_leave_all_router (zvrf->rtadv.sock, ifp);
738
739 if (zvrf->rtadv.adv_if_count == 0)
740 rtadv_event (zvrf, RTADV_STOP, 0);
741 }
742
743 return CMD_SUCCESS;
744 }
745
746 DEFUN (no_ipv6_nd_suppress_ra,
747 no_ipv6_nd_suppress_ra_cmd,
748 "no ipv6 nd suppress-ra",
749 NO_STR
750 "Interface IPv6 config commands\n"
751 "Neighbor discovery\n"
752 "Suppress Router Advertisement\n")
753 {
754 struct interface *ifp;
755 struct zebra_if *zif;
756 struct zebra_vrf *zvrf;
757
758 ifp = vty->index;
759 zif = ifp->info;
760 zvrf = vrf_info_lookup (ifp->vrf_id);
761
762 if (if_is_loopback (ifp))
763 {
764 vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
765 return CMD_WARNING;
766 }
767
768 if (! zif->rtadv.AdvSendAdvertisements)
769 {
770 zif->rtadv.AdvSendAdvertisements = 1;
771 zif->rtadv.AdvIntervalTimer = 0;
772 zvrf->rtadv.adv_if_count++;
773
774 if_join_all_router (zvrf->rtadv.sock, ifp);
775
776 if (zvrf->rtadv.adv_if_count == 1)
777 rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock);
778 }
779
780 return CMD_SUCCESS;
781 }
782
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")
790 {
791 unsigned interval;
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);
795
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))
798 {
799 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
800 return CMD_WARNING;
801 }
802
803 if (zif->rtadv.MaxRtrAdvInterval % 1000)
804 zvrf->rtadv.adv_msec_if_count--;
805
806 if (interval % 1000)
807 zvrf->rtadv.adv_msec_if_count++;
808
809 zif->rtadv.MaxRtrAdvInterval = interval;
810 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
811 zif->rtadv.AdvIntervalTimer = 0;
812
813 return CMD_SUCCESS;
814 }
815
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")
823 {
824 unsigned interval;
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);
828
829 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
830 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
831 {
832 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
833 return CMD_WARNING;
834 }
835
836 if (zif->rtadv.MaxRtrAdvInterval % 1000)
837 zvrf->rtadv.adv_msec_if_count--;
838
839 /* convert to milliseconds */
840 interval = interval * 1000;
841
842 zif->rtadv.MaxRtrAdvInterval = interval;
843 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
844 zif->rtadv.AdvIntervalTimer = 0;
845
846 return CMD_SUCCESS;
847 }
848
849 DEFUN (no_ipv6_nd_ra_interval,
850 no_ipv6_nd_ra_interval_cmd,
851 "no ipv6 nd ra-interval",
852 NO_STR
853 "Interface IPv6 config commands\n"
854 "Neighbor discovery\n"
855 "Router Advertisement interval\n")
856 {
857 struct interface *ifp;
858 struct zebra_if *zif;
859 struct zebra_vrf *zvrf;
860
861 ifp = (struct interface *) vty->index;
862 zif = ifp->info;
863 zvrf = vrf_info_lookup (ifp->vrf_id);
864
865 if (zif->rtadv.MaxRtrAdvInterval % 1000)
866 zvrf->rtadv.adv_msec_if_count--;
867
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;
871
872 return CMD_SUCCESS;
873 }
874
875 ALIAS (no_ipv6_nd_ra_interval,
876 no_ipv6_nd_ra_interval_val_cmd,
877 "no ipv6 nd ra-interval <1-1800>",
878 NO_STR
879 "Interface IPv6 config commands\n"
880 "Neighbor discovery\n"
881 "Router Advertisement interval\n")
882
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>",
886 NO_STR
887 "Interface IPv6 config commands\n"
888 "Neighbor discovery\n"
889 "Router Advertisement interval\n"
890 "Router Advertisement interval in milliseconds\n")
891
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"
897 "Router lifetime\n"
898 "Router lifetime in seconds (0 stands for a non-default gw)\n")
899 {
900 int lifetime;
901 struct interface *ifp;
902 struct zebra_if *zif;
903
904 ifp = (struct interface *) vty->index;
905 zif = ifp->info;
906
907 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
908
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))
914 {
915 vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
916 return CMD_WARNING;
917 }
918
919 zif->rtadv.AdvDefaultLifetime = lifetime;
920
921 return CMD_SUCCESS;
922 }
923
924 DEFUN (no_ipv6_nd_ra_lifetime,
925 no_ipv6_nd_ra_lifetime_cmd,
926 "no ipv6 nd ra-lifetime",
927 NO_STR
928 "Interface IPv6 config commands\n"
929 "Neighbor discovery\n"
930 "Router lifetime\n")
931 {
932 struct interface *ifp;
933 struct zebra_if *zif;
934
935 ifp = (struct interface *) vty->index;
936 zif = ifp->info;
937
938 zif->rtadv.AdvDefaultLifetime = -1;
939
940 return CMD_SUCCESS;
941 }
942
943 ALIAS (no_ipv6_nd_ra_lifetime,
944 no_ipv6_nd_ra_lifetime_val_cmd,
945 "no ipv6 nd ra-lifetime <0-9000>",
946 NO_STR
947 "Interface IPv6 config commands\n"
948 "Neighbor discovery\n"
949 "Router lifetime\n"
950 "Router lifetime in seconds (0 stands for a non-default gw)\n")
951
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"
957 "Reachable time\n"
958 "Reachable time in milliseconds\n")
959 {
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);
963 return CMD_SUCCESS;
964 }
965
966 DEFUN (no_ipv6_nd_reachable_time,
967 no_ipv6_nd_reachable_time_cmd,
968 "no ipv6 nd reachable-time",
969 NO_STR
970 "Interface IPv6 config commands\n"
971 "Neighbor discovery\n"
972 "Reachable time\n")
973 {
974 struct interface *ifp;
975 struct zebra_if *zif;
976
977 ifp = (struct interface *) vty->index;
978 zif = ifp->info;
979
980 zif->rtadv.AdvReachableTime = 0;
981
982 return CMD_SUCCESS;
983 }
984
985 ALIAS (no_ipv6_nd_reachable_time,
986 no_ipv6_nd_reachable_time_val_cmd,
987 "no ipv6 nd reachable-time <1-3600000>",
988 NO_STR
989 "Interface IPv6 config commands\n"
990 "Neighbor discovery\n"
991 "Reachable time\n"
992 "Reachable time in milliseconds\n")
993
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")
1001 {
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);
1005 return CMD_SUCCESS;
1006 }
1007
1008 DEFUN (no_ipv6_nd_homeagent_preference,
1009 no_ipv6_nd_homeagent_preference_cmd,
1010 "no ipv6 nd home-agent-preference",
1011 NO_STR
1012 "Interface IPv6 config commands\n"
1013 "Neighbor discovery\n"
1014 "Home Agent preference\n")
1015 {
1016 struct interface *ifp;
1017 struct zebra_if *zif;
1018
1019 ifp = (struct interface *) vty->index;
1020 zif = ifp->info;
1021
1022 zif->rtadv.HomeAgentPreference = 0;
1023
1024 return CMD_SUCCESS;
1025 }
1026
1027 ALIAS (no_ipv6_nd_homeagent_preference,
1028 no_ipv6_nd_homeagent_preference_val_cmd,
1029 "no ipv6 nd home-agent-preference <0-65535>",
1030 NO_STR
1031 "Interface IPv6 config commands\n"
1032 "Neighbor discovery\n"
1033 "Home Agent preference\n"
1034 "preference value (default is 0, least preferred)\n")
1035
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")
1043 {
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);
1047 return CMD_SUCCESS;
1048 }
1049
1050 DEFUN (no_ipv6_nd_homeagent_lifetime,
1051 no_ipv6_nd_homeagent_lifetime_cmd,
1052 "no ipv6 nd home-agent-lifetime",
1053 NO_STR
1054 "Interface IPv6 config commands\n"
1055 "Neighbor discovery\n"
1056 "Home Agent lifetime\n")
1057 {
1058 struct interface *ifp;
1059 struct zebra_if *zif;
1060
1061 ifp = (struct interface *) vty->index;
1062 zif = ifp->info;
1063
1064 zif->rtadv.HomeAgentLifetime = -1;
1065
1066 return CMD_SUCCESS;
1067 }
1068
1069 ALIAS (no_ipv6_nd_homeagent_lifetime,
1070 no_ipv6_nd_homeagent_lifetime_val_cmd,
1071 "no ipv6 nd home-agent-lifetime <0-65520>",
1072 NO_STR
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")
1077
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")
1084 {
1085 struct interface *ifp;
1086 struct zebra_if *zif;
1087
1088 ifp = (struct interface *) vty->index;
1089 zif = ifp->info;
1090
1091 zif->rtadv.AdvManagedFlag = 1;
1092
1093 return CMD_SUCCESS;
1094 }
1095
1096 DEFUN (no_ipv6_nd_managed_config_flag,
1097 no_ipv6_nd_managed_config_flag_cmd,
1098 "no ipv6 nd managed-config-flag",
1099 NO_STR
1100 "Interface IPv6 config commands\n"
1101 "Neighbor discovery\n"
1102 "Managed address configuration flag\n")
1103 {
1104 struct interface *ifp;
1105 struct zebra_if *zif;
1106
1107 ifp = (struct interface *) vty->index;
1108 zif = ifp->info;
1109
1110 zif->rtadv.AdvManagedFlag = 0;
1111
1112 return CMD_SUCCESS;
1113 }
1114
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")
1121 {
1122 struct interface *ifp;
1123 struct zebra_if *zif;
1124
1125 ifp = (struct interface *) vty->index;
1126 zif = ifp->info;
1127
1128 zif->rtadv.AdvHomeAgentFlag = 1;
1129
1130 return CMD_SUCCESS;
1131 }
1132
1133 DEFUN (no_ipv6_nd_homeagent_config_flag,
1134 no_ipv6_nd_homeagent_config_flag_cmd,
1135 "no ipv6 nd home-agent-config-flag",
1136 NO_STR
1137 "Interface IPv6 config commands\n"
1138 "Neighbor discovery\n"
1139 "Home Agent configuration flag\n")
1140 {
1141 struct interface *ifp;
1142 struct zebra_if *zif;
1143
1144 ifp = (struct interface *) vty->index;
1145 zif = ifp->info;
1146
1147 zif->rtadv.AdvHomeAgentFlag = 0;
1148
1149 return CMD_SUCCESS;
1150 }
1151
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")
1158 {
1159 struct interface *ifp;
1160 struct zebra_if *zif;
1161
1162 ifp = (struct interface *) vty->index;
1163 zif = ifp->info;
1164
1165 zif->rtadv.AdvIntervalOption = 1;
1166
1167 return CMD_SUCCESS;
1168 }
1169
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",
1173 NO_STR
1174 "Interface IPv6 config commands\n"
1175 "Neighbor discovery\n"
1176 "Advertisement Interval Option\n")
1177 {
1178 struct interface *ifp;
1179 struct zebra_if *zif;
1180
1181 ifp = (struct interface *) vty->index;
1182 zif = ifp->info;
1183
1184 zif->rtadv.AdvIntervalOption = 0;
1185
1186 return CMD_SUCCESS;
1187 }
1188
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")
1195 {
1196 struct interface *ifp;
1197 struct zebra_if *zif;
1198
1199 ifp = (struct interface *) vty->index;
1200 zif = ifp->info;
1201
1202 zif->rtadv.AdvOtherConfigFlag = 1;
1203
1204 return CMD_SUCCESS;
1205 }
1206
1207 DEFUN (no_ipv6_nd_other_config_flag,
1208 no_ipv6_nd_other_config_flag_cmd,
1209 "no ipv6 nd other-config-flag",
1210 NO_STR
1211 "Interface IPv6 config commands\n"
1212 "Neighbor discovery\n"
1213 "Other statefull configuration flag\n")
1214 {
1215 struct interface *ifp;
1216 struct zebra_if *zif;
1217
1218 ifp = (struct interface *) vty->index;
1219 zif = ifp->info;
1220
1221 zif->rtadv.AdvOtherConfigFlag = 0;
1222
1223 return CMD_SUCCESS;
1224 }
1225
1226 DEFUN (ipv6_nd_prefix,
1227 ipv6_nd_prefix_cmd,
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"
1233 "IPv6 prefix\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")
1241 {
1242 int i;
1243 int ret;
1244 int cursor = 1;
1245 struct interface *ifp;
1246 struct zebra_if *zebra_if;
1247 struct rtadv_prefix rp;
1248
1249 ifp = (struct interface *) vty->index;
1250 zebra_if = ifp->info;
1251
1252 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1253 if (!ret)
1254 {
1255 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1256 return CMD_WARNING;
1257 }
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;
1264
1265 if (argc > 1)
1266 {
1267 if ((isdigit(argv[1][0])) || strncmp (argv[1], "i", 1) == 0)
1268 {
1269 if ( strncmp (argv[1], "i", 1) == 0)
1270 rp.AdvValidLifetime = UINT32_MAX;
1271 else
1272 rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
1273 (char **)NULL, 10);
1274
1275 if ( strncmp (argv[2], "i", 1) == 0)
1276 rp.AdvPreferredLifetime = UINT32_MAX;
1277 else
1278 rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
1279 (char **)NULL, 10);
1280
1281 if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
1282 {
1283 vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
1284 return CMD_WARNING;
1285 }
1286 cursor = cursor + 2;
1287 }
1288 if (argc > cursor)
1289 {
1290 for (i = cursor; i < argc; i++)
1291 {
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;
1298 }
1299 }
1300 }
1301
1302 rtadv_prefix_set (zebra_if, &rp);
1303
1304 return CMD_SUCCESS;
1305 }
1306
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"
1314 "IPv6 prefix\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")
1321
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"
1329 "IPv6 prefix\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")
1336
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"
1344 "IPv6 prefix\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")
1352
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"
1360 "IPv6 prefix\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")
1366
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"
1374 "IPv6 prefix\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")
1380
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"
1388 "IPv6 prefix\n"
1389 "Valid lifetime in seconds\n"
1390 "Infinite valid lifetime\n"
1391 "Preferred lifetime in seconds\n"
1392 "Infinite preferred lifetime\n"
1393 "Set Router Address flag\n")
1394
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"
1402 "IPv6 prefix\n"
1403 "Valid lifetime in seconds\n"
1404 "Infinite valid lifetime\n"
1405 "Preferred lifetime in seconds\n"
1406 "Infinite preferred lifetime\n")
1407
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"
1414 "IPv6 prefix\n"
1415 "Do not use prefix for autoconfiguration\n"
1416 "Do not use prefix for onlink determination\n")
1417
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"
1424 "IPv6 prefix\n"
1425 "Do not use prefix for onlink determination\n"
1426 "Do not use prefix for autoconfiguration\n")
1427
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"
1434 "IPv6 prefix\n"
1435 "Do not use prefix for autoconfiguration\n")
1436
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"
1443 "IPv6 prefix\n"
1444 "Do not use prefix for onlink determination\n")
1445
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"
1452 "IPv6 prefix\n"
1453 "Set Router Address flag\n")
1454
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"
1461 "IPv6 prefix\n")
1462
1463 DEFUN (no_ipv6_nd_prefix,
1464 no_ipv6_nd_prefix_cmd,
1465 "no ipv6 nd prefix IPV6PREFIX",
1466 NO_STR
1467 "Interface IPv6 config commands\n"
1468 "Neighbor discovery\n"
1469 "Prefix information\n"
1470 "IPv6 prefix\n")
1471 {
1472 int ret;
1473 struct interface *ifp;
1474 struct zebra_if *zebra_if;
1475 struct rtadv_prefix rp;
1476
1477 ifp = (struct interface *) vty->index;
1478 zebra_if = ifp->info;
1479
1480 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1481 if (!ret)
1482 {
1483 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1484 return CMD_WARNING;
1485 }
1486 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1487
1488 ret = rtadv_prefix_reset (zebra_if, &rp);
1489 if (!ret)
1490 {
1491 vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
1492 return CMD_WARNING;
1493 }
1494
1495 return CMD_SUCCESS;
1496 }
1497
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|)",
1501 NO_STR
1502 "Interface IPv6 config commands\n"
1503 "Neighbor discovery\n"
1504 "Prefix information\n"
1505 "IPv6 prefix\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")
1513
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|)",
1517 NO_STR
1518 "Interface IPv6 config commands\n"
1519 "Neighbor discovery\n"
1520 "Prefix information\n"
1521 "IPv6 prefix\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")
1528
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|)",
1532 NO_STR
1533 "Interface IPv6 config commands\n"
1534 "Neighbor discovery\n"
1535 "Prefix information\n"
1536 "IPv6 prefix\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")
1544
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|)",
1548 NO_STR
1549 "Interface IPv6 config commands\n"
1550 "Neighbor discovery\n"
1551 "Prefix information\n"
1552 "IPv6 prefix\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")
1558
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|)",
1562 NO_STR
1563 "Interface IPv6 config commands\n"
1564 "Neighbor discovery\n"
1565 "Prefix information\n"
1566 "IPv6 prefix\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")
1572
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|)",
1576 NO_STR
1577 "Interface IPv6 config commands\n"
1578 "Neighbor discovery\n"
1579 "Prefix information\n"
1580 "IPv6 prefix\n"
1581 "Valid lifetime in seconds\n"
1582 "Infinite valid lifetime\n"
1583 "Preferred lifetime in seconds\n"
1584 "Infinite preferred lifetime\n"
1585 "Set Router Address flag\n")
1586
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)",
1590 NO_STR
1591 "Interface IPv6 config commands\n"
1592 "Neighbor discovery\n"
1593 "Prefix information\n"
1594 "IPv6 prefix\n"
1595 "Valid lifetime in seconds\n"
1596 "Infinite valid lifetime\n"
1597 "Preferred lifetime in seconds\n"
1598 "Infinite preferred lifetime\n")
1599
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|)",
1603 NO_STR
1604 "Interface IPv6 config commands\n"
1605 "Neighbor discovery\n"
1606 "Prefix information\n"
1607 "IPv6 prefix\n"
1608 "Do not use prefix for autoconfiguration\n"
1609 "Do not use prefix for onlink determination\n")
1610
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|)",
1614 NO_STR
1615 "Interface IPv6 config commands\n"
1616 "Neighbor discovery\n"
1617 "Prefix information\n"
1618 "IPv6 prefix\n"
1619 "Do not use prefix for onlink determination\n"
1620 "Do not use prefix for autoconfiguration\n")
1621
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|)",
1625 NO_STR
1626 "Interface IPv6 config commands\n"
1627 "Neighbor discovery\n"
1628 "Prefix information\n"
1629 "IPv6 prefix\n"
1630 "Do not use prefix for autoconfiguration\n")
1631
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|)",
1635 NO_STR
1636 "Interface IPv6 config commands\n"
1637 "Neighbor discovery\n"
1638 "Prefix information\n"
1639 "IPv6 prefix\n"
1640 "Do not use prefix for onlink determination\n")
1641
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|)",
1645 NO_STR
1646 "Interface IPv6 config commands\n"
1647 "Neighbor discovery\n"
1648 "Prefix information\n"
1649 "IPv6 prefix\n"
1650 "Set Router Address flag\n")
1651
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")
1661 {
1662 struct interface *ifp;
1663 struct zebra_if *zif;
1664 int i = 0;
1665
1666 ifp = (struct interface *) vty->index;
1667 zif = ifp->info;
1668
1669 while (0 != rtadv_pref_strs[i])
1670 {
1671 if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
1672 {
1673 zif->rtadv.DefaultPreference = i;
1674 return CMD_SUCCESS;
1675 }
1676 i++;
1677 }
1678
1679 return CMD_ERR_NO_MATCH;
1680 }
1681
1682 DEFUN (no_ipv6_nd_router_preference,
1683 no_ipv6_nd_router_preference_cmd,
1684 "no ipv6 nd router-preference",
1685 NO_STR
1686 "Interface IPv6 config commands\n"
1687 "Neighbor discovery\n"
1688 "Default router preference\n")
1689 {
1690 struct interface *ifp;
1691 struct zebra_if *zif;
1692
1693 ifp = (struct interface *) vty->index;
1694 zif = ifp->info;
1695
1696 zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
1697
1698 return CMD_SUCCESS;
1699 }
1700
1701 ALIAS (no_ipv6_nd_router_preference,
1702 no_ipv6_nd_router_preference_val_cmd,
1703 "no ipv6 nd router-preference (high|medium|low)",
1704 NO_STR
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")
1711
1712 DEFUN (ipv6_nd_mtu,
1713 ipv6_nd_mtu_cmd,
1714 "ipv6 nd mtu <1-65535>",
1715 "Interface IPv6 config commands\n"
1716 "Neighbor discovery\n"
1717 "Advertised MTU\n"
1718 "MTU in bytes\n")
1719 {
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);
1723 return CMD_SUCCESS;
1724 }
1725
1726 DEFUN (no_ipv6_nd_mtu,
1727 no_ipv6_nd_mtu_cmd,
1728 "no ipv6 nd mtu",
1729 NO_STR
1730 "Interface IPv6 config commands\n"
1731 "Neighbor discovery\n"
1732 "Advertised MTU\n")
1733 {
1734 struct interface *ifp = (struct interface *) vty->index;
1735 struct zebra_if *zif = ifp->info;
1736 zif->rtadv.AdvLinkMTU = 0;
1737 return CMD_SUCCESS;
1738 }
1739
1740 ALIAS (no_ipv6_nd_mtu,
1741 no_ipv6_nd_mtu_val_cmd,
1742 "no ipv6 nd mtu <1-65535>",
1743 NO_STR
1744 "Interface IPv6 config commands\n"
1745 "Neighbor discovery\n"
1746 "Advertised MTU\n"
1747 "MTU in bytes\n")
1748
1749 /* Write configuration about router advertisement. */
1750 void
1751 rtadv_config_write (struct vty *vty, struct interface *ifp)
1752 {
1753 struct zebra_if *zif;
1754 struct listnode *node;
1755 struct rtadv_prefix *rprefix;
1756 u_char buf[INET6_ADDRSTRLEN];
1757 int interval;
1758
1759 zif = ifp->info;
1760
1761 if (! if_is_loopback (ifp))
1762 {
1763 if (zif->rtadv.AdvSendAdvertisements)
1764 vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
1765 }
1766
1767
1768 interval = zif->rtadv.MaxRtrAdvInterval;
1769 if (interval % 1000)
1770 vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
1771 VTY_NEWLINE);
1772 else
1773 if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
1774 vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
1775 VTY_NEWLINE);
1776
1777 if (zif->rtadv.AdvIntervalOption)
1778 vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1779
1780 if (zif->rtadv.AdvDefaultLifetime != -1)
1781 vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1782 VTY_NEWLINE);
1783
1784 if (zif->rtadv.HomeAgentPreference)
1785 vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1786 zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1787
1788 if (zif->rtadv.HomeAgentLifetime != -1)
1789 vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
1790 zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
1791
1792 if (zif->rtadv.AdvHomeAgentFlag)
1793 vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
1794
1795 if (zif->rtadv.AdvReachableTime)
1796 vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
1797 VTY_NEWLINE);
1798
1799 if (zif->rtadv.AdvManagedFlag)
1800 vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
1801
1802 if (zif->rtadv.AdvOtherConfigFlag)
1803 vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
1804
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],
1808 VTY_NEWLINE);
1809
1810 if (zif->rtadv.AdvLinkMTU)
1811 vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1812
1813 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
1814 {
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))
1821 {
1822 if (rprefix->AdvValidLifetime == UINT32_MAX)
1823 vty_out (vty, " infinite");
1824 else
1825 vty_out (vty, " %u", rprefix->AdvValidLifetime);
1826 if (rprefix->AdvPreferredLifetime == UINT32_MAX)
1827 vty_out (vty, " infinite");
1828 else
1829 vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
1830 }
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);
1838 }
1839 }
1840
1841
1842 static void
1843 rtadv_event (struct zebra_vrf *zvrf, enum rtadv_event event, int val)
1844 {
1845 struct rtadv *rtadv = &zvrf->rtadv;
1846
1847 switch (event)
1848 {
1849 case RTADV_START:
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,
1854 zvrf, 0);
1855 break;
1856 case RTADV_STOP:
1857 if (rtadv->ra_timer)
1858 {
1859 thread_cancel (rtadv->ra_timer);
1860 rtadv->ra_timer = NULL;
1861 }
1862 if (rtadv->ra_read)
1863 {
1864 thread_cancel (rtadv->ra_read);
1865 rtadv->ra_read = NULL;
1866 }
1867 break;
1868 case RTADV_TIMER:
1869 if (! rtadv->ra_timer)
1870 rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zvrf,
1871 val);
1872 break;
1873 case RTADV_TIMER_MSEC:
1874 if (! rtadv->ra_timer)
1875 rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
1876 zvrf, val);
1877 break;
1878 case RTADV_READ:
1879 if (! rtadv->ra_read)
1880 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
1881 break;
1882 default:
1883 break;
1884 }
1885 return;
1886 }
1887
1888 void
1889 rtadv_init (struct zebra_vrf *zvrf)
1890 {
1891 zvrf->rtadv.sock = rtadv_make_socket (zvrf->vrf_id);
1892 }
1893
1894 void
1895 rtadv_terminate (struct zebra_vrf *zvrf)
1896 {
1897 rtadv_event (zvrf, RTADV_STOP, 0);
1898
1899 if (zvrf->rtadv.sock >= 0)
1900 {
1901 close (zvrf->rtadv.sock);
1902 zvrf->rtadv.sock = -1;
1903 }
1904
1905 zvrf->rtadv.adv_if_count = 0;
1906 zvrf->rtadv.adv_msec_if_count = 0;
1907 }
1908
1909 void
1910 rtadv_cmd_init (void)
1911 {
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);
1972 }
1973
1974 static int
1975 if_join_all_router (int sock, struct interface *ifp)
1976 {
1977 int ret;
1978
1979 struct ipv6_mreq mreq;
1980
1981 memset (&mreq, 0, sizeof (struct ipv6_mreq));
1982 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
1983 mreq.ipv6mr_interface = ifp->ifindex;
1984
1985 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1986 (char *) &mreq, sizeof mreq);
1987 if (ret < 0)
1988 zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno));
1989
1990 zlog_info ("rtadv: %s join to all-routers multicast group", ifp->name);
1991
1992 return 0;
1993 }
1994
1995 static int
1996 if_leave_all_router (int sock, struct interface *ifp)
1997 {
1998 int ret;
1999
2000 struct ipv6_mreq mreq;
2001
2002 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2003 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2004 mreq.ipv6mr_interface = ifp->ifindex;
2005
2006 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
2007 (char *) &mreq, sizeof mreq);
2008 if (ret < 0)
2009 zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno));
2010
2011 zlog_info ("rtadv: %s leave from all-routers multicast group", ifp->name);
2012
2013 return 0;
2014 }
2015
2016 #else
2017 void
2018 rtadv_init (struct zebra_vrf *zvrf)
2019 {
2020 /* Empty.*/;
2021 }
2022 void
2023 rtadv_terminate (struct zebra_vrf *zvrf)
2024 {
2025 /* Empty.*/;
2026 }
2027 void
2028 rtadv_cmd_init (void)
2029 {
2030 /* Empty.*/;
2031 }
2032 #endif /* HAVE_RTADV && HAVE_IPV6 */