]> git.proxmox.com Git - mirror_frr.git/blame - zebra/rtadv.c
lib: migrate to new memory-type handling
[mirror_frr.git] / zebra / rtadv.c
CommitLineData
718e3744 1/* Router advertisement
7cee1bb1 2 * Copyright (C) 2005 6WIND <jean-mickael.guerin@6wind.com>
718e3744 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"
4a04e5f7 29#include "stream.h"
718e3744 30#include "log.h"
31#include "prefix.h"
32#include "linklist.h"
33#include "command.h"
edd7c245 34#include "privs.h"
cd80d74f 35#include "vrf.h"
718e3744 36
37#include "zebra/interface.h"
38#include "zebra/rtadv.h"
39#include "zebra/debug.h"
537d8ea9 40#include "zebra/rib.h"
4b5e1359 41#include "zebra/zserv.h"
fe18ee2d 42#include "zebra/zebra_ns.h"
7c551956 43#include "zebra/zebra_vrf.h"
718e3744 44
edd7c245 45extern struct zebra_privs_t zserv_privs;
46
8da4e946 47#if defined (HAVE_IPV6) && defined (HAVE_RTADV)
718e3744 48
fa2b17e3 49#ifdef OPEN_BSD
50#include <netinet/icmp6.h>
51#endif
52
718e3744 53/* If RFC2133 definition is used. */
54#ifndef IPV6_JOIN_GROUP
55#define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
56#endif
57#ifndef IPV6_LEAVE_GROUP
58#define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
59#endif
60
61#define ALLNODE "ff02::1"
62#define ALLROUTER "ff02::2"
63
7cee1bb1 64enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
65 RTADV_TIMER_MSEC, RTADV_READ};
718e3744 66
43459b1f 67static void rtadv_event (struct zebra_ns *, enum rtadv_event, int);
718e3744 68
a1ac18c4 69static int if_join_all_router (int, struct interface *);
70static int if_leave_all_router (int, struct interface *);
6b0655a2 71
911ad1e2 72static int
b892f1dd 73rtadv_increment_received(struct zebra_ns *zns, ifindex_t *ifindex)
911ad1e2 74{
795b5abf
QY
75 int ret = -1;
76 struct interface *iface;
77 struct zebra_if *zif;
78
911ad1e2 79 iface = if_lookup_by_index_per_ns (zns, *ifindex);
80 if (iface && iface->info)
81 {
82 zif = iface->info;
83 zif->ra_rcvd++;
84 ret = 0;
85 }
795b5abf
QY
86 return ret;
87}
88
a1ac18c4 89static int
911ad1e2 90rtadv_recv_packet (struct zebra_ns *zns, int sock, u_char *buf, int buflen,
b892f1dd 91 struct sockaddr_in6 *from, ifindex_t *ifindex,
718e3744 92 int *hoplimit)
93{
94 int ret;
95 struct msghdr msg;
96 struct iovec iov;
97 struct cmsghdr *cmsgptr;
98 struct in6_addr dst;
99
100 char adata[1024];
101
102 /* Fill in message and iovec. */
103 msg.msg_name = (void *) from;
104 msg.msg_namelen = sizeof (struct sockaddr_in6);
105 msg.msg_iov = &iov;
106 msg.msg_iovlen = 1;
107 msg.msg_control = (void *) adata;
108 msg.msg_controllen = sizeof adata;
109 iov.iov_base = buf;
110 iov.iov_len = buflen;
111
112 /* If recvmsg fail return minus value. */
113 ret = recvmsg (sock, &msg, 0);
114 if (ret < 0)
115 return ret;
116
b99760ab 117 for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
718e3744 118 cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
119 {
120 /* I want interface index which this packet comes from. */
121 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
122 cmsgptr->cmsg_type == IPV6_PKTINFO)
123 {
124 struct in6_pktinfo *ptr;
125
126 ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
127 *ifindex = ptr->ipi6_ifindex;
128 memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
129 }
130
131 /* Incoming packet's hop limit. */
132 if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
133 cmsgptr->cmsg_type == IPV6_HOPLIMIT)
b0b709ab
SH
134 {
135 int *hoptr = (int *) CMSG_DATA (cmsgptr);
136 *hoplimit = *hoptr;
137 }
718e3744 138 }
795b5abf 139
911ad1e2 140 rtadv_increment_received(zns, ifindex);
718e3744 141 return ret;
142}
143
144#define RTADV_MSG_SIZE 4096
145
146/* Send router advertisement packet. */
a1ac18c4 147static void
718e3744 148rtadv_send_packet (int sock, struct interface *ifp)
149{
150 struct msghdr msg;
151 struct iovec iov;
152 struct cmsghdr *cmsgptr;
153 struct in6_pktinfo *pkt;
154 struct sockaddr_in6 addr;
57492d56 155 static void *adata = NULL;
718e3744 156 unsigned char buf[RTADV_MSG_SIZE];
157 struct nd_router_advert *rtadv;
158 int ret;
159 int len = 0;
160 struct zebra_if *zif;
1eb8ef25 161 struct rtadv_prefix *rprefix;
718e3744 162 u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
52dc7ee6 163 struct listnode *node;
d660f698 164 u_int16_t pkt_RouterLifetime;
718e3744 165
57492d56 166 /*
167 * Allocate control message bufffer. This is dynamic because
168 * CMSG_SPACE is not guaranteed not to call a function. Note that
169 * the size will be different on different architectures due to
170 * differing alignment rules.
171 */
172 if (adata == NULL)
173 {
174 /* XXX Free on shutdown. */
175 adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
176
177 if (adata == NULL)
f360eac0 178 zlog_err("rtadv_send_packet: can't malloc control data");
57492d56 179 }
180
718e3744 181 /* Logging of packet. */
182 if (IS_ZEBRA_DEBUG_PACKET)
f360eac0 183 zlog_debug ("%s(%u): Tx RA, socket %u",
184 ifp->name, ifp->ifindex, sock);
718e3744 185
186 /* Fill in sockaddr_in6. */
187 memset (&addr, 0, sizeof (struct sockaddr_in6));
188 addr.sin6_family = AF_INET6;
189#ifdef SIN6_LEN
190 addr.sin6_len = sizeof (struct sockaddr_in6);
191#endif /* SIN6_LEN */
192 addr.sin6_port = htons (IPPROTO_ICMPV6);
aca43b65 193 IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
718e3744 194
195 /* Fetch interface information. */
196 zif = ifp->info;
197
198 /* Make router advertisement message. */
199 rtadv = (struct nd_router_advert *) buf;
200
201 rtadv->nd_ra_type = ND_ROUTER_ADVERT;
202 rtadv->nd_ra_code = 0;
203 rtadv->nd_ra_cksum = 0;
204
205 rtadv->nd_ra_curhoplimit = 64;
b60668d0
CC
206
207 /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
208 rtadv->nd_ra_flags_reserved =
209 zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
210 rtadv->nd_ra_flags_reserved <<= 3;
211
718e3744 212 if (zif->rtadv.AdvManagedFlag)
213 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
214 if (zif->rtadv.AdvOtherConfigFlag)
215 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
7cee1bb1 216 if (zif->rtadv.AdvHomeAgentFlag)
217 rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
d660f698
DO
218 /* Note that according to Neighbor Discovery (RFC 4861 [18]),
219 * AdvDefaultLifetime is by default based on the value of
220 * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
221 * field of Router Advertisements. Given that this field is expressed
222 * in seconds, a small MaxRtrAdvInterval value can result in a zero
223 * value for this field. To prevent this, routers SHOULD keep
224 * AdvDefaultLifetime in at least one second, even if the use of
225 * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
226 pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ?
227 zif->rtadv.AdvDefaultLifetime :
228 MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
229 rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime);
718e3744 230 rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
231 rtadv->nd_ra_retransmit = htonl (0);
232
233 len = sizeof (struct nd_router_advert);
234
d660f698
DO
235 /* If both the Home Agent Preference and Home Agent Lifetime are set to
236 * their default values specified above, this option SHOULD NOT be
237 * included in the Router Advertisement messages sent by this home
238 * agent. -- RFC6275, 7.4 */
239 if
240 (
241 zif->rtadv.AdvHomeAgentFlag &&
242 (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
243 )
7cee1bb1 244 {
245 struct nd_opt_homeagent_info *ndopt_hai =
246 (struct nd_opt_homeagent_info *)(buf + len);
247 ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
248 ndopt_hai->nd_opt_hai_len = 1;
249 ndopt_hai->nd_opt_hai_reserved = 0;
250 ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
d660f698
DO
251 /* 16-bit unsigned integer. The lifetime associated with the home
252 * agent in units of seconds. The default value is the same as the
253 * Router Lifetime, as specified in the main body of the Router
254 * Advertisement. The maximum value corresponds to 18.2 hours. A
255 * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
256 ndopt_hai->nd_opt_hai_lifetime = htons
257 (
258 zif->rtadv.HomeAgentLifetime != -1 ?
259 zif->rtadv.HomeAgentLifetime :
260 MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
261 );
7cee1bb1 262 len += sizeof(struct nd_opt_homeagent_info);
263 }
264
265 if (zif->rtadv.AdvIntervalOption)
266 {
267 struct nd_opt_adv_interval *ndopt_adv =
268 (struct nd_opt_adv_interval *)(buf + len);
269 ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
270 ndopt_adv->nd_opt_ai_len = 1;
271 ndopt_adv->nd_opt_ai_reserved = 0;
272 ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
273 len += sizeof(struct nd_opt_adv_interval);
274 }
275
718e3744 276 /* Fill in prefix. */
1eb8ef25 277 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
718e3744 278 {
279 struct nd_opt_prefix_info *pinfo;
718e3744 280
281 pinfo = (struct nd_opt_prefix_info *) (buf + len);
282
283 pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
284 pinfo->nd_opt_pi_len = 4;
285 pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
286
287 pinfo->nd_opt_pi_flags_reserved = 0;
288 if (rprefix->AdvOnLinkFlag)
289 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
290 if (rprefix->AdvAutonomousFlag)
291 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
7cee1bb1 292 if (rprefix->AdvRouterAddressFlag)
293 pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
718e3744 294
295 pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
296 pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
297 pinfo->nd_opt_pi_reserved2 = 0;
298
aca43b65 299 IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
718e3744 300
301#ifdef DEBUG
302 {
303 u_char buf[INET6_ADDRSTRLEN];
304
b6178002 305 zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
3e31cded 306 buf, INET6_ADDRSTRLEN));
718e3744 307
308 }
309#endif /* DEBUG */
310
311 len += sizeof (struct nd_opt_prefix_info);
312 }
313
314 /* Hardware address. */
718e3744 315 if (ifp->hw_addr_len != 0)
316 {
317 buf[len++] = ND_OPT_SOURCE_LINKADDR;
50adf783
DW
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;
718e3744 322
323 memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
324 len += ifp->hw_addr_len;
50adf783
DW
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;
718e3744 329 }
718e3744 330
6ae93c05
DO
331 /* MTU */
332 if (zif->rtadv.AdvLinkMTU)
333 {
334 struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
335 opt->nd_opt_mtu_type = ND_OPT_MTU;
336 opt->nd_opt_mtu_len = 1;
337 opt->nd_opt_mtu_reserved = 0;
338 opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
339 len += sizeof (struct nd_opt_mtu);
340 }
341
718e3744 342 msg.msg_name = (void *) &addr;
343 msg.msg_namelen = sizeof (struct sockaddr_in6);
344 msg.msg_iov = &iov;
345 msg.msg_iovlen = 1;
346 msg.msg_control = (void *) adata;
f841e02e 347 msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
57492d56 348 msg.msg_flags = 0;
718e3744 349 iov.iov_base = buf;
350 iov.iov_len = len;
351
b99760ab 352 cmsgptr = ZCMSG_FIRSTHDR(&msg);
57492d56 353 cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
718e3744 354 cmsgptr->cmsg_level = IPPROTO_IPV6;
355 cmsgptr->cmsg_type = IPV6_PKTINFO;
80893817 356
718e3744 357 pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
358 memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
359 pkt->ipi6_ifindex = ifp->ifindex;
360
361 ret = sendmsg (sock, &msg, 0);
9ccabd1c 362 if (ret < 0)
363 {
f360eac0 364 zlog_err ("%s(%u): Tx RA failed, socket %u error %d (%s)",
365 ifp->name, ifp->ifindex, sock, errno, safe_strerror(errno));
9ccabd1c 366 }
795b5abf
QY
367 else
368 zif->ra_sent++;
718e3744 369}
370
a1ac18c4 371static int
718e3744 372rtadv_timer (struct thread *thread)
373{
43459b1f 374 struct zebra_ns *zns = THREAD_ARG (thread);
375 vrf_iter_t iter;
1eb8ef25 376 struct listnode *node, *nnode;
718e3744 377 struct interface *ifp;
378 struct zebra_if *zif;
7cee1bb1 379 int period;
718e3744 380
43459b1f 381 zns->rtadv.ra_timer = NULL;
382 if (zns->rtadv.adv_msec_if_count == 0)
7cee1bb1 383 {
384 period = 1000; /* 1 s */
43459b1f 385 rtadv_event (zns, RTADV_TIMER, 1 /* 1 s */);
7cee1bb1 386 }
387 else
388 {
389 period = 10; /* 10 ms */
43459b1f 390 rtadv_event (zns, RTADV_TIMER_MSEC, 10 /* 10 ms */);
7cee1bb1 391 }
718e3744 392
43459b1f 393 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
394 for (ALL_LIST_ELEMENTS (vrf_iter2iflist (iter), node, nnode, ifp))
395 {
c23af4d3 396 if (if_is_loopback (ifp) ||
397 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK) ||
398 ! if_is_operative (ifp))
43459b1f 399 continue;
400
401 zif = ifp->info;
402
403 if (zif->rtadv.AdvSendAdvertisements)
404 {
6c9678b4 405 if (zif->rtadv.inFastRexmit)
43459b1f 406 {
6c9678b4
DD
407 /* We assume we fast rexmit every sec so no additional vars */
408 if (--zif->rtadv.NumFastReXmitsRemain <= 0)
409 zif->rtadv.inFastRexmit = 0;
410
411 if (IS_ZEBRA_DEBUG_SEND)
412 zlog_debug("Fast RA Rexmit on interface %s", ifp->name);
413
43459b1f 414 rtadv_send_packet (zns->rtadv.sock, ifp);
415 }
6c9678b4
DD
416 else
417 {
418 zif->rtadv.AdvIntervalTimer -= period;
419 if (zif->rtadv.AdvIntervalTimer <= 0)
420 {
421 /* FIXME: using MaxRtrAdvInterval each time isn't what section
422 6.2.4 of RFC4861 tells to do. */
423 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
424 rtadv_send_packet (zns->rtadv.sock, ifp);
425 }
426 }
43459b1f 427 }
428 }
718e3744 429
718e3744 430 return 0;
431}
432
a1ac18c4 433static void
718e3744 434rtadv_process_solicit (struct interface *ifp)
435{
cd80d74f 436 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 437 struct zebra_ns *zns = zvrf->zns;
718e3744 438
43459b1f 439 assert (zns);
440 rtadv_send_packet (zns->rtadv.sock, ifp);
718e3744 441}
442
a1ac18c4 443static void
a80beece
DS
444rtadv_process_advert (u_char *msg, unsigned int len, struct interface *ifp,
445 struct sockaddr_in6 *addr)
718e3744 446{
a80beece
DS
447 struct nd_router_advert *radvert;
448 char addr_str[INET6_ADDRSTRLEN];
449 struct zebra_if *zif;
1d20ccf3 450 struct prefix p;
a80beece
DS
451
452 zif = ifp->info;
453
454 inet_ntop (AF_INET6, &addr->sin6_addr, addr_str, INET6_ADDRSTRLEN);
455
a80beece 456 if (len < sizeof(struct nd_router_advert)) {
f360eac0 457 zlog_warn("%s(%u): Rx RA with invalid length %d from %s",
458 ifp->name, ifp->ifindex, len, addr_str);
a80beece
DS
459 return;
460 }
461 if (!IN6_IS_ADDR_LINKLOCAL(&addr->sin6_addr)) {
f360eac0 462 zlog_warn("%s(%u): Rx RA with non-linklocal source address from %s",
463 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
464 return;
465 }
466
467 radvert = (struct nd_router_advert *) msg;
468
469 if ((radvert->nd_ra_curhoplimit && zif->rtadv.AdvCurHopLimit) &&
470 (radvert->nd_ra_curhoplimit != zif->rtadv.AdvCurHopLimit))
471 {
f360eac0 472 zlog_warn("%s(%u): Rx RA - our AdvCurHopLimit doesn't agree with %s",
473 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
474 }
475
476 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_MANAGED) &&
477 !zif->rtadv.AdvManagedFlag)
478 {
f360eac0 479 zlog_warn("%s(%u): Rx RA - our AdvManagedFlag doesn't agree with %s",
480 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
481 }
482
483 if ((radvert->nd_ra_flags_reserved & ND_RA_FLAG_OTHER) &&
484 !zif->rtadv.AdvOtherConfigFlag)
485 {
f360eac0 486 zlog_warn("%s(%u): Rx RA - our AdvOtherConfigFlag doesn't agree with %s",
487 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
488 }
489
490 if ((radvert->nd_ra_reachable && zif->rtadv.AdvReachableTime) &&
491 (ntohl(radvert->nd_ra_reachable) != zif->rtadv.AdvReachableTime))
492 {
f360eac0 493 zlog_warn("%s(%u): Rx RA - our AdvReachableTime doesn't agree with %s",
494 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
495 }
496
497 if ((radvert->nd_ra_retransmit && zif->rtadv.AdvRetransTimer) &&
4e3afb14 498 (ntohl(radvert->nd_ra_retransmit) != (unsigned int)zif->rtadv.AdvRetransTimer))
a80beece 499 {
f360eac0 500 zlog_warn("%s(%u): Rx RA - our AdvRetransTimer doesn't agree with %s",
501 ifp->name, ifp->ifindex, addr_str);
a80beece
DS
502 }
503
1d20ccf3 504 /* Create entry for neighbor if not known. */
505 p.family = AF_INET6;
506 IPV6_ADDR_COPY (&p.u.prefix, &addr->sin6_addr);
507 p.prefixlen = IPV6_MAX_PREFIXLEN;
a80beece 508
1d20ccf3 509 if (!nbr_connected_check(ifp, &p))
510 nbr_connected_add_ipv6 (ifp, &addr->sin6_addr);
718e3744 511}
512
a80beece 513
a1ac18c4 514static void
b892f1dd 515rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex, int hoplimit,
43459b1f 516 struct sockaddr_in6 *from, struct zebra_ns *zns)
718e3744 517{
518 struct icmp6_hdr *icmph;
519 struct interface *ifp;
520 struct zebra_if *zif;
f360eac0 521 char addr_str[INET6_ADDRSTRLEN];
522
523 inet_ntop (AF_INET6, &from->sin6_addr, addr_str, INET6_ADDRSTRLEN);
718e3744 524
525 /* Interface search. */
43459b1f 526 ifp = if_lookup_by_index_per_ns (zns, ifindex);
718e3744 527 if (ifp == NULL)
528 {
f360eac0 529 zlog_warn ("RA/RS received on unknown IF %u from %s",
530 ifindex, addr_str);
718e3744 531 return;
532 }
533
f360eac0 534 if (IS_ZEBRA_DEBUG_PACKET)
535 zlog_debug ("%s(%u): Rx RA/RS len %d from %s",
536 ifp->name, ifp->ifindex, len, addr_str);
537
c23af4d3 538 if (if_is_loopback (ifp) ||
539 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
718e3744 540 return;
541
542 /* Check interface configuration. */
543 zif = ifp->info;
544 if (! zif->rtadv.AdvSendAdvertisements)
545 return;
546
547 /* ICMP message length check. */
548 if (len < sizeof (struct icmp6_hdr))
549 {
f360eac0 550 zlog_warn ("%s(%u): Rx RA with Invalid ICMPV6 packet length %d",
551 ifp->name, ifp->ifindex, len);
718e3744 552 return;
553 }
554
555 icmph = (struct icmp6_hdr *) buf;
556
557 /* ICMP message type check. */
558 if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
559 icmph->icmp6_type != ND_ROUTER_ADVERT)
560 {
f360eac0 561 zlog_warn ("%s(%u): Rx RA - Unwanted ICMPV6 message type %d",
562 ifp->name, ifp->ifindex, icmph->icmp6_type);
718e3744 563 return;
564 }
565
566 /* Hoplimit check. */
567 if (hoplimit >= 0 && hoplimit != 255)
568 {
f360eac0 569 zlog_warn ("%s(%u): Rx RA - Invalid hoplimit %d",
570 ifp->name, ifp->ifindex, hoplimit);
718e3744 571 return;
572 }
573
574 /* Check ICMP message type. */
575 if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
576 rtadv_process_solicit (ifp);
577 else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
a80beece 578 rtadv_process_advert (buf, len, ifp, from);
718e3744 579
580 return;
581}
582
a1ac18c4 583static int
718e3744 584rtadv_read (struct thread *thread)
585{
586 int sock;
587 int len;
588 u_char buf[RTADV_MSG_SIZE];
589 struct sockaddr_in6 from;
b892f1dd 590 ifindex_t ifindex = 0;
718e3744 591 int hoplimit = -1;
43459b1f 592 struct zebra_ns *zns = THREAD_ARG (thread);
718e3744 593
594 sock = THREAD_FD (thread);
43459b1f 595 zns->rtadv.ra_read = NULL;
718e3744 596
597 /* Register myself. */
43459b1f 598 rtadv_event (zns, RTADV_READ, sock);
718e3744 599
d9ce8324 600 len = rtadv_recv_packet (zns, sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
718e3744 601
602 if (len < 0)
603 {
f360eac0 604 zlog_warn ("RA/RS recv failed, socket %u error %s",
605 sock, safe_strerror (errno));
718e3744 606 return len;
607 }
608
43459b1f 609 rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, &from, zns);
718e3744 610
611 return 0;
612}
613
a1ac18c4 614static int
43459b1f 615rtadv_make_socket (void)
718e3744 616{
617 int sock;
43459b1f 618 int ret = 0;
718e3744 619 struct icmp6_filter filter;
620
edd7c245 621 if ( zserv_privs.change (ZPRIVS_RAISE) )
622 zlog_err ("rtadv_make_socket: could not raise privs, %s",
6099b3b5 623 safe_strerror (errno) );
edd7c245 624
43459b1f 625 sock = socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
718e3744 626
edd7c245 627 if ( zserv_privs.change (ZPRIVS_LOWER) )
628 zlog_err ("rtadv_make_socket: could not lower privs, %s",
6099b3b5 629 safe_strerror (errno) );
edd7c245 630
718e3744 631 if (sock < 0)
a5c304ab
MS
632 {
633 close (sock);
634 return -1;
635 }
718e3744 636
637 ret = setsockopt_ipv6_pktinfo (sock, 1);
718e3744 638 if (ret < 0)
a5c304ab
MS
639 {
640 close (sock);
641 return ret;
642 }
718e3744 643 ret = setsockopt_ipv6_multicast_loop (sock, 0);
644 if (ret < 0)
a5c304ab
MS
645 {
646 close (sock);
647 return ret;
648 }
718e3744 649 ret = setsockopt_ipv6_unicast_hops (sock, 255);
650 if (ret < 0)
a5c304ab
MS
651 {
652 close (sock);
653 return ret;
654 }
718e3744 655 ret = setsockopt_ipv6_multicast_hops (sock, 255);
656 if (ret < 0)
a5c304ab
MS
657 {
658 close (sock);
659 return ret;
660 }
718e3744 661 ret = setsockopt_ipv6_hoplimit (sock, 1);
662 if (ret < 0)
a5c304ab
MS
663 {
664 close (sock);
665 return ret;
666 }
718e3744 667
668 ICMP6_FILTER_SETBLOCKALL(&filter);
669 ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
670 ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
671
672 ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
673 sizeof (struct icmp6_filter));
674 if (ret < 0)
675 {
6099b3b5 676 zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
718e3744 677 return ret;
678 }
679
680 return sock;
681}
6b0655a2 682
a1ac18c4 683static struct rtadv_prefix *
66e5cd87 684rtadv_prefix_new (void)
718e3744 685{
393deb9b 686 return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
718e3744 687}
688
a1ac18c4 689static void
718e3744 690rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
691{
692 XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
693}
694
a1ac18c4 695static struct rtadv_prefix *
aca43b65 696rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
718e3744 697{
52dc7ee6 698 struct listnode *node;
718e3744 699 struct rtadv_prefix *rprefix;
700
1eb8ef25 701 for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
aca43b65 702 if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
1eb8ef25 703 return rprefix;
718e3744 704 return NULL;
705}
706
a1ac18c4 707static struct rtadv_prefix *
aca43b65 708rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
718e3744 709{
710 struct rtadv_prefix *rprefix;
711
712 rprefix = rtadv_prefix_lookup (rplist, p);
713 if (rprefix)
714 return rprefix;
715
716 rprefix = rtadv_prefix_new ();
aca43b65 717 memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
718e3744 718 listnode_add (rplist, rprefix);
719
720 return rprefix;
721}
722
a1ac18c4 723static void
718e3744 724rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
725{
726 struct rtadv_prefix *rprefix;
727
728 rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
729
730 /* Set parameters. */
731 rprefix->AdvValidLifetime = rp->AdvValidLifetime;
732 rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
733 rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
734 rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
7cee1bb1 735 rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
718e3744 736}
737
a1ac18c4 738static int
718e3744 739rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
740{
741 struct rtadv_prefix *rprefix;
742
743 rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
744 if (rprefix != NULL)
745 {
746 listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
747 rtadv_prefix_free (rprefix);
748 return 1;
749 }
750 else
751 return 0;
752}
753
4a04e5f7 754static void
b6120505
DW
755ipv6_nd_suppress_ra_set (struct interface *ifp, ipv6_nd_suppress_ra_status status)
756{
757 struct zebra_if *zif;
758 struct zebra_vrf *zvrf;
43459b1f 759 struct zebra_ns *zns;
b6120505
DW
760
761 zif = ifp->info;
762 zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 763 zns = zvrf->zns;
b6120505
DW
764
765 if (status == RA_SUPPRESS)
766 {
767 /* RA is currently enabled */
768 if (zif->rtadv.AdvSendAdvertisements)
769 {
770 zif->rtadv.AdvSendAdvertisements = 0;
771 zif->rtadv.AdvIntervalTimer = 0;
43459b1f 772 zns->rtadv.adv_if_count--;
b6120505 773
43459b1f 774 if_leave_all_router (zns->rtadv.sock, ifp);
b6120505 775
43459b1f 776 if (zns->rtadv.adv_if_count == 0)
777 rtadv_event (zns, RTADV_STOP, 0);
b6120505
DW
778 }
779 }
780 else
781 {
782 if (! zif->rtadv.AdvSendAdvertisements)
783 {
784 zif->rtadv.AdvSendAdvertisements = 1;
785 zif->rtadv.AdvIntervalTimer = 0;
43459b1f 786 zns->rtadv.adv_if_count++;
b6120505 787
6c9678b4
DD
788 if (zif->rtadv.MaxRtrAdvInterval >= 1000)
789 {
790 /* Enable Fast RA only when RA interval is in secs */
791 zif->rtadv.inFastRexmit = 1;
792 zif->rtadv.NumFastReXmitsRemain = RTADV_NUM_FAST_REXMITS;
793 }
794
43459b1f 795 if_join_all_router (zns->rtadv.sock, ifp);
b6120505 796
43459b1f 797 if (zns->rtadv.adv_if_count == 1)
798 rtadv_event (zns, RTADV_START, zns->rtadv.sock);
b6120505
DW
799 }
800 }
801}
802
4a04e5f7 803/*
804 * Handle client (BGP) message to enable or disable IPv6 RA on an interface.
805 * Note that while the client could request RA on an interface on which the
806 * operator has not enabled RA, RA won't be disabled upon client request
5c81b96a 807 * if the operator has explicitly enabled RA. The enable request can also
808 * specify a RA interval (in seconds).
4a04e5f7 809 */
810void
811zebra_interface_radv_set (struct zserv *client, int sock, u_short length,
812 struct zebra_vrf *zvrf, int enable)
813{
814 struct stream *s;
815 unsigned int ifindex;
816 struct interface *ifp;
817 struct zebra_if *zif;
5c81b96a 818 int ra_interval;
4a04e5f7 819
820 s = client->ibuf;
821
5c81b96a 822 /* Get interface index and RA interval. */
4a04e5f7 823 ifindex = stream_getl (s);
5c81b96a 824 ra_interval = stream_getl (s);
4a04e5f7 825
826 if (IS_ZEBRA_DEBUG_EVENT)
5c81b96a 827 zlog_debug("%u: IF %u RA %s from client %s, interval %ds",
4a04e5f7 828 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
5c81b96a 829 zebra_route_string(client->proto), ra_interval);
4a04e5f7 830
831 /* Locate interface and check VRF match. */
832 ifp = if_lookup_by_index_per_ns (zebra_ns_lookup (NS_DEFAULT), ifindex);
833 if (!ifp)
834 {
835 zlog_warn("%u: IF %u RA %s client %s - interface unknown",
836 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
837 zebra_route_string(client->proto));
838 return;
839 }
840 if (ifp->vrf_id != zvrf->vrf_id)
841 {
842 zlog_warn("%u: IF %u RA %s client %s - VRF mismatch, IF VRF %u",
843 zvrf->vrf_id, ifindex, enable ? "enable" : "disable",
844 zebra_route_string(client->proto), ifp->vrf_id);
845 return;
846 }
847
848 zif = ifp->info;
849 if (enable)
5c81b96a 850 {
851 ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
852 if (ra_interval &&
853 (ra_interval * 1000) < zif->rtadv.MaxRtrAdvInterval)
854 zif->rtadv.MaxRtrAdvInterval = ra_interval * 1000;
855 }
4a04e5f7 856 else
857 {
858 if (!zif->rtadv.configured)
5c81b96a 859 {
860 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
861 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
862 }
4a04e5f7 863 }
864}
865
718e3744 866DEFUN (ipv6_nd_suppress_ra,
867 ipv6_nd_suppress_ra_cmd,
868 "ipv6 nd suppress-ra",
3e31cded 869 "Interface IPv6 config commands\n"
718e3744 870 "Neighbor discovery\n"
871 "Suppress Router Advertisement\n")
872{
873 struct interface *ifp;
4a04e5f7 874 struct zebra_if *zif;
718e3744 875
876 ifp = vty->index;
718e3744 877
c23af4d3 878 if (if_is_loopback (ifp) ||
879 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
718e3744 880 {
c23af4d3 881 vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
718e3744 882 return CMD_WARNING;
883 }
884
b6120505 885 ipv6_nd_suppress_ra_set (ifp, RA_SUPPRESS);
4a04e5f7 886 zif = ifp->info;
887 zif->rtadv.configured = 0;
718e3744 888 return CMD_SUCCESS;
889}
890
718e3744 891DEFUN (no_ipv6_nd_suppress_ra,
892 no_ipv6_nd_suppress_ra_cmd,
893 "no ipv6 nd suppress-ra",
894 NO_STR
3e31cded 895 "Interface IPv6 config commands\n"
718e3744 896 "Neighbor discovery\n"
897 "Suppress Router Advertisement\n")
898{
899 struct interface *ifp;
4a04e5f7 900 struct zebra_if *zif;
718e3744 901
902 ifp = vty->index;
718e3744 903
c23af4d3 904 if (if_is_loopback (ifp) ||
905 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK))
718e3744 906 {
c23af4d3 907 vty_out (vty, "Cannot configure IPv6 Router Advertisements on this interface%s", VTY_NEWLINE);
718e3744 908 return CMD_WARNING;
909 }
910
b6120505 911 ipv6_nd_suppress_ra_set (ifp, RA_ENABLE);
4a04e5f7 912 zif = ifp->info;
913 zif->rtadv.configured = 1;
718e3744 914 return CMD_SUCCESS;
915}
916
7cee1bb1 917DEFUN (ipv6_nd_ra_interval_msec,
918 ipv6_nd_ra_interval_msec_cmd,
4afa50b3 919 "ipv6 nd ra-interval msec <70-1800000>",
7cee1bb1 920 "Interface IPv6 config commands\n"
921 "Neighbor discovery\n"
922 "Router Advertisement interval\n"
923 "Router Advertisement interval in milliseconds\n")
924{
4afa50b3
DO
925 unsigned interval;
926 struct interface *ifp = (struct interface *) vty->index;
927 struct zebra_if *zif = ifp->info;
cd80d74f 928 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 929 struct zebra_ns *zns;
7cee1bb1 930
43459b1f 931 zns = zvrf->zns;
4afa50b3
DO
932 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
933 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
934 {
935 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
936 return CMD_WARNING;
937 }
7cee1bb1 938
939 if (zif->rtadv.MaxRtrAdvInterval % 1000)
43459b1f 940 zns->rtadv.adv_msec_if_count--;
7cee1bb1 941
942 if (interval % 1000)
43459b1f 943 zns->rtadv.adv_msec_if_count++;
7cee1bb1 944
945 zif->rtadv.MaxRtrAdvInterval = interval;
946 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
947 zif->rtadv.AdvIntervalTimer = 0;
948
949 return CMD_SUCCESS;
950}
951
718e3744 952DEFUN (ipv6_nd_ra_interval,
953 ipv6_nd_ra_interval_cmd,
4afa50b3 954 "ipv6 nd ra-interval <1-1800>",
3e31cded 955 "Interface IPv6 config commands\n"
718e3744 956 "Neighbor discovery\n"
957 "Router Advertisement interval\n"
958 "Router Advertisement interval in seconds\n")
959{
4afa50b3
DO
960 unsigned interval;
961 struct interface *ifp = (struct interface *) vty->index;
962 struct zebra_if *zif = ifp->info;
cd80d74f 963 struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 964 struct zebra_ns *zns;
718e3744 965
43459b1f 966 zns = zvrf->zns;
4afa50b3
DO
967 VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
968 if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
969 {
970 vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
971 return CMD_WARNING;
972 }
718e3744 973
7cee1bb1 974 if (zif->rtadv.MaxRtrAdvInterval % 1000)
43459b1f 975 zns->rtadv.adv_msec_if_count--;
7cee1bb1 976
977 /* convert to milliseconds */
978 interval = interval * 1000;
979
718e3744 980 zif->rtadv.MaxRtrAdvInterval = interval;
981 zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
982 zif->rtadv.AdvIntervalTimer = 0;
983
984 return CMD_SUCCESS;
985}
986
987DEFUN (no_ipv6_nd_ra_interval,
988 no_ipv6_nd_ra_interval_cmd,
989 "no ipv6 nd ra-interval",
990 NO_STR
3e31cded 991 "Interface IPv6 config commands\n"
718e3744 992 "Neighbor discovery\n"
993 "Router Advertisement interval\n")
994{
995 struct interface *ifp;
996 struct zebra_if *zif;
cd80d74f 997 struct zebra_vrf *zvrf;
43459b1f 998 struct zebra_ns *zns;
718e3744 999
1000 ifp = (struct interface *) vty->index;
1001 zif = ifp->info;
cd80d74f 1002 zvrf = vrf_info_lookup (ifp->vrf_id);
43459b1f 1003 zns = zvrf->zns;
718e3744 1004
7cee1bb1 1005 if (zif->rtadv.MaxRtrAdvInterval % 1000)
43459b1f 1006 zns->rtadv.adv_msec_if_count--;
7cee1bb1 1007
718e3744 1008 zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
1009 zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
1010 zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
1011
1012 return CMD_SUCCESS;
1013}
1014
4afa50b3
DO
1015ALIAS (no_ipv6_nd_ra_interval,
1016 no_ipv6_nd_ra_interval_val_cmd,
1017 "no ipv6 nd ra-interval <1-1800>",
1018 NO_STR
1019 "Interface IPv6 config commands\n"
1020 "Neighbor discovery\n"
1021 "Router Advertisement interval\n")
1022
1023ALIAS (no_ipv6_nd_ra_interval,
1024 no_ipv6_nd_ra_interval_msec_val_cmd,
1025 "no ipv6 nd ra-interval msec <1-1800000>",
1026 NO_STR
1027 "Interface IPv6 config commands\n"
1028 "Neighbor discovery\n"
1029 "Router Advertisement interval\n"
1030 "Router Advertisement interval in milliseconds\n")
1031
718e3744 1032DEFUN (ipv6_nd_ra_lifetime,
1033 ipv6_nd_ra_lifetime_cmd,
4afa50b3 1034 "ipv6 nd ra-lifetime <0-9000>",
3e31cded 1035 "Interface IPv6 config commands\n"
718e3744 1036 "Neighbor discovery\n"
1037 "Router lifetime\n"
4afa50b3 1038 "Router lifetime in seconds (0 stands for a non-default gw)\n")
718e3744 1039{
1040 int lifetime;
1041 struct interface *ifp;
1042 struct zebra_if *zif;
1043
1044 ifp = (struct interface *) vty->index;
1045 zif = ifp->info;
1046
4afa50b3 1047 VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
718e3744 1048
d660f698
DO
1049 /* The value to be placed in the Router Lifetime field
1050 * of Router Advertisements sent from the interface,
1051 * in seconds. MUST be either zero or between
1052 * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
4afa50b3 1053 if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
718e3744 1054 {
4afa50b3 1055 vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
718e3744 1056 return CMD_WARNING;
1057 }
1058
1059 zif->rtadv.AdvDefaultLifetime = lifetime;
1060
1061 return CMD_SUCCESS;
1062}
1063
1064DEFUN (no_ipv6_nd_ra_lifetime,
1065 no_ipv6_nd_ra_lifetime_cmd,
1066 "no ipv6 nd ra-lifetime",
1067 NO_STR
3e31cded 1068 "Interface IPv6 config commands\n"
718e3744 1069 "Neighbor discovery\n"
1070 "Router lifetime\n")
1071{
1072 struct interface *ifp;
1073 struct zebra_if *zif;
1074
1075 ifp = (struct interface *) vty->index;
1076 zif = ifp->info;
1077
d660f698 1078 zif->rtadv.AdvDefaultLifetime = -1;
718e3744 1079
1080 return CMD_SUCCESS;
1081}
1082
4afa50b3
DO
1083ALIAS (no_ipv6_nd_ra_lifetime,
1084 no_ipv6_nd_ra_lifetime_val_cmd,
1085 "no ipv6 nd ra-lifetime <0-9000>",
1086 NO_STR
1087 "Interface IPv6 config commands\n"
1088 "Neighbor discovery\n"
1089 "Router lifetime\n"
1090 "Router lifetime in seconds (0 stands for a non-default gw)\n")
1091
718e3744 1092DEFUN (ipv6_nd_reachable_time,
1093 ipv6_nd_reachable_time_cmd,
4afa50b3 1094 "ipv6 nd reachable-time <1-3600000>",
3e31cded 1095 "Interface IPv6 config commands\n"
718e3744 1096 "Neighbor discovery\n"
1097 "Reachable time\n"
1098 "Reachable time in milliseconds\n")
1099{
4afa50b3
DO
1100 struct interface *ifp = (struct interface *) vty->index;
1101 struct zebra_if *zif = ifp->info;
1102 VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
718e3744 1103 return CMD_SUCCESS;
1104}
1105
1106DEFUN (no_ipv6_nd_reachable_time,
1107 no_ipv6_nd_reachable_time_cmd,
1108 "no ipv6 nd reachable-time",
1109 NO_STR
3e31cded 1110 "Interface IPv6 config commands\n"
718e3744 1111 "Neighbor discovery\n"
1112 "Reachable time\n")
1113{
1114 struct interface *ifp;
1115 struct zebra_if *zif;
1116
1117 ifp = (struct interface *) vty->index;
1118 zif = ifp->info;
1119
1120 zif->rtadv.AdvReachableTime = 0;
1121
1122 return CMD_SUCCESS;
1123}
1124
4afa50b3
DO
1125ALIAS (no_ipv6_nd_reachable_time,
1126 no_ipv6_nd_reachable_time_val_cmd,
1127 "no ipv6 nd reachable-time <1-3600000>",
1128 NO_STR
1129 "Interface IPv6 config commands\n"
1130 "Neighbor discovery\n"
1131 "Reachable time\n"
1132 "Reachable time in milliseconds\n")
1133
7cee1bb1 1134DEFUN (ipv6_nd_homeagent_preference,
1135 ipv6_nd_homeagent_preference_cmd,
4afa50b3 1136 "ipv6 nd home-agent-preference <0-65535>",
7cee1bb1 1137 "Interface IPv6 config commands\n"
1138 "Neighbor discovery\n"
1139 "Home Agent preference\n"
4afa50b3 1140 "preference value (default is 0, least preferred)\n")
7cee1bb1 1141{
4afa50b3
DO
1142 struct interface *ifp = (struct interface *) vty->index;
1143 struct zebra_if *zif = ifp->info;
1144 VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
7cee1bb1 1145 return CMD_SUCCESS;
1146}
1147
1148DEFUN (no_ipv6_nd_homeagent_preference,
1149 no_ipv6_nd_homeagent_preference_cmd,
1150 "no ipv6 nd home-agent-preference",
1151 NO_STR
1152 "Interface IPv6 config commands\n"
1153 "Neighbor discovery\n"
1154 "Home Agent preference\n")
1155{
1156 struct interface *ifp;
1157 struct zebra_if *zif;
1158
1159 ifp = (struct interface *) vty->index;
1160 zif = ifp->info;
1161
1162 zif->rtadv.HomeAgentPreference = 0;
1163
1164 return CMD_SUCCESS;
1165}
1166
4afa50b3
DO
1167ALIAS (no_ipv6_nd_homeagent_preference,
1168 no_ipv6_nd_homeagent_preference_val_cmd,
1169 "no ipv6 nd home-agent-preference <0-65535>",
1170 NO_STR
1171 "Interface IPv6 config commands\n"
1172 "Neighbor discovery\n"
1173 "Home Agent preference\n"
1174 "preference value (default is 0, least preferred)\n")
1175
7cee1bb1 1176DEFUN (ipv6_nd_homeagent_lifetime,
1177 ipv6_nd_homeagent_lifetime_cmd,
4afa50b3 1178 "ipv6 nd home-agent-lifetime <0-65520>",
7cee1bb1 1179 "Interface IPv6 config commands\n"
1180 "Neighbor discovery\n"
1181 "Home Agent lifetime\n"
4afa50b3 1182 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
7cee1bb1 1183{
4afa50b3
DO
1184 struct interface *ifp = (struct interface *) vty->index;
1185 struct zebra_if *zif = ifp->info;
1186 VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
7cee1bb1 1187 return CMD_SUCCESS;
1188}
1189
1190DEFUN (no_ipv6_nd_homeagent_lifetime,
1191 no_ipv6_nd_homeagent_lifetime_cmd,
1192 "no ipv6 nd home-agent-lifetime",
1193 NO_STR
1194 "Interface IPv6 config commands\n"
1195 "Neighbor discovery\n"
1196 "Home Agent lifetime\n")
1197{
1198 struct interface *ifp;
1199 struct zebra_if *zif;
1200
1201 ifp = (struct interface *) vty->index;
1202 zif = ifp->info;
1203
d660f698 1204 zif->rtadv.HomeAgentLifetime = -1;
7cee1bb1 1205
1206 return CMD_SUCCESS;
1207}
1208
4afa50b3
DO
1209ALIAS (no_ipv6_nd_homeagent_lifetime,
1210 no_ipv6_nd_homeagent_lifetime_val_cmd,
1211 "no ipv6 nd home-agent-lifetime <0-65520>",
1212 NO_STR
1213 "Interface IPv6 config commands\n"
1214 "Neighbor discovery\n"
1215 "Home Agent lifetime\n"
1216 "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
1217
718e3744 1218DEFUN (ipv6_nd_managed_config_flag,
1219 ipv6_nd_managed_config_flag_cmd,
1220 "ipv6 nd managed-config-flag",
3e31cded 1221 "Interface IPv6 config commands\n"
718e3744 1222 "Neighbor discovery\n"
1223 "Managed address configuration flag\n")
1224{
1225 struct interface *ifp;
1226 struct zebra_if *zif;
1227
1228 ifp = (struct interface *) vty->index;
1229 zif = ifp->info;
1230
1231 zif->rtadv.AdvManagedFlag = 1;
1232
1233 return CMD_SUCCESS;
1234}
1235
1236DEFUN (no_ipv6_nd_managed_config_flag,
1237 no_ipv6_nd_managed_config_flag_cmd,
1238 "no ipv6 nd managed-config-flag",
1239 NO_STR
3e31cded 1240 "Interface IPv6 config commands\n"
718e3744 1241 "Neighbor discovery\n"
1242 "Managed address configuration flag\n")
1243{
1244 struct interface *ifp;
1245 struct zebra_if *zif;
1246
1247 ifp = (struct interface *) vty->index;
1248 zif = ifp->info;
1249
1250 zif->rtadv.AdvManagedFlag = 0;
1251
1252 return CMD_SUCCESS;
1253}
1254
7cee1bb1 1255DEFUN (ipv6_nd_homeagent_config_flag,
1256 ipv6_nd_homeagent_config_flag_cmd,
1257 "ipv6 nd home-agent-config-flag",
1258 "Interface IPv6 config commands\n"
1259 "Neighbor discovery\n"
1260 "Home Agent configuration flag\n")
1261{
1262 struct interface *ifp;
1263 struct zebra_if *zif;
1264
1265 ifp = (struct interface *) vty->index;
1266 zif = ifp->info;
1267
1268 zif->rtadv.AdvHomeAgentFlag = 1;
1269
1270 return CMD_SUCCESS;
1271}
1272
1273DEFUN (no_ipv6_nd_homeagent_config_flag,
1274 no_ipv6_nd_homeagent_config_flag_cmd,
1275 "no ipv6 nd home-agent-config-flag",
1276 NO_STR
1277 "Interface IPv6 config commands\n"
1278 "Neighbor discovery\n"
1279 "Home Agent configuration flag\n")
1280{
1281 struct interface *ifp;
1282 struct zebra_if *zif;
1283
1284 ifp = (struct interface *) vty->index;
1285 zif = ifp->info;
1286
1287 zif->rtadv.AdvHomeAgentFlag = 0;
1288
1289 return CMD_SUCCESS;
1290}
1291
1292DEFUN (ipv6_nd_adv_interval_config_option,
1293 ipv6_nd_adv_interval_config_option_cmd,
1294 "ipv6 nd adv-interval-option",
1295 "Interface IPv6 config commands\n"
1296 "Neighbor discovery\n"
1297 "Advertisement Interval Option\n")
1298{
1299 struct interface *ifp;
1300 struct zebra_if *zif;
1301
1302 ifp = (struct interface *) vty->index;
1303 zif = ifp->info;
1304
1305 zif->rtadv.AdvIntervalOption = 1;
1306
1307 return CMD_SUCCESS;
1308}
1309
1310DEFUN (no_ipv6_nd_adv_interval_config_option,
1311 no_ipv6_nd_adv_interval_config_option_cmd,
1312 "no ipv6 nd adv-interval-option",
1313 NO_STR
1314 "Interface IPv6 config commands\n"
1315 "Neighbor discovery\n"
1316 "Advertisement Interval Option\n")
1317{
1318 struct interface *ifp;
1319 struct zebra_if *zif;
1320
1321 ifp = (struct interface *) vty->index;
1322 zif = ifp->info;
1323
1324 zif->rtadv.AdvIntervalOption = 0;
1325
1326 return CMD_SUCCESS;
1327}
1328
718e3744 1329DEFUN (ipv6_nd_other_config_flag,
1330 ipv6_nd_other_config_flag_cmd,
1331 "ipv6 nd other-config-flag",
3e31cded 1332 "Interface IPv6 config commands\n"
718e3744 1333 "Neighbor discovery\n"
1334 "Other statefull configuration flag\n")
1335{
1336 struct interface *ifp;
1337 struct zebra_if *zif;
1338
1339 ifp = (struct interface *) vty->index;
1340 zif = ifp->info;
1341
1342 zif->rtadv.AdvOtherConfigFlag = 1;
1343
1344 return CMD_SUCCESS;
1345}
1346
1347DEFUN (no_ipv6_nd_other_config_flag,
1348 no_ipv6_nd_other_config_flag_cmd,
1349 "no ipv6 nd other-config-flag",
1350 NO_STR
3e31cded 1351 "Interface IPv6 config commands\n"
718e3744 1352 "Neighbor discovery\n"
1353 "Other statefull configuration flag\n")
1354{
1355 struct interface *ifp;
1356 struct zebra_if *zif;
1357
1358 ifp = (struct interface *) vty->index;
1359 zif = ifp->info;
1360
1361 zif->rtadv.AdvOtherConfigFlag = 0;
1362
1363 return CMD_SUCCESS;
1364}
1365
3e31cded 1366DEFUN (ipv6_nd_prefix,
1367 ipv6_nd_prefix_cmd,
1368 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
7cee1bb1 1369 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
3e31cded 1370 "Interface IPv6 config commands\n"
718e3744 1371 "Neighbor discovery\n"
1372 "Prefix information\n"
1373 "IPv6 prefix\n"
1374 "Valid lifetime in seconds\n"
3e31cded 1375 "Infinite valid lifetime\n"
718e3744 1376 "Preferred lifetime in seconds\n"
3e31cded 1377 "Infinite preferred lifetime\n"
1378 "Do not use prefix for onlink determination\n"
7cee1bb1 1379 "Do not use prefix for autoconfiguration\n"
1380 "Set Router Address flag\n")
718e3744 1381{
1382 int i;
1383 int ret;
3e31cded 1384 int cursor = 1;
718e3744 1385 struct interface *ifp;
1386 struct zebra_if *zebra_if;
1387 struct rtadv_prefix rp;
1388
1389 ifp = (struct interface *) vty->index;
1390 zebra_if = ifp->info;
1391
aca43b65 1392 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
718e3744 1393 if (!ret)
1394 {
1395 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1396 return CMD_WARNING;
1397 }
6bb1273e 1398 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
3e31cded 1399 rp.AdvOnLinkFlag = 1;
1400 rp.AdvAutonomousFlag = 1;
7cee1bb1 1401 rp.AdvRouterAddressFlag = 0;
3e31cded 1402 rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
1403 rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
718e3744 1404
3e31cded 1405 if (argc > 1)
718e3744 1406 {
27b87393
DL
1407 if ((isdigit((unsigned char)argv[1][0]))
1408 || strncmp (argv[1], "i", 1) == 0)
718e3744 1409 {
3e31cded 1410 if ( strncmp (argv[1], "i", 1) == 0)
1411 rp.AdvValidLifetime = UINT32_MAX;
1412 else
1413 rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
1414 (char **)NULL, 10);
1415
1416 if ( strncmp (argv[2], "i", 1) == 0)
1417 rp.AdvPreferredLifetime = UINT32_MAX;
1418 else
1419 rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
1420 (char **)NULL, 10);
1421
1422 if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
1423 {
1424 vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
1425 return CMD_WARNING;
1426 }
1427 cursor = cursor + 2;
718e3744 1428 }
3e31cded 1429 if (argc > cursor)
718e3744 1430 {
3e31cded 1431 for (i = cursor; i < argc; i++)
1432 {
1433 if (strncmp (argv[i], "of", 2) == 0)
1434 rp.AdvOnLinkFlag = 0;
1435 if (strncmp (argv[i], "no", 2) == 0)
1436 rp.AdvAutonomousFlag = 0;
7cee1bb1 1437 if (strncmp (argv[i], "ro", 2) == 0)
1438 rp.AdvRouterAddressFlag = 1;
3e31cded 1439 }
718e3744 1440 }
1441 }
1442
1443 rtadv_prefix_set (zebra_if, &rp);
1444
1445 return CMD_SUCCESS;
1446}
1447
7cee1bb1 1448ALIAS (ipv6_nd_prefix,
1449 ipv6_nd_prefix_val_nortaddr_cmd,
1450 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1451 "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
1452 "Interface IPv6 config commands\n"
1453 "Neighbor discovery\n"
1454 "Prefix information\n"
1455 "IPv6 prefix\n"
1456 "Valid lifetime in seconds\n"
1457 "Infinite valid lifetime\n"
1458 "Preferred lifetime in seconds\n"
1459 "Infinite preferred lifetime\n"
1460 "Do not use prefix for onlink determination\n"
1461 "Do not use prefix for autoconfiguration\n")
1462
3e31cded 1463ALIAS (ipv6_nd_prefix,
1464 ipv6_nd_prefix_val_rev_cmd,
1465 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1466 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1467 "Interface IPv6 config commands\n"
1468 "Neighbor discovery\n"
1469 "Prefix information\n"
1470 "IPv6 prefix\n"
1471 "Valid lifetime in seconds\n"
1472 "Infinite valid lifetime\n"
1473 "Preferred lifetime in seconds\n"
1474 "Infinite preferred lifetime\n"
1475 "Do not use prefix for autoconfiguration\n"
1476 "Do not use prefix for onlink determination\n")
1477
7cee1bb1 1478ALIAS (ipv6_nd_prefix,
1479 ipv6_nd_prefix_val_rev_rtaddr_cmd,
1480 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1481 "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1482 "Interface IPv6 config commands\n"
1483 "Neighbor discovery\n"
1484 "Prefix information\n"
1485 "IPv6 prefix\n"
1486 "Valid lifetime in seconds\n"
1487 "Infinite valid lifetime\n"
1488 "Preferred lifetime in seconds\n"
1489 "Infinite preferred lifetime\n"
1490 "Do not use prefix for autoconfiguration\n"
1491 "Do not use prefix for onlink determination\n"
1492 "Set Router Address flag\n")
1493
3e31cded 1494ALIAS (ipv6_nd_prefix,
1495 ipv6_nd_prefix_val_noauto_cmd,
1496 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1497 "(<0-4294967295>|infinite) (no-autoconfig|)",
1498 "Interface IPv6 config commands\n"
1499 "Neighbor discovery\n"
1500 "Prefix information\n"
1501 "IPv6 prefix\n"
1502 "Valid lifetime in seconds\n"
1503 "Infinite valid lifetime\n"
1504 "Preferred lifetime in seconds\n"
1505 "Infinite preferred lifetime\n"
7cee1bb1 1506 "Do not use prefix for autoconfiguration")
3e31cded 1507
1508ALIAS (ipv6_nd_prefix,
1509 ipv6_nd_prefix_val_offlink_cmd,
1510 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1511 "(<0-4294967295>|infinite) (off-link|)",
1512 "Interface IPv6 config commands\n"
1513 "Neighbor discovery\n"
1514 "Prefix information\n"
1515 "IPv6 prefix\n"
1516 "Valid lifetime in seconds\n"
1517 "Infinite valid lifetime\n"
1518 "Preferred lifetime in seconds\n"
1519 "Infinite preferred lifetime\n"
1520 "Do not use prefix for onlink determination\n")
1521
7cee1bb1 1522ALIAS (ipv6_nd_prefix,
1523 ipv6_nd_prefix_val_rtaddr_cmd,
1524 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1525 "(<0-4294967295>|infinite) (router-address|)",
1526 "Interface IPv6 config commands\n"
1527 "Neighbor discovery\n"
1528 "Prefix information\n"
1529 "IPv6 prefix\n"
1530 "Valid lifetime in seconds\n"
1531 "Infinite valid lifetime\n"
1532 "Preferred lifetime in seconds\n"
1533 "Infinite preferred lifetime\n"
1534 "Set Router Address flag\n")
1535
3e31cded 1536ALIAS (ipv6_nd_prefix,
1537 ipv6_nd_prefix_val_cmd,
1538 "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
1539 "(<0-4294967295>|infinite)",
1540 "Interface IPv6 config commands\n"
1541 "Neighbor discovery\n"
1542 "Prefix information\n"
1543 "IPv6 prefix\n"
1544 "Valid lifetime in seconds\n"
1545 "Infinite valid lifetime\n"
1546 "Preferred lifetime in seconds\n"
1547 "Infinite preferred lifetime\n")
1548
1549ALIAS (ipv6_nd_prefix,
1550 ipv6_nd_prefix_noval_cmd,
1551 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1552 "Interface IPv6 config commands\n"
1553 "Neighbor discovery\n"
1554 "Prefix information\n"
1555 "IPv6 prefix\n"
1556 "Do not use prefix for autoconfiguration\n"
1557 "Do not use prefix for onlink determination\n")
1558
1559ALIAS (ipv6_nd_prefix,
1560 ipv6_nd_prefix_noval_rev_cmd,
1561 "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1562 "Interface IPv6 config commands\n"
1563 "Neighbor discovery\n"
1564 "Prefix information\n"
1565 "IPv6 prefix\n"
1566 "Do not use prefix for onlink determination\n"
1567 "Do not use prefix for autoconfiguration\n")
1568
1569ALIAS (ipv6_nd_prefix,
1570 ipv6_nd_prefix_noval_noauto_cmd,
1571 "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1572 "Interface IPv6 config commands\n"
1573 "Neighbor discovery\n"
1574 "Prefix information\n"
1575 "IPv6 prefix\n"
1576 "Do not use prefix for autoconfiguration\n")
1577
1578ALIAS (ipv6_nd_prefix,
1579 ipv6_nd_prefix_noval_offlink_cmd,
1580 "ipv6 nd prefix X:X::X:X/M (off-link|)",
1581 "Interface IPv6 config commands\n"
1582 "Neighbor discovery\n"
1583 "Prefix information\n"
1584 "IPv6 prefix\n"
1585 "Do not use prefix for onlink determination\n")
1586
7cee1bb1 1587ALIAS (ipv6_nd_prefix,
1588 ipv6_nd_prefix_noval_rtaddr_cmd,
1589 "ipv6 nd prefix X:X::X:X/M (router-address|)",
1590 "Interface IPv6 config commands\n"
1591 "Neighbor discovery\n"
1592 "Prefix information\n"
1593 "IPv6 prefix\n"
1594 "Set Router Address flag\n")
1595
3e31cded 1596ALIAS (ipv6_nd_prefix,
1597 ipv6_nd_prefix_prefix_cmd,
1598 "ipv6 nd prefix X:X::X:X/M",
1599 "Interface IPv6 config commands\n"
718e3744 1600 "Neighbor discovery\n"
1601 "Prefix information\n"
1602 "IPv6 prefix\n")
1603
3e31cded 1604DEFUN (no_ipv6_nd_prefix,
1605 no_ipv6_nd_prefix_cmd,
1606 "no ipv6 nd prefix IPV6PREFIX",
718e3744 1607 NO_STR
3e31cded 1608 "Interface IPv6 config commands\n"
718e3744 1609 "Neighbor discovery\n"
1610 "Prefix information\n"
1611 "IPv6 prefix\n")
1612{
1613 int ret;
1614 struct interface *ifp;
1615 struct zebra_if *zebra_if;
1616 struct rtadv_prefix rp;
1617
1618 ifp = (struct interface *) vty->index;
1619 zebra_if = ifp->info;
1620
aca43b65 1621 ret = str2prefix_ipv6 (argv[0], &rp.prefix);
718e3744 1622 if (!ret)
1623 {
1624 vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
1625 return CMD_WARNING;
1626 }
6bb1273e 1627 apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
718e3744 1628
1629 ret = rtadv_prefix_reset (zebra_if, &rp);
1630 if (!ret)
1631 {
1632 vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
1633 return CMD_WARNING;
1634 }
1635
1636 return CMD_SUCCESS;
1637}
b60668d0 1638
813d4307
DW
1639ALIAS (no_ipv6_nd_prefix,
1640 no_ipv6_nd_prefix_val_nortaddr_cmd,
1641 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
1642 NO_STR
1643 "Interface IPv6 config commands\n"
1644 "Neighbor discovery\n"
1645 "Prefix information\n"
1646 "IPv6 prefix\n"
1647 "Valid lifetime in seconds\n"
1648 "Infinite valid lifetime\n"
1649 "Preferred lifetime in seconds\n"
1650 "Infinite preferred lifetime\n"
1651 "Do not use prefix for onlink determination\n"
1652 "Do not use prefix for autoconfiguration\n"
1653 "Set Router Address flag\n")
1654
1655ALIAS (no_ipv6_nd_prefix,
1656 no_ipv6_nd_prefix_val_rev_cmd,
1657 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
1658 NO_STR
1659 "Interface IPv6 config commands\n"
1660 "Neighbor discovery\n"
1661 "Prefix information\n"
1662 "IPv6 prefix\n"
1663 "Valid lifetime in seconds\n"
1664 "Infinite valid lifetime\n"
1665 "Preferred lifetime in seconds\n"
1666 "Infinite preferred lifetime\n"
1667 "Do not use prefix for autoconfiguration\n"
1668 "Do not use prefix for onlink determination\n")
1669
1670ALIAS (no_ipv6_nd_prefix,
1671 no_ipv6_nd_prefix_val_rev_rtaddr_cmd,
1672 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
1673 NO_STR
1674 "Interface IPv6 config commands\n"
1675 "Neighbor discovery\n"
1676 "Prefix information\n"
1677 "IPv6 prefix\n"
1678 "Valid lifetime in seconds\n"
1679 "Infinite valid lifetime\n"
1680 "Preferred lifetime in seconds\n"
1681 "Infinite preferred lifetime\n"
1682 "Do not use prefix for autoconfiguration\n"
1683 "Do not use prefix for onlink determination\n"
1684 "Set Router Address flag\n")
1685
1686ALIAS (no_ipv6_nd_prefix,
1687 no_ipv6_nd_prefix_val_noauto_cmd,
1688 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (no-autoconfig|)",
1689 NO_STR
1690 "Interface IPv6 config commands\n"
1691 "Neighbor discovery\n"
1692 "Prefix information\n"
1693 "IPv6 prefix\n"
1694 "Valid lifetime in seconds\n"
1695 "Infinite valid lifetime\n"
1696 "Preferred lifetime in seconds\n"
1697 "Infinite preferred lifetime\n"
1698 "Do not use prefix for autoconfiguration")
1699
1700ALIAS (no_ipv6_nd_prefix,
1701 no_ipv6_nd_prefix_val_offlink_cmd,
1702 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (off-link|)",
1703 NO_STR
1704 "Interface IPv6 config commands\n"
1705 "Neighbor discovery\n"
1706 "Prefix information\n"
1707 "IPv6 prefix\n"
1708 "Valid lifetime in seconds\n"
1709 "Infinite valid lifetime\n"
1710 "Preferred lifetime in seconds\n"
1711 "Infinite preferred lifetime\n"
1712 "Do not use prefix for onlink determination\n")
1713
1714ALIAS (no_ipv6_nd_prefix,
1715 no_ipv6_nd_prefix_val_rtaddr_cmd,
1716 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite) (router-address|)",
1717 NO_STR
1718 "Interface IPv6 config commands\n"
1719 "Neighbor discovery\n"
1720 "Prefix information\n"
1721 "IPv6 prefix\n"
1722 "Valid lifetime in seconds\n"
1723 "Infinite valid lifetime\n"
1724 "Preferred lifetime in seconds\n"
1725 "Infinite preferred lifetime\n"
1726 "Set Router Address flag\n")
1727
1728ALIAS (no_ipv6_nd_prefix,
1729 no_ipv6_nd_prefix_val_cmd,
1730 "no ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) (<0-4294967295>|infinite)",
1731 NO_STR
1732 "Interface IPv6 config commands\n"
1733 "Neighbor discovery\n"
1734 "Prefix information\n"
1735 "IPv6 prefix\n"
1736 "Valid lifetime in seconds\n"
1737 "Infinite valid lifetime\n"
1738 "Preferred lifetime in seconds\n"
1739 "Infinite preferred lifetime\n")
1740
1741ALIAS (no_ipv6_nd_prefix,
1742 no_ipv6_nd_prefix_noval_cmd,
1743 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
1744 NO_STR
1745 "Interface IPv6 config commands\n"
1746 "Neighbor discovery\n"
1747 "Prefix information\n"
1748 "IPv6 prefix\n"
1749 "Do not use prefix for autoconfiguration\n"
1750 "Do not use prefix for onlink determination\n")
1751
1752ALIAS (no_ipv6_nd_prefix,
1753 no_ipv6_nd_prefix_noval_rev_cmd,
1754 "no ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
1755 NO_STR
1756 "Interface IPv6 config commands\n"
1757 "Neighbor discovery\n"
1758 "Prefix information\n"
1759 "IPv6 prefix\n"
1760 "Do not use prefix for onlink determination\n"
1761 "Do not use prefix for autoconfiguration\n")
1762
1763ALIAS (no_ipv6_nd_prefix,
1764 no_ipv6_nd_prefix_noval_noauto_cmd,
1765 "no ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
1766 NO_STR
1767 "Interface IPv6 config commands\n"
1768 "Neighbor discovery\n"
1769 "Prefix information\n"
1770 "IPv6 prefix\n"
1771 "Do not use prefix for autoconfiguration\n")
1772
1773ALIAS (no_ipv6_nd_prefix,
1774 no_ipv6_nd_prefix_noval_offlink_cmd,
1775 "no ipv6 nd prefix X:X::X:X/M (off-link|)",
1776 NO_STR
1777 "Interface IPv6 config commands\n"
1778 "Neighbor discovery\n"
1779 "Prefix information\n"
1780 "IPv6 prefix\n"
1781 "Do not use prefix for onlink determination\n")
1782
1783ALIAS (no_ipv6_nd_prefix,
1784 no_ipv6_nd_prefix_noval_rtaddr_cmd,
1785 "no ipv6 nd prefix X:X::X:X/M (router-address|)",
1786 NO_STR
1787 "Interface IPv6 config commands\n"
1788 "Neighbor discovery\n"
1789 "Prefix information\n"
1790 "IPv6 prefix\n"
1791 "Set Router Address flag\n")
1792
b60668d0
CC
1793DEFUN (ipv6_nd_router_preference,
1794 ipv6_nd_router_preference_cmd,
1795 "ipv6 nd router-preference (high|medium|low)",
1796 "Interface IPv6 config commands\n"
1797 "Neighbor discovery\n"
1798 "Default router preference\n"
1799 "High default router preference\n"
1800 "Low default router preference\n"
1801 "Medium default router preference (default)\n")
1802{
1803 struct interface *ifp;
1804 struct zebra_if *zif;
1805 int i = 0;
1806
1807 ifp = (struct interface *) vty->index;
1808 zif = ifp->info;
1809
1810 while (0 != rtadv_pref_strs[i])
1811 {
1812 if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
1813 {
1814 zif->rtadv.DefaultPreference = i;
1815 return CMD_SUCCESS;
1816 }
1817 i++;
1818 }
1819
1820 return CMD_ERR_NO_MATCH;
1821}
1822
1823DEFUN (no_ipv6_nd_router_preference,
1824 no_ipv6_nd_router_preference_cmd,
1825 "no ipv6 nd router-preference",
1826 NO_STR
1827 "Interface IPv6 config commands\n"
1828 "Neighbor discovery\n"
1829 "Default router preference\n")
1830{
1831 struct interface *ifp;
1832 struct zebra_if *zif;
1833
1834 ifp = (struct interface *) vty->index;
1835 zif = ifp->info;
1836
1837 zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
1838
1839 return CMD_SUCCESS;
1840}
1841
4afa50b3
DO
1842ALIAS (no_ipv6_nd_router_preference,
1843 no_ipv6_nd_router_preference_val_cmd,
2b00515a 1844 "no ipv6 nd router-preference (high|medium|low)",
4afa50b3
DO
1845 NO_STR
1846 "Interface IPv6 config commands\n"
1847 "Neighbor discovery\n"
1848 "Default router preference\n"
1849 "High default router preference\n"
1850 "Low default router preference\n"
1851 "Medium default router preference (default)\n")
1852
6ae93c05
DO
1853DEFUN (ipv6_nd_mtu,
1854 ipv6_nd_mtu_cmd,
1855 "ipv6 nd mtu <1-65535>",
1856 "Interface IPv6 config commands\n"
1857 "Neighbor discovery\n"
1858 "Advertised MTU\n"
1859 "MTU in bytes\n")
1860{
1861 struct interface *ifp = (struct interface *) vty->index;
1862 struct zebra_if *zif = ifp->info;
1863 VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
1864 return CMD_SUCCESS;
1865}
1866
1867DEFUN (no_ipv6_nd_mtu,
1868 no_ipv6_nd_mtu_cmd,
1869 "no ipv6 nd mtu",
1870 NO_STR
1871 "Interface IPv6 config commands\n"
1872 "Neighbor discovery\n"
1873 "Advertised MTU\n")
1874{
1875 struct interface *ifp = (struct interface *) vty->index;
1876 struct zebra_if *zif = ifp->info;
1877 zif->rtadv.AdvLinkMTU = 0;
1878 return CMD_SUCCESS;
1879}
1880
1881ALIAS (no_ipv6_nd_mtu,
1882 no_ipv6_nd_mtu_val_cmd,
1883 "no ipv6 nd mtu <1-65535>",
1884 NO_STR
1885 "Interface IPv6 config commands\n"
1886 "Neighbor discovery\n"
1887 "Advertised MTU\n"
1888 "MTU in bytes\n")
1889
718e3744 1890/* Write configuration about router advertisement. */
1891void
1892rtadv_config_write (struct vty *vty, struct interface *ifp)
1893{
1894 struct zebra_if *zif;
52dc7ee6 1895 struct listnode *node;
718e3744 1896 struct rtadv_prefix *rprefix;
35d921cc 1897 char buf[PREFIX_STRLEN];
7cee1bb1 1898 int interval;
718e3744 1899
718e3744 1900 zif = ifp->info;
1901
c23af4d3 1902 if (!(if_is_loopback (ifp) ||
1903 CHECK_FLAG(ifp->status, ZEBRA_INTERFACE_VRF_LOOPBACK)))
718e3744 1904 {
c5b37afc 1905 if (zif->rtadv.AdvSendAdvertisements)
1906 vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
718e3744 1907 }
7cee1bb1 1908
1909 interval = zif->rtadv.MaxRtrAdvInterval;
1910 if (interval % 1000)
1911 vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
1912 VTY_NEWLINE);
1913 else
1914 if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
1915 vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
718e3744 1916 VTY_NEWLINE);
1917
6134b875
DO
1918 if (zif->rtadv.AdvIntervalOption)
1919 vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
1920
d660f698 1921 if (zif->rtadv.AdvDefaultLifetime != -1)
718e3744 1922 vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
1923 VTY_NEWLINE);
1924
6134b875
DO
1925 if (zif->rtadv.HomeAgentPreference)
1926 vty_out (vty, " ipv6 nd home-agent-preference %u%s",
1927 zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
1928
d660f698 1929 if (zif->rtadv.HomeAgentLifetime != -1)
6134b875
DO
1930 vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
1931 zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
1932
1933 if (zif->rtadv.AdvHomeAgentFlag)
1934 vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
1935
718e3744 1936 if (zif->rtadv.AdvReachableTime)
1937 vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
1938 VTY_NEWLINE);
1939
1940 if (zif->rtadv.AdvManagedFlag)
1941 vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
1942
1943 if (zif->rtadv.AdvOtherConfigFlag)
1944 vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
1945
b60668d0
CC
1946 if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
1947 vty_out (vty, " ipv6 nd router-preference %s%s",
1948 rtadv_pref_strs[zif->rtadv.DefaultPreference],
1949 VTY_NEWLINE);
1950
6ae93c05
DO
1951 if (zif->rtadv.AdvLinkMTU)
1952 vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
1953
1eb8ef25 1954 for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
718e3744 1955 {
35d921cc
TT
1956 vty_out (vty, " ipv6 nd prefix %s",
1957 prefix2str (&rprefix->prefix, buf, sizeof(buf)));
3e31cded 1958 if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
1959 (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
1960 {
1961 if (rprefix->AdvValidLifetime == UINT32_MAX)
1962 vty_out (vty, " infinite");
1963 else
1964 vty_out (vty, " %u", rprefix->AdvValidLifetime);
1965 if (rprefix->AdvPreferredLifetime == UINT32_MAX)
1966 vty_out (vty, " infinite");
1967 else
1968 vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
1969 }
1970 if (!rprefix->AdvOnLinkFlag)
1971 vty_out (vty, " off-link");
1972 if (!rprefix->AdvAutonomousFlag)
1973 vty_out (vty, " no-autoconfig");
7cee1bb1 1974 if (rprefix->AdvRouterAddressFlag)
1975 vty_out (vty, " router-address");
718e3744 1976 vty_out (vty, "%s", VTY_NEWLINE);
1977 }
1978}
1979
718e3744 1980
a1ac18c4 1981static void
43459b1f 1982rtadv_event (struct zebra_ns *zns, enum rtadv_event event, int val)
718e3744 1983{
43459b1f 1984 struct rtadv *rtadv = &zns->rtadv;
cd80d74f 1985
718e3744 1986 switch (event)
1987 {
1988 case RTADV_START:
1989 if (! rtadv->ra_read)
6c9678b4 1990 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
718e3744 1991 if (! rtadv->ra_timer)
6c9678b4
DD
1992 rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
1993 zns, 0);
718e3744 1994 break;
1995 case RTADV_STOP:
1996 if (rtadv->ra_timer)
1997 {
1998 thread_cancel (rtadv->ra_timer);
1999 rtadv->ra_timer = NULL;
2000 }
2001 if (rtadv->ra_read)
2002 {
2003 thread_cancel (rtadv->ra_read);
2004 rtadv->ra_read = NULL;
2005 }
2006 break;
2007 case RTADV_TIMER:
2008 if (! rtadv->ra_timer)
43459b1f 2009 rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zns,
3e31cded 2010 val);
718e3744 2011 break;
7cee1bb1 2012 case RTADV_TIMER_MSEC:
2013 if (! rtadv->ra_timer)
2014 rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
43459b1f 2015 zns, val);
7cee1bb1 2016 break;
718e3744 2017 case RTADV_READ:
2018 if (! rtadv->ra_read)
43459b1f 2019 rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zns, val);
718e3744 2020 break;
2021 default:
2022 break;
2023 }
2024 return;
2025}
2026
2027void
43459b1f 2028rtadv_init (struct zebra_ns *zns)
718e3744 2029{
43459b1f 2030 zns->rtadv.sock = rtadv_make_socket ();
cd80d74f 2031}
718e3744 2032
cd80d74f 2033void
43459b1f 2034rtadv_terminate (struct zebra_ns *zns)
cd80d74f 2035{
43459b1f 2036 rtadv_event (zns, RTADV_STOP, 0);
2037 if (zns->rtadv.sock >= 0)
cd80d74f 2038 {
43459b1f 2039 close (zns->rtadv.sock);
2040 zns->rtadv.sock = -1;
cd80d74f 2041 }
718e3744 2042
43459b1f 2043 zns->rtadv.adv_if_count = 0;
2044 zns->rtadv.adv_msec_if_count = 0;
cd80d74f 2045}
718e3744 2046
cd80d74f
FL
2047void
2048rtadv_cmd_init (void)
2049{
718e3744 2050 install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
2051 install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
718e3744 2052 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
7cee1bb1 2053 install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
718e3744 2054 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
4afa50b3
DO
2055 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
2056 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
718e3744 2057 install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
2058 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
4afa50b3 2059 install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
718e3744 2060 install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
2061 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
4afa50b3 2062 install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
718e3744 2063 install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
2064 install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
2065 install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
2066 install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
7cee1bb1 2067 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
2068 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
2069 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
2070 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
4afa50b3 2071 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
7cee1bb1 2072 install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
2073 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
4afa50b3 2074 install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
7cee1bb1 2075 install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
2076 install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
3e31cded 2077 install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
7cee1bb1 2078 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
2079 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
3e31cded 2080 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
2081 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
2082 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
7cee1bb1 2083 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
3e31cded 2084 install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
2085 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
2086 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
2087 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
2088 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
7cee1bb1 2089 install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
3e31cded 2090 install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
2091 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
813d4307
DW
2092 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_rtaddr_cmd);
2093 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_nortaddr_cmd);
2094 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rev_cmd);
2095 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_noauto_cmd);
2096 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_offlink_cmd);
2097 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_rtaddr_cmd);
2098 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_val_cmd);
2099 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_cmd);
2100 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rev_cmd);
2101 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_noauto_cmd);
2102 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_offlink_cmd);
2103 install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_noval_rtaddr_cmd);
b60668d0
CC
2104 install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
2105 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
4afa50b3 2106 install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
6ae93c05
DO
2107 install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
2108 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
2109 install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
718e3744 2110}
2111
a1ac18c4 2112static int
718e3744 2113if_join_all_router (int sock, struct interface *ifp)
2114{
2115 int ret;
2116
2117 struct ipv6_mreq mreq;
2118
2119 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2120 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2121 mreq.ipv6mr_interface = ifp->ifindex;
2122
2123 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
2124 (char *) &mreq, sizeof mreq);
2125 if (ret < 0)
f360eac0 2126 zlog_warn ("%s(%u): Failed to join group, socket %u error %s",
2127 ifp->name, ifp->ifindex, sock, safe_strerror (errno));
718e3744 2128
f360eac0 2129 if (IS_ZEBRA_DEBUG_EVENT)
2130 zlog_debug ("%s(%u): Join All-Routers multicast group, socket %u",
2131 ifp->name, ifp->ifindex, sock);
718e3744 2132
2133 return 0;
2134}
2135
a1ac18c4 2136static int
718e3744 2137if_leave_all_router (int sock, struct interface *ifp)
2138{
2139 int ret;
2140
2141 struct ipv6_mreq mreq;
2142
2143 memset (&mreq, 0, sizeof (struct ipv6_mreq));
2144 inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
2145 mreq.ipv6mr_interface = ifp->ifindex;
2146
2147 ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
2148 (char *) &mreq, sizeof mreq);
2149 if (ret < 0)
f360eac0 2150 zlog_warn ("%s(%u): Failed to leave group, socket %u error %s",
2151 ifp->name, ifp->ifindex, sock,safe_strerror (errno));
718e3744 2152
f360eac0 2153 if (IS_ZEBRA_DEBUG_EVENT)
2154 zlog_debug ("%s(%u): Leave All-Routers multicast group, socket %u",
2155 ifp->name, ifp->ifindex, sock);
718e3744 2156
2157 return 0;
2158}
2159
2160#else
2161void
43459b1f 2162rtadv_init (struct zebra_ns *zns)
cd80d74f
FL
2163{
2164 /* Empty.*/;
2165}
2166void
43459b1f 2167rtadv_terminate (struct zebra_ns *zns)
cd80d74f
FL
2168{
2169 /* Empty.*/;
2170}
2171void
2172rtadv_cmd_init (void)
718e3744 2173{
2174 /* Empty.*/;
2175}
8da4e946 2176#endif /* HAVE_RTADV && HAVE_IPV6 */