ospf6_interface.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605
  1. /*
  2. * Copyright (C) 2003 Yasuhiro Ohara
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "memory.h"
  23. #include "if.h"
  24. #include "log.h"
  25. #include "command.h"
  26. #include "thread.h"
  27. #include "prefix.h"
  28. #include "plist.h"
  29. #include "ospf6_lsa.h"
  30. #include "ospf6_lsdb.h"
  31. #include "ospf6_network.h"
  32. #include "ospf6_message.h"
  33. #include "ospf6_route.h"
  34. #include "ospf6_top.h"
  35. #include "ospf6_area.h"
  36. #include "ospf6_interface.h"
  37. #include "ospf6_neighbor.h"
  38. #include "ospf6_intra.h"
  39. #include "ospf6_spf.h"
  40. #include "ospf6d.h"
  41. unsigned char conf_debug_ospf6_interface = 0;
  42. const char *ospf6_interface_state_str[] =
  43. {
  44. "None",
  45. "Down",
  46. "Loopback",
  47. "Waiting",
  48. "PointToPoint",
  49. "DROther",
  50. "BDR",
  51. "DR",
  52. NULL
  53. };
  54. struct ospf6_interface *
  55. ospf6_interface_lookup_by_ifindex (int ifindex)
  56. {
  57. struct ospf6_interface *oi;
  58. struct interface *ifp;
  59. ifp = if_lookup_by_index (ifindex);
  60. if (ifp == NULL)
  61. return (struct ospf6_interface *) NULL;
  62. oi = (struct ospf6_interface *) ifp->info;
  63. return oi;
  64. }
  65. /* schedule routing table recalculation */
  66. static void
  67. ospf6_interface_lsdb_hook (struct ospf6_lsa *lsa)
  68. {
  69. switch (ntohs (lsa->header->type))
  70. {
  71. case OSPF6_LSTYPE_LINK:
  72. if (OSPF6_INTERFACE (lsa->lsdb->data)->state == OSPF6_INTERFACE_DR)
  73. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (OSPF6_INTERFACE (lsa->lsdb->data));
  74. ospf6_spf_schedule (OSPF6_INTERFACE (lsa->lsdb->data)->area);
  75. break;
  76. default:
  77. break;
  78. }
  79. }
  80. /* Create new ospf6 interface structure */
  81. struct ospf6_interface *
  82. ospf6_interface_create (struct interface *ifp)
  83. {
  84. struct ospf6_interface *oi;
  85. unsigned int iobuflen;
  86. oi = (struct ospf6_interface *)
  87. XCALLOC (MTYPE_OSPF6_IF, sizeof (struct ospf6_interface));
  88. if (!oi)
  89. {
  90. zlog_err ("Can't malloc ospf6_interface for ifindex %d", ifp->ifindex);
  91. return (struct ospf6_interface *) NULL;
  92. }
  93. oi->area = (struct ospf6_area *) NULL;
  94. oi->neighbor_list = list_new ();
  95. oi->neighbor_list->cmp = ospf6_neighbor_cmp;
  96. oi->linklocal_addr = (struct in6_addr *) NULL;
  97. oi->instance_id = 0;
  98. oi->transdelay = 1;
  99. oi->priority = 1;
  100. oi->hello_interval = 10;
  101. oi->dead_interval = 40;
  102. oi->rxmt_interval = 5;
  103. oi->cost = 1;
  104. oi->state = OSPF6_INTERFACE_DOWN;
  105. oi->flag = 0;
  106. /* Try to adjust I/O buffer size with IfMtu */
  107. oi->ifmtu = ifp->mtu6;
  108. iobuflen = ospf6_iobuf_size (ifp->mtu6);
  109. if (oi->ifmtu > iobuflen)
  110. {
  111. if (IS_OSPF6_DEBUG_INTERFACE)
  112. zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
  113. ifp->name, iobuflen);
  114. oi->ifmtu = iobuflen;
  115. }
  116. oi->lsupdate_list = ospf6_lsdb_create (oi);
  117. oi->lsack_list = ospf6_lsdb_create (oi);
  118. oi->lsdb = ospf6_lsdb_create (oi);
  119. oi->lsdb->hook_add = ospf6_interface_lsdb_hook;
  120. oi->lsdb->hook_remove = ospf6_interface_lsdb_hook;
  121. oi->lsdb_self = ospf6_lsdb_create (oi);
  122. oi->route_connected = OSPF6_ROUTE_TABLE_CREATE (INTERFACE, CONNECTED_ROUTES);
  123. oi->route_connected->scope = oi;
  124. /* link both */
  125. oi->interface = ifp;
  126. ifp->info = oi;
  127. return oi;
  128. }
  129. void
  130. ospf6_interface_delete (struct ospf6_interface *oi)
  131. {
  132. struct listnode *node, *nnode;
  133. struct ospf6_neighbor *on;
  134. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  135. ospf6_neighbor_delete (on);
  136. list_delete (oi->neighbor_list);
  137. THREAD_OFF (oi->thread_send_hello);
  138. THREAD_OFF (oi->thread_send_lsupdate);
  139. THREAD_OFF (oi->thread_send_lsack);
  140. ospf6_lsdb_remove_all (oi->lsdb);
  141. ospf6_lsdb_remove_all (oi->lsupdate_list);
  142. ospf6_lsdb_remove_all (oi->lsack_list);
  143. ospf6_lsdb_delete (oi->lsdb);
  144. ospf6_lsdb_delete (oi->lsdb_self);
  145. ospf6_lsdb_delete (oi->lsupdate_list);
  146. ospf6_lsdb_delete (oi->lsack_list);
  147. ospf6_route_table_delete (oi->route_connected);
  148. /* cut link */
  149. oi->interface->info = NULL;
  150. /* plist_name */
  151. if (oi->plist_name)
  152. XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
  153. XFREE (MTYPE_OSPF6_IF, oi);
  154. }
  155. void
  156. ospf6_interface_enable (struct ospf6_interface *oi)
  157. {
  158. UNSET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
  159. oi->thread_send_hello =
  160. thread_add_event (master, ospf6_hello_send, oi, 0);
  161. }
  162. void
  163. ospf6_interface_disable (struct ospf6_interface *oi)
  164. {
  165. struct listnode *node, *nnode;
  166. struct ospf6_neighbor *on;
  167. SET_FLAG (oi->flag, OSPF6_INTERFACE_DISABLE);
  168. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  169. ospf6_neighbor_delete (on);
  170. list_delete_all_node (oi->neighbor_list);
  171. ospf6_lsdb_remove_all (oi->lsdb);
  172. ospf6_lsdb_remove_all (oi->lsupdate_list);
  173. ospf6_lsdb_remove_all (oi->lsack_list);
  174. THREAD_OFF (oi->thread_send_hello);
  175. THREAD_OFF (oi->thread_send_lsupdate);
  176. THREAD_OFF (oi->thread_send_lsack);
  177. }
  178. static struct in6_addr *
  179. ospf6_interface_get_linklocal_address (struct interface *ifp)
  180. {
  181. struct listnode *n;
  182. struct connected *c;
  183. struct in6_addr *l = (struct in6_addr *) NULL;
  184. /* for each connected address */
  185. for (ALL_LIST_ELEMENTS_RO (ifp->connected, n, c))
  186. {
  187. /* if family not AF_INET6, ignore */
  188. if (c->address->family != AF_INET6)
  189. continue;
  190. /* linklocal scope check */
  191. if (IN6_IS_ADDR_LINKLOCAL (&c->address->u.prefix6))
  192. l = &c->address->u.prefix6;
  193. }
  194. return l;
  195. }
  196. void
  197. ospf6_interface_if_add (struct interface *ifp)
  198. {
  199. struct ospf6_interface *oi;
  200. unsigned int iobuflen;
  201. oi = (struct ospf6_interface *) ifp->info;
  202. if (oi == NULL)
  203. return;
  204. /* Try to adjust I/O buffer size with IfMtu */
  205. if (oi->ifmtu == 0)
  206. oi->ifmtu = ifp->mtu6;
  207. iobuflen = ospf6_iobuf_size (ifp->mtu6);
  208. if (oi->ifmtu > iobuflen)
  209. {
  210. if (IS_OSPF6_DEBUG_INTERFACE)
  211. zlog_debug ("Interface %s: IfMtu is adjusted to I/O buffer size: %d.",
  212. ifp->name, iobuflen);
  213. oi->ifmtu = iobuflen;
  214. }
  215. /* interface start */
  216. if (oi->area)
  217. thread_add_event (master, interface_up, oi, 0);
  218. }
  219. void
  220. ospf6_interface_if_del (struct interface *ifp)
  221. {
  222. struct ospf6_interface *oi;
  223. oi = (struct ospf6_interface *) ifp->info;
  224. if (oi == NULL)
  225. return;
  226. /* interface stop */
  227. if (oi->area)
  228. thread_execute (master, interface_down, oi, 0);
  229. listnode_delete (oi->area->if_list, oi);
  230. oi->area = (struct ospf6_area *) NULL;
  231. /* cut link */
  232. oi->interface = NULL;
  233. ifp->info = NULL;
  234. ospf6_interface_delete (oi);
  235. }
  236. void
  237. ospf6_interface_state_update (struct interface *ifp)
  238. {
  239. struct ospf6_interface *oi;
  240. oi = (struct ospf6_interface *) ifp->info;
  241. if (oi == NULL)
  242. return;
  243. if (oi->area == NULL)
  244. return;
  245. if (if_is_up (ifp))
  246. thread_add_event (master, interface_up, oi, 0);
  247. else
  248. thread_add_event (master, interface_down, oi, 0);
  249. return;
  250. }
  251. void
  252. ospf6_interface_connected_route_update (struct interface *ifp)
  253. {
  254. struct ospf6_interface *oi;
  255. struct ospf6_route *route;
  256. struct connected *c;
  257. struct listnode *node, *nnode;
  258. oi = (struct ospf6_interface *) ifp->info;
  259. if (oi == NULL)
  260. return;
  261. /* reset linklocal pointer */
  262. oi->linklocal_addr = ospf6_interface_get_linklocal_address (ifp);
  263. /* if area is null, do not make connected-route list */
  264. if (oi->area == NULL)
  265. return;
  266. /* update "route to advertise" interface route table */
  267. ospf6_route_remove_all (oi->route_connected);
  268. for (ALL_LIST_ELEMENTS (oi->interface->connected, node, nnode, c))
  269. {
  270. if (c->address->family != AF_INET6)
  271. continue;
  272. CONTINUE_IF_ADDRESS_LINKLOCAL (IS_OSPF6_DEBUG_INTERFACE, c->address);
  273. CONTINUE_IF_ADDRESS_UNSPECIFIED (IS_OSPF6_DEBUG_INTERFACE, c->address);
  274. CONTINUE_IF_ADDRESS_LOOPBACK (IS_OSPF6_DEBUG_INTERFACE, c->address);
  275. CONTINUE_IF_ADDRESS_V4COMPAT (IS_OSPF6_DEBUG_INTERFACE, c->address);
  276. CONTINUE_IF_ADDRESS_V4MAPPED (IS_OSPF6_DEBUG_INTERFACE, c->address);
  277. /* apply filter */
  278. if (oi->plist_name)
  279. {
  280. struct prefix_list *plist;
  281. enum prefix_list_type ret;
  282. char buf[128];
  283. prefix2str (c->address, buf, sizeof (buf));
  284. plist = prefix_list_lookup (AFI_IP6, oi->plist_name);
  285. ret = prefix_list_apply (plist, (void *) c->address);
  286. if (ret == PREFIX_DENY)
  287. {
  288. if (IS_OSPF6_DEBUG_INTERFACE)
  289. zlog_debug ("%s on %s filtered by prefix-list %s ",
  290. buf, oi->interface->name, oi->plist_name);
  291. continue;
  292. }
  293. }
  294. route = ospf6_route_create ();
  295. memcpy (&route->prefix, c->address, sizeof (struct prefix));
  296. apply_mask (&route->prefix);
  297. route->type = OSPF6_DEST_TYPE_NETWORK;
  298. route->path.area_id = oi->area->area_id;
  299. route->path.type = OSPF6_PATH_TYPE_INTRA;
  300. route->path.cost = oi->cost;
  301. route->nexthop[0].ifindex = oi->interface->ifindex;
  302. inet_pton (AF_INET6, "::1", &route->nexthop[0].address);
  303. ospf6_route_add (route, oi->route_connected);
  304. }
  305. /* create new Link-LSA */
  306. OSPF6_LINK_LSA_SCHEDULE (oi);
  307. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  308. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  309. }
  310. static void
  311. ospf6_interface_state_change (u_char next_state, struct ospf6_interface *oi)
  312. {
  313. u_char prev_state;
  314. prev_state = oi->state;
  315. oi->state = next_state;
  316. if (prev_state == next_state)
  317. return;
  318. /* log */
  319. if (IS_OSPF6_DEBUG_INTERFACE)
  320. {
  321. zlog_debug ("Interface state change %s: %s -> %s", oi->interface->name,
  322. ospf6_interface_state_str[prev_state],
  323. ospf6_interface_state_str[next_state]);
  324. }
  325. if ((prev_state == OSPF6_INTERFACE_DR ||
  326. prev_state == OSPF6_INTERFACE_BDR) &&
  327. (next_state != OSPF6_INTERFACE_DR &&
  328. next_state != OSPF6_INTERFACE_BDR))
  329. ospf6_leave_alldrouters (oi->interface->ifindex);
  330. if ((prev_state != OSPF6_INTERFACE_DR &&
  331. prev_state != OSPF6_INTERFACE_BDR) &&
  332. (next_state == OSPF6_INTERFACE_DR ||
  333. next_state == OSPF6_INTERFACE_BDR))
  334. ospf6_join_alldrouters (oi->interface->ifindex);
  335. OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
  336. if (next_state == OSPF6_INTERFACE_DOWN)
  337. {
  338. OSPF6_NETWORK_LSA_EXECUTE (oi);
  339. OSPF6_INTRA_PREFIX_LSA_EXECUTE_TRANSIT (oi);
  340. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  341. }
  342. else if (prev_state == OSPF6_INTERFACE_DR ||
  343. next_state == OSPF6_INTERFACE_DR)
  344. {
  345. OSPF6_NETWORK_LSA_SCHEDULE (oi);
  346. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  347. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  348. }
  349. }
  350. /* DR Election, RFC2328 section 9.4 */
  351. #define IS_ELIGIBLE(n) \
  352. ((n)->state >= OSPF6_NEIGHBOR_TWOWAY && (n)->priority != 0)
  353. static struct ospf6_neighbor *
  354. better_bdrouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
  355. {
  356. if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id) &&
  357. (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id))
  358. return NULL;
  359. else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter == a->router_id)
  360. return b;
  361. else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter == b->router_id)
  362. return a;
  363. if (a->bdrouter == a->router_id && b->bdrouter != b->router_id)
  364. return a;
  365. if (a->bdrouter != a->router_id && b->bdrouter == b->router_id)
  366. return b;
  367. if (a->priority > b->priority)
  368. return a;
  369. if (a->priority < b->priority)
  370. return b;
  371. if (ntohl (a->router_id) > ntohl (b->router_id))
  372. return a;
  373. if (ntohl (a->router_id) < ntohl (b->router_id))
  374. return b;
  375. zlog_warn ("Router-ID duplicate ?");
  376. return a;
  377. }
  378. static struct ospf6_neighbor *
  379. better_drouter (struct ospf6_neighbor *a, struct ospf6_neighbor *b)
  380. {
  381. if ((a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id) &&
  382. (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id))
  383. return NULL;
  384. else if (a == NULL || ! IS_ELIGIBLE (a) || a->drouter != a->router_id)
  385. return b;
  386. else if (b == NULL || ! IS_ELIGIBLE (b) || b->drouter != b->router_id)
  387. return a;
  388. if (a->drouter == a->router_id && b->drouter != b->router_id)
  389. return a;
  390. if (a->drouter != a->router_id && b->drouter == b->router_id)
  391. return b;
  392. if (a->priority > b->priority)
  393. return a;
  394. if (a->priority < b->priority)
  395. return b;
  396. if (ntohl (a->router_id) > ntohl (b->router_id))
  397. return a;
  398. if (ntohl (a->router_id) < ntohl (b->router_id))
  399. return b;
  400. zlog_warn ("Router-ID duplicate ?");
  401. return a;
  402. }
  403. static u_char
  404. dr_election (struct ospf6_interface *oi)
  405. {
  406. struct listnode *node, *nnode;
  407. struct ospf6_neighbor *on, *drouter, *bdrouter, myself;
  408. struct ospf6_neighbor *best_drouter, *best_bdrouter;
  409. u_char next_state = 0;
  410. drouter = bdrouter = NULL;
  411. best_drouter = best_bdrouter = NULL;
  412. /* pseudo neighbor myself, including noting current DR/BDR (1) */
  413. memset (&myself, 0, sizeof (myself));
  414. inet_ntop (AF_INET, &oi->area->ospf6->router_id, myself.name,
  415. sizeof (myself.name));
  416. myself.state = OSPF6_NEIGHBOR_TWOWAY;
  417. myself.drouter = oi->drouter;
  418. myself.bdrouter = oi->bdrouter;
  419. myself.priority = oi->priority;
  420. myself.router_id = oi->area->ospf6->router_id;
  421. /* Electing BDR (2) */
  422. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  423. bdrouter = better_bdrouter (bdrouter, on);
  424. best_bdrouter = bdrouter;
  425. bdrouter = better_bdrouter (best_bdrouter, &myself);
  426. /* Electing DR (3) */
  427. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  428. drouter = better_drouter (drouter, on);
  429. best_drouter = drouter;
  430. drouter = better_drouter (best_drouter, &myself);
  431. if (drouter == NULL)
  432. drouter = bdrouter;
  433. /* the router itself is newly/no longer DR/BDR (4) */
  434. if ((drouter == &myself && myself.drouter != myself.router_id) ||
  435. (drouter != &myself && myself.drouter == myself.router_id) ||
  436. (bdrouter == &myself && myself.bdrouter != myself.router_id) ||
  437. (bdrouter != &myself && myself.bdrouter == myself.router_id))
  438. {
  439. myself.drouter = (drouter ? drouter->router_id : htonl (0));
  440. myself.bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
  441. /* compatible to Electing BDR (2) */
  442. bdrouter = better_bdrouter (best_bdrouter, &myself);
  443. /* compatible to Electing DR (3) */
  444. drouter = better_drouter (best_drouter, &myself);
  445. if (drouter == NULL)
  446. drouter = bdrouter;
  447. }
  448. /* Set interface state accordingly (5) */
  449. if (drouter && drouter == &myself)
  450. next_state = OSPF6_INTERFACE_DR;
  451. else if (bdrouter && bdrouter == &myself)
  452. next_state = OSPF6_INTERFACE_BDR;
  453. else
  454. next_state = OSPF6_INTERFACE_DROTHER;
  455. /* If NBMA, schedule Start for each neighbor having priority of 0 (6) */
  456. /* XXX */
  457. /* If DR or BDR change, invoke AdjOK? for each neighbor (7) */
  458. /* RFC 2328 section 12.4. Originating LSAs (3) will be handled
  459. accordingly after AdjOK */
  460. if (oi->drouter != (drouter ? drouter->router_id : htonl (0)) ||
  461. oi->bdrouter != (bdrouter ? bdrouter->router_id : htonl (0)))
  462. {
  463. if (IS_OSPF6_DEBUG_INTERFACE)
  464. zlog_debug ("DR Election on %s: DR: %s BDR: %s", oi->interface->name,
  465. (drouter ? drouter->name : "0.0.0.0"),
  466. (bdrouter ? bdrouter->name : "0.0.0.0"));
  467. for (ALL_LIST_ELEMENTS_RO (oi->neighbor_list, node, on))
  468. {
  469. if (on->state < OSPF6_NEIGHBOR_TWOWAY)
  470. continue;
  471. /* Schedule AdjOK. */
  472. thread_add_event (master, adj_ok, on, 0);
  473. }
  474. }
  475. oi->drouter = (drouter ? drouter->router_id : htonl (0));
  476. oi->bdrouter = (bdrouter ? bdrouter->router_id : htonl (0));
  477. return next_state;
  478. }
  479. /* Interface State Machine */
  480. int
  481. interface_up (struct thread *thread)
  482. {
  483. struct ospf6_interface *oi;
  484. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  485. assert (oi && oi->interface);
  486. if (IS_OSPF6_DEBUG_INTERFACE)
  487. zlog_debug ("Interface Event %s: [InterfaceUp]",
  488. oi->interface->name);
  489. /* check physical interface is up */
  490. if (! if_is_up (oi->interface))
  491. {
  492. if (IS_OSPF6_DEBUG_INTERFACE)
  493. zlog_debug ("Interface %s is down, can't execute [InterfaceUp]",
  494. oi->interface->name);
  495. return 0;
  496. }
  497. /* if already enabled, do nothing */
  498. if (oi->state > OSPF6_INTERFACE_DOWN)
  499. {
  500. if (IS_OSPF6_DEBUG_INTERFACE)
  501. zlog_debug ("Interface %s already enabled",
  502. oi->interface->name);
  503. return 0;
  504. }
  505. /* Join AllSPFRouters */
  506. ospf6_join_allspfrouters (oi->interface->ifindex);
  507. /* Update interface route */
  508. ospf6_interface_connected_route_update (oi->interface);
  509. /* Schedule Hello */
  510. if (! CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
  511. thread_add_event (master, ospf6_hello_send, oi, 0);
  512. /* decide next interface state */
  513. if (if_is_pointopoint (oi->interface))
  514. ospf6_interface_state_change (OSPF6_INTERFACE_POINTTOPOINT, oi);
  515. else if (oi->priority == 0)
  516. ospf6_interface_state_change (OSPF6_INTERFACE_DROTHER, oi);
  517. else
  518. {
  519. ospf6_interface_state_change (OSPF6_INTERFACE_WAITING, oi);
  520. thread_add_timer (master, wait_timer, oi, oi->dead_interval);
  521. }
  522. return 0;
  523. }
  524. int
  525. wait_timer (struct thread *thread)
  526. {
  527. struct ospf6_interface *oi;
  528. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  529. assert (oi && oi->interface);
  530. if (IS_OSPF6_DEBUG_INTERFACE)
  531. zlog_debug ("Interface Event %s: [WaitTimer]",
  532. oi->interface->name);
  533. if (oi->state == OSPF6_INTERFACE_WAITING)
  534. ospf6_interface_state_change (dr_election (oi), oi);
  535. return 0;
  536. }
  537. int
  538. backup_seen (struct thread *thread)
  539. {
  540. struct ospf6_interface *oi;
  541. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  542. assert (oi && oi->interface);
  543. if (IS_OSPF6_DEBUG_INTERFACE)
  544. zlog_debug ("Interface Event %s: [BackupSeen]",
  545. oi->interface->name);
  546. if (oi->state == OSPF6_INTERFACE_WAITING)
  547. ospf6_interface_state_change (dr_election (oi), oi);
  548. return 0;
  549. }
  550. int
  551. neighbor_change (struct thread *thread)
  552. {
  553. struct ospf6_interface *oi;
  554. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  555. assert (oi && oi->interface);
  556. if (IS_OSPF6_DEBUG_INTERFACE)
  557. zlog_debug ("Interface Event %s: [NeighborChange]",
  558. oi->interface->name);
  559. if (oi->state == OSPF6_INTERFACE_DROTHER ||
  560. oi->state == OSPF6_INTERFACE_BDR ||
  561. oi->state == OSPF6_INTERFACE_DR)
  562. ospf6_interface_state_change (dr_election (oi), oi);
  563. return 0;
  564. }
  565. static int
  566. loopind (struct thread *thread)
  567. {
  568. struct ospf6_interface *oi;
  569. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  570. assert (oi && oi->interface);
  571. if (IS_OSPF6_DEBUG_INTERFACE)
  572. zlog_debug ("Interface Event %s: [LoopInd]",
  573. oi->interface->name);
  574. /* XXX not yet */
  575. return 0;
  576. }
  577. int
  578. interface_down (struct thread *thread)
  579. {
  580. struct ospf6_interface *oi;
  581. struct listnode *node, *nnode;
  582. struct ospf6_neighbor *on;
  583. oi = (struct ospf6_interface *) THREAD_ARG (thread);
  584. assert (oi && oi->interface);
  585. if (IS_OSPF6_DEBUG_INTERFACE)
  586. zlog_debug ("Interface Event %s: [InterfaceDown]",
  587. oi->interface->name);
  588. /* Leave AllSPFRouters */
  589. if (oi->state > OSPF6_INTERFACE_DOWN)
  590. ospf6_leave_allspfrouters (oi->interface->ifindex);
  591. ospf6_interface_state_change (OSPF6_INTERFACE_DOWN, oi);
  592. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  593. ospf6_neighbor_delete (on);
  594. list_delete_all_node (oi->neighbor_list);
  595. return 0;
  596. }
  597. /* show specified interface structure */
  598. static int
  599. ospf6_interface_show (struct vty *vty, struct interface *ifp)
  600. {
  601. struct ospf6_interface *oi;
  602. struct connected *c;
  603. struct prefix *p;
  604. struct listnode *i;
  605. char strbuf[64], drouter[32], bdrouter[32];
  606. const char *updown[3] = {"down", "up", NULL};
  607. const char *type;
  608. struct timeval res, now;
  609. char duration[32];
  610. struct ospf6_lsa *lsa;
  611. /* check physical interface type */
  612. if (if_is_loopback (ifp))
  613. type = "LOOPBACK";
  614. else if (if_is_broadcast (ifp))
  615. type = "BROADCAST";
  616. else if (if_is_pointopoint (ifp))
  617. type = "POINTOPOINT";
  618. else
  619. type = "UNKNOWN";
  620. vty_out (vty, "%s is %s, type %s%s",
  621. ifp->name, updown[if_is_up (ifp)], type,
  622. VNL);
  623. vty_out (vty, " Interface ID: %d%s", ifp->ifindex, VNL);
  624. if (ifp->info == NULL)
  625. {
  626. vty_out (vty, " OSPF not enabled on this interface%s", VNL);
  627. return 0;
  628. }
  629. else
  630. oi = (struct ospf6_interface *) ifp->info;
  631. vty_out (vty, " Internet Address:%s", VNL);
  632. for (ALL_LIST_ELEMENTS_RO (ifp->connected, i, c))
  633. {
  634. p = c->address;
  635. prefix2str (p, strbuf, sizeof (strbuf));
  636. switch (p->family)
  637. {
  638. case AF_INET:
  639. vty_out (vty, " inet : %s%s", strbuf,
  640. VNL);
  641. break;
  642. case AF_INET6:
  643. vty_out (vty, " inet6: %s%s", strbuf,
  644. VNL);
  645. break;
  646. default:
  647. vty_out (vty, " ??? : %s%s", strbuf,
  648. VNL);
  649. break;
  650. }
  651. }
  652. if (oi->area)
  653. {
  654. vty_out (vty, " Instance ID %d, Interface MTU %d (autodetect: %d)%s",
  655. oi->instance_id, oi->ifmtu, ifp->mtu6, VNL);
  656. inet_ntop (AF_INET, &oi->area->area_id,
  657. strbuf, sizeof (strbuf));
  658. vty_out (vty, " Area ID %s, Cost %hu%s", strbuf, oi->cost,
  659. VNL);
  660. }
  661. else
  662. vty_out (vty, " Not Attached to Area%s", VNL);
  663. vty_out (vty, " State %s, Transmit Delay %d sec, Priority %d%s",
  664. ospf6_interface_state_str[oi->state],
  665. oi->transdelay, oi->priority,
  666. VNL);
  667. vty_out (vty, " Timer intervals configured:%s", VNL);
  668. vty_out (vty, " Hello %d, Dead %d, Retransmit %d%s",
  669. oi->hello_interval, oi->dead_interval, oi->rxmt_interval,
  670. VNL);
  671. inet_ntop (AF_INET, &oi->drouter, drouter, sizeof (drouter));
  672. inet_ntop (AF_INET, &oi->bdrouter, bdrouter, sizeof (bdrouter));
  673. vty_out (vty, " DR: %s BDR: %s%s", drouter, bdrouter, VNL);
  674. vty_out (vty, " Number of I/F scoped LSAs is %u%s",
  675. oi->lsdb->count, VNL);
  676. quagga_gettime (QUAGGA_CLK_MONOTONIC, &now);
  677. timerclear (&res);
  678. if (oi->thread_send_lsupdate)
  679. timersub (&oi->thread_send_lsupdate->u.sands, &now, &res);
  680. timerstring (&res, duration, sizeof (duration));
  681. vty_out (vty, " %d Pending LSAs for LSUpdate in Time %s [thread %s]%s",
  682. oi->lsupdate_list->count, duration,
  683. (oi->thread_send_lsupdate ? "on" : "off"),
  684. VNL);
  685. for (lsa = ospf6_lsdb_head (oi->lsupdate_list); lsa;
  686. lsa = ospf6_lsdb_next (lsa))
  687. vty_out (vty, " %s%s", lsa->name, VNL);
  688. timerclear (&res);
  689. if (oi->thread_send_lsack)
  690. timersub (&oi->thread_send_lsack->u.sands, &now, &res);
  691. timerstring (&res, duration, sizeof (duration));
  692. vty_out (vty, " %d Pending LSAs for LSAck in Time %s [thread %s]%s",
  693. oi->lsack_list->count, duration,
  694. (oi->thread_send_lsack ? "on" : "off"),
  695. VNL);
  696. for (lsa = ospf6_lsdb_head (oi->lsack_list); lsa;
  697. lsa = ospf6_lsdb_next (lsa))
  698. vty_out (vty, " %s%s", lsa->name, VNL);
  699. return 0;
  700. }
  701. /* show interface */
  702. DEFUN (show_ipv6_ospf6_interface,
  703. show_ipv6_ospf6_interface_ifname_cmd,
  704. "show ipv6 ospf6 interface IFNAME",
  705. SHOW_STR
  706. IP6_STR
  707. OSPF6_STR
  708. INTERFACE_STR
  709. IFNAME_STR
  710. )
  711. {
  712. struct interface *ifp;
  713. struct listnode *i;
  714. if (argc)
  715. {
  716. ifp = if_lookup_by_name (argv[0]);
  717. if (ifp == NULL)
  718. {
  719. vty_out (vty, "No such Interface: %s%s", argv[0],
  720. VNL);
  721. return CMD_WARNING;
  722. }
  723. ospf6_interface_show (vty, ifp);
  724. }
  725. else
  726. {
  727. for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
  728. ospf6_interface_show (vty, ifp);
  729. }
  730. return CMD_SUCCESS;
  731. }
  732. ALIAS (show_ipv6_ospf6_interface,
  733. show_ipv6_ospf6_interface_cmd,
  734. "show ipv6 ospf6 interface",
  735. SHOW_STR
  736. IP6_STR
  737. OSPF6_STR
  738. INTERFACE_STR
  739. )
  740. DEFUN (show_ipv6_ospf6_interface_ifname_prefix,
  741. show_ipv6_ospf6_interface_ifname_prefix_cmd,
  742. "show ipv6 ospf6 interface IFNAME prefix",
  743. SHOW_STR
  744. IP6_STR
  745. OSPF6_STR
  746. INTERFACE_STR
  747. IFNAME_STR
  748. "Display connected prefixes to advertise\n"
  749. )
  750. {
  751. struct interface *ifp;
  752. struct ospf6_interface *oi;
  753. ifp = if_lookup_by_name (argv[0]);
  754. if (ifp == NULL)
  755. {
  756. vty_out (vty, "No such Interface: %s%s", argv[0], VNL);
  757. return CMD_WARNING;
  758. }
  759. oi = ifp->info;
  760. if (oi == NULL)
  761. {
  762. vty_out (vty, "OSPFv3 is not enabled on %s%s", argv[0], VNL);
  763. return CMD_WARNING;
  764. }
  765. argc--;
  766. argv++;
  767. ospf6_route_table_show (vty, argc, argv, oi->route_connected);
  768. return CMD_SUCCESS;
  769. }
  770. ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
  771. show_ipv6_ospf6_interface_ifname_prefix_detail_cmd,
  772. "show ipv6 ospf6 interface IFNAME prefix (X:X::X:X|X:X::X:X/M|detail)",
  773. SHOW_STR
  774. IP6_STR
  775. OSPF6_STR
  776. INTERFACE_STR
  777. IFNAME_STR
  778. "Display connected prefixes to advertise\n"
  779. OSPF6_ROUTE_ADDRESS_STR
  780. OSPF6_ROUTE_PREFIX_STR
  781. "Dispaly details of the prefixes\n"
  782. )
  783. ALIAS (show_ipv6_ospf6_interface_ifname_prefix,
  784. show_ipv6_ospf6_interface_ifname_prefix_match_cmd,
  785. "show ipv6 ospf6 interface IFNAME prefix X:X::X:X/M (match|detail)",
  786. SHOW_STR
  787. IP6_STR
  788. OSPF6_STR
  789. INTERFACE_STR
  790. IFNAME_STR
  791. "Display connected prefixes to advertise\n"
  792. OSPF6_ROUTE_PREFIX_STR
  793. OSPF6_ROUTE_MATCH_STR
  794. "Dispaly details of the prefixes\n"
  795. )
  796. DEFUN (show_ipv6_ospf6_interface_prefix,
  797. show_ipv6_ospf6_interface_prefix_cmd,
  798. "show ipv6 ospf6 interface prefix",
  799. SHOW_STR
  800. IP6_STR
  801. OSPF6_STR
  802. INTERFACE_STR
  803. "Display connected prefixes to advertise\n"
  804. )
  805. {
  806. struct listnode *i;
  807. struct ospf6_interface *oi;
  808. struct interface *ifp;
  809. for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
  810. {
  811. oi = (struct ospf6_interface *) ifp->info;
  812. if (oi == NULL)
  813. continue;
  814. ospf6_route_table_show (vty, argc, argv, oi->route_connected);
  815. }
  816. return CMD_SUCCESS;
  817. }
  818. ALIAS (show_ipv6_ospf6_interface_prefix,
  819. show_ipv6_ospf6_interface_prefix_detail_cmd,
  820. "show ipv6 ospf6 interface prefix (X:X::X:X|X:X::X:X/M|detail)",
  821. SHOW_STR
  822. IP6_STR
  823. OSPF6_STR
  824. INTERFACE_STR
  825. "Display connected prefixes to advertise\n"
  826. OSPF6_ROUTE_ADDRESS_STR
  827. OSPF6_ROUTE_PREFIX_STR
  828. "Dispaly details of the prefixes\n"
  829. )
  830. ALIAS (show_ipv6_ospf6_interface_prefix,
  831. show_ipv6_ospf6_interface_prefix_match_cmd,
  832. "show ipv6 ospf6 interface prefix X:X::X:X/M (match|detail)",
  833. SHOW_STR
  834. IP6_STR
  835. OSPF6_STR
  836. INTERFACE_STR
  837. "Display connected prefixes to advertise\n"
  838. OSPF6_ROUTE_PREFIX_STR
  839. OSPF6_ROUTE_MATCH_STR
  840. "Dispaly details of the prefixes\n"
  841. )
  842. /* interface variable set command */
  843. DEFUN (ipv6_ospf6_ifmtu,
  844. ipv6_ospf6_ifmtu_cmd,
  845. "ipv6 ospf6 ifmtu <1-65535>",
  846. IP6_STR
  847. OSPF6_STR
  848. "Interface MTU\n"
  849. "OSPFv3 Interface MTU\n"
  850. )
  851. {
  852. struct ospf6_interface *oi;
  853. struct interface *ifp;
  854. unsigned int ifmtu, iobuflen;
  855. struct listnode *node, *nnode;
  856. struct ospf6_neighbor *on;
  857. ifp = (struct interface *) vty->index;
  858. assert (ifp);
  859. oi = (struct ospf6_interface *) ifp->info;
  860. if (oi == NULL)
  861. oi = ospf6_interface_create (ifp);
  862. assert (oi);
  863. ifmtu = strtol (argv[0], NULL, 10);
  864. if (oi->ifmtu == ifmtu)
  865. return CMD_SUCCESS;
  866. if (ifp->mtu6 != 0 && ifp->mtu6 < ifmtu)
  867. {
  868. vty_out (vty, "%s's ospf6 ifmtu cannot go beyond physical mtu (%d)%s",
  869. ifp->name, ifp->mtu6, VNL);
  870. return CMD_WARNING;
  871. }
  872. if (oi->ifmtu < ifmtu)
  873. {
  874. iobuflen = ospf6_iobuf_size (ifmtu);
  875. if (iobuflen < ifmtu)
  876. {
  877. vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
  878. ifp->name, iobuflen, VNL);
  879. oi->ifmtu = iobuflen;
  880. }
  881. else
  882. oi->ifmtu = ifmtu;
  883. }
  884. else
  885. oi->ifmtu = ifmtu;
  886. /* re-establish adjacencies */
  887. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  888. {
  889. THREAD_OFF (on->inactivity_timer);
  890. thread_add_event (master, inactivity_timer, on, 0);
  891. }
  892. return CMD_SUCCESS;
  893. }
  894. DEFUN (no_ipv6_ospf6_ifmtu,
  895. no_ipv6_ospf6_ifmtu_cmd,
  896. "no ipv6 ospf6 ifmtu",
  897. NO_STR
  898. IP6_STR
  899. OSPF6_STR
  900. "Interface MTU\n"
  901. )
  902. {
  903. struct ospf6_interface *oi;
  904. struct interface *ifp;
  905. unsigned int iobuflen;
  906. struct listnode *node, *nnode;
  907. struct ospf6_neighbor *on;
  908. ifp = (struct interface *) vty->index;
  909. assert (ifp);
  910. oi = (struct ospf6_interface *) ifp->info;
  911. if (oi == NULL)
  912. oi = ospf6_interface_create (ifp);
  913. assert (oi);
  914. if (oi->ifmtu < ifp->mtu)
  915. {
  916. iobuflen = ospf6_iobuf_size (ifp->mtu);
  917. if (iobuflen < ifp->mtu)
  918. {
  919. vty_out (vty, "%s's ifmtu is adjusted to I/O buffer size (%d).%s",
  920. ifp->name, iobuflen, VNL);
  921. oi->ifmtu = iobuflen;
  922. }
  923. else
  924. oi->ifmtu = ifp->mtu;
  925. }
  926. else
  927. oi->ifmtu = ifp->mtu;
  928. /* re-establish adjacencies */
  929. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  930. {
  931. THREAD_OFF (on->inactivity_timer);
  932. thread_add_event (master, inactivity_timer, on, 0);
  933. }
  934. return CMD_SUCCESS;
  935. }
  936. DEFUN (ipv6_ospf6_cost,
  937. ipv6_ospf6_cost_cmd,
  938. "ipv6 ospf6 cost <1-65535>",
  939. IP6_STR
  940. OSPF6_STR
  941. "Interface cost\n"
  942. "Outgoing metric of this interface\n"
  943. )
  944. {
  945. struct ospf6_interface *oi;
  946. struct interface *ifp;
  947. unsigned long int lcost;
  948. ifp = (struct interface *) vty->index;
  949. assert (ifp);
  950. oi = (struct ospf6_interface *) ifp->info;
  951. if (oi == NULL)
  952. oi = ospf6_interface_create (ifp);
  953. assert (oi);
  954. lcost = strtol (argv[0], NULL, 10);
  955. if (lcost > UINT32_MAX)
  956. {
  957. vty_out (vty, "Cost %ld is out of range%s", lcost, VNL);
  958. return CMD_WARNING;
  959. }
  960. if (oi->cost == lcost)
  961. return CMD_SUCCESS;
  962. oi->cost = lcost;
  963. /* update cost held in route_connected list in ospf6_interface */
  964. ospf6_interface_connected_route_update (oi->interface);
  965. /* execute LSA hooks */
  966. if (oi->area)
  967. {
  968. OSPF6_LINK_LSA_SCHEDULE (oi);
  969. OSPF6_ROUTER_LSA_SCHEDULE (oi->area);
  970. OSPF6_NETWORK_LSA_SCHEDULE (oi);
  971. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  972. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  973. }
  974. return CMD_SUCCESS;
  975. }
  976. DEFUN (ipv6_ospf6_hellointerval,
  977. ipv6_ospf6_hellointerval_cmd,
  978. "ipv6 ospf6 hello-interval <1-65535>",
  979. IP6_STR
  980. OSPF6_STR
  981. "Interval time of Hello packets\n"
  982. SECONDS_STR
  983. )
  984. {
  985. struct ospf6_interface *oi;
  986. struct interface *ifp;
  987. ifp = (struct interface *) vty->index;
  988. assert (ifp);
  989. oi = (struct ospf6_interface *) ifp->info;
  990. if (oi == NULL)
  991. oi = ospf6_interface_create (ifp);
  992. assert (oi);
  993. oi->hello_interval = strtol (argv[0], NULL, 10);
  994. return CMD_SUCCESS;
  995. }
  996. /* interface variable set command */
  997. DEFUN (ipv6_ospf6_deadinterval,
  998. ipv6_ospf6_deadinterval_cmd,
  999. "ipv6 ospf6 dead-interval <1-65535>",
  1000. IP6_STR
  1001. OSPF6_STR
  1002. "Interval time after which a neighbor is declared down\n"
  1003. SECONDS_STR
  1004. )
  1005. {
  1006. struct ospf6_interface *oi;
  1007. struct interface *ifp;
  1008. ifp = (struct interface *) vty->index;
  1009. assert (ifp);
  1010. oi = (struct ospf6_interface *) ifp->info;
  1011. if (oi == NULL)
  1012. oi = ospf6_interface_create (ifp);
  1013. assert (oi);
  1014. oi->dead_interval = strtol (argv[0], NULL, 10);
  1015. return CMD_SUCCESS;
  1016. }
  1017. /* interface variable set command */
  1018. DEFUN (ipv6_ospf6_transmitdelay,
  1019. ipv6_ospf6_transmitdelay_cmd,
  1020. "ipv6 ospf6 transmit-delay <1-3600>",
  1021. IP6_STR
  1022. OSPF6_STR
  1023. "Transmit delay of this interface\n"
  1024. SECONDS_STR
  1025. )
  1026. {
  1027. struct ospf6_interface *oi;
  1028. struct interface *ifp;
  1029. ifp = (struct interface *) vty->index;
  1030. assert (ifp);
  1031. oi = (struct ospf6_interface *) ifp->info;
  1032. if (oi == NULL)
  1033. oi = ospf6_interface_create (ifp);
  1034. assert (oi);
  1035. oi->transdelay = strtol (argv[0], NULL, 10);
  1036. return CMD_SUCCESS;
  1037. }
  1038. /* interface variable set command */
  1039. DEFUN (ipv6_ospf6_retransmitinterval,
  1040. ipv6_ospf6_retransmitinterval_cmd,
  1041. "ipv6 ospf6 retransmit-interval <1-65535>",
  1042. IP6_STR
  1043. OSPF6_STR
  1044. "Time between retransmitting lost link state advertisements\n"
  1045. SECONDS_STR
  1046. )
  1047. {
  1048. struct ospf6_interface *oi;
  1049. struct interface *ifp;
  1050. ifp = (struct interface *) vty->index;
  1051. assert (ifp);
  1052. oi = (struct ospf6_interface *) ifp->info;
  1053. if (oi == NULL)
  1054. oi = ospf6_interface_create (ifp);
  1055. assert (oi);
  1056. oi->rxmt_interval = strtol (argv[0], NULL, 10);
  1057. return CMD_SUCCESS;
  1058. }
  1059. /* interface variable set command */
  1060. DEFUN (ipv6_ospf6_priority,
  1061. ipv6_ospf6_priority_cmd,
  1062. "ipv6 ospf6 priority <0-255>",
  1063. IP6_STR
  1064. OSPF6_STR
  1065. "Router priority\n"
  1066. "Priority value\n"
  1067. )
  1068. {
  1069. struct ospf6_interface *oi;
  1070. struct interface *ifp;
  1071. ifp = (struct interface *) vty->index;
  1072. assert (ifp);
  1073. oi = (struct ospf6_interface *) ifp->info;
  1074. if (oi == NULL)
  1075. oi = ospf6_interface_create (ifp);
  1076. assert (oi);
  1077. oi->priority = strtol (argv[0], NULL, 10);
  1078. if (oi->area)
  1079. ospf6_interface_state_change (dr_election (oi), oi);
  1080. return CMD_SUCCESS;
  1081. }
  1082. DEFUN (ipv6_ospf6_instance,
  1083. ipv6_ospf6_instance_cmd,
  1084. "ipv6 ospf6 instance-id <0-255>",
  1085. IP6_STR
  1086. OSPF6_STR
  1087. "Instance ID for this interface\n"
  1088. "Instance ID value\n"
  1089. )
  1090. {
  1091. struct ospf6_interface *oi;
  1092. struct interface *ifp;
  1093. ifp = (struct interface *)vty->index;
  1094. assert (ifp);
  1095. oi = (struct ospf6_interface *)ifp->info;
  1096. if (oi == NULL)
  1097. oi = ospf6_interface_create (ifp);
  1098. assert (oi);
  1099. oi->instance_id = strtol (argv[0], NULL, 10);
  1100. return CMD_SUCCESS;
  1101. }
  1102. DEFUN (ipv6_ospf6_passive,
  1103. ipv6_ospf6_passive_cmd,
  1104. "ipv6 ospf6 passive",
  1105. IP6_STR
  1106. OSPF6_STR
  1107. "passive interface, No adjacency will be formed on this interface\n"
  1108. )
  1109. {
  1110. struct ospf6_interface *oi;
  1111. struct interface *ifp;
  1112. struct listnode *node, *nnode;
  1113. struct ospf6_neighbor *on;
  1114. ifp = (struct interface *) vty->index;
  1115. assert (ifp);
  1116. oi = (struct ospf6_interface *) ifp->info;
  1117. if (oi == NULL)
  1118. oi = ospf6_interface_create (ifp);
  1119. assert (oi);
  1120. SET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
  1121. THREAD_OFF (oi->thread_send_hello);
  1122. for (ALL_LIST_ELEMENTS (oi->neighbor_list, node, nnode, on))
  1123. {
  1124. THREAD_OFF (on->inactivity_timer);
  1125. thread_add_event (master, inactivity_timer, on, 0);
  1126. }
  1127. return CMD_SUCCESS;
  1128. }
  1129. DEFUN (no_ipv6_ospf6_passive,
  1130. no_ipv6_ospf6_passive_cmd,
  1131. "no ipv6 ospf6 passive",
  1132. NO_STR
  1133. IP6_STR
  1134. OSPF6_STR
  1135. "passive interface: No Adjacency will be formed on this I/F\n"
  1136. )
  1137. {
  1138. struct ospf6_interface *oi;
  1139. struct interface *ifp;
  1140. ifp = (struct interface *) vty->index;
  1141. assert (ifp);
  1142. oi = (struct ospf6_interface *) ifp->info;
  1143. if (oi == NULL)
  1144. oi = ospf6_interface_create (ifp);
  1145. assert (oi);
  1146. UNSET_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE);
  1147. THREAD_OFF (oi->thread_send_hello);
  1148. oi->thread_send_hello =
  1149. thread_add_event (master, ospf6_hello_send, oi, 0);
  1150. return CMD_SUCCESS;
  1151. }
  1152. DEFUN (ipv6_ospf6_advertise_prefix_list,
  1153. ipv6_ospf6_advertise_prefix_list_cmd,
  1154. "ipv6 ospf6 advertise prefix-list WORD",
  1155. IP6_STR
  1156. OSPF6_STR
  1157. "Advertising options\n"
  1158. "Filter prefix using prefix-list\n"
  1159. "Prefix list name\n"
  1160. )
  1161. {
  1162. struct ospf6_interface *oi;
  1163. struct interface *ifp;
  1164. ifp = (struct interface *) vty->index;
  1165. assert (ifp);
  1166. oi = (struct ospf6_interface *) ifp->info;
  1167. if (oi == NULL)
  1168. oi = ospf6_interface_create (ifp);
  1169. assert (oi);
  1170. if (oi->plist_name)
  1171. XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
  1172. oi->plist_name = XSTRDUP (MTYPE_PREFIX_LIST_STR, argv[0]);
  1173. ospf6_interface_connected_route_update (oi->interface);
  1174. OSPF6_LINK_LSA_SCHEDULE (oi);
  1175. if (oi->state == OSPF6_INTERFACE_DR)
  1176. {
  1177. OSPF6_NETWORK_LSA_SCHEDULE (oi);
  1178. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  1179. }
  1180. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  1181. return CMD_SUCCESS;
  1182. }
  1183. DEFUN (no_ipv6_ospf6_advertise_prefix_list,
  1184. no_ipv6_ospf6_advertise_prefix_list_cmd,
  1185. "no ipv6 ospf6 advertise prefix-list",
  1186. NO_STR
  1187. IP6_STR
  1188. OSPF6_STR
  1189. "Advertising options\n"
  1190. "Filter prefix using prefix-list\n"
  1191. )
  1192. {
  1193. struct ospf6_interface *oi;
  1194. struct interface *ifp;
  1195. ifp = (struct interface *) vty->index;
  1196. assert (ifp);
  1197. oi = (struct ospf6_interface *) ifp->info;
  1198. if (oi == NULL)
  1199. oi = ospf6_interface_create (ifp);
  1200. assert (oi);
  1201. if (oi->plist_name)
  1202. {
  1203. XFREE (MTYPE_PREFIX_LIST_STR, oi->plist_name);
  1204. oi->plist_name = NULL;
  1205. }
  1206. ospf6_interface_connected_route_update (oi->interface);
  1207. OSPF6_LINK_LSA_SCHEDULE (oi);
  1208. if (oi->state == OSPF6_INTERFACE_DR)
  1209. {
  1210. OSPF6_NETWORK_LSA_SCHEDULE (oi);
  1211. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_TRANSIT (oi);
  1212. }
  1213. OSPF6_INTRA_PREFIX_LSA_SCHEDULE_STUB (oi->area);
  1214. return CMD_SUCCESS;
  1215. }
  1216. static int
  1217. config_write_ospf6_interface (struct vty *vty)
  1218. {
  1219. struct listnode *i;
  1220. struct ospf6_interface *oi;
  1221. struct interface *ifp;
  1222. for (ALL_LIST_ELEMENTS_RO (iflist, i, ifp))
  1223. {
  1224. oi = (struct ospf6_interface *) ifp->info;
  1225. if (oi == NULL)
  1226. continue;
  1227. vty_out (vty, "interface %s%s",
  1228. oi->interface->name, VNL);
  1229. if (ifp->desc)
  1230. vty_out (vty, " description %s%s", ifp->desc, VNL);
  1231. if (ifp->mtu6 != oi->ifmtu)
  1232. vty_out (vty, " ipv6 ospf6 ifmtu %d%s", oi->ifmtu, VNL);
  1233. vty_out (vty, " ipv6 ospf6 cost %d%s",
  1234. oi->cost, VNL);
  1235. vty_out (vty, " ipv6 ospf6 hello-interval %d%s",
  1236. oi->hello_interval, VNL);
  1237. vty_out (vty, " ipv6 ospf6 dead-interval %d%s",
  1238. oi->dead_interval, VNL);
  1239. vty_out (vty, " ipv6 ospf6 retransmit-interval %d%s",
  1240. oi->rxmt_interval, VNL);
  1241. vty_out (vty, " ipv6 ospf6 priority %d%s",
  1242. oi->priority, VNL);
  1243. vty_out (vty, " ipv6 ospf6 transmit-delay %d%s",
  1244. oi->transdelay, VNL);
  1245. vty_out (vty, " ipv6 ospf6 instance-id %d%s",
  1246. oi->instance_id, VNL);
  1247. if (oi->plist_name)
  1248. vty_out (vty, " ipv6 ospf6 advertise prefix-list %s%s",
  1249. oi->plist_name, VNL);
  1250. if (CHECK_FLAG (oi->flag, OSPF6_INTERFACE_PASSIVE))
  1251. vty_out (vty, " ipv6 ospf6 passive%s", VNL);
  1252. vty_out (vty, "!%s", VNL);
  1253. }
  1254. return 0;
  1255. }
  1256. static struct cmd_node interface_node =
  1257. {
  1258. INTERFACE_NODE,
  1259. "%s(config-if)# ",
  1260. 1 /* VTYSH */
  1261. };
  1262. void
  1263. ospf6_interface_init (void)
  1264. {
  1265. /* Install interface node. */
  1266. install_node (&interface_node, config_write_ospf6_interface);
  1267. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_cmd);
  1268. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
  1269. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
  1270. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
  1271. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
  1272. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
  1273. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
  1274. install_element (VIEW_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
  1275. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_cmd);
  1276. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_cmd);
  1277. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_detail_cmd);
  1278. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_prefix_match_cmd);
  1279. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_cmd);
  1280. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_cmd);
  1281. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_detail_cmd);
  1282. install_element (ENABLE_NODE, &show_ipv6_ospf6_interface_ifname_prefix_match_cmd);
  1283. install_element (CONFIG_NODE, &interface_cmd);
  1284. install_default (INTERFACE_NODE);
  1285. install_element (INTERFACE_NODE, &interface_desc_cmd);
  1286. install_element (INTERFACE_NODE, &no_interface_desc_cmd);
  1287. install_element (INTERFACE_NODE, &ipv6_ospf6_cost_cmd);
  1288. install_element (INTERFACE_NODE, &ipv6_ospf6_ifmtu_cmd);
  1289. install_element (INTERFACE_NODE, &no_ipv6_ospf6_ifmtu_cmd);
  1290. install_element (INTERFACE_NODE, &ipv6_ospf6_deadinterval_cmd);
  1291. install_element (INTERFACE_NODE, &ipv6_ospf6_hellointerval_cmd);
  1292. install_element (INTERFACE_NODE, &ipv6_ospf6_priority_cmd);
  1293. install_element (INTERFACE_NODE, &ipv6_ospf6_retransmitinterval_cmd);
  1294. install_element (INTERFACE_NODE, &ipv6_ospf6_transmitdelay_cmd);
  1295. install_element (INTERFACE_NODE, &ipv6_ospf6_instance_cmd);
  1296. install_element (INTERFACE_NODE, &ipv6_ospf6_passive_cmd);
  1297. install_element (INTERFACE_NODE, &no_ipv6_ospf6_passive_cmd);
  1298. install_element (INTERFACE_NODE, &ipv6_ospf6_advertise_prefix_list_cmd);
  1299. install_element (INTERFACE_NODE, &no_ipv6_ospf6_advertise_prefix_list_cmd);
  1300. }
  1301. DEFUN (debug_ospf6_interface,
  1302. debug_ospf6_interface_cmd,
  1303. "debug ospf6 interface",
  1304. DEBUG_STR
  1305. OSPF6_STR
  1306. "Debug OSPFv3 Interface\n"
  1307. )
  1308. {
  1309. OSPF6_DEBUG_INTERFACE_ON ();
  1310. return CMD_SUCCESS;
  1311. }
  1312. DEFUN (no_debug_ospf6_interface,
  1313. no_debug_ospf6_interface_cmd,
  1314. "no debug ospf6 interface",
  1315. NO_STR
  1316. DEBUG_STR
  1317. OSPF6_STR
  1318. "Debug OSPFv3 Interface\n"
  1319. )
  1320. {
  1321. OSPF6_DEBUG_INTERFACE_OFF ();
  1322. return CMD_SUCCESS;
  1323. }
  1324. int
  1325. config_write_ospf6_debug_interface (struct vty *vty)
  1326. {
  1327. if (IS_OSPF6_DEBUG_INTERFACE)
  1328. vty_out (vty, "debug ospf6 interface%s", VNL);
  1329. return 0;
  1330. }
  1331. void
  1332. install_element_ospf6_debug_interface (void)
  1333. {
  1334. install_element (ENABLE_NODE, &debug_ospf6_interface_cmd);
  1335. install_element (ENABLE_NODE, &no_debug_ospf6_interface_cmd);
  1336. install_element (CONFIG_NODE, &debug_ospf6_interface_cmd);
  1337. install_element (CONFIG_NODE, &no_debug_ospf6_interface_cmd);
  1338. }