Annotation of embedaddon/quagga/zebra/rtadv.c, revision 1.1.1.3
1.1 misho 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"
1.1.1.3 ! misho 34: #include "vrf.h"
1.1 misho 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:
1.1.1.3 ! misho 44: #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
1.1 misho 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:
1.1.1.3 ! misho 66: static void rtadv_event (struct zebra_vrf *, enum rtadv_event, int);
1.1 misho 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,
1.1.1.3 ! misho 73: struct sockaddr_in6 *from, ifindex_t *ifindex,
1.1 misho 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;
1.1.1.2 misho 147: u_int16_t pkt_RouterLifetime;
1.1 misho 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);
1.1.1.2 misho 175: IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
1.1 misho 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;
1.1.1.2 misho 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);
1.1 misho 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:
1.1.1.2 misho 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: )
1.1 misho 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);
1.1.1.2 misho 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: );
1.1 misho 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:
1.1.1.2 misho 281: IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
1.1 misho 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: if (ifp->hw_addr_len != 0)
298: {
299: buf[len++] = ND_OPT_SOURCE_LINKADDR;
300:
301: /* Option length should be rounded up to next octet if
302: the link address does not end on an octet boundary. */
303: buf[len++] = (ifp->hw_addr_len + 9) >> 3;
304:
305: memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
306: len += ifp->hw_addr_len;
307:
308: /* Pad option to end on an octet boundary. */
309: memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
310: len += -(ifp->hw_addr_len + 2) & 0x7;
311: }
312:
1.1.1.2 misho 313: /* MTU */
314: if (zif->rtadv.AdvLinkMTU)
315: {
316: struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
317: opt->nd_opt_mtu_type = ND_OPT_MTU;
318: opt->nd_opt_mtu_len = 1;
319: opt->nd_opt_mtu_reserved = 0;
320: opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
321: len += sizeof (struct nd_opt_mtu);
322: }
323:
1.1 misho 324: msg.msg_name = (void *) &addr;
325: msg.msg_namelen = sizeof (struct sockaddr_in6);
326: msg.msg_iov = &iov;
327: msg.msg_iovlen = 1;
328: msg.msg_control = (void *) adata;
329: msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
330: msg.msg_flags = 0;
331: iov.iov_base = buf;
332: iov.iov_len = len;
333:
334: cmsgptr = ZCMSG_FIRSTHDR(&msg);
335: cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
336: cmsgptr->cmsg_level = IPPROTO_IPV6;
337: cmsgptr->cmsg_type = IPV6_PKTINFO;
338:
339: pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
340: memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
341: pkt->ipi6_ifindex = ifp->ifindex;
342:
343: ret = sendmsg (sock, &msg, 0);
344: if (ret < 0)
345: {
346: zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
347: errno, safe_strerror(errno));
348: }
349: }
350:
351: static int
352: rtadv_timer (struct thread *thread)
353: {
1.1.1.3 ! misho 354: struct zebra_vrf *zvrf = THREAD_ARG (thread);
1.1 misho 355: struct listnode *node, *nnode;
356: struct interface *ifp;
357: struct zebra_if *zif;
358: int period;
359:
1.1.1.3 ! misho 360: zvrf->rtadv.ra_timer = NULL;
! 361: if (zvrf->rtadv.adv_msec_if_count == 0)
1.1 misho 362: {
363: period = 1000; /* 1 s */
1.1.1.3 ! misho 364: rtadv_event (zvrf, RTADV_TIMER, 1 /* 1 s */);
1.1 misho 365: }
366: else
367: {
368: period = 10; /* 10 ms */
1.1.1.3 ! misho 369: rtadv_event (zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
1.1 misho 370: }
371:
1.1.1.3 ! misho 372: for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf->vrf_id), node, nnode, ifp))
1.1 misho 373: {
1.1.1.2 misho 374: if (if_is_loopback (ifp) || ! if_is_operative (ifp))
1.1 misho 375: continue;
376:
377: zif = ifp->info;
378:
379: if (zif->rtadv.AdvSendAdvertisements)
380: {
381: zif->rtadv.AdvIntervalTimer -= period;
382: if (zif->rtadv.AdvIntervalTimer <= 0)
383: {
1.1.1.2 misho 384: /* FIXME: using MaxRtrAdvInterval each time isn't what section
385: 6.2.4 of RFC4861 tells to do. */
1.1 misho 386: zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
1.1.1.3 ! misho 387: rtadv_send_packet (zvrf->rtadv.sock, ifp);
1.1 misho 388: }
389: }
390: }
391: return 0;
392: }
393:
394: static void
395: rtadv_process_solicit (struct interface *ifp)
396: {
1.1.1.3 ! misho 397: struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
! 398:
! 399: zlog_info ("Router solicitation received on %s vrf %u", ifp->name, zvrf->vrf_id);
1.1 misho 400:
1.1.1.3 ! misho 401: rtadv_send_packet (zvrf->rtadv.sock, ifp);
1.1 misho 402: }
403:
404: static void
405: rtadv_process_advert (void)
406: {
407: zlog_info ("Router advertisement received");
408: }
409:
410: static void
1.1.1.3 ! misho 411: rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex,
! 412: int hoplimit, vrf_id_t vrf_id)
1.1 misho 413: {
414: struct icmp6_hdr *icmph;
415: struct interface *ifp;
416: struct zebra_if *zif;
417:
418: /* Interface search. */
1.1.1.3 ! misho 419: ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
1.1 misho 420: if (ifp == NULL)
421: {
1.1.1.3 ! misho 422: zlog_warn ("Unknown interface index: %d, vrf %u", ifindex, vrf_id);
1.1 misho 423: return;
424: }
425:
426: if (if_is_loopback (ifp))
427: return;
428:
429: /* Check interface configuration. */
430: zif = ifp->info;
431: if (! zif->rtadv.AdvSendAdvertisements)
432: return;
433:
434: /* ICMP message length check. */
435: if (len < sizeof (struct icmp6_hdr))
436: {
437: zlog_warn ("Invalid ICMPV6 packet length: %d", len);
438: return;
439: }
440:
441: icmph = (struct icmp6_hdr *) buf;
442:
443: /* ICMP message type check. */
444: if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
445: icmph->icmp6_type != ND_ROUTER_ADVERT)
446: {
447: zlog_warn ("Unwanted ICMPV6 message type: %d", icmph->icmp6_type);
448: return;
449: }
450:
451: /* Hoplimit check. */
452: if (hoplimit >= 0 && hoplimit != 255)
453: {
454: zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
455: hoplimit);
456: return;
457: }
458:
459: /* Check ICMP message type. */
460: if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
461: rtadv_process_solicit (ifp);
462: else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
463: rtadv_process_advert ();
464:
465: return;
466: }
467:
468: static int
469: rtadv_read (struct thread *thread)
470: {
471: int sock;
472: int len;
473: u_char buf[RTADV_MSG_SIZE];
474: struct sockaddr_in6 from;
1.1.1.3 ! misho 475: ifindex_t ifindex = 0;
1.1 misho 476: int hoplimit = -1;
1.1.1.3 ! misho 477: struct zebra_vrf *zvrf = THREAD_ARG (thread);
1.1 misho 478:
479: sock = THREAD_FD (thread);
1.1.1.3 ! misho 480: zvrf->rtadv.ra_read = NULL;
1.1 misho 481:
482: /* Register myself. */
1.1.1.3 ! misho 483: rtadv_event (zvrf, RTADV_READ, sock);
1.1 misho 484:
485: len = rtadv_recv_packet (sock, buf, BUFSIZ, &from, &ifindex, &hoplimit);
486:
487: if (len < 0)
488: {
489: zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno));
490: return len;
491: }
492:
1.1.1.3 ! misho 493: rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, zvrf->vrf_id);
1.1 misho 494:
495: return 0;
496: }
497:
498: static int
1.1.1.3 ! misho 499: rtadv_make_socket (vrf_id_t vrf_id)
1.1 misho 500: {
501: int sock;
502: int ret;
503: struct icmp6_filter filter;
504:
505: if ( zserv_privs.change (ZPRIVS_RAISE) )
506: zlog_err ("rtadv_make_socket: could not raise privs, %s",
507: safe_strerror (errno) );
508:
1.1.1.3 ! misho 509: sock = vrf_socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, vrf_id);
1.1 misho 510:
511: if ( zserv_privs.change (ZPRIVS_LOWER) )
512: zlog_err ("rtadv_make_socket: could not lower privs, %s",
513: safe_strerror (errno) );
514:
515: /* When we can't make ICMPV6 socket simply back. Router
516: advertisement feature will not be supported. */
517: if (sock < 0)
1.1.1.3 ! misho 518: {
! 519: close (sock);
! 520: return -1;
! 521: }
1.1 misho 522:
523: ret = setsockopt_ipv6_pktinfo (sock, 1);
524: if (ret < 0)
1.1.1.3 ! misho 525: {
! 526: close (sock);
! 527: return ret;
! 528: }
1.1 misho 529: ret = setsockopt_ipv6_multicast_loop (sock, 0);
530: if (ret < 0)
1.1.1.3 ! misho 531: {
! 532: close (sock);
! 533: return ret;
! 534: }
1.1 misho 535: ret = setsockopt_ipv6_unicast_hops (sock, 255);
536: if (ret < 0)
1.1.1.3 ! misho 537: {
! 538: close (sock);
! 539: return ret;
! 540: }
1.1 misho 541: ret = setsockopt_ipv6_multicast_hops (sock, 255);
542: if (ret < 0)
1.1.1.3 ! misho 543: {
! 544: close (sock);
! 545: return ret;
! 546: }
1.1 misho 547: ret = setsockopt_ipv6_hoplimit (sock, 1);
548: if (ret < 0)
1.1.1.3 ! misho 549: {
! 550: close (sock);
! 551: return ret;
! 552: }
1.1 misho 553:
554: ICMP6_FILTER_SETBLOCKALL(&filter);
555: ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
556: ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
557:
558: ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
559: sizeof (struct icmp6_filter));
560: if (ret < 0)
561: {
562: zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
563: return ret;
564: }
565:
566: return sock;
567: }
1.1.1.3 ! misho 568:
1.1 misho 569: static struct rtadv_prefix *
570: rtadv_prefix_new (void)
571: {
572: return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
573: }
574:
575: static void
576: rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
577: {
578: XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
579: }
580:
581: static struct rtadv_prefix *
1.1.1.2 misho 582: rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
1.1 misho 583: {
584: struct listnode *node;
585: struct rtadv_prefix *rprefix;
586:
587: for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
1.1.1.2 misho 588: if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
1.1 misho 589: return rprefix;
590: return NULL;
591: }
592:
593: static struct rtadv_prefix *
1.1.1.2 misho 594: rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
1.1 misho 595: {
596: struct rtadv_prefix *rprefix;
597:
598: rprefix = rtadv_prefix_lookup (rplist, p);
599: if (rprefix)
600: return rprefix;
601:
602: rprefix = rtadv_prefix_new ();
1.1.1.2 misho 603: memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
1.1 misho 604: listnode_add (rplist, rprefix);
605:
606: return rprefix;
607: }
608:
609: static void
610: rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
611: {
612: struct rtadv_prefix *rprefix;
613:
614: rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
615:
616: /* Set parameters. */
617: rprefix->AdvValidLifetime = rp->AdvValidLifetime;
618: rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
619: rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
620: rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
621: rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
622: }
623:
624: static int
625: rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
626: {
627: struct rtadv_prefix *rprefix;
628:
629: rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
630: if (rprefix != NULL)
631: {
632: listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
633: rtadv_prefix_free (rprefix);
634: return 1;
635: }
636: else
637: return 0;
638: }
639:
640: DEFUN (ipv6_nd_suppress_ra,
641: ipv6_nd_suppress_ra_cmd,
642: "ipv6 nd suppress-ra",
643: "Interface IPv6 config commands\n"
644: "Neighbor discovery\n"
645: "Suppress Router Advertisement\n")
646: {
647: struct interface *ifp;
648: struct zebra_if *zif;
1.1.1.3 ! misho 649: struct zebra_vrf *zvrf;
1.1 misho 650:
651: ifp = vty->index;
652: zif = ifp->info;
1.1.1.3 ! misho 653: zvrf = vrf_info_lookup (ifp->vrf_id);
1.1 misho 654:
655: if (if_is_loopback (ifp))
656: {
657: vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
658: return CMD_WARNING;
659: }
660:
661: if (zif->rtadv.AdvSendAdvertisements)
662: {
663: zif->rtadv.AdvSendAdvertisements = 0;
664: zif->rtadv.AdvIntervalTimer = 0;
1.1.1.3 ! misho 665: zvrf->rtadv.adv_if_count--;
1.1 misho 666:
1.1.1.3 ! misho 667: if_leave_all_router (zvrf->rtadv.sock, ifp);
1.1 misho 668:
1.1.1.3 ! misho 669: if (zvrf->rtadv.adv_if_count == 0)
! 670: rtadv_event (zvrf, RTADV_STOP, 0);
1.1 misho 671: }
672:
673: return CMD_SUCCESS;
674: }
675:
676: DEFUN (no_ipv6_nd_suppress_ra,
677: no_ipv6_nd_suppress_ra_cmd,
678: "no ipv6 nd suppress-ra",
679: NO_STR
680: "Interface IPv6 config commands\n"
681: "Neighbor discovery\n"
682: "Suppress Router Advertisement\n")
683: {
684: struct interface *ifp;
685: struct zebra_if *zif;
1.1.1.3 ! misho 686: struct zebra_vrf *zvrf;
1.1 misho 687:
688: ifp = vty->index;
689: zif = ifp->info;
1.1.1.3 ! misho 690: zvrf = vrf_info_lookup (ifp->vrf_id);
1.1 misho 691:
692: if (if_is_loopback (ifp))
693: {
694: vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
695: return CMD_WARNING;
696: }
697:
698: if (! zif->rtadv.AdvSendAdvertisements)
699: {
700: zif->rtadv.AdvSendAdvertisements = 1;
701: zif->rtadv.AdvIntervalTimer = 0;
1.1.1.3 ! misho 702: zvrf->rtadv.adv_if_count++;
1.1 misho 703:
1.1.1.3 ! misho 704: if_join_all_router (zvrf->rtadv.sock, ifp);
1.1 misho 705:
1.1.1.3 ! misho 706: if (zvrf->rtadv.adv_if_count == 1)
! 707: rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock);
1.1 misho 708: }
709:
710: return CMD_SUCCESS;
711: }
712:
713: DEFUN (ipv6_nd_ra_interval_msec,
714: ipv6_nd_ra_interval_msec_cmd,
1.1.1.2 misho 715: "ipv6 nd ra-interval msec <70-1800000>",
1.1 misho 716: "Interface IPv6 config commands\n"
717: "Neighbor discovery\n"
718: "Router Advertisement interval\n"
719: "Router Advertisement interval in milliseconds\n")
720: {
1.1.1.2 misho 721: unsigned interval;
722: struct interface *ifp = (struct interface *) vty->index;
723: struct zebra_if *zif = ifp->info;
1.1.1.3 ! misho 724: struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
1.1.1.2 misho 725:
726: VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
727: if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
728: {
729: vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
730: return CMD_WARNING;
731: }
1.1 misho 732:
733: if (zif->rtadv.MaxRtrAdvInterval % 1000)
1.1.1.3 ! misho 734: zvrf->rtadv.adv_msec_if_count--;
1.1 misho 735:
736: if (interval % 1000)
1.1.1.3 ! misho 737: zvrf->rtadv.adv_msec_if_count++;
1.1 misho 738:
739: zif->rtadv.MaxRtrAdvInterval = interval;
740: zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
741: zif->rtadv.AdvIntervalTimer = 0;
742:
743: return CMD_SUCCESS;
744: }
745:
746: DEFUN (ipv6_nd_ra_interval,
747: ipv6_nd_ra_interval_cmd,
1.1.1.2 misho 748: "ipv6 nd ra-interval <1-1800>",
1.1 misho 749: "Interface IPv6 config commands\n"
750: "Neighbor discovery\n"
751: "Router Advertisement interval\n"
752: "Router Advertisement interval in seconds\n")
753: {
1.1.1.2 misho 754: unsigned interval;
755: struct interface *ifp = (struct interface *) vty->index;
756: struct zebra_if *zif = ifp->info;
1.1.1.3 ! misho 757: struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
1.1.1.2 misho 758:
759: VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
760: if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
761: {
762: vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
763: return CMD_WARNING;
764: }
1.1 misho 765:
766: if (zif->rtadv.MaxRtrAdvInterval % 1000)
1.1.1.3 ! misho 767: zvrf->rtadv.adv_msec_if_count--;
1.1 misho 768:
769: /* convert to milliseconds */
770: interval = interval * 1000;
771:
772: zif->rtadv.MaxRtrAdvInterval = interval;
773: zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
774: zif->rtadv.AdvIntervalTimer = 0;
775:
776: return CMD_SUCCESS;
777: }
778:
779: DEFUN (no_ipv6_nd_ra_interval,
780: no_ipv6_nd_ra_interval_cmd,
781: "no ipv6 nd ra-interval",
782: NO_STR
783: "Interface IPv6 config commands\n"
784: "Neighbor discovery\n"
785: "Router Advertisement interval\n")
786: {
787: struct interface *ifp;
788: struct zebra_if *zif;
1.1.1.3 ! misho 789: struct zebra_vrf *zvrf;
1.1 misho 790:
791: ifp = (struct interface *) vty->index;
792: zif = ifp->info;
1.1.1.3 ! misho 793: zvrf = vrf_info_lookup (ifp->vrf_id);
1.1 misho 794:
795: if (zif->rtadv.MaxRtrAdvInterval % 1000)
1.1.1.3 ! misho 796: zvrf->rtadv.adv_msec_if_count--;
1.1 misho 797:
798: zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
799: zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
800: zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
801:
802: return CMD_SUCCESS;
803: }
804:
1.1.1.2 misho 805: ALIAS (no_ipv6_nd_ra_interval,
806: no_ipv6_nd_ra_interval_val_cmd,
807: "no ipv6 nd ra-interval <1-1800>",
808: NO_STR
809: "Interface IPv6 config commands\n"
810: "Neighbor discovery\n"
811: "Router Advertisement interval\n")
812:
813: ALIAS (no_ipv6_nd_ra_interval,
814: no_ipv6_nd_ra_interval_msec_val_cmd,
815: "no ipv6 nd ra-interval msec <1-1800000>",
816: NO_STR
817: "Interface IPv6 config commands\n"
818: "Neighbor discovery\n"
819: "Router Advertisement interval\n"
820: "Router Advertisement interval in milliseconds\n")
821:
1.1 misho 822: DEFUN (ipv6_nd_ra_lifetime,
823: ipv6_nd_ra_lifetime_cmd,
1.1.1.2 misho 824: "ipv6 nd ra-lifetime <0-9000>",
1.1 misho 825: "Interface IPv6 config commands\n"
826: "Neighbor discovery\n"
827: "Router lifetime\n"
1.1.1.2 misho 828: "Router lifetime in seconds (0 stands for a non-default gw)\n")
1.1 misho 829: {
830: int lifetime;
831: struct interface *ifp;
832: struct zebra_if *zif;
833:
834: ifp = (struct interface *) vty->index;
835: zif = ifp->info;
836:
1.1.1.2 misho 837: VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
1.1 misho 838:
1.1.1.2 misho 839: /* The value to be placed in the Router Lifetime field
840: * of Router Advertisements sent from the interface,
841: * in seconds. MUST be either zero or between
842: * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
843: if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
1.1 misho 844: {
1.1.1.2 misho 845: vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
1.1 misho 846: return CMD_WARNING;
847: }
848:
849: zif->rtadv.AdvDefaultLifetime = lifetime;
850:
851: return CMD_SUCCESS;
852: }
853:
854: DEFUN (no_ipv6_nd_ra_lifetime,
855: no_ipv6_nd_ra_lifetime_cmd,
856: "no ipv6 nd ra-lifetime",
857: NO_STR
858: "Interface IPv6 config commands\n"
859: "Neighbor discovery\n"
860: "Router lifetime\n")
861: {
862: struct interface *ifp;
863: struct zebra_if *zif;
864:
865: ifp = (struct interface *) vty->index;
866: zif = ifp->info;
867:
1.1.1.2 misho 868: zif->rtadv.AdvDefaultLifetime = -1;
1.1 misho 869:
870: return CMD_SUCCESS;
871: }
872:
1.1.1.2 misho 873: ALIAS (no_ipv6_nd_ra_lifetime,
874: no_ipv6_nd_ra_lifetime_val_cmd,
875: "no ipv6 nd ra-lifetime <0-9000>",
876: NO_STR
877: "Interface IPv6 config commands\n"
878: "Neighbor discovery\n"
879: "Router lifetime\n"
880: "Router lifetime in seconds (0 stands for a non-default gw)\n")
881:
1.1 misho 882: DEFUN (ipv6_nd_reachable_time,
883: ipv6_nd_reachable_time_cmd,
1.1.1.2 misho 884: "ipv6 nd reachable-time <1-3600000>",
1.1 misho 885: "Interface IPv6 config commands\n"
886: "Neighbor discovery\n"
887: "Reachable time\n"
888: "Reachable time in milliseconds\n")
889: {
1.1.1.2 misho 890: struct interface *ifp = (struct interface *) vty->index;
891: struct zebra_if *zif = ifp->info;
892: VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
1.1 misho 893: return CMD_SUCCESS;
894: }
895:
896: DEFUN (no_ipv6_nd_reachable_time,
897: no_ipv6_nd_reachable_time_cmd,
898: "no ipv6 nd reachable-time",
899: NO_STR
900: "Interface IPv6 config commands\n"
901: "Neighbor discovery\n"
902: "Reachable time\n")
903: {
904: struct interface *ifp;
905: struct zebra_if *zif;
906:
907: ifp = (struct interface *) vty->index;
908: zif = ifp->info;
909:
910: zif->rtadv.AdvReachableTime = 0;
911:
912: return CMD_SUCCESS;
913: }
914:
1.1.1.2 misho 915: ALIAS (no_ipv6_nd_reachable_time,
916: no_ipv6_nd_reachable_time_val_cmd,
917: "no ipv6 nd reachable-time <1-3600000>",
918: NO_STR
919: "Interface IPv6 config commands\n"
920: "Neighbor discovery\n"
921: "Reachable time\n"
922: "Reachable time in milliseconds\n")
923:
1.1 misho 924: DEFUN (ipv6_nd_homeagent_preference,
925: ipv6_nd_homeagent_preference_cmd,
1.1.1.2 misho 926: "ipv6 nd home-agent-preference <0-65535>",
1.1 misho 927: "Interface IPv6 config commands\n"
928: "Neighbor discovery\n"
929: "Home Agent preference\n"
1.1.1.2 misho 930: "preference value (default is 0, least preferred)\n")
1.1 misho 931: {
1.1.1.2 misho 932: struct interface *ifp = (struct interface *) vty->index;
933: struct zebra_if *zif = ifp->info;
934: VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
1.1 misho 935: return CMD_SUCCESS;
936: }
937:
938: DEFUN (no_ipv6_nd_homeagent_preference,
939: no_ipv6_nd_homeagent_preference_cmd,
940: "no ipv6 nd home-agent-preference",
941: NO_STR
942: "Interface IPv6 config commands\n"
943: "Neighbor discovery\n"
944: "Home Agent preference\n")
945: {
946: struct interface *ifp;
947: struct zebra_if *zif;
948:
949: ifp = (struct interface *) vty->index;
950: zif = ifp->info;
951:
952: zif->rtadv.HomeAgentPreference = 0;
953:
954: return CMD_SUCCESS;
955: }
956:
1.1.1.2 misho 957: ALIAS (no_ipv6_nd_homeagent_preference,
958: no_ipv6_nd_homeagent_preference_val_cmd,
959: "no ipv6 nd home-agent-preference <0-65535>",
960: NO_STR
961: "Interface IPv6 config commands\n"
962: "Neighbor discovery\n"
963: "Home Agent preference\n"
964: "preference value (default is 0, least preferred)\n")
965:
1.1 misho 966: DEFUN (ipv6_nd_homeagent_lifetime,
967: ipv6_nd_homeagent_lifetime_cmd,
1.1.1.2 misho 968: "ipv6 nd home-agent-lifetime <0-65520>",
1.1 misho 969: "Interface IPv6 config commands\n"
970: "Neighbor discovery\n"
971: "Home Agent lifetime\n"
1.1.1.2 misho 972: "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1.1 misho 973: {
1.1.1.2 misho 974: struct interface *ifp = (struct interface *) vty->index;
975: struct zebra_if *zif = ifp->info;
976: VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
1.1 misho 977: return CMD_SUCCESS;
978: }
979:
980: DEFUN (no_ipv6_nd_homeagent_lifetime,
981: no_ipv6_nd_homeagent_lifetime_cmd,
982: "no ipv6 nd home-agent-lifetime",
983: NO_STR
984: "Interface IPv6 config commands\n"
985: "Neighbor discovery\n"
986: "Home Agent lifetime\n")
987: {
988: struct interface *ifp;
989: struct zebra_if *zif;
990:
991: ifp = (struct interface *) vty->index;
992: zif = ifp->info;
993:
1.1.1.2 misho 994: zif->rtadv.HomeAgentLifetime = -1;
1.1 misho 995:
996: return CMD_SUCCESS;
997: }
998:
1.1.1.2 misho 999: ALIAS (no_ipv6_nd_homeagent_lifetime,
1000: no_ipv6_nd_homeagent_lifetime_val_cmd,
1001: "no ipv6 nd home-agent-lifetime <0-65520>",
1002: NO_STR
1003: "Interface IPv6 config commands\n"
1004: "Neighbor discovery\n"
1005: "Home Agent lifetime\n"
1006: "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1007:
1.1 misho 1008: DEFUN (ipv6_nd_managed_config_flag,
1009: ipv6_nd_managed_config_flag_cmd,
1010: "ipv6 nd managed-config-flag",
1011: "Interface IPv6 config commands\n"
1012: "Neighbor discovery\n"
1013: "Managed address configuration flag\n")
1014: {
1015: struct interface *ifp;
1016: struct zebra_if *zif;
1017:
1018: ifp = (struct interface *) vty->index;
1019: zif = ifp->info;
1020:
1021: zif->rtadv.AdvManagedFlag = 1;
1022:
1023: return CMD_SUCCESS;
1024: }
1025:
1026: DEFUN (no_ipv6_nd_managed_config_flag,
1027: no_ipv6_nd_managed_config_flag_cmd,
1028: "no ipv6 nd managed-config-flag",
1029: NO_STR
1030: "Interface IPv6 config commands\n"
1031: "Neighbor discovery\n"
1032: "Managed address configuration flag\n")
1033: {
1034: struct interface *ifp;
1035: struct zebra_if *zif;
1036:
1037: ifp = (struct interface *) vty->index;
1038: zif = ifp->info;
1039:
1040: zif->rtadv.AdvManagedFlag = 0;
1041:
1042: return CMD_SUCCESS;
1043: }
1044:
1045: DEFUN (ipv6_nd_homeagent_config_flag,
1046: ipv6_nd_homeagent_config_flag_cmd,
1047: "ipv6 nd home-agent-config-flag",
1048: "Interface IPv6 config commands\n"
1049: "Neighbor discovery\n"
1050: "Home Agent configuration flag\n")
1051: {
1052: struct interface *ifp;
1053: struct zebra_if *zif;
1054:
1055: ifp = (struct interface *) vty->index;
1056: zif = ifp->info;
1057:
1058: zif->rtadv.AdvHomeAgentFlag = 1;
1059:
1060: return CMD_SUCCESS;
1061: }
1062:
1063: DEFUN (no_ipv6_nd_homeagent_config_flag,
1064: no_ipv6_nd_homeagent_config_flag_cmd,
1065: "no ipv6 nd home-agent-config-flag",
1066: NO_STR
1067: "Interface IPv6 config commands\n"
1068: "Neighbor discovery\n"
1069: "Home Agent configuration flag\n")
1070: {
1071: struct interface *ifp;
1072: struct zebra_if *zif;
1073:
1074: ifp = (struct interface *) vty->index;
1075: zif = ifp->info;
1076:
1077: zif->rtadv.AdvHomeAgentFlag = 0;
1078:
1079: return CMD_SUCCESS;
1080: }
1081:
1082: DEFUN (ipv6_nd_adv_interval_config_option,
1083: ipv6_nd_adv_interval_config_option_cmd,
1084: "ipv6 nd adv-interval-option",
1085: "Interface IPv6 config commands\n"
1086: "Neighbor discovery\n"
1087: "Advertisement Interval Option\n")
1088: {
1089: struct interface *ifp;
1090: struct zebra_if *zif;
1091:
1092: ifp = (struct interface *) vty->index;
1093: zif = ifp->info;
1094:
1095: zif->rtadv.AdvIntervalOption = 1;
1096:
1097: return CMD_SUCCESS;
1098: }
1099:
1100: DEFUN (no_ipv6_nd_adv_interval_config_option,
1101: no_ipv6_nd_adv_interval_config_option_cmd,
1102: "no ipv6 nd adv-interval-option",
1103: NO_STR
1104: "Interface IPv6 config commands\n"
1105: "Neighbor discovery\n"
1106: "Advertisement Interval Option\n")
1107: {
1108: struct interface *ifp;
1109: struct zebra_if *zif;
1110:
1111: ifp = (struct interface *) vty->index;
1112: zif = ifp->info;
1113:
1114: zif->rtadv.AdvIntervalOption = 0;
1115:
1116: return CMD_SUCCESS;
1117: }
1118:
1119: DEFUN (ipv6_nd_other_config_flag,
1120: ipv6_nd_other_config_flag_cmd,
1121: "ipv6 nd other-config-flag",
1122: "Interface IPv6 config commands\n"
1123: "Neighbor discovery\n"
1124: "Other statefull configuration flag\n")
1125: {
1126: struct interface *ifp;
1127: struct zebra_if *zif;
1128:
1129: ifp = (struct interface *) vty->index;
1130: zif = ifp->info;
1131:
1132: zif->rtadv.AdvOtherConfigFlag = 1;
1133:
1134: return CMD_SUCCESS;
1135: }
1136:
1137: DEFUN (no_ipv6_nd_other_config_flag,
1138: no_ipv6_nd_other_config_flag_cmd,
1139: "no ipv6 nd other-config-flag",
1140: NO_STR
1141: "Interface IPv6 config commands\n"
1142: "Neighbor discovery\n"
1143: "Other statefull configuration flag\n")
1144: {
1145: struct interface *ifp;
1146: struct zebra_if *zif;
1147:
1148: ifp = (struct interface *) vty->index;
1149: zif = ifp->info;
1150:
1151: zif->rtadv.AdvOtherConfigFlag = 0;
1152:
1153: return CMD_SUCCESS;
1154: }
1155:
1156: DEFUN (ipv6_nd_prefix,
1157: ipv6_nd_prefix_cmd,
1158: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1159: "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1160: "Interface IPv6 config commands\n"
1161: "Neighbor discovery\n"
1162: "Prefix information\n"
1163: "IPv6 prefix\n"
1164: "Valid lifetime in seconds\n"
1165: "Infinite valid lifetime\n"
1166: "Preferred lifetime in seconds\n"
1167: "Infinite preferred lifetime\n"
1168: "Do not use prefix for onlink determination\n"
1169: "Do not use prefix for autoconfiguration\n"
1170: "Set Router Address flag\n")
1171: {
1172: int i;
1173: int ret;
1174: int cursor = 1;
1175: struct interface *ifp;
1176: struct zebra_if *zebra_if;
1177: struct rtadv_prefix rp;
1178:
1179: ifp = (struct interface *) vty->index;
1180: zebra_if = ifp->info;
1181:
1.1.1.2 misho 1182: ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1.1 misho 1183: if (!ret)
1184: {
1185: vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1186: return CMD_WARNING;
1187: }
1.1.1.2 misho 1188: apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1.1 misho 1189: rp.AdvOnLinkFlag = 1;
1190: rp.AdvAutonomousFlag = 1;
1191: rp.AdvRouterAddressFlag = 0;
1192: rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
1193: rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
1194:
1195: if (argc > 1)
1196: {
1.1.1.3 ! misho 1197: if ((isdigit((unsigned char)argv[1][0]))
! 1198: || strncmp (argv[1], "i", 1) == 0)
1.1 misho 1199: {
1200: if ( strncmp (argv[1], "i", 1) == 0)
1201: rp.AdvValidLifetime = UINT32_MAX;
1202: else
1203: rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
1204: (char **)NULL, 10);
1205:
1206: if ( strncmp (argv[2], "i", 1) == 0)
1207: rp.AdvPreferredLifetime = UINT32_MAX;
1208: else
1209: rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
1210: (char **)NULL, 10);
1211:
1212: if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
1213: {
1214: vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
1215: return CMD_WARNING;
1216: }
1217: cursor = cursor + 2;
1218: }
1219: if (argc > cursor)
1220: {
1221: for (i = cursor; i < argc; i++)
1222: {
1223: if (strncmp (argv[i], "of", 2) == 0)
1224: rp.AdvOnLinkFlag = 0;
1225: if (strncmp (argv[i], "no", 2) == 0)
1226: rp.AdvAutonomousFlag = 0;
1227: if (strncmp (argv[i], "ro", 2) == 0)
1228: rp.AdvRouterAddressFlag = 1;
1229: }
1230: }
1231: }
1232:
1233: rtadv_prefix_set (zebra_if, &rp);
1234:
1235: return CMD_SUCCESS;
1236: }
1237:
1238: ALIAS (ipv6_nd_prefix,
1239: ipv6_nd_prefix_val_nortaddr_cmd,
1240: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1241: "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1242: "Interface IPv6 config commands\n"
1243: "Neighbor discovery\n"
1244: "Prefix information\n"
1245: "IPv6 prefix\n"
1246: "Valid lifetime in seconds\n"
1247: "Infinite valid lifetime\n"
1248: "Preferred lifetime in seconds\n"
1249: "Infinite preferred lifetime\n"
1250: "Do not use prefix for onlink determination\n"
1251: "Do not use prefix for autoconfiguration\n")
1252:
1253: ALIAS (ipv6_nd_prefix,
1254: ipv6_nd_prefix_val_rev_cmd,
1255: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1256: "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1257: "Interface IPv6 config commands\n"
1258: "Neighbor discovery\n"
1259: "Prefix information\n"
1260: "IPv6 prefix\n"
1261: "Valid lifetime in seconds\n"
1262: "Infinite valid lifetime\n"
1263: "Preferred lifetime in seconds\n"
1264: "Infinite preferred lifetime\n"
1265: "Do not use prefix for autoconfiguration\n"
1266: "Do not use prefix for onlink determination\n")
1267:
1268: ALIAS (ipv6_nd_prefix,
1269: ipv6_nd_prefix_val_rev_rtaddr_cmd,
1270: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1271: "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1272: "Interface IPv6 config commands\n"
1273: "Neighbor discovery\n"
1274: "Prefix information\n"
1275: "IPv6 prefix\n"
1276: "Valid lifetime in seconds\n"
1277: "Infinite valid lifetime\n"
1278: "Preferred lifetime in seconds\n"
1279: "Infinite preferred lifetime\n"
1280: "Do not use prefix for autoconfiguration\n"
1281: "Do not use prefix for onlink determination\n"
1282: "Set Router Address flag\n")
1283:
1284: ALIAS (ipv6_nd_prefix,
1285: ipv6_nd_prefix_val_noauto_cmd,
1286: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1287: "(<0-4294967295>|infinite) (no-autoconfig|)",
1288: "Interface IPv6 config commands\n"
1289: "Neighbor discovery\n"
1290: "Prefix information\n"
1291: "IPv6 prefix\n"
1292: "Valid lifetime in seconds\n"
1293: "Infinite valid lifetime\n"
1294: "Preferred lifetime in seconds\n"
1295: "Infinite preferred lifetime\n"
1296: "Do not use prefix for autoconfiguration")
1297:
1298: ALIAS (ipv6_nd_prefix,
1299: ipv6_nd_prefix_val_offlink_cmd,
1300: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1301: "(<0-4294967295>|infinite) (off-link|)",
1302: "Interface IPv6 config commands\n"
1303: "Neighbor discovery\n"
1304: "Prefix information\n"
1305: "IPv6 prefix\n"
1306: "Valid lifetime in seconds\n"
1307: "Infinite valid lifetime\n"
1308: "Preferred lifetime in seconds\n"
1309: "Infinite preferred lifetime\n"
1310: "Do not use prefix for onlink determination\n")
1311:
1312: ALIAS (ipv6_nd_prefix,
1313: ipv6_nd_prefix_val_rtaddr_cmd,
1314: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1315: "(<0-4294967295>|infinite) (router-address|)",
1316: "Interface IPv6 config commands\n"
1317: "Neighbor discovery\n"
1318: "Prefix information\n"
1319: "IPv6 prefix\n"
1320: "Valid lifetime in seconds\n"
1321: "Infinite valid lifetime\n"
1322: "Preferred lifetime in seconds\n"
1323: "Infinite preferred lifetime\n"
1324: "Set Router Address flag\n")
1325:
1326: ALIAS (ipv6_nd_prefix,
1327: ipv6_nd_prefix_val_cmd,
1328: "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1329: "(<0-4294967295>|infinite)",
1330: "Interface IPv6 config commands\n"
1331: "Neighbor discovery\n"
1332: "Prefix information\n"
1333: "IPv6 prefix\n"
1334: "Valid lifetime in seconds\n"
1335: "Infinite valid lifetime\n"
1336: "Preferred lifetime in seconds\n"
1337: "Infinite preferred lifetime\n")
1338:
1339: ALIAS (ipv6_nd_prefix,
1340: ipv6_nd_prefix_noval_cmd,
1341: "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1342: "Interface IPv6 config commands\n"
1343: "Neighbor discovery\n"
1344: "Prefix information\n"
1345: "IPv6 prefix\n"
1346: "Do not use prefix for autoconfiguration\n"
1347: "Do not use prefix for onlink determination\n")
1348:
1349: ALIAS (ipv6_nd_prefix,
1350: ipv6_nd_prefix_noval_rev_cmd,
1351: "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1352: "Interface IPv6 config commands\n"
1353: "Neighbor discovery\n"
1354: "Prefix information\n"
1355: "IPv6 prefix\n"
1356: "Do not use prefix for onlink determination\n"
1357: "Do not use prefix for autoconfiguration\n")
1358:
1359: ALIAS (ipv6_nd_prefix,
1360: ipv6_nd_prefix_noval_noauto_cmd,
1361: "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1362: "Interface IPv6 config commands\n"
1363: "Neighbor discovery\n"
1364: "Prefix information\n"
1365: "IPv6 prefix\n"
1366: "Do not use prefix for autoconfiguration\n")
1367:
1368: ALIAS (ipv6_nd_prefix,
1369: ipv6_nd_prefix_noval_offlink_cmd,
1370: "ipv6 nd prefix X:X::X:X/M (off-link|)",
1371: "Interface IPv6 config commands\n"
1372: "Neighbor discovery\n"
1373: "Prefix information\n"
1374: "IPv6 prefix\n"
1375: "Do not use prefix for onlink determination\n")
1376:
1377: ALIAS (ipv6_nd_prefix,
1378: ipv6_nd_prefix_noval_rtaddr_cmd,
1379: "ipv6 nd prefix X:X::X:X/M (router-address|)",
1380: "Interface IPv6 config commands\n"
1381: "Neighbor discovery\n"
1382: "Prefix information\n"
1383: "IPv6 prefix\n"
1384: "Set Router Address flag\n")
1385:
1386: ALIAS (ipv6_nd_prefix,
1387: ipv6_nd_prefix_prefix_cmd,
1388: "ipv6 nd prefix X:X::X:X/M",
1389: "Interface IPv6 config commands\n"
1390: "Neighbor discovery\n"
1391: "Prefix information\n"
1392: "IPv6 prefix\n")
1393:
1394: DEFUN (no_ipv6_nd_prefix,
1395: no_ipv6_nd_prefix_cmd,
1396: "no ipv6 nd prefix IPV6PREFIX",
1397: NO_STR
1398: "Interface IPv6 config commands\n"
1399: "Neighbor discovery\n"
1400: "Prefix information\n"
1401: "IPv6 prefix\n")
1402: {
1403: int ret;
1404: struct interface *ifp;
1405: struct zebra_if *zebra_if;
1406: struct rtadv_prefix rp;
1407:
1408: ifp = (struct interface *) vty->index;
1409: zebra_if = ifp->info;
1410:
1.1.1.2 misho 1411: ret = str2prefix_ipv6 (argv[0], &rp.prefix);
1.1 misho 1412: if (!ret)
1413: {
1414: vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1415: return CMD_WARNING;
1416: }
1.1.1.2 misho 1417: apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
1.1 misho 1418:
1419: ret = rtadv_prefix_reset (zebra_if, &rp);
1420: if (!ret)
1421: {
1422: vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
1423: return CMD_WARNING;
1424: }
1425:
1426: return CMD_SUCCESS;
1427: }
1428:
1429: DEFUN (ipv6_nd_router_preference,
1430: ipv6_nd_router_preference_cmd,
1431: "ipv6 nd router-preference (high|medium|low)",
1432: "Interface IPv6 config commands\n"
1433: "Neighbor discovery\n"
1434: "Default router preference\n"
1435: "High default router preference\n"
1436: "Low default router preference\n"
1437: "Medium default router preference (default)\n")
1438: {
1439: struct interface *ifp;
1440: struct zebra_if *zif;
1441: int i = 0;
1442:
1443: ifp = (struct interface *) vty->index;
1444: zif = ifp->info;
1445:
1446: while (0 != rtadv_pref_strs[i])
1447: {
1448: if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
1449: {
1450: zif->rtadv.DefaultPreference = i;
1451: return CMD_SUCCESS;
1452: }
1453: i++;
1454: }
1455:
1456: return CMD_ERR_NO_MATCH;
1457: }
1458:
1459: DEFUN (no_ipv6_nd_router_preference,
1460: no_ipv6_nd_router_preference_cmd,
1461: "no ipv6 nd router-preference",
1462: NO_STR
1463: "Interface IPv6 config commands\n"
1464: "Neighbor discovery\n"
1465: "Default router preference\n")
1466: {
1467: struct interface *ifp;
1468: struct zebra_if *zif;
1469:
1470: ifp = (struct interface *) vty->index;
1471: zif = ifp->info;
1472:
1473: zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
1474:
1475: return CMD_SUCCESS;
1476: }
1477:
1.1.1.2 misho 1478: ALIAS (no_ipv6_nd_router_preference,
1479: no_ipv6_nd_router_preference_val_cmd,
1.1.1.3 ! misho 1480: "no ipv6 nd router-preference (high|medium|low)",
1.1.1.2 misho 1481: NO_STR
1482: "Interface IPv6 config commands\n"
1483: "Neighbor discovery\n"
1484: "Default router preference\n"
1485: "High default router preference\n"
1486: "Low default router preference\n"
1487: "Medium default router preference (default)\n")
1488:
1489: DEFUN (ipv6_nd_mtu,
1490: ipv6_nd_mtu_cmd,
1491: "ipv6 nd mtu <1-65535>",
1492: "Interface IPv6 config commands\n"
1493: "Neighbor discovery\n"
1494: "Advertised MTU\n"
1495: "MTU in bytes\n")
1496: {
1497: struct interface *ifp = (struct interface *) vty->index;
1498: struct zebra_if *zif = ifp->info;
1499: VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
1500: return CMD_SUCCESS;
1501: }
1502:
1503: DEFUN (no_ipv6_nd_mtu,
1504: no_ipv6_nd_mtu_cmd,
1505: "no ipv6 nd mtu",
1506: NO_STR
1507: "Interface IPv6 config commands\n"
1508: "Neighbor discovery\n"
1509: "Advertised MTU\n")
1510: {
1511: struct interface *ifp = (struct interface *) vty->index;
1512: struct zebra_if *zif = ifp->info;
1513: zif->rtadv.AdvLinkMTU = 0;
1514: return CMD_SUCCESS;
1515: }
1516:
1517: ALIAS (no_ipv6_nd_mtu,
1518: no_ipv6_nd_mtu_val_cmd,
1519: "no ipv6 nd mtu <1-65535>",
1520: NO_STR
1521: "Interface IPv6 config commands\n"
1522: "Neighbor discovery\n"
1523: "Advertised MTU\n"
1524: "MTU in bytes\n")
1525:
1.1 misho 1526: /* Write configuration about router advertisement. */
1527: void
1528: rtadv_config_write (struct vty *vty, struct interface *ifp)
1529: {
1530: struct zebra_if *zif;
1531: struct listnode *node;
1532: struct rtadv_prefix *rprefix;
1.1.1.3 ! misho 1533: char buf[PREFIX_STRLEN];
1.1 misho 1534: int interval;
1535:
1536: zif = ifp->info;
1537:
1538: if (! if_is_loopback (ifp))
1539: {
1540: if (zif->rtadv.AdvSendAdvertisements)
1541: vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
1542: else
1543: vty_out (vty, " ipv6 nd suppress-ra%s", VTY_NEWLINE);
1544: }
1545:
1546:
1547: interval = zif->rtadv.MaxRtrAdvInterval;
1548: if (interval % 1000)
1549: vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
1550: VTY_NEWLINE);
1551: else
1552: if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
1553: vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
1554: VTY_NEWLINE);
1555:
1.1.1.2 misho 1556: if (zif->rtadv.AdvIntervalOption)
1557: vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1558:
1559: if (zif->rtadv.AdvDefaultLifetime != -1)
1.1 misho 1560: vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1561: VTY_NEWLINE);
1562:
1.1.1.2 misho 1563: if (zif->rtadv.HomeAgentPreference)
1564: vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1565: zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1566:
1567: if (zif->rtadv.HomeAgentLifetime != -1)
1568: vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
1569: zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
1570:
1571: if (zif->rtadv.AdvHomeAgentFlag)
1572: vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
1573:
1.1 misho 1574: if (zif->rtadv.AdvReachableTime)
1575: vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
1576: VTY_NEWLINE);
1577:
1578: if (zif->rtadv.AdvManagedFlag)
1579: vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
1580:
1581: if (zif->rtadv.AdvOtherConfigFlag)
1582: vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
1583:
1584: if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
1585: vty_out (vty, " ipv6 nd router-preference %s%s",
1586: rtadv_pref_strs[zif->rtadv.DefaultPreference],
1587: VTY_NEWLINE);
1588:
1.1.1.2 misho 1589: if (zif->rtadv.AdvLinkMTU)
1590: vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1591:
1.1 misho 1592: for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
1593: {
1.1.1.3 ! misho 1594: vty_out (vty, " ipv6 nd prefix %s",
! 1595: prefix2str (&rprefix->prefix, buf, sizeof(buf)));
1.1 misho 1596: if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
1597: (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
1598: {
1599: if (rprefix->AdvValidLifetime == UINT32_MAX)
1600: vty_out (vty, " infinite");
1601: else
1602: vty_out (vty, " %u", rprefix->AdvValidLifetime);
1603: if (rprefix->AdvPreferredLifetime == UINT32_MAX)
1604: vty_out (vty, " infinite");
1605: else
1606: vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
1607: }
1608: if (!rprefix->AdvOnLinkFlag)
1609: vty_out (vty, " off-link");
1610: if (!rprefix->AdvAutonomousFlag)
1611: vty_out (vty, " no-autoconfig");
1612: if (rprefix->AdvRouterAddressFlag)
1613: vty_out (vty, " router-address");
1614: vty_out (vty, "%s", VTY_NEWLINE);
1615: }
1616: }
1617:
1618:
1619: static void
1.1.1.3 ! misho 1620: rtadv_event (struct zebra_vrf *zvrf, enum rtadv_event event, int val)
1.1 misho 1621: {
1.1.1.3 ! misho 1622: struct rtadv *rtadv = &zvrf->rtadv;
! 1623:
1.1 misho 1624: switch (event)
1625: {
1626: case RTADV_START:
1627: if (! rtadv->ra_read)
1.1.1.3 ! misho 1628: rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
1.1 misho 1629: if (! rtadv->ra_timer)
1630: rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
1.1.1.3 ! misho 1631: zvrf, 0);
1.1 misho 1632: break;
1633: case RTADV_STOP:
1634: if (rtadv->ra_timer)
1635: {
1636: thread_cancel (rtadv->ra_timer);
1637: rtadv->ra_timer = NULL;
1638: }
1639: if (rtadv->ra_read)
1640: {
1641: thread_cancel (rtadv->ra_read);
1642: rtadv->ra_read = NULL;
1643: }
1644: break;
1645: case RTADV_TIMER:
1646: if (! rtadv->ra_timer)
1.1.1.3 ! misho 1647: rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zvrf,
1.1 misho 1648: val);
1649: break;
1650: case RTADV_TIMER_MSEC:
1651: if (! rtadv->ra_timer)
1652: rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
1.1.1.3 ! misho 1653: zvrf, val);
1.1 misho 1654: break;
1655: case RTADV_READ:
1656: if (! rtadv->ra_read)
1.1.1.3 ! misho 1657: rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
1.1 misho 1658: break;
1659: default:
1660: break;
1661: }
1662: return;
1663: }
1664:
1665: void
1.1.1.3 ! misho 1666: rtadv_init (struct zebra_vrf *zvrf)
1.1 misho 1667: {
1.1.1.3 ! misho 1668: zvrf->rtadv.sock = rtadv_make_socket (zvrf->vrf_id);
! 1669: }
1.1 misho 1670:
1.1.1.3 ! misho 1671: void
! 1672: rtadv_terminate (struct zebra_vrf *zvrf)
! 1673: {
! 1674: rtadv_event (zvrf, RTADV_STOP, 0);
! 1675:
! 1676: if (zvrf->rtadv.sock >= 0)
! 1677: {
! 1678: close (zvrf->rtadv.sock);
! 1679: zvrf->rtadv.sock = -1;
! 1680: }
1.1 misho 1681:
1.1.1.3 ! misho 1682: zvrf->rtadv.adv_if_count = 0;
! 1683: zvrf->rtadv.adv_msec_if_count = 0;
! 1684: }
1.1 misho 1685:
1.1.1.3 ! misho 1686: void
! 1687: rtadv_cmd_init (void)
! 1688: {
1.1 misho 1689: install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
1690: install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
1691: install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
1692: install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
1693: install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
1.1.1.2 misho 1694: install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
1695: install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
1.1 misho 1696: install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
1697: install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
1.1.1.2 misho 1698: install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
1.1 misho 1699: install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
1700: install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
1.1.1.2 misho 1701: install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
1.1 misho 1702: install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
1703: install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
1704: install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
1705: install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
1706: install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
1707: install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
1708: install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
1709: install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
1.1.1.2 misho 1710: install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
1.1 misho 1711: install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
1712: install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
1.1.1.2 misho 1713: install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
1.1 misho 1714: install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
1715: install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
1716: install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
1717: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
1718: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
1719: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
1720: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
1721: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
1722: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
1723: install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
1724: install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
1725: install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
1726: install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
1727: install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
1728: install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
1729: install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
1730: install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
1731: install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
1732: install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
1.1.1.2 misho 1733: install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
1734: install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
1735: install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
1736: install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
1.1 misho 1737: }
1738:
1739: static int
1740: if_join_all_router (int sock, struct interface *ifp)
1741: {
1742: int ret;
1743:
1744: struct ipv6_mreq mreq;
1745:
1746: memset (&mreq, 0, sizeof (struct ipv6_mreq));
1747: inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
1748: mreq.ipv6mr_interface = ifp->ifindex;
1749:
1750: ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
1751: (char *) &mreq, sizeof mreq);
1752: if (ret < 0)
1753: zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno));
1754:
1755: zlog_info ("rtadv: %s join to all-routers multicast group", ifp->name);
1756:
1757: return 0;
1758: }
1759:
1760: static int
1761: if_leave_all_router (int sock, struct interface *ifp)
1762: {
1763: int ret;
1764:
1765: struct ipv6_mreq mreq;
1766:
1767: memset (&mreq, 0, sizeof (struct ipv6_mreq));
1768: inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
1769: mreq.ipv6mr_interface = ifp->ifindex;
1770:
1771: ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
1772: (char *) &mreq, sizeof mreq);
1773: if (ret < 0)
1774: zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno));
1775:
1776: zlog_info ("rtadv: %s leave from all-routers multicast group", ifp->name);
1777:
1778: return 0;
1779: }
1780:
1781: #else
1782: void
1.1.1.3 ! misho 1783: rtadv_init (struct zebra_vrf *zvrf)
! 1784: {
! 1785: /* Empty.*/;
! 1786: }
! 1787: void
! 1788: rtadv_terminate (struct zebra_vrf *zvrf)
! 1789: {
! 1790: /* Empty.*/;
! 1791: }
! 1792: void
! 1793: rtadv_cmd_init (void)
1.1 misho 1794: {
1795: /* Empty.*/;
1796: }
1.1.1.3 ! misho 1797: #endif /* HAVE_RTADV && HAVE_IPV6 */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>