rtadv.c 50 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796
  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. #include <zebra.h>
  23. #include "memory.h"
  24. #include "sockopt.h"
  25. #include "thread.h"
  26. #include "if.h"
  27. #include "log.h"
  28. #include "prefix.h"
  29. #include "linklist.h"
  30. #include "command.h"
  31. #include "privs.h"
  32. #include "vrf.h"
  33. #include "zebra/interface.h"
  34. #include "zebra/rtadv.h"
  35. #include "zebra/debug.h"
  36. #include "zebra/rib.h"
  37. #include "zebra/zserv.h"
  38. extern struct zebra_privs_t zserv_privs;
  39. #if defined (HAVE_IPV6) && defined (HAVE_RTADV)
  40. #ifdef OPEN_BSD
  41. #include <netinet/icmp6.h>
  42. #endif
  43. /* If RFC2133 definition is used. */
  44. #ifndef IPV6_JOIN_GROUP
  45. #define IPV6_JOIN_GROUP IPV6_ADD_MEMBERSHIP
  46. #endif
  47. #ifndef IPV6_LEAVE_GROUP
  48. #define IPV6_LEAVE_GROUP IPV6_DROP_MEMBERSHIP
  49. #endif
  50. #define ALLNODE "ff02::1"
  51. #define ALLROUTER "ff02::2"
  52. extern struct zebra_t zebrad;
  53. enum rtadv_event {RTADV_START, RTADV_STOP, RTADV_TIMER,
  54. RTADV_TIMER_MSEC, RTADV_READ};
  55. static void rtadv_event (struct zebra_vrf *, enum rtadv_event, int);
  56. static int if_join_all_router (int, struct interface *);
  57. static int if_leave_all_router (int, struct interface *);
  58. static int
  59. rtadv_recv_packet (int sock, u_char *buf, int buflen,
  60. struct sockaddr_in6 *from, ifindex_t *ifindex,
  61. int *hoplimit)
  62. {
  63. int ret;
  64. struct msghdr msg;
  65. struct iovec iov;
  66. struct cmsghdr *cmsgptr;
  67. struct in6_addr dst;
  68. char adata[1024];
  69. /* Fill in message and iovec. */
  70. msg.msg_name = (void *) from;
  71. msg.msg_namelen = sizeof (struct sockaddr_in6);
  72. msg.msg_iov = &iov;
  73. msg.msg_iovlen = 1;
  74. msg.msg_control = (void *) adata;
  75. msg.msg_controllen = sizeof adata;
  76. iov.iov_base = buf;
  77. iov.iov_len = buflen;
  78. /* If recvmsg fail return minus value. */
  79. ret = recvmsg (sock, &msg, 0);
  80. if (ret < 0)
  81. return ret;
  82. for (cmsgptr = ZCMSG_FIRSTHDR(&msg); cmsgptr != NULL;
  83. cmsgptr = CMSG_NXTHDR(&msg, cmsgptr))
  84. {
  85. /* I want interface index which this packet comes from. */
  86. if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
  87. cmsgptr->cmsg_type == IPV6_PKTINFO)
  88. {
  89. struct in6_pktinfo *ptr;
  90. ptr = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
  91. *ifindex = ptr->ipi6_ifindex;
  92. memcpy(&dst, &ptr->ipi6_addr, sizeof(ptr->ipi6_addr));
  93. }
  94. /* Incoming packet's hop limit. */
  95. if (cmsgptr->cmsg_level == IPPROTO_IPV6 &&
  96. cmsgptr->cmsg_type == IPV6_HOPLIMIT)
  97. {
  98. int *hoptr = (int *) CMSG_DATA (cmsgptr);
  99. *hoplimit = *hoptr;
  100. }
  101. }
  102. return ret;
  103. }
  104. #define RTADV_MSG_SIZE 4096
  105. /* Send router advertisement packet. */
  106. static void
  107. rtadv_send_packet (int sock, struct interface *ifp)
  108. {
  109. struct msghdr msg;
  110. struct iovec iov;
  111. struct cmsghdr *cmsgptr;
  112. struct in6_pktinfo *pkt;
  113. struct sockaddr_in6 addr;
  114. #ifdef HAVE_STRUCT_SOCKADDR_DL
  115. struct sockaddr_dl *sdl;
  116. #endif /* HAVE_STRUCT_SOCKADDR_DL */
  117. static void *adata = NULL;
  118. unsigned char buf[RTADV_MSG_SIZE];
  119. struct nd_router_advert *rtadv;
  120. int ret;
  121. int len = 0;
  122. struct zebra_if *zif;
  123. struct rtadv_prefix *rprefix;
  124. u_char all_nodes_addr[] = {0xff,0x02,0,0,0,0,0,0,0,0,0,0,0,0,0,1};
  125. struct listnode *node;
  126. u_int16_t pkt_RouterLifetime;
  127. /*
  128. * Allocate control message bufffer. This is dynamic because
  129. * CMSG_SPACE is not guaranteed not to call a function. Note that
  130. * the size will be different on different architectures due to
  131. * differing alignment rules.
  132. */
  133. if (adata == NULL)
  134. {
  135. /* XXX Free on shutdown. */
  136. adata = malloc(CMSG_SPACE(sizeof(struct in6_pktinfo)));
  137. if (adata == NULL)
  138. zlog_err("rtadv_send_packet: can't malloc control data\n");
  139. }
  140. /* Logging of packet. */
  141. if (IS_ZEBRA_DEBUG_PACKET)
  142. zlog_debug ("Router advertisement send to %s", ifp->name);
  143. /* Fill in sockaddr_in6. */
  144. memset (&addr, 0, sizeof (struct sockaddr_in6));
  145. addr.sin6_family = AF_INET6;
  146. #ifdef SIN6_LEN
  147. addr.sin6_len = sizeof (struct sockaddr_in6);
  148. #endif /* SIN6_LEN */
  149. addr.sin6_port = htons (IPPROTO_ICMPV6);
  150. IPV6_ADDR_COPY (&addr.sin6_addr, all_nodes_addr);
  151. /* Fetch interface information. */
  152. zif = ifp->info;
  153. /* Make router advertisement message. */
  154. rtadv = (struct nd_router_advert *) buf;
  155. rtadv->nd_ra_type = ND_ROUTER_ADVERT;
  156. rtadv->nd_ra_code = 0;
  157. rtadv->nd_ra_cksum = 0;
  158. rtadv->nd_ra_curhoplimit = 64;
  159. /* RFC4191: Default Router Preference is 0 if Router Lifetime is 0. */
  160. rtadv->nd_ra_flags_reserved =
  161. zif->rtadv.AdvDefaultLifetime == 0 ? 0 : zif->rtadv.DefaultPreference;
  162. rtadv->nd_ra_flags_reserved <<= 3;
  163. if (zif->rtadv.AdvManagedFlag)
  164. rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_MANAGED;
  165. if (zif->rtadv.AdvOtherConfigFlag)
  166. rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_OTHER;
  167. if (zif->rtadv.AdvHomeAgentFlag)
  168. rtadv->nd_ra_flags_reserved |= ND_RA_FLAG_HOME_AGENT;
  169. /* Note that according to Neighbor Discovery (RFC 4861 [18]),
  170. * AdvDefaultLifetime is by default based on the value of
  171. * MaxRtrAdvInterval. AdvDefaultLifetime is used in the Router Lifetime
  172. * field of Router Advertisements. Given that this field is expressed
  173. * in seconds, a small MaxRtrAdvInterval value can result in a zero
  174. * value for this field. To prevent this, routers SHOULD keep
  175. * AdvDefaultLifetime in at least one second, even if the use of
  176. * MaxRtrAdvInterval would result in a smaller value. -- RFC6275, 7.5 */
  177. pkt_RouterLifetime = zif->rtadv.AdvDefaultLifetime != -1 ?
  178. zif->rtadv.AdvDefaultLifetime :
  179. MAX (1, 0.003 * zif->rtadv.MaxRtrAdvInterval);
  180. rtadv->nd_ra_router_lifetime = htons (pkt_RouterLifetime);
  181. rtadv->nd_ra_reachable = htonl (zif->rtadv.AdvReachableTime);
  182. rtadv->nd_ra_retransmit = htonl (0);
  183. len = sizeof (struct nd_router_advert);
  184. /* If both the Home Agent Preference and Home Agent Lifetime are set to
  185. * their default values specified above, this option SHOULD NOT be
  186. * included in the Router Advertisement messages sent by this home
  187. * agent. -- RFC6275, 7.4 */
  188. if
  189. (
  190. zif->rtadv.AdvHomeAgentFlag &&
  191. (zif->rtadv.HomeAgentPreference || zif->rtadv.HomeAgentLifetime != -1)
  192. )
  193. {
  194. struct nd_opt_homeagent_info *ndopt_hai =
  195. (struct nd_opt_homeagent_info *)(buf + len);
  196. ndopt_hai->nd_opt_hai_type = ND_OPT_HA_INFORMATION;
  197. ndopt_hai->nd_opt_hai_len = 1;
  198. ndopt_hai->nd_opt_hai_reserved = 0;
  199. ndopt_hai->nd_opt_hai_preference = htons(zif->rtadv.HomeAgentPreference);
  200. /* 16-bit unsigned integer. The lifetime associated with the home
  201. * agent in units of seconds. The default value is the same as the
  202. * Router Lifetime, as specified in the main body of the Router
  203. * Advertisement. The maximum value corresponds to 18.2 hours. A
  204. * value of 0 MUST NOT be used. -- RFC6275, 7.5 */
  205. ndopt_hai->nd_opt_hai_lifetime = htons
  206. (
  207. zif->rtadv.HomeAgentLifetime != -1 ?
  208. zif->rtadv.HomeAgentLifetime :
  209. MAX (1, pkt_RouterLifetime) /* 0 is OK for RL, but not for HAL*/
  210. );
  211. len += sizeof(struct nd_opt_homeagent_info);
  212. }
  213. if (zif->rtadv.AdvIntervalOption)
  214. {
  215. struct nd_opt_adv_interval *ndopt_adv =
  216. (struct nd_opt_adv_interval *)(buf + len);
  217. ndopt_adv->nd_opt_ai_type = ND_OPT_ADV_INTERVAL;
  218. ndopt_adv->nd_opt_ai_len = 1;
  219. ndopt_adv->nd_opt_ai_reserved = 0;
  220. ndopt_adv->nd_opt_ai_interval = htonl(zif->rtadv.MaxRtrAdvInterval);
  221. len += sizeof(struct nd_opt_adv_interval);
  222. }
  223. /* Fill in prefix. */
  224. for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
  225. {
  226. struct nd_opt_prefix_info *pinfo;
  227. pinfo = (struct nd_opt_prefix_info *) (buf + len);
  228. pinfo->nd_opt_pi_type = ND_OPT_PREFIX_INFORMATION;
  229. pinfo->nd_opt_pi_len = 4;
  230. pinfo->nd_opt_pi_prefix_len = rprefix->prefix.prefixlen;
  231. pinfo->nd_opt_pi_flags_reserved = 0;
  232. if (rprefix->AdvOnLinkFlag)
  233. pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_ONLINK;
  234. if (rprefix->AdvAutonomousFlag)
  235. pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_AUTO;
  236. if (rprefix->AdvRouterAddressFlag)
  237. pinfo->nd_opt_pi_flags_reserved |= ND_OPT_PI_FLAG_RADDR;
  238. pinfo->nd_opt_pi_valid_time = htonl (rprefix->AdvValidLifetime);
  239. pinfo->nd_opt_pi_preferred_time = htonl (rprefix->AdvPreferredLifetime);
  240. pinfo->nd_opt_pi_reserved2 = 0;
  241. IPV6_ADDR_COPY (&pinfo->nd_opt_pi_prefix, &rprefix->prefix.prefix);
  242. #ifdef DEBUG
  243. {
  244. u_char buf[INET6_ADDRSTRLEN];
  245. zlog_debug ("DEBUG %s", inet_ntop (AF_INET6, &pinfo->nd_opt_pi_prefix,
  246. buf, INET6_ADDRSTRLEN));
  247. }
  248. #endif /* DEBUG */
  249. len += sizeof (struct nd_opt_prefix_info);
  250. }
  251. /* Hardware address. */
  252. if (ifp->hw_addr_len != 0)
  253. {
  254. buf[len++] = ND_OPT_SOURCE_LINKADDR;
  255. /* Option length should be rounded up to next octet if
  256. the link address does not end on an octet boundary. */
  257. buf[len++] = (ifp->hw_addr_len + 9) >> 3;
  258. memcpy (buf + len, ifp->hw_addr, ifp->hw_addr_len);
  259. len += ifp->hw_addr_len;
  260. /* Pad option to end on an octet boundary. */
  261. memset (buf + len, 0, -(ifp->hw_addr_len + 2) & 0x7);
  262. len += -(ifp->hw_addr_len + 2) & 0x7;
  263. }
  264. /* MTU */
  265. if (zif->rtadv.AdvLinkMTU)
  266. {
  267. struct nd_opt_mtu * opt = (struct nd_opt_mtu *) (buf + len);
  268. opt->nd_opt_mtu_type = ND_OPT_MTU;
  269. opt->nd_opt_mtu_len = 1;
  270. opt->nd_opt_mtu_reserved = 0;
  271. opt->nd_opt_mtu_mtu = htonl (zif->rtadv.AdvLinkMTU);
  272. len += sizeof (struct nd_opt_mtu);
  273. }
  274. msg.msg_name = (void *) &addr;
  275. msg.msg_namelen = sizeof (struct sockaddr_in6);
  276. msg.msg_iov = &iov;
  277. msg.msg_iovlen = 1;
  278. msg.msg_control = (void *) adata;
  279. msg.msg_controllen = CMSG_SPACE(sizeof(struct in6_pktinfo));
  280. msg.msg_flags = 0;
  281. iov.iov_base = buf;
  282. iov.iov_len = len;
  283. cmsgptr = ZCMSG_FIRSTHDR(&msg);
  284. cmsgptr->cmsg_len = CMSG_LEN(sizeof(struct in6_pktinfo));
  285. cmsgptr->cmsg_level = IPPROTO_IPV6;
  286. cmsgptr->cmsg_type = IPV6_PKTINFO;
  287. pkt = (struct in6_pktinfo *) CMSG_DATA (cmsgptr);
  288. memset (&pkt->ipi6_addr, 0, sizeof (struct in6_addr));
  289. pkt->ipi6_ifindex = ifp->ifindex;
  290. ret = sendmsg (sock, &msg, 0);
  291. if (ret < 0)
  292. {
  293. zlog_err ("rtadv_send_packet: sendmsg %d (%s)\n",
  294. errno, safe_strerror(errno));
  295. }
  296. }
  297. static int
  298. rtadv_timer (struct thread *thread)
  299. {
  300. struct zebra_vrf *zvrf = THREAD_ARG (thread);
  301. struct listnode *node, *nnode;
  302. struct interface *ifp;
  303. struct zebra_if *zif;
  304. int period;
  305. zvrf->rtadv.ra_timer = NULL;
  306. if (zvrf->rtadv.adv_msec_if_count == 0)
  307. {
  308. period = 1000; /* 1 s */
  309. rtadv_event (zvrf, RTADV_TIMER, 1 /* 1 s */);
  310. }
  311. else
  312. {
  313. period = 10; /* 10 ms */
  314. rtadv_event (zvrf, RTADV_TIMER_MSEC, 10 /* 10 ms */);
  315. }
  316. for (ALL_LIST_ELEMENTS (vrf_iflist (zvrf->vrf_id), node, nnode, ifp))
  317. {
  318. if (if_is_loopback (ifp) || ! if_is_operative (ifp))
  319. continue;
  320. zif = ifp->info;
  321. if (zif->rtadv.AdvSendAdvertisements)
  322. {
  323. zif->rtadv.AdvIntervalTimer -= period;
  324. if (zif->rtadv.AdvIntervalTimer <= 0)
  325. {
  326. /* FIXME: using MaxRtrAdvInterval each time isn't what section
  327. 6.2.4 of RFC4861 tells to do. */
  328. zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
  329. rtadv_send_packet (zvrf->rtadv.sock, ifp);
  330. }
  331. }
  332. }
  333. return 0;
  334. }
  335. static void
  336. rtadv_process_solicit (struct interface *ifp)
  337. {
  338. struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
  339. zlog_info ("Router solicitation received on %s vrf %u", ifp->name, zvrf->vrf_id);
  340. rtadv_send_packet (zvrf->rtadv.sock, ifp);
  341. }
  342. static void
  343. rtadv_process_advert (void)
  344. {
  345. zlog_info ("Router advertisement received");
  346. }
  347. static void
  348. rtadv_process_packet (u_char *buf, unsigned int len, ifindex_t ifindex,
  349. int hoplimit, vrf_id_t vrf_id)
  350. {
  351. struct icmp6_hdr *icmph;
  352. struct interface *ifp;
  353. struct zebra_if *zif;
  354. /* Interface search. */
  355. ifp = if_lookup_by_index_vrf (ifindex, vrf_id);
  356. if (ifp == NULL)
  357. {
  358. zlog_warn ("Unknown interface index: %d, vrf %u", ifindex, vrf_id);
  359. return;
  360. }
  361. if (if_is_loopback (ifp))
  362. return;
  363. /* Check interface configuration. */
  364. zif = ifp->info;
  365. if (! zif->rtadv.AdvSendAdvertisements)
  366. return;
  367. /* ICMP message length check. */
  368. if (len < sizeof (struct icmp6_hdr))
  369. {
  370. zlog_warn ("Invalid ICMPV6 packet length: %d", len);
  371. return;
  372. }
  373. icmph = (struct icmp6_hdr *) buf;
  374. /* ICMP message type check. */
  375. if (icmph->icmp6_type != ND_ROUTER_SOLICIT &&
  376. icmph->icmp6_type != ND_ROUTER_ADVERT)
  377. {
  378. zlog_warn ("Unwanted ICMPV6 message type: %d", icmph->icmp6_type);
  379. return;
  380. }
  381. /* Hoplimit check. */
  382. if (hoplimit >= 0 && hoplimit != 255)
  383. {
  384. zlog_warn ("Invalid hoplimit %d for router advertisement ICMP packet",
  385. hoplimit);
  386. return;
  387. }
  388. /* Check ICMP message type. */
  389. if (icmph->icmp6_type == ND_ROUTER_SOLICIT)
  390. rtadv_process_solicit (ifp);
  391. else if (icmph->icmp6_type == ND_ROUTER_ADVERT)
  392. rtadv_process_advert ();
  393. return;
  394. }
  395. static int
  396. rtadv_read (struct thread *thread)
  397. {
  398. int sock;
  399. int len;
  400. u_char buf[RTADV_MSG_SIZE];
  401. struct sockaddr_in6 from;
  402. ifindex_t ifindex = 0;
  403. int hoplimit = -1;
  404. struct zebra_vrf *zvrf = THREAD_ARG (thread);
  405. sock = THREAD_FD (thread);
  406. zvrf->rtadv.ra_read = NULL;
  407. /* Register myself. */
  408. rtadv_event (zvrf, RTADV_READ, sock);
  409. len = rtadv_recv_packet (sock, buf, sizeof (buf), &from, &ifindex, &hoplimit);
  410. if (len < 0)
  411. {
  412. zlog_warn ("router solicitation recv failed: %s.", safe_strerror (errno));
  413. return len;
  414. }
  415. rtadv_process_packet (buf, (unsigned)len, ifindex, hoplimit, zvrf->vrf_id);
  416. return 0;
  417. }
  418. static int
  419. rtadv_make_socket (vrf_id_t vrf_id)
  420. {
  421. int sock;
  422. int ret;
  423. struct icmp6_filter filter;
  424. if ( zserv_privs.change (ZPRIVS_RAISE) )
  425. zlog_err ("rtadv_make_socket: could not raise privs, %s",
  426. safe_strerror (errno) );
  427. sock = vrf_socket (AF_INET6, SOCK_RAW, IPPROTO_ICMPV6, vrf_id);
  428. if ( zserv_privs.change (ZPRIVS_LOWER) )
  429. zlog_err ("rtadv_make_socket: could not lower privs, %s",
  430. safe_strerror (errno) );
  431. /* When we can't make ICMPV6 socket simply back. Router
  432. advertisement feature will not be supported. */
  433. if (sock < 0)
  434. {
  435. close (sock);
  436. return -1;
  437. }
  438. ret = setsockopt_ipv6_pktinfo (sock, 1);
  439. if (ret < 0)
  440. {
  441. close (sock);
  442. return ret;
  443. }
  444. ret = setsockopt_ipv6_multicast_loop (sock, 0);
  445. if (ret < 0)
  446. {
  447. close (sock);
  448. return ret;
  449. }
  450. ret = setsockopt_ipv6_unicast_hops (sock, 255);
  451. if (ret < 0)
  452. {
  453. close (sock);
  454. return ret;
  455. }
  456. ret = setsockopt_ipv6_multicast_hops (sock, 255);
  457. if (ret < 0)
  458. {
  459. close (sock);
  460. return ret;
  461. }
  462. ret = setsockopt_ipv6_hoplimit (sock, 1);
  463. if (ret < 0)
  464. {
  465. close (sock);
  466. return ret;
  467. }
  468. ICMP6_FILTER_SETBLOCKALL(&filter);
  469. ICMP6_FILTER_SETPASS (ND_ROUTER_SOLICIT, &filter);
  470. ICMP6_FILTER_SETPASS (ND_ROUTER_ADVERT, &filter);
  471. ret = setsockopt (sock, IPPROTO_ICMPV6, ICMP6_FILTER, &filter,
  472. sizeof (struct icmp6_filter));
  473. if (ret < 0)
  474. {
  475. zlog_info ("ICMP6_FILTER set fail: %s", safe_strerror (errno));
  476. return ret;
  477. }
  478. return sock;
  479. }
  480. static struct rtadv_prefix *
  481. rtadv_prefix_new (void)
  482. {
  483. return XCALLOC (MTYPE_RTADV_PREFIX, sizeof (struct rtadv_prefix));
  484. }
  485. static void
  486. rtadv_prefix_free (struct rtadv_prefix *rtadv_prefix)
  487. {
  488. XFREE (MTYPE_RTADV_PREFIX, rtadv_prefix);
  489. }
  490. static struct rtadv_prefix *
  491. rtadv_prefix_lookup (struct list *rplist, struct prefix_ipv6 *p)
  492. {
  493. struct listnode *node;
  494. struct rtadv_prefix *rprefix;
  495. for (ALL_LIST_ELEMENTS_RO (rplist, node, rprefix))
  496. if (prefix_same ((struct prefix *) &rprefix->prefix, (struct prefix *) p))
  497. return rprefix;
  498. return NULL;
  499. }
  500. static struct rtadv_prefix *
  501. rtadv_prefix_get (struct list *rplist, struct prefix_ipv6 *p)
  502. {
  503. struct rtadv_prefix *rprefix;
  504. rprefix = rtadv_prefix_lookup (rplist, p);
  505. if (rprefix)
  506. return rprefix;
  507. rprefix = rtadv_prefix_new ();
  508. memcpy (&rprefix->prefix, p, sizeof (struct prefix_ipv6));
  509. listnode_add (rplist, rprefix);
  510. return rprefix;
  511. }
  512. static void
  513. rtadv_prefix_set (struct zebra_if *zif, struct rtadv_prefix *rp)
  514. {
  515. struct rtadv_prefix *rprefix;
  516. rprefix = rtadv_prefix_get (zif->rtadv.AdvPrefixList, &rp->prefix);
  517. /* Set parameters. */
  518. rprefix->AdvValidLifetime = rp->AdvValidLifetime;
  519. rprefix->AdvPreferredLifetime = rp->AdvPreferredLifetime;
  520. rprefix->AdvOnLinkFlag = rp->AdvOnLinkFlag;
  521. rprefix->AdvAutonomousFlag = rp->AdvAutonomousFlag;
  522. rprefix->AdvRouterAddressFlag = rp->AdvRouterAddressFlag;
  523. }
  524. static int
  525. rtadv_prefix_reset (struct zebra_if *zif, struct rtadv_prefix *rp)
  526. {
  527. struct rtadv_prefix *rprefix;
  528. rprefix = rtadv_prefix_lookup (zif->rtadv.AdvPrefixList, &rp->prefix);
  529. if (rprefix != NULL)
  530. {
  531. listnode_delete (zif->rtadv.AdvPrefixList, (void *) rprefix);
  532. rtadv_prefix_free (rprefix);
  533. return 1;
  534. }
  535. else
  536. return 0;
  537. }
  538. DEFUN (ipv6_nd_suppress_ra,
  539. ipv6_nd_suppress_ra_cmd,
  540. "ipv6 nd suppress-ra",
  541. "Interface IPv6 config commands\n"
  542. "Neighbor discovery\n"
  543. "Suppress Router Advertisement\n")
  544. {
  545. struct interface *ifp;
  546. struct zebra_if *zif;
  547. struct zebra_vrf *zvrf;
  548. ifp = vty->index;
  549. zif = ifp->info;
  550. zvrf = vrf_info_lookup (ifp->vrf_id);
  551. if (if_is_loopback (ifp))
  552. {
  553. vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
  554. return CMD_WARNING;
  555. }
  556. if (zif->rtadv.AdvSendAdvertisements)
  557. {
  558. zif->rtadv.AdvSendAdvertisements = 0;
  559. zif->rtadv.AdvIntervalTimer = 0;
  560. zvrf->rtadv.adv_if_count--;
  561. if_leave_all_router (zvrf->rtadv.sock, ifp);
  562. if (zvrf->rtadv.adv_if_count == 0)
  563. rtadv_event (zvrf, RTADV_STOP, 0);
  564. }
  565. return CMD_SUCCESS;
  566. }
  567. DEFUN (no_ipv6_nd_suppress_ra,
  568. no_ipv6_nd_suppress_ra_cmd,
  569. "no ipv6 nd suppress-ra",
  570. NO_STR
  571. "Interface IPv6 config commands\n"
  572. "Neighbor discovery\n"
  573. "Suppress Router Advertisement\n")
  574. {
  575. struct interface *ifp;
  576. struct zebra_if *zif;
  577. struct zebra_vrf *zvrf;
  578. ifp = vty->index;
  579. zif = ifp->info;
  580. zvrf = vrf_info_lookup (ifp->vrf_id);
  581. if (if_is_loopback (ifp))
  582. {
  583. vty_out (vty, "Invalid interface%s", VTY_NEWLINE);
  584. return CMD_WARNING;
  585. }
  586. if (! zif->rtadv.AdvSendAdvertisements)
  587. {
  588. zif->rtadv.AdvSendAdvertisements = 1;
  589. zif->rtadv.AdvIntervalTimer = 0;
  590. zvrf->rtadv.adv_if_count++;
  591. if_join_all_router (zvrf->rtadv.sock, ifp);
  592. if (zvrf->rtadv.adv_if_count == 1)
  593. rtadv_event (zvrf, RTADV_START, zvrf->rtadv.sock);
  594. }
  595. return CMD_SUCCESS;
  596. }
  597. DEFUN (ipv6_nd_ra_interval_msec,
  598. ipv6_nd_ra_interval_msec_cmd,
  599. "ipv6 nd ra-interval msec <70-1800000>",
  600. "Interface IPv6 config commands\n"
  601. "Neighbor discovery\n"
  602. "Router Advertisement interval\n"
  603. "Router Advertisement interval in milliseconds\n")
  604. {
  605. unsigned interval;
  606. struct interface *ifp = (struct interface *) vty->index;
  607. struct zebra_if *zif = ifp->info;
  608. struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
  609. VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 70, 1800000);
  610. if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime * 1000))
  611. {
  612. vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
  613. return CMD_WARNING;
  614. }
  615. if (zif->rtadv.MaxRtrAdvInterval % 1000)
  616. zvrf->rtadv.adv_msec_if_count--;
  617. if (interval % 1000)
  618. zvrf->rtadv.adv_msec_if_count++;
  619. zif->rtadv.MaxRtrAdvInterval = interval;
  620. zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
  621. zif->rtadv.AdvIntervalTimer = 0;
  622. return CMD_SUCCESS;
  623. }
  624. DEFUN (ipv6_nd_ra_interval,
  625. ipv6_nd_ra_interval_cmd,
  626. "ipv6 nd ra-interval <1-1800>",
  627. "Interface IPv6 config commands\n"
  628. "Neighbor discovery\n"
  629. "Router Advertisement interval\n"
  630. "Router Advertisement interval in seconds\n")
  631. {
  632. unsigned interval;
  633. struct interface *ifp = (struct interface *) vty->index;
  634. struct zebra_if *zif = ifp->info;
  635. struct zebra_vrf *zvrf = vrf_info_lookup (ifp->vrf_id);
  636. VTY_GET_INTEGER_RANGE ("router advertisement interval", interval, argv[0], 1, 1800);
  637. if ((zif->rtadv.AdvDefaultLifetime != -1 && interval > (unsigned)zif->rtadv.AdvDefaultLifetime))
  638. {
  639. vty_out (vty, "This ra-interval would conflict with configured ra-lifetime!%s", VTY_NEWLINE);
  640. return CMD_WARNING;
  641. }
  642. if (zif->rtadv.MaxRtrAdvInterval % 1000)
  643. zvrf->rtadv.adv_msec_if_count--;
  644. /* convert to milliseconds */
  645. interval = interval * 1000;
  646. zif->rtadv.MaxRtrAdvInterval = interval;
  647. zif->rtadv.MinRtrAdvInterval = 0.33 * interval;
  648. zif->rtadv.AdvIntervalTimer = 0;
  649. return CMD_SUCCESS;
  650. }
  651. DEFUN (no_ipv6_nd_ra_interval,
  652. no_ipv6_nd_ra_interval_cmd,
  653. "no ipv6 nd ra-interval",
  654. NO_STR
  655. "Interface IPv6 config commands\n"
  656. "Neighbor discovery\n"
  657. "Router Advertisement interval\n")
  658. {
  659. struct interface *ifp;
  660. struct zebra_if *zif;
  661. struct zebra_vrf *zvrf;
  662. ifp = (struct interface *) vty->index;
  663. zif = ifp->info;
  664. zvrf = vrf_info_lookup (ifp->vrf_id);
  665. if (zif->rtadv.MaxRtrAdvInterval % 1000)
  666. zvrf->rtadv.adv_msec_if_count--;
  667. zif->rtadv.MaxRtrAdvInterval = RTADV_MAX_RTR_ADV_INTERVAL;
  668. zif->rtadv.MinRtrAdvInterval = RTADV_MIN_RTR_ADV_INTERVAL;
  669. zif->rtadv.AdvIntervalTimer = zif->rtadv.MaxRtrAdvInterval;
  670. return CMD_SUCCESS;
  671. }
  672. ALIAS (no_ipv6_nd_ra_interval,
  673. no_ipv6_nd_ra_interval_val_cmd,
  674. "no ipv6 nd ra-interval <1-1800>",
  675. NO_STR
  676. "Interface IPv6 config commands\n"
  677. "Neighbor discovery\n"
  678. "Router Advertisement interval\n")
  679. ALIAS (no_ipv6_nd_ra_interval,
  680. no_ipv6_nd_ra_interval_msec_val_cmd,
  681. "no ipv6 nd ra-interval msec <1-1800000>",
  682. NO_STR
  683. "Interface IPv6 config commands\n"
  684. "Neighbor discovery\n"
  685. "Router Advertisement interval\n"
  686. "Router Advertisement interval in milliseconds\n")
  687. DEFUN (ipv6_nd_ra_lifetime,
  688. ipv6_nd_ra_lifetime_cmd,
  689. "ipv6 nd ra-lifetime <0-9000>",
  690. "Interface IPv6 config commands\n"
  691. "Neighbor discovery\n"
  692. "Router lifetime\n"
  693. "Router lifetime in seconds (0 stands for a non-default gw)\n")
  694. {
  695. int lifetime;
  696. struct interface *ifp;
  697. struct zebra_if *zif;
  698. ifp = (struct interface *) vty->index;
  699. zif = ifp->info;
  700. VTY_GET_INTEGER_RANGE ("router lifetime", lifetime, argv[0], 0, 9000);
  701. /* The value to be placed in the Router Lifetime field
  702. * of Router Advertisements sent from the interface,
  703. * in seconds. MUST be either zero or between
  704. * MaxRtrAdvInterval and 9000 seconds. -- RFC4861, 6.2.1 */
  705. if ((lifetime != 0 && lifetime * 1000 < zif->rtadv.MaxRtrAdvInterval))
  706. {
  707. vty_out (vty, "This ra-lifetime would conflict with configured ra-interval%s", VTY_NEWLINE);
  708. return CMD_WARNING;
  709. }
  710. zif->rtadv.AdvDefaultLifetime = lifetime;
  711. return CMD_SUCCESS;
  712. }
  713. DEFUN (no_ipv6_nd_ra_lifetime,
  714. no_ipv6_nd_ra_lifetime_cmd,
  715. "no ipv6 nd ra-lifetime",
  716. NO_STR
  717. "Interface IPv6 config commands\n"
  718. "Neighbor discovery\n"
  719. "Router lifetime\n")
  720. {
  721. struct interface *ifp;
  722. struct zebra_if *zif;
  723. ifp = (struct interface *) vty->index;
  724. zif = ifp->info;
  725. zif->rtadv.AdvDefaultLifetime = -1;
  726. return CMD_SUCCESS;
  727. }
  728. ALIAS (no_ipv6_nd_ra_lifetime,
  729. no_ipv6_nd_ra_lifetime_val_cmd,
  730. "no ipv6 nd ra-lifetime <0-9000>",
  731. NO_STR
  732. "Interface IPv6 config commands\n"
  733. "Neighbor discovery\n"
  734. "Router lifetime\n"
  735. "Router lifetime in seconds (0 stands for a non-default gw)\n")
  736. DEFUN (ipv6_nd_reachable_time,
  737. ipv6_nd_reachable_time_cmd,
  738. "ipv6 nd reachable-time <1-3600000>",
  739. "Interface IPv6 config commands\n"
  740. "Neighbor discovery\n"
  741. "Reachable time\n"
  742. "Reachable time in milliseconds\n")
  743. {
  744. struct interface *ifp = (struct interface *) vty->index;
  745. struct zebra_if *zif = ifp->info;
  746. VTY_GET_INTEGER_RANGE ("reachable time", zif->rtadv.AdvReachableTime, argv[0], 1, RTADV_MAX_REACHABLE_TIME);
  747. return CMD_SUCCESS;
  748. }
  749. DEFUN (no_ipv6_nd_reachable_time,
  750. no_ipv6_nd_reachable_time_cmd,
  751. "no ipv6 nd reachable-time",
  752. NO_STR
  753. "Interface IPv6 config commands\n"
  754. "Neighbor discovery\n"
  755. "Reachable time\n")
  756. {
  757. struct interface *ifp;
  758. struct zebra_if *zif;
  759. ifp = (struct interface *) vty->index;
  760. zif = ifp->info;
  761. zif->rtadv.AdvReachableTime = 0;
  762. return CMD_SUCCESS;
  763. }
  764. ALIAS (no_ipv6_nd_reachable_time,
  765. no_ipv6_nd_reachable_time_val_cmd,
  766. "no ipv6 nd reachable-time <1-3600000>",
  767. NO_STR
  768. "Interface IPv6 config commands\n"
  769. "Neighbor discovery\n"
  770. "Reachable time\n"
  771. "Reachable time in milliseconds\n")
  772. DEFUN (ipv6_nd_homeagent_preference,
  773. ipv6_nd_homeagent_preference_cmd,
  774. "ipv6 nd home-agent-preference <0-65535>",
  775. "Interface IPv6 config commands\n"
  776. "Neighbor discovery\n"
  777. "Home Agent preference\n"
  778. "preference value (default is 0, least preferred)\n")
  779. {
  780. struct interface *ifp = (struct interface *) vty->index;
  781. struct zebra_if *zif = ifp->info;
  782. VTY_GET_INTEGER_RANGE ("home agent preference", zif->rtadv.HomeAgentPreference, argv[0], 0, 65535);
  783. return CMD_SUCCESS;
  784. }
  785. DEFUN (no_ipv6_nd_homeagent_preference,
  786. no_ipv6_nd_homeagent_preference_cmd,
  787. "no ipv6 nd home-agent-preference",
  788. NO_STR
  789. "Interface IPv6 config commands\n"
  790. "Neighbor discovery\n"
  791. "Home Agent preference\n")
  792. {
  793. struct interface *ifp;
  794. struct zebra_if *zif;
  795. ifp = (struct interface *) vty->index;
  796. zif = ifp->info;
  797. zif->rtadv.HomeAgentPreference = 0;
  798. return CMD_SUCCESS;
  799. }
  800. ALIAS (no_ipv6_nd_homeagent_preference,
  801. no_ipv6_nd_homeagent_preference_val_cmd,
  802. "no ipv6 nd home-agent-preference <0-65535>",
  803. NO_STR
  804. "Interface IPv6 config commands\n"
  805. "Neighbor discovery\n"
  806. "Home Agent preference\n"
  807. "preference value (default is 0, least preferred)\n")
  808. DEFUN (ipv6_nd_homeagent_lifetime,
  809. ipv6_nd_homeagent_lifetime_cmd,
  810. "ipv6 nd home-agent-lifetime <0-65520>",
  811. "Interface IPv6 config commands\n"
  812. "Neighbor discovery\n"
  813. "Home Agent lifetime\n"
  814. "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
  815. {
  816. struct interface *ifp = (struct interface *) vty->index;
  817. struct zebra_if *zif = ifp->info;
  818. VTY_GET_INTEGER_RANGE ("home agent lifetime", zif->rtadv.HomeAgentLifetime, argv[0], 0, RTADV_MAX_HALIFETIME);
  819. return CMD_SUCCESS;
  820. }
  821. DEFUN (no_ipv6_nd_homeagent_lifetime,
  822. no_ipv6_nd_homeagent_lifetime_cmd,
  823. "no ipv6 nd home-agent-lifetime",
  824. NO_STR
  825. "Interface IPv6 config commands\n"
  826. "Neighbor discovery\n"
  827. "Home Agent lifetime\n")
  828. {
  829. struct interface *ifp;
  830. struct zebra_if *zif;
  831. ifp = (struct interface *) vty->index;
  832. zif = ifp->info;
  833. zif->rtadv.HomeAgentLifetime = -1;
  834. return CMD_SUCCESS;
  835. }
  836. ALIAS (no_ipv6_nd_homeagent_lifetime,
  837. no_ipv6_nd_homeagent_lifetime_val_cmd,
  838. "no ipv6 nd home-agent-lifetime <0-65520>",
  839. NO_STR
  840. "Interface IPv6 config commands\n"
  841. "Neighbor discovery\n"
  842. "Home Agent lifetime\n"
  843. "Home Agent lifetime in seconds (0 to track ra-lifetime)\n")
  844. DEFUN (ipv6_nd_managed_config_flag,
  845. ipv6_nd_managed_config_flag_cmd,
  846. "ipv6 nd managed-config-flag",
  847. "Interface IPv6 config commands\n"
  848. "Neighbor discovery\n"
  849. "Managed address configuration flag\n")
  850. {
  851. struct interface *ifp;
  852. struct zebra_if *zif;
  853. ifp = (struct interface *) vty->index;
  854. zif = ifp->info;
  855. zif->rtadv.AdvManagedFlag = 1;
  856. return CMD_SUCCESS;
  857. }
  858. DEFUN (no_ipv6_nd_managed_config_flag,
  859. no_ipv6_nd_managed_config_flag_cmd,
  860. "no ipv6 nd managed-config-flag",
  861. NO_STR
  862. "Interface IPv6 config commands\n"
  863. "Neighbor discovery\n"
  864. "Managed address configuration flag\n")
  865. {
  866. struct interface *ifp;
  867. struct zebra_if *zif;
  868. ifp = (struct interface *) vty->index;
  869. zif = ifp->info;
  870. zif->rtadv.AdvManagedFlag = 0;
  871. return CMD_SUCCESS;
  872. }
  873. DEFUN (ipv6_nd_homeagent_config_flag,
  874. ipv6_nd_homeagent_config_flag_cmd,
  875. "ipv6 nd home-agent-config-flag",
  876. "Interface IPv6 config commands\n"
  877. "Neighbor discovery\n"
  878. "Home Agent configuration flag\n")
  879. {
  880. struct interface *ifp;
  881. struct zebra_if *zif;
  882. ifp = (struct interface *) vty->index;
  883. zif = ifp->info;
  884. zif->rtadv.AdvHomeAgentFlag = 1;
  885. return CMD_SUCCESS;
  886. }
  887. DEFUN (no_ipv6_nd_homeagent_config_flag,
  888. no_ipv6_nd_homeagent_config_flag_cmd,
  889. "no ipv6 nd home-agent-config-flag",
  890. NO_STR
  891. "Interface IPv6 config commands\n"
  892. "Neighbor discovery\n"
  893. "Home Agent configuration flag\n")
  894. {
  895. struct interface *ifp;
  896. struct zebra_if *zif;
  897. ifp = (struct interface *) vty->index;
  898. zif = ifp->info;
  899. zif->rtadv.AdvHomeAgentFlag = 0;
  900. return CMD_SUCCESS;
  901. }
  902. DEFUN (ipv6_nd_adv_interval_config_option,
  903. ipv6_nd_adv_interval_config_option_cmd,
  904. "ipv6 nd adv-interval-option",
  905. "Interface IPv6 config commands\n"
  906. "Neighbor discovery\n"
  907. "Advertisement Interval Option\n")
  908. {
  909. struct interface *ifp;
  910. struct zebra_if *zif;
  911. ifp = (struct interface *) vty->index;
  912. zif = ifp->info;
  913. zif->rtadv.AdvIntervalOption = 1;
  914. return CMD_SUCCESS;
  915. }
  916. DEFUN (no_ipv6_nd_adv_interval_config_option,
  917. no_ipv6_nd_adv_interval_config_option_cmd,
  918. "no ipv6 nd adv-interval-option",
  919. NO_STR
  920. "Interface IPv6 config commands\n"
  921. "Neighbor discovery\n"
  922. "Advertisement Interval Option\n")
  923. {
  924. struct interface *ifp;
  925. struct zebra_if *zif;
  926. ifp = (struct interface *) vty->index;
  927. zif = ifp->info;
  928. zif->rtadv.AdvIntervalOption = 0;
  929. return CMD_SUCCESS;
  930. }
  931. DEFUN (ipv6_nd_other_config_flag,
  932. ipv6_nd_other_config_flag_cmd,
  933. "ipv6 nd other-config-flag",
  934. "Interface IPv6 config commands\n"
  935. "Neighbor discovery\n"
  936. "Other statefull configuration flag\n")
  937. {
  938. struct interface *ifp;
  939. struct zebra_if *zif;
  940. ifp = (struct interface *) vty->index;
  941. zif = ifp->info;
  942. zif->rtadv.AdvOtherConfigFlag = 1;
  943. return CMD_SUCCESS;
  944. }
  945. DEFUN (no_ipv6_nd_other_config_flag,
  946. no_ipv6_nd_other_config_flag_cmd,
  947. "no ipv6 nd other-config-flag",
  948. NO_STR
  949. "Interface IPv6 config commands\n"
  950. "Neighbor discovery\n"
  951. "Other statefull configuration flag\n")
  952. {
  953. struct interface *ifp;
  954. struct zebra_if *zif;
  955. ifp = (struct interface *) vty->index;
  956. zif = ifp->info;
  957. zif->rtadv.AdvOtherConfigFlag = 0;
  958. return CMD_SUCCESS;
  959. }
  960. DEFUN (ipv6_nd_prefix,
  961. ipv6_nd_prefix_cmd,
  962. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  963. "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|) (router-address|)",
  964. "Interface IPv6 config commands\n"
  965. "Neighbor discovery\n"
  966. "Prefix information\n"
  967. "IPv6 prefix\n"
  968. "Valid lifetime in seconds\n"
  969. "Infinite valid lifetime\n"
  970. "Preferred lifetime in seconds\n"
  971. "Infinite preferred lifetime\n"
  972. "Do not use prefix for onlink determination\n"
  973. "Do not use prefix for autoconfiguration\n"
  974. "Set Router Address flag\n")
  975. {
  976. int i;
  977. int ret;
  978. int cursor = 1;
  979. struct interface *ifp;
  980. struct zebra_if *zebra_if;
  981. struct rtadv_prefix rp;
  982. ifp = (struct interface *) vty->index;
  983. zebra_if = ifp->info;
  984. ret = str2prefix_ipv6 (argv[0], &rp.prefix);
  985. if (!ret)
  986. {
  987. vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
  988. return CMD_WARNING;
  989. }
  990. apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
  991. rp.AdvOnLinkFlag = 1;
  992. rp.AdvAutonomousFlag = 1;
  993. rp.AdvRouterAddressFlag = 0;
  994. rp.AdvValidLifetime = RTADV_VALID_LIFETIME;
  995. rp.AdvPreferredLifetime = RTADV_PREFERRED_LIFETIME;
  996. if (argc > 1)
  997. {
  998. if ((isdigit((unsigned char)argv[1][0]))
  999. || strncmp (argv[1], "i", 1) == 0)
  1000. {
  1001. if ( strncmp (argv[1], "i", 1) == 0)
  1002. rp.AdvValidLifetime = UINT32_MAX;
  1003. else
  1004. rp.AdvValidLifetime = (u_int32_t) strtoll (argv[1],
  1005. (char **)NULL, 10);
  1006. if ( strncmp (argv[2], "i", 1) == 0)
  1007. rp.AdvPreferredLifetime = UINT32_MAX;
  1008. else
  1009. rp.AdvPreferredLifetime = (u_int32_t) strtoll (argv[2],
  1010. (char **)NULL, 10);
  1011. if (rp.AdvPreferredLifetime > rp.AdvValidLifetime)
  1012. {
  1013. vty_out (vty, "Invalid preferred lifetime%s", VTY_NEWLINE);
  1014. return CMD_WARNING;
  1015. }
  1016. cursor = cursor + 2;
  1017. }
  1018. if (argc > cursor)
  1019. {
  1020. for (i = cursor; i < argc; i++)
  1021. {
  1022. if (strncmp (argv[i], "of", 2) == 0)
  1023. rp.AdvOnLinkFlag = 0;
  1024. if (strncmp (argv[i], "no", 2) == 0)
  1025. rp.AdvAutonomousFlag = 0;
  1026. if (strncmp (argv[i], "ro", 2) == 0)
  1027. rp.AdvRouterAddressFlag = 1;
  1028. }
  1029. }
  1030. }
  1031. rtadv_prefix_set (zebra_if, &rp);
  1032. return CMD_SUCCESS;
  1033. }
  1034. ALIAS (ipv6_nd_prefix,
  1035. ipv6_nd_prefix_val_nortaddr_cmd,
  1036. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1037. "(<0-4294967295>|infinite) (off-link|) (no-autoconfig|)",
  1038. "Interface IPv6 config commands\n"
  1039. "Neighbor discovery\n"
  1040. "Prefix information\n"
  1041. "IPv6 prefix\n"
  1042. "Valid lifetime in seconds\n"
  1043. "Infinite valid lifetime\n"
  1044. "Preferred lifetime in seconds\n"
  1045. "Infinite preferred lifetime\n"
  1046. "Do not use prefix for onlink determination\n"
  1047. "Do not use prefix for autoconfiguration\n")
  1048. ALIAS (ipv6_nd_prefix,
  1049. ipv6_nd_prefix_val_rev_cmd,
  1050. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1051. "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|)",
  1052. "Interface IPv6 config commands\n"
  1053. "Neighbor discovery\n"
  1054. "Prefix information\n"
  1055. "IPv6 prefix\n"
  1056. "Valid lifetime in seconds\n"
  1057. "Infinite valid lifetime\n"
  1058. "Preferred lifetime in seconds\n"
  1059. "Infinite preferred lifetime\n"
  1060. "Do not use prefix for autoconfiguration\n"
  1061. "Do not use prefix for onlink determination\n")
  1062. ALIAS (ipv6_nd_prefix,
  1063. ipv6_nd_prefix_val_rev_rtaddr_cmd,
  1064. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1065. "(<0-4294967295>|infinite) (no-autoconfig|) (off-link|) (router-address|)",
  1066. "Interface IPv6 config commands\n"
  1067. "Neighbor discovery\n"
  1068. "Prefix information\n"
  1069. "IPv6 prefix\n"
  1070. "Valid lifetime in seconds\n"
  1071. "Infinite valid lifetime\n"
  1072. "Preferred lifetime in seconds\n"
  1073. "Infinite preferred lifetime\n"
  1074. "Do not use prefix for autoconfiguration\n"
  1075. "Do not use prefix for onlink determination\n"
  1076. "Set Router Address flag\n")
  1077. ALIAS (ipv6_nd_prefix,
  1078. ipv6_nd_prefix_val_noauto_cmd,
  1079. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1080. "(<0-4294967295>|infinite) (no-autoconfig|)",
  1081. "Interface IPv6 config commands\n"
  1082. "Neighbor discovery\n"
  1083. "Prefix information\n"
  1084. "IPv6 prefix\n"
  1085. "Valid lifetime in seconds\n"
  1086. "Infinite valid lifetime\n"
  1087. "Preferred lifetime in seconds\n"
  1088. "Infinite preferred lifetime\n"
  1089. "Do not use prefix for autoconfiguration")
  1090. ALIAS (ipv6_nd_prefix,
  1091. ipv6_nd_prefix_val_offlink_cmd,
  1092. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1093. "(<0-4294967295>|infinite) (off-link|)",
  1094. "Interface IPv6 config commands\n"
  1095. "Neighbor discovery\n"
  1096. "Prefix information\n"
  1097. "IPv6 prefix\n"
  1098. "Valid lifetime in seconds\n"
  1099. "Infinite valid lifetime\n"
  1100. "Preferred lifetime in seconds\n"
  1101. "Infinite preferred lifetime\n"
  1102. "Do not use prefix for onlink determination\n")
  1103. ALIAS (ipv6_nd_prefix,
  1104. ipv6_nd_prefix_val_rtaddr_cmd,
  1105. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1106. "(<0-4294967295>|infinite) (router-address|)",
  1107. "Interface IPv6 config commands\n"
  1108. "Neighbor discovery\n"
  1109. "Prefix information\n"
  1110. "IPv6 prefix\n"
  1111. "Valid lifetime in seconds\n"
  1112. "Infinite valid lifetime\n"
  1113. "Preferred lifetime in seconds\n"
  1114. "Infinite preferred lifetime\n"
  1115. "Set Router Address flag\n")
  1116. ALIAS (ipv6_nd_prefix,
  1117. ipv6_nd_prefix_val_cmd,
  1118. "ipv6 nd prefix X:X::X:X/M (<0-4294967295>|infinite) "
  1119. "(<0-4294967295>|infinite)",
  1120. "Interface IPv6 config commands\n"
  1121. "Neighbor discovery\n"
  1122. "Prefix information\n"
  1123. "IPv6 prefix\n"
  1124. "Valid lifetime in seconds\n"
  1125. "Infinite valid lifetime\n"
  1126. "Preferred lifetime in seconds\n"
  1127. "Infinite preferred lifetime\n")
  1128. ALIAS (ipv6_nd_prefix,
  1129. ipv6_nd_prefix_noval_cmd,
  1130. "ipv6 nd prefix X:X::X:X/M (no-autoconfig|) (off-link|)",
  1131. "Interface IPv6 config commands\n"
  1132. "Neighbor discovery\n"
  1133. "Prefix information\n"
  1134. "IPv6 prefix\n"
  1135. "Do not use prefix for autoconfiguration\n"
  1136. "Do not use prefix for onlink determination\n")
  1137. ALIAS (ipv6_nd_prefix,
  1138. ipv6_nd_prefix_noval_rev_cmd,
  1139. "ipv6 nd prefix X:X::X:X/M (off-link|) (no-autoconfig|)",
  1140. "Interface IPv6 config commands\n"
  1141. "Neighbor discovery\n"
  1142. "Prefix information\n"
  1143. "IPv6 prefix\n"
  1144. "Do not use prefix for onlink determination\n"
  1145. "Do not use prefix for autoconfiguration\n")
  1146. ALIAS (ipv6_nd_prefix,
  1147. ipv6_nd_prefix_noval_noauto_cmd,
  1148. "ipv6 nd prefix X:X::X:X/M (no-autoconfig|)",
  1149. "Interface IPv6 config commands\n"
  1150. "Neighbor discovery\n"
  1151. "Prefix information\n"
  1152. "IPv6 prefix\n"
  1153. "Do not use prefix for autoconfiguration\n")
  1154. ALIAS (ipv6_nd_prefix,
  1155. ipv6_nd_prefix_noval_offlink_cmd,
  1156. "ipv6 nd prefix X:X::X:X/M (off-link|)",
  1157. "Interface IPv6 config commands\n"
  1158. "Neighbor discovery\n"
  1159. "Prefix information\n"
  1160. "IPv6 prefix\n"
  1161. "Do not use prefix for onlink determination\n")
  1162. ALIAS (ipv6_nd_prefix,
  1163. ipv6_nd_prefix_noval_rtaddr_cmd,
  1164. "ipv6 nd prefix X:X::X:X/M (router-address|)",
  1165. "Interface IPv6 config commands\n"
  1166. "Neighbor discovery\n"
  1167. "Prefix information\n"
  1168. "IPv6 prefix\n"
  1169. "Set Router Address flag\n")
  1170. ALIAS (ipv6_nd_prefix,
  1171. ipv6_nd_prefix_prefix_cmd,
  1172. "ipv6 nd prefix X:X::X:X/M",
  1173. "Interface IPv6 config commands\n"
  1174. "Neighbor discovery\n"
  1175. "Prefix information\n"
  1176. "IPv6 prefix\n")
  1177. DEFUN (no_ipv6_nd_prefix,
  1178. no_ipv6_nd_prefix_cmd,
  1179. "no ipv6 nd prefix IPV6PREFIX",
  1180. NO_STR
  1181. "Interface IPv6 config commands\n"
  1182. "Neighbor discovery\n"
  1183. "Prefix information\n"
  1184. "IPv6 prefix\n")
  1185. {
  1186. int ret;
  1187. struct interface *ifp;
  1188. struct zebra_if *zebra_if;
  1189. struct rtadv_prefix rp;
  1190. ifp = (struct interface *) vty->index;
  1191. zebra_if = ifp->info;
  1192. ret = str2prefix_ipv6 (argv[0], &rp.prefix);
  1193. if (!ret)
  1194. {
  1195. vty_out (vty, "Malformed IPv6 prefix%s", VTY_NEWLINE);
  1196. return CMD_WARNING;
  1197. }
  1198. apply_mask_ipv6 (&rp.prefix); /* RFC4861 4.6.2 */
  1199. ret = rtadv_prefix_reset (zebra_if, &rp);
  1200. if (!ret)
  1201. {
  1202. vty_out (vty, "Non-exist IPv6 prefix%s", VTY_NEWLINE);
  1203. return CMD_WARNING;
  1204. }
  1205. return CMD_SUCCESS;
  1206. }
  1207. DEFUN (ipv6_nd_router_preference,
  1208. ipv6_nd_router_preference_cmd,
  1209. "ipv6 nd router-preference (high|medium|low)",
  1210. "Interface IPv6 config commands\n"
  1211. "Neighbor discovery\n"
  1212. "Default router preference\n"
  1213. "High default router preference\n"
  1214. "Low default router preference\n"
  1215. "Medium default router preference (default)\n")
  1216. {
  1217. struct interface *ifp;
  1218. struct zebra_if *zif;
  1219. int i = 0;
  1220. ifp = (struct interface *) vty->index;
  1221. zif = ifp->info;
  1222. while (0 != rtadv_pref_strs[i])
  1223. {
  1224. if (strncmp (argv[0], rtadv_pref_strs[i], 1) == 0)
  1225. {
  1226. zif->rtadv.DefaultPreference = i;
  1227. return CMD_SUCCESS;
  1228. }
  1229. i++;
  1230. }
  1231. return CMD_ERR_NO_MATCH;
  1232. }
  1233. DEFUN (no_ipv6_nd_router_preference,
  1234. no_ipv6_nd_router_preference_cmd,
  1235. "no ipv6 nd router-preference",
  1236. NO_STR
  1237. "Interface IPv6 config commands\n"
  1238. "Neighbor discovery\n"
  1239. "Default router preference\n")
  1240. {
  1241. struct interface *ifp;
  1242. struct zebra_if *zif;
  1243. ifp = (struct interface *) vty->index;
  1244. zif = ifp->info;
  1245. zif->rtadv.DefaultPreference = RTADV_PREF_MEDIUM; /* Default per RFC4191. */
  1246. return CMD_SUCCESS;
  1247. }
  1248. ALIAS (no_ipv6_nd_router_preference,
  1249. no_ipv6_nd_router_preference_val_cmd,
  1250. "no ipv6 nd router-preference (high|medium|low)",
  1251. NO_STR
  1252. "Interface IPv6 config commands\n"
  1253. "Neighbor discovery\n"
  1254. "Default router preference\n"
  1255. "High default router preference\n"
  1256. "Low default router preference\n"
  1257. "Medium default router preference (default)\n")
  1258. DEFUN (ipv6_nd_mtu,
  1259. ipv6_nd_mtu_cmd,
  1260. "ipv6 nd mtu <1-65535>",
  1261. "Interface IPv6 config commands\n"
  1262. "Neighbor discovery\n"
  1263. "Advertised MTU\n"
  1264. "MTU in bytes\n")
  1265. {
  1266. struct interface *ifp = (struct interface *) vty->index;
  1267. struct zebra_if *zif = ifp->info;
  1268. VTY_GET_INTEGER_RANGE ("MTU", zif->rtadv.AdvLinkMTU, argv[0], 1, 65535);
  1269. return CMD_SUCCESS;
  1270. }
  1271. DEFUN (no_ipv6_nd_mtu,
  1272. no_ipv6_nd_mtu_cmd,
  1273. "no ipv6 nd mtu",
  1274. NO_STR
  1275. "Interface IPv6 config commands\n"
  1276. "Neighbor discovery\n"
  1277. "Advertised MTU\n")
  1278. {
  1279. struct interface *ifp = (struct interface *) vty->index;
  1280. struct zebra_if *zif = ifp->info;
  1281. zif->rtadv.AdvLinkMTU = 0;
  1282. return CMD_SUCCESS;
  1283. }
  1284. ALIAS (no_ipv6_nd_mtu,
  1285. no_ipv6_nd_mtu_val_cmd,
  1286. "no ipv6 nd mtu <1-65535>",
  1287. NO_STR
  1288. "Interface IPv6 config commands\n"
  1289. "Neighbor discovery\n"
  1290. "Advertised MTU\n"
  1291. "MTU in bytes\n")
  1292. /* Write configuration about router advertisement. */
  1293. void
  1294. rtadv_config_write (struct vty *vty, struct interface *ifp)
  1295. {
  1296. struct zebra_if *zif;
  1297. struct listnode *node;
  1298. struct rtadv_prefix *rprefix;
  1299. char buf[PREFIX_STRLEN];
  1300. int interval;
  1301. zif = ifp->info;
  1302. if (! if_is_loopback (ifp))
  1303. {
  1304. if (zif->rtadv.AdvSendAdvertisements)
  1305. vty_out (vty, " no ipv6 nd suppress-ra%s", VTY_NEWLINE);
  1306. }
  1307. interval = zif->rtadv.MaxRtrAdvInterval;
  1308. if (interval % 1000)
  1309. vty_out (vty, " ipv6 nd ra-interval msec %d%s", interval,
  1310. VTY_NEWLINE);
  1311. else
  1312. if (interval != RTADV_MAX_RTR_ADV_INTERVAL)
  1313. vty_out (vty, " ipv6 nd ra-interval %d%s", interval / 1000,
  1314. VTY_NEWLINE);
  1315. if (zif->rtadv.AdvIntervalOption)
  1316. vty_out (vty, " ipv6 nd adv-interval-option%s", VTY_NEWLINE);
  1317. if (zif->rtadv.AdvDefaultLifetime != -1)
  1318. vty_out (vty, " ipv6 nd ra-lifetime %d%s", zif->rtadv.AdvDefaultLifetime,
  1319. VTY_NEWLINE);
  1320. if (zif->rtadv.HomeAgentPreference)
  1321. vty_out (vty, " ipv6 nd home-agent-preference %u%s",
  1322. zif->rtadv.HomeAgentPreference, VTY_NEWLINE);
  1323. if (zif->rtadv.HomeAgentLifetime != -1)
  1324. vty_out (vty, " ipv6 nd home-agent-lifetime %u%s",
  1325. zif->rtadv.HomeAgentLifetime, VTY_NEWLINE);
  1326. if (zif->rtadv.AdvHomeAgentFlag)
  1327. vty_out (vty, " ipv6 nd home-agent-config-flag%s", VTY_NEWLINE);
  1328. if (zif->rtadv.AdvReachableTime)
  1329. vty_out (vty, " ipv6 nd reachable-time %d%s", zif->rtadv.AdvReachableTime,
  1330. VTY_NEWLINE);
  1331. if (zif->rtadv.AdvManagedFlag)
  1332. vty_out (vty, " ipv6 nd managed-config-flag%s", VTY_NEWLINE);
  1333. if (zif->rtadv.AdvOtherConfigFlag)
  1334. vty_out (vty, " ipv6 nd other-config-flag%s", VTY_NEWLINE);
  1335. if (zif->rtadv.DefaultPreference != RTADV_PREF_MEDIUM)
  1336. vty_out (vty, " ipv6 nd router-preference %s%s",
  1337. rtadv_pref_strs[zif->rtadv.DefaultPreference],
  1338. VTY_NEWLINE);
  1339. if (zif->rtadv.AdvLinkMTU)
  1340. vty_out (vty, " ipv6 nd mtu %d%s", zif->rtadv.AdvLinkMTU, VTY_NEWLINE);
  1341. for (ALL_LIST_ELEMENTS_RO (zif->rtadv.AdvPrefixList, node, rprefix))
  1342. {
  1343. vty_out (vty, " ipv6 nd prefix %s",
  1344. prefix2str (&rprefix->prefix, buf, sizeof(buf)));
  1345. if ((rprefix->AdvValidLifetime != RTADV_VALID_LIFETIME) ||
  1346. (rprefix->AdvPreferredLifetime != RTADV_PREFERRED_LIFETIME))
  1347. {
  1348. if (rprefix->AdvValidLifetime == UINT32_MAX)
  1349. vty_out (vty, " infinite");
  1350. else
  1351. vty_out (vty, " %u", rprefix->AdvValidLifetime);
  1352. if (rprefix->AdvPreferredLifetime == UINT32_MAX)
  1353. vty_out (vty, " infinite");
  1354. else
  1355. vty_out (vty, " %u", rprefix->AdvPreferredLifetime);
  1356. }
  1357. if (!rprefix->AdvOnLinkFlag)
  1358. vty_out (vty, " off-link");
  1359. if (!rprefix->AdvAutonomousFlag)
  1360. vty_out (vty, " no-autoconfig");
  1361. if (rprefix->AdvRouterAddressFlag)
  1362. vty_out (vty, " router-address");
  1363. vty_out (vty, "%s", VTY_NEWLINE);
  1364. }
  1365. }
  1366. static void
  1367. rtadv_event (struct zebra_vrf *zvrf, enum rtadv_event event, int val)
  1368. {
  1369. struct rtadv *rtadv = &zvrf->rtadv;
  1370. switch (event)
  1371. {
  1372. case RTADV_START:
  1373. if (! rtadv->ra_read)
  1374. rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
  1375. if (! rtadv->ra_timer)
  1376. rtadv->ra_timer = thread_add_event (zebrad.master, rtadv_timer,
  1377. zvrf, 0);
  1378. break;
  1379. case RTADV_STOP:
  1380. if (rtadv->ra_timer)
  1381. {
  1382. thread_cancel (rtadv->ra_timer);
  1383. rtadv->ra_timer = NULL;
  1384. }
  1385. if (rtadv->ra_read)
  1386. {
  1387. thread_cancel (rtadv->ra_read);
  1388. rtadv->ra_read = NULL;
  1389. }
  1390. break;
  1391. case RTADV_TIMER:
  1392. if (! rtadv->ra_timer)
  1393. rtadv->ra_timer = thread_add_timer (zebrad.master, rtadv_timer, zvrf,
  1394. val);
  1395. break;
  1396. case RTADV_TIMER_MSEC:
  1397. if (! rtadv->ra_timer)
  1398. rtadv->ra_timer = thread_add_timer_msec (zebrad.master, rtadv_timer,
  1399. zvrf, val);
  1400. break;
  1401. case RTADV_READ:
  1402. if (! rtadv->ra_read)
  1403. rtadv->ra_read = thread_add_read (zebrad.master, rtadv_read, zvrf, val);
  1404. break;
  1405. default:
  1406. break;
  1407. }
  1408. return;
  1409. }
  1410. void
  1411. rtadv_init (struct zebra_vrf *zvrf)
  1412. {
  1413. zvrf->rtadv.sock = rtadv_make_socket (zvrf->vrf_id);
  1414. }
  1415. void
  1416. rtadv_terminate (struct zebra_vrf *zvrf)
  1417. {
  1418. rtadv_event (zvrf, RTADV_STOP, 0);
  1419. if (zvrf->rtadv.sock >= 0)
  1420. {
  1421. close (zvrf->rtadv.sock);
  1422. zvrf->rtadv.sock = -1;
  1423. }
  1424. zvrf->rtadv.adv_if_count = 0;
  1425. zvrf->rtadv.adv_msec_if_count = 0;
  1426. }
  1427. void
  1428. rtadv_cmd_init (void)
  1429. {
  1430. install_element (INTERFACE_NODE, &ipv6_nd_suppress_ra_cmd);
  1431. install_element (INTERFACE_NODE, &no_ipv6_nd_suppress_ra_cmd);
  1432. install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_cmd);
  1433. install_element (INTERFACE_NODE, &ipv6_nd_ra_interval_msec_cmd);
  1434. install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_cmd);
  1435. install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_val_cmd);
  1436. install_element (INTERFACE_NODE, &no_ipv6_nd_ra_interval_msec_val_cmd);
  1437. install_element (INTERFACE_NODE, &ipv6_nd_ra_lifetime_cmd);
  1438. install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_cmd);
  1439. install_element (INTERFACE_NODE, &no_ipv6_nd_ra_lifetime_val_cmd);
  1440. install_element (INTERFACE_NODE, &ipv6_nd_reachable_time_cmd);
  1441. install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_cmd);
  1442. install_element (INTERFACE_NODE, &no_ipv6_nd_reachable_time_val_cmd);
  1443. install_element (INTERFACE_NODE, &ipv6_nd_managed_config_flag_cmd);
  1444. install_element (INTERFACE_NODE, &no_ipv6_nd_managed_config_flag_cmd);
  1445. install_element (INTERFACE_NODE, &ipv6_nd_other_config_flag_cmd);
  1446. install_element (INTERFACE_NODE, &no_ipv6_nd_other_config_flag_cmd);
  1447. install_element (INTERFACE_NODE, &ipv6_nd_homeagent_config_flag_cmd);
  1448. install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_config_flag_cmd);
  1449. install_element (INTERFACE_NODE, &ipv6_nd_homeagent_preference_cmd);
  1450. install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_cmd);
  1451. install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_preference_val_cmd);
  1452. install_element (INTERFACE_NODE, &ipv6_nd_homeagent_lifetime_cmd);
  1453. install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_cmd);
  1454. install_element (INTERFACE_NODE, &no_ipv6_nd_homeagent_lifetime_val_cmd);
  1455. install_element (INTERFACE_NODE, &ipv6_nd_adv_interval_config_option_cmd);
  1456. install_element (INTERFACE_NODE, &no_ipv6_nd_adv_interval_config_option_cmd);
  1457. install_element (INTERFACE_NODE, &ipv6_nd_prefix_cmd);
  1458. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_rtaddr_cmd);
  1459. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_nortaddr_cmd);
  1460. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rev_cmd);
  1461. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_noauto_cmd);
  1462. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_offlink_cmd);
  1463. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_rtaddr_cmd);
  1464. install_element (INTERFACE_NODE, &ipv6_nd_prefix_val_cmd);
  1465. install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_cmd);
  1466. install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rev_cmd);
  1467. install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_noauto_cmd);
  1468. install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_offlink_cmd);
  1469. install_element (INTERFACE_NODE, &ipv6_nd_prefix_noval_rtaddr_cmd);
  1470. install_element (INTERFACE_NODE, &ipv6_nd_prefix_prefix_cmd);
  1471. install_element (INTERFACE_NODE, &no_ipv6_nd_prefix_cmd);
  1472. install_element (INTERFACE_NODE, &ipv6_nd_router_preference_cmd);
  1473. install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_cmd);
  1474. install_element (INTERFACE_NODE, &no_ipv6_nd_router_preference_val_cmd);
  1475. install_element (INTERFACE_NODE, &ipv6_nd_mtu_cmd);
  1476. install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_cmd);
  1477. install_element (INTERFACE_NODE, &no_ipv6_nd_mtu_val_cmd);
  1478. }
  1479. static int
  1480. if_join_all_router (int sock, struct interface *ifp)
  1481. {
  1482. int ret;
  1483. struct ipv6_mreq mreq;
  1484. memset (&mreq, 0, sizeof (struct ipv6_mreq));
  1485. inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
  1486. mreq.ipv6mr_interface = ifp->ifindex;
  1487. ret = setsockopt (sock, IPPROTO_IPV6, IPV6_JOIN_GROUP,
  1488. (char *) &mreq, sizeof mreq);
  1489. if (ret < 0)
  1490. zlog_warn ("can't setsockopt IPV6_JOIN_GROUP: %s", safe_strerror (errno));
  1491. zlog_info ("rtadv: %s join to all-routers multicast group", ifp->name);
  1492. return 0;
  1493. }
  1494. static int
  1495. if_leave_all_router (int sock, struct interface *ifp)
  1496. {
  1497. int ret;
  1498. struct ipv6_mreq mreq;
  1499. memset (&mreq, 0, sizeof (struct ipv6_mreq));
  1500. inet_pton (AF_INET6, ALLROUTER, &mreq.ipv6mr_multiaddr);
  1501. mreq.ipv6mr_interface = ifp->ifindex;
  1502. ret = setsockopt (sock, IPPROTO_IPV6, IPV6_LEAVE_GROUP,
  1503. (char *) &mreq, sizeof mreq);
  1504. if (ret < 0)
  1505. zlog_warn ("can't setsockopt IPV6_LEAVE_GROUP: %s", safe_strerror (errno));
  1506. zlog_info ("rtadv: %s leave from all-routers multicast group", ifp->name);
  1507. return 0;
  1508. }
  1509. #else
  1510. void
  1511. rtadv_init (struct zebra_vrf *zvrf)
  1512. {
  1513. /* Empty.*/;
  1514. }
  1515. void
  1516. rtadv_terminate (struct zebra_vrf *zvrf)
  1517. {
  1518. /* Empty.*/;
  1519. }
  1520. void
  1521. rtadv_cmd_init (void)
  1522. {
  1523. /* Empty.*/;
  1524. }
  1525. #endif /* HAVE_RTADV && HAVE_IPV6 */