ospf6_interface.c 39 KB

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