ospf_opaque.c 71 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487
  1. /*
  2. * This is an implementation of rfc2370.
  3. * Copyright (C) 2001 KDD R&D Laboratories, Inc.
  4. * http://www.kddlabs.co.jp/
  5. *
  6. * This file is part of GNU Zebra.
  7. *
  8. * GNU Zebra is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License as published by the
  10. * Free Software Foundation; either version 2, or (at your option) any
  11. * later version.
  12. *
  13. * GNU Zebra is distributed in the hope that it will be useful, but
  14. * WITHOUT ANY WARRANTY; without even the implied warranty of
  15. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  16. * General Public License for more details.
  17. *
  18. * You should have received a copy of the GNU General Public License
  19. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  20. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  21. * 02111-1307, USA.
  22. */
  23. /***** MTYPE definitions are not reflected to "memory.h" yet. *****/
  24. #define MTYPE_OSPF_OPAQUE_FUNCTAB 0
  25. #define MTYPE_OPAQUE_INFO_PER_TYPE 0
  26. #define MTYPE_OPAQUE_INFO_PER_ID 0
  27. #include <zebra.h>
  28. #ifdef HAVE_OPAQUE_LSA
  29. #include "linklist.h"
  30. #include "prefix.h"
  31. #include "if.h"
  32. #include "table.h"
  33. #include "memory.h"
  34. #include "command.h"
  35. #include "vty.h"
  36. #include "stream.h"
  37. #include "log.h"
  38. #include "thread.h"
  39. #include "hash.h"
  40. #include "sockunion.h" /* for inet_aton() */
  41. #include "ospfd/ospfd.h"
  42. #include "ospfd/ospf_interface.h"
  43. #include "ospfd/ospf_ism.h"
  44. #include "ospfd/ospf_asbr.h"
  45. #include "ospfd/ospf_lsa.h"
  46. #include "ospfd/ospf_lsdb.h"
  47. #include "ospfd/ospf_neighbor.h"
  48. #include "ospfd/ospf_nsm.h"
  49. #include "ospfd/ospf_flood.h"
  50. #include "ospfd/ospf_packet.h"
  51. #include "ospfd/ospf_spf.h"
  52. #include "ospfd/ospf_dump.h"
  53. #include "ospfd/ospf_route.h"
  54. #include "ospfd/ospf_ase.h"
  55. #include "ospfd/ospf_zebra.h"
  56. /*------------------------------------------------------------------------*
  57. * Followings are initialize/terminate functions for Opaque-LSAs handling.
  58. *------------------------------------------------------------------------*/
  59. #ifdef HAVE_OSPF_TE
  60. #include "ospfd/ospf_te.h"
  61. #endif /* HAVE_OSPF_TE */
  62. #ifdef SUPPORT_OSPF_API
  63. int ospf_apiserver_init (void);
  64. void ospf_apiserver_term (void);
  65. /* Init apiserver? It's disabled by default. */
  66. int ospf_apiserver_enable;
  67. #endif /* SUPPORT_OSPF_API */
  68. static void ospf_opaque_register_vty (void);
  69. static void ospf_opaque_funclist_init (void);
  70. static void ospf_opaque_funclist_term (void);
  71. static void free_opaque_info_per_type (void *val);
  72. static void free_opaque_info_per_id (void *val);
  73. static int ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa);
  74. static int ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa);
  75. void
  76. ospf_opaque_init (void)
  77. {
  78. ospf_opaque_register_vty ();
  79. ospf_opaque_funclist_init ();
  80. #ifdef HAVE_OSPF_TE
  81. if (ospf_mpls_te_init () != 0)
  82. exit (1);
  83. #endif /* HAVE_OSPF_TE */
  84. #ifdef SUPPORT_OSPF_API
  85. if ((ospf_apiserver_enable) && (ospf_apiserver_init () != 0))
  86. exit (1);
  87. #endif /* SUPPORT_OSPF_API */
  88. return;
  89. }
  90. void
  91. ospf_opaque_term (void)
  92. {
  93. #ifdef HAVE_OSPF_TE
  94. ospf_mpls_te_term ();
  95. #endif /* HAVE_OSPF_TE */
  96. #ifdef SUPPORT_OSPF_API
  97. ospf_apiserver_term ();
  98. #endif /* SUPPORT_OSPF_API */
  99. ospf_opaque_funclist_term ();
  100. return;
  101. }
  102. int
  103. ospf_opaque_type9_lsa_init (struct ospf_interface *oi)
  104. {
  105. if (oi->opaque_lsa_self != NULL)
  106. list_delete (oi->opaque_lsa_self);
  107. oi->opaque_lsa_self = list_new ();
  108. oi->opaque_lsa_self->del = free_opaque_info_per_type;
  109. oi->t_opaque_lsa_self = NULL;
  110. return 0;
  111. }
  112. void
  113. ospf_opaque_type9_lsa_term (struct ospf_interface *oi)
  114. {
  115. OSPF_TIMER_OFF (oi->t_opaque_lsa_self);
  116. if (oi->opaque_lsa_self != NULL)
  117. list_delete (oi->opaque_lsa_self);
  118. oi->opaque_lsa_self = NULL;
  119. return;
  120. }
  121. int
  122. ospf_opaque_type10_lsa_init (struct ospf_area *area)
  123. {
  124. if (area->opaque_lsa_self != NULL)
  125. list_delete (area->opaque_lsa_self);
  126. area->opaque_lsa_self = list_new ();
  127. area->opaque_lsa_self->del = free_opaque_info_per_type;
  128. area->t_opaque_lsa_self = NULL;
  129. #ifdef MONITOR_LSDB_CHANGE
  130. area->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook;
  131. area->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook;
  132. #endif /* MONITOR_LSDB_CHANGE */
  133. return 0;
  134. }
  135. void
  136. ospf_opaque_type10_lsa_term (struct ospf_area *area)
  137. {
  138. #ifdef MONITOR_LSDB_CHANGE
  139. area->lsdb->new_lsa_hook =
  140. area->lsdb->del_lsa_hook = NULL;
  141. #endif /* MONITOR_LSDB_CHANGE */
  142. OSPF_TIMER_OFF (area->t_opaque_lsa_self);
  143. if (area->opaque_lsa_self != NULL)
  144. list_delete (area->opaque_lsa_self);
  145. area->opaque_lsa_self = NULL;
  146. return;
  147. }
  148. int
  149. ospf_opaque_type11_lsa_init (struct ospf *top)
  150. {
  151. if (top->opaque_lsa_self != NULL)
  152. list_delete (top->opaque_lsa_self);
  153. top->opaque_lsa_self = list_new ();
  154. top->opaque_lsa_self->del = free_opaque_info_per_type;
  155. top->t_opaque_lsa_self = NULL;
  156. #ifdef MONITOR_LSDB_CHANGE
  157. top->lsdb->new_lsa_hook = ospf_opaque_lsa_install_hook;
  158. top->lsdb->del_lsa_hook = ospf_opaque_lsa_delete_hook;
  159. #endif /* MONITOR_LSDB_CHANGE */
  160. return 0;
  161. }
  162. void
  163. ospf_opaque_type11_lsa_term (struct ospf *top)
  164. {
  165. #ifdef MONITOR_LSDB_CHANGE
  166. top->lsdb->new_lsa_hook =
  167. top->lsdb->del_lsa_hook = NULL;
  168. #endif /* MONITOR_LSDB_CHANGE */
  169. OSPF_TIMER_OFF (top->t_opaque_lsa_self);
  170. if (top->opaque_lsa_self != NULL)
  171. list_delete (top->opaque_lsa_self);
  172. top->opaque_lsa_self = NULL;
  173. return;
  174. }
  175. static const char *
  176. ospf_opaque_type_name (u_char opaque_type)
  177. {
  178. const char *name = "Unknown";
  179. switch (opaque_type)
  180. {
  181. case OPAQUE_TYPE_WILDCARD: /* This is a special assignment! */
  182. name = "Wildcard";
  183. break;
  184. case OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA:
  185. name = "Traffic Engineering LSA";
  186. break;
  187. case OPAQUE_TYPE_SYCAMORE_OPTICAL_TOPOLOGY_DESC:
  188. name = "Sycamore optical topology description";
  189. break;
  190. case OPAQUE_TYPE_GRACE_LSA:
  191. name = "Grace-LSA";
  192. break;
  193. default:
  194. if (OPAQUE_TYPE_RANGE_UNASSIGNED (opaque_type))
  195. name = "Unassigned";
  196. else
  197. {
  198. u_int32_t bigger_range = opaque_type;
  199. /*
  200. * Get around type-limits warning: comparison is always true due to limited range of data type
  201. */
  202. if (OPAQUE_TYPE_RANGE_RESERVED (bigger_range))
  203. name = "Private/Experimental";
  204. }
  205. break;
  206. }
  207. return name;
  208. }
  209. /*------------------------------------------------------------------------*
  210. * Followings are management functions to store user specified callbacks.
  211. *------------------------------------------------------------------------*/
  212. struct opaque_info_per_type; /* Forward declaration. */
  213. struct ospf_opaque_functab
  214. {
  215. u_char opaque_type;
  216. struct opaque_info_per_type *oipt;
  217. int (* new_if_hook)(struct interface *ifp);
  218. int (* del_if_hook)(struct interface *ifp);
  219. void (* ism_change_hook)(struct ospf_interface *oi, int old_status);
  220. void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status);
  221. void (* config_write_router)(struct vty *vty);
  222. void (* config_write_if )(struct vty *vty, struct interface *ifp);
  223. void (* config_write_debug )(struct vty *vty);
  224. void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa);
  225. int (* lsa_originator)(void *arg);
  226. struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa);
  227. int (* new_lsa_hook)(struct ospf_lsa *lsa);
  228. int (* del_lsa_hook)(struct ospf_lsa *lsa);
  229. };
  230. /* Handle LSA-9/10/11 altogether. */
  231. static struct list *ospf_opaque_wildcard_funclist;
  232. static struct list *ospf_opaque_type9_funclist;
  233. static struct list *ospf_opaque_type10_funclist;
  234. static struct list *ospf_opaque_type11_funclist;
  235. static void
  236. ospf_opaque_del_functab (void *val)
  237. {
  238. XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, val);
  239. return;
  240. }
  241. static void
  242. ospf_opaque_funclist_init (void)
  243. {
  244. struct list *funclist;
  245. funclist = ospf_opaque_wildcard_funclist = list_new ();
  246. funclist->del = ospf_opaque_del_functab;
  247. funclist = ospf_opaque_type9_funclist = list_new ();
  248. funclist->del = ospf_opaque_del_functab;
  249. funclist = ospf_opaque_type10_funclist = list_new ();
  250. funclist->del = ospf_opaque_del_functab;
  251. funclist = ospf_opaque_type11_funclist = list_new ();
  252. funclist->del = ospf_opaque_del_functab;
  253. return;
  254. }
  255. static void
  256. ospf_opaque_funclist_term (void)
  257. {
  258. struct list *funclist;
  259. funclist = ospf_opaque_wildcard_funclist;
  260. list_delete (funclist);
  261. funclist = ospf_opaque_type9_funclist;
  262. list_delete (funclist);
  263. funclist = ospf_opaque_type10_funclist;
  264. list_delete (funclist);
  265. funclist = ospf_opaque_type11_funclist;
  266. list_delete (funclist);
  267. return;
  268. }
  269. static struct list *
  270. ospf_get_opaque_funclist (u_char lsa_type)
  271. {
  272. struct list *funclist = NULL;
  273. switch (lsa_type)
  274. {
  275. case OPAQUE_TYPE_WILDCARD:
  276. /* XXX
  277. * This is an ugly trick to handle type-9/10/11 LSA altogether.
  278. * Yes, "OPAQUE_TYPE_WILDCARD (value 0)" is not an LSA-type, nor
  279. * an officially assigned opaque-type.
  280. * Though it is possible that the value might be officially used
  281. * in the future, we use it internally as a special label, for now.
  282. */
  283. funclist = ospf_opaque_wildcard_funclist;
  284. break;
  285. case OSPF_OPAQUE_LINK_LSA:
  286. funclist = ospf_opaque_type9_funclist;
  287. break;
  288. case OSPF_OPAQUE_AREA_LSA:
  289. funclist = ospf_opaque_type10_funclist;
  290. break;
  291. case OSPF_OPAQUE_AS_LSA:
  292. funclist = ospf_opaque_type11_funclist;
  293. break;
  294. default:
  295. zlog_warn ("ospf_get_opaque_funclist: Unexpected LSA-type(%u)", lsa_type);
  296. break;
  297. }
  298. return funclist;
  299. }
  300. /* XXX: such a huge argument list can /not/ be healthy... */
  301. int
  302. ospf_register_opaque_functab (
  303. u_char lsa_type,
  304. u_char opaque_type,
  305. int (* new_if_hook)(struct interface *ifp),
  306. int (* del_if_hook)(struct interface *ifp),
  307. void (* ism_change_hook)(struct ospf_interface *oi, int old_status),
  308. void (* nsm_change_hook)(struct ospf_neighbor *nbr, int old_status),
  309. void (* config_write_router)(struct vty *vty),
  310. void (* config_write_if )(struct vty *vty, struct interface *ifp),
  311. void (* config_write_debug )(struct vty *vty),
  312. void (* show_opaque_info )(struct vty *vty, struct ospf_lsa *lsa),
  313. int (* lsa_originator)(void *arg),
  314. struct ospf_lsa *(* lsa_refresher )(struct ospf_lsa *lsa),
  315. int (* new_lsa_hook)(struct ospf_lsa *lsa),
  316. int (* del_lsa_hook)(struct ospf_lsa *lsa))
  317. {
  318. struct list *funclist;
  319. struct ospf_opaque_functab *new;
  320. int rc = -1;
  321. if ((funclist = ospf_get_opaque_funclist (lsa_type)) == NULL)
  322. {
  323. zlog_warn ("ospf_register_opaque_functab: Cannot get funclist"
  324. " for Type-%u LSAs?",
  325. lsa_type);
  326. goto out;
  327. }
  328. else
  329. {
  330. struct listnode *node, *nnode;
  331. struct ospf_opaque_functab *functab;
  332. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  333. if (functab->opaque_type == opaque_type)
  334. {
  335. zlog_warn ("ospf_register_opaque_functab: Duplicated entry?:"
  336. " lsa_type(%u), opaque_type(%u)",
  337. lsa_type, opaque_type);
  338. goto out;
  339. }
  340. }
  341. if ((new = XCALLOC (MTYPE_OSPF_OPAQUE_FUNCTAB,
  342. sizeof (struct ospf_opaque_functab))) == NULL)
  343. {
  344. zlog_warn ("ospf_register_opaque_functab: XMALLOC: %s",
  345. safe_strerror (errno));
  346. goto out;
  347. }
  348. new->opaque_type = opaque_type;
  349. new->oipt = NULL;
  350. new->new_if_hook = new_if_hook;
  351. new->del_if_hook = del_if_hook;
  352. new->ism_change_hook = ism_change_hook;
  353. new->nsm_change_hook = nsm_change_hook;
  354. new->config_write_router = config_write_router;
  355. new->config_write_if = config_write_if;
  356. new->config_write_debug = config_write_debug;
  357. new->show_opaque_info = show_opaque_info;
  358. new->lsa_originator = lsa_originator;
  359. new->lsa_refresher = lsa_refresher;
  360. new->new_lsa_hook = new_lsa_hook;
  361. new->del_lsa_hook = del_lsa_hook;
  362. listnode_add (funclist, new);
  363. rc = 0;
  364. out:
  365. return rc;
  366. }
  367. void
  368. ospf_delete_opaque_functab (u_char lsa_type, u_char opaque_type)
  369. {
  370. struct list *funclist;
  371. struct listnode *node, *nnode;
  372. struct ospf_opaque_functab *functab;
  373. if ((funclist = ospf_get_opaque_funclist (lsa_type)) != NULL)
  374. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  375. {
  376. if (functab->opaque_type == opaque_type)
  377. {
  378. /* Cleanup internal control information, if it still remains. */
  379. if (functab->oipt != NULL)
  380. free_opaque_info_per_type (functab->oipt);
  381. /* Dequeue listnode entry from the list. */
  382. listnode_delete (funclist, functab);
  383. /* Avoid misjudgement in the next lookup. */
  384. if (listcount (funclist) == 0)
  385. funclist->head = funclist->tail = NULL;
  386. XFREE (MTYPE_OSPF_OPAQUE_FUNCTAB, functab);
  387. break;
  388. }
  389. }
  390. return;
  391. }
  392. static struct ospf_opaque_functab *
  393. ospf_opaque_functab_lookup (struct ospf_lsa *lsa)
  394. {
  395. struct list *funclist;
  396. struct listnode *node;
  397. struct ospf_opaque_functab *functab;
  398. u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));
  399. if ((funclist = ospf_get_opaque_funclist (lsa->data->type)) != NULL)
  400. for (ALL_LIST_ELEMENTS_RO (funclist, node, functab))
  401. if (functab->opaque_type == key)
  402. return functab;
  403. return NULL;
  404. }
  405. /*------------------------------------------------------------------------*
  406. * Followings are management functions for self-originated LSA entries.
  407. *------------------------------------------------------------------------*/
  408. /*
  409. * Opaque-LSA control information per opaque-type.
  410. * Single Opaque-Type may have multiple instances; each of them will be
  411. * identified by their opaque-id.
  412. */
  413. struct opaque_info_per_type
  414. {
  415. u_char lsa_type;
  416. u_char opaque_type;
  417. enum { PROC_NORMAL, PROC_SUSPEND } status;
  418. /*
  419. * Thread for (re-)origination scheduling for this opaque-type.
  420. *
  421. * Initial origination of Opaque-LSAs is controlled by generic
  422. * Opaque-LSA handling module so that same opaque-type entries are
  423. * called all at once when certain conditions are met.
  424. * However, there might be cases that some Opaque-LSA clients need
  425. * to (re-)originate their own Opaque-LSAs out-of-sync with others.
  426. * This thread is prepared for that specific purpose.
  427. */
  428. struct thread *t_opaque_lsa_self;
  429. /*
  430. * Backpointer to an "owner" which is LSA-type dependent.
  431. * type-9: struct ospf_interface
  432. * type-10: struct ospf_area
  433. * type-11: struct ospf
  434. */
  435. void *owner;
  436. /* Collection of callback functions for this opaque-type. */
  437. struct ospf_opaque_functab *functab;
  438. /* List of Opaque-LSA control informations per opaque-id. */
  439. struct list *id_list;
  440. };
  441. /* Opaque-LSA control information per opaque-id. */
  442. struct opaque_info_per_id
  443. {
  444. u_int32_t opaque_id;
  445. /* Thread for refresh/flush scheduling for this opaque-type/id. */
  446. struct thread *t_opaque_lsa_self;
  447. /* Backpointer to Opaque-LSA control information per opaque-type. */
  448. struct opaque_info_per_type *opqctl_type;
  449. /* Here comes an actual Opaque-LSA entry for this opaque-type/id. */
  450. struct ospf_lsa *lsa;
  451. };
  452. static struct opaque_info_per_type *register_opaque_info_per_type (struct ospf_opaque_functab *functab, struct ospf_lsa *new);
  453. static struct opaque_info_per_type *lookup_opaque_info_by_type (struct ospf_lsa *lsa);
  454. static struct opaque_info_per_id *register_opaque_info_per_id (struct opaque_info_per_type *oipt, struct ospf_lsa *new);
  455. static struct opaque_info_per_id *lookup_opaque_info_by_id (struct opaque_info_per_type *oipt, struct ospf_lsa *lsa);
  456. static struct opaque_info_per_id *register_opaque_lsa (struct ospf_lsa *new);
  457. static struct opaque_info_per_type *
  458. register_opaque_info_per_type (struct ospf_opaque_functab *functab,
  459. struct ospf_lsa *new)
  460. {
  461. struct ospf *top;
  462. struct opaque_info_per_type *oipt;
  463. if ((oipt = XCALLOC (MTYPE_OPAQUE_INFO_PER_TYPE,
  464. sizeof (struct opaque_info_per_type))) == NULL)
  465. {
  466. zlog_warn ("register_opaque_info_per_type: XMALLOC: %s", safe_strerror (errno));
  467. goto out;
  468. }
  469. switch (new->data->type)
  470. {
  471. case OSPF_OPAQUE_LINK_LSA:
  472. oipt->owner = new->oi;
  473. listnode_add (new->oi->opaque_lsa_self, oipt);
  474. break;
  475. case OSPF_OPAQUE_AREA_LSA:
  476. oipt->owner = new->area;
  477. listnode_add (new->area->opaque_lsa_self, oipt);
  478. break;
  479. case OSPF_OPAQUE_AS_LSA:
  480. top = ospf_lookup ();
  481. if (new->area != NULL && (top = new->area->ospf) == NULL)
  482. {
  483. free_opaque_info_per_type ((void *) oipt);
  484. oipt = NULL;
  485. goto out; /* This case may not exist. */
  486. }
  487. oipt->owner = top;
  488. listnode_add (top->opaque_lsa_self, oipt);
  489. break;
  490. default:
  491. zlog_warn ("register_opaque_info_per_type: Unexpected LSA-type(%u)", new->data->type);
  492. free_opaque_info_per_type ((void *) oipt);
  493. oipt = NULL;
  494. goto out; /* This case may not exist. */
  495. }
  496. oipt->lsa_type = new->data->type;
  497. oipt->opaque_type = GET_OPAQUE_TYPE (ntohl (new->data->id.s_addr));
  498. oipt->status = PROC_NORMAL;
  499. oipt->t_opaque_lsa_self = NULL;
  500. oipt->functab = functab;
  501. functab->oipt = oipt;
  502. oipt->id_list = list_new ();
  503. oipt->id_list->del = free_opaque_info_per_id;
  504. out:
  505. return oipt;
  506. }
  507. static void
  508. free_opaque_info_per_type (void *val)
  509. {
  510. struct opaque_info_per_type *oipt = (struct opaque_info_per_type *) val;
  511. struct opaque_info_per_id *oipi;
  512. struct ospf_lsa *lsa;
  513. struct listnode *node, *nnode;
  514. /* Control information per opaque-id may still exist. */
  515. for (ALL_LIST_ELEMENTS (oipt->id_list, node, nnode, oipi))
  516. {
  517. if ((lsa = oipi->lsa) == NULL)
  518. continue;
  519. if (IS_LSA_MAXAGE (lsa))
  520. continue;
  521. ospf_opaque_lsa_flush_schedule (lsa);
  522. }
  523. /* Remove "oipt" from its owner's self-originated LSA list. */
  524. switch (oipt->lsa_type)
  525. {
  526. case OSPF_OPAQUE_LINK_LSA:
  527. {
  528. struct ospf_interface *oi = (struct ospf_interface *)(oipt->owner);
  529. listnode_delete (oi->opaque_lsa_self, oipt);
  530. break;
  531. }
  532. case OSPF_OPAQUE_AREA_LSA:
  533. {
  534. struct ospf_area *area = (struct ospf_area *)(oipt->owner);
  535. listnode_delete (area->opaque_lsa_self, oipt);
  536. break;
  537. }
  538. case OSPF_OPAQUE_AS_LSA:
  539. {
  540. struct ospf *top = (struct ospf *)(oipt->owner);
  541. listnode_delete (top->opaque_lsa_self, oipt);
  542. break;
  543. }
  544. default:
  545. zlog_warn ("free_opaque_info_per_type: Unexpected LSA-type(%u)", oipt->lsa_type);
  546. break; /* This case may not exist. */
  547. }
  548. OSPF_TIMER_OFF (oipt->t_opaque_lsa_self);
  549. list_delete (oipt->id_list);
  550. XFREE (MTYPE_OPAQUE_INFO_PER_TYPE, oipt);
  551. return;
  552. }
  553. static struct opaque_info_per_type *
  554. lookup_opaque_info_by_type (struct ospf_lsa *lsa)
  555. {
  556. struct ospf *top;
  557. struct ospf_area *area;
  558. struct ospf_interface *oi;
  559. struct list *listtop = NULL;
  560. struct listnode *node, *nnode;
  561. struct opaque_info_per_type *oipt = NULL;
  562. u_char key = GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr));
  563. switch (lsa->data->type)
  564. {
  565. case OSPF_OPAQUE_LINK_LSA:
  566. if ((oi = lsa->oi) != NULL)
  567. listtop = oi->opaque_lsa_self;
  568. else
  569. zlog_warn ("Type-9 Opaque-LSA: Reference to OI is missing?");
  570. break;
  571. case OSPF_OPAQUE_AREA_LSA:
  572. if ((area = lsa->area) != NULL)
  573. listtop = area->opaque_lsa_self;
  574. else
  575. zlog_warn ("Type-10 Opaque-LSA: Reference to AREA is missing?");
  576. break;
  577. case OSPF_OPAQUE_AS_LSA:
  578. top = ospf_lookup ();
  579. if ((area = lsa->area) != NULL && (top = area->ospf) == NULL)
  580. {
  581. zlog_warn ("Type-11 Opaque-LSA: Reference to OSPF is missing?");
  582. break; /* Unlikely to happen. */
  583. }
  584. listtop = top->opaque_lsa_self;
  585. break;
  586. default:
  587. zlog_warn ("lookup_opaque_info_by_type: Unexpected LSA-type(%u)", lsa->data->type);
  588. break;
  589. }
  590. if (listtop != NULL)
  591. for (ALL_LIST_ELEMENTS (listtop, node, nnode, oipt))
  592. if (oipt->opaque_type == key)
  593. return oipt;
  594. return NULL;
  595. }
  596. static struct opaque_info_per_id *
  597. register_opaque_info_per_id (struct opaque_info_per_type *oipt,
  598. struct ospf_lsa *new)
  599. {
  600. struct opaque_info_per_id *oipi;
  601. if ((oipi = XCALLOC (MTYPE_OPAQUE_INFO_PER_ID,
  602. sizeof (struct opaque_info_per_id))) == NULL)
  603. {
  604. zlog_warn ("register_opaque_info_per_id: XMALLOC: %s", safe_strerror (errno));
  605. goto out;
  606. }
  607. oipi->opaque_id = GET_OPAQUE_ID (ntohl (new->data->id.s_addr));
  608. oipi->t_opaque_lsa_self = NULL;
  609. oipi->opqctl_type = oipt;
  610. oipi->lsa = ospf_lsa_lock (new);
  611. listnode_add (oipt->id_list, oipi);
  612. out:
  613. return oipi;
  614. }
  615. static void
  616. free_opaque_info_per_id (void *val)
  617. {
  618. struct opaque_info_per_id *oipi = (struct opaque_info_per_id *) val;
  619. OSPF_TIMER_OFF (oipi->t_opaque_lsa_self);
  620. if (oipi->lsa != NULL)
  621. ospf_lsa_unlock (&oipi->lsa);
  622. XFREE (MTYPE_OPAQUE_INFO_PER_ID, oipi);
  623. return;
  624. }
  625. static struct opaque_info_per_id *
  626. lookup_opaque_info_by_id (struct opaque_info_per_type *oipt,
  627. struct ospf_lsa *lsa)
  628. {
  629. struct listnode *node, *nnode;
  630. struct opaque_info_per_id *oipi;
  631. u_int32_t key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr));
  632. for (ALL_LIST_ELEMENTS (oipt->id_list, node, nnode, oipi))
  633. if (oipi->opaque_id == key)
  634. return oipi;
  635. return NULL;
  636. }
  637. static struct opaque_info_per_id *
  638. register_opaque_lsa (struct ospf_lsa *new)
  639. {
  640. struct ospf_opaque_functab *functab;
  641. struct opaque_info_per_type *oipt;
  642. struct opaque_info_per_id *oipi = NULL;
  643. if ((functab = ospf_opaque_functab_lookup (new)) == NULL)
  644. goto out;
  645. if ((oipt = lookup_opaque_info_by_type (new)) == NULL
  646. && (oipt = register_opaque_info_per_type (functab, new)) == NULL)
  647. goto out;
  648. if ((oipi = register_opaque_info_per_id (oipt, new)) == NULL)
  649. goto out;
  650. out:
  651. return oipi;
  652. }
  653. /*------------------------------------------------------------------------*
  654. * Followings are (vty) configuration functions for Opaque-LSAs handling.
  655. *------------------------------------------------------------------------*/
  656. DEFUN (capability_opaque,
  657. capability_opaque_cmd,
  658. "capability opaque",
  659. "Enable specific OSPF feature\n"
  660. "Opaque LSA\n")
  661. {
  662. struct ospf *ospf = (struct ospf *) vty->index;
  663. /* Turn on the "master switch" of opaque-lsa capability. */
  664. if (!CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
  665. {
  666. if (IS_DEBUG_OSPF_EVENT)
  667. zlog_debug ("Opaque capability: OFF -> ON");
  668. SET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);
  669. ospf_renegotiate_optional_capabilities (ospf);
  670. }
  671. return CMD_SUCCESS;
  672. }
  673. ALIAS (capability_opaque,
  674. ospf_opaque_capable_cmd,
  675. "ospf opaque-lsa",
  676. "OSPF specific commands\n"
  677. "Enable the Opaque-LSA capability (rfc2370)\n")
  678. DEFUN (no_capability_opaque,
  679. no_capability_opaque_cmd,
  680. "no capability opaque",
  681. NO_STR
  682. "Enable specific OSPF feature\n"
  683. "Opaque LSA\n")
  684. {
  685. struct ospf *ospf = (struct ospf *) vty->index;
  686. /* Turn off the "master switch" of opaque-lsa capability. */
  687. if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
  688. {
  689. if (IS_DEBUG_OSPF_EVENT)
  690. zlog_debug ("Opaque capability: ON -> OFF");
  691. UNSET_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE);
  692. ospf_renegotiate_optional_capabilities (ospf);
  693. }
  694. return CMD_SUCCESS;
  695. }
  696. ALIAS (no_capability_opaque,
  697. no_ospf_opaque_capable_cmd,
  698. "no ospf opaque-lsa",
  699. NO_STR
  700. "OSPF specific commands\n"
  701. "Disable the Opaque-LSA capability (rfc2370)\n")
  702. static void
  703. ospf_opaque_register_vty (void)
  704. {
  705. install_element (OSPF_NODE, &capability_opaque_cmd);
  706. install_element (OSPF_NODE, &no_capability_opaque_cmd);
  707. install_element (OSPF_NODE, &ospf_opaque_capable_cmd);
  708. install_element (OSPF_NODE, &no_ospf_opaque_capable_cmd);
  709. return;
  710. }
  711. /*------------------------------------------------------------------------*
  712. * Followings are collection of user-registered function callers.
  713. *------------------------------------------------------------------------*/
  714. static int
  715. opaque_lsa_new_if_callback (struct list *funclist, struct interface *ifp)
  716. {
  717. struct listnode *node, *nnode;
  718. struct ospf_opaque_functab *functab;
  719. int rc = -1;
  720. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  721. if (functab->new_if_hook != NULL)
  722. if ((* functab->new_if_hook)(ifp) != 0)
  723. goto out;
  724. rc = 0;
  725. out:
  726. return rc;
  727. }
  728. static int
  729. opaque_lsa_del_if_callback (struct list *funclist, struct interface *ifp)
  730. {
  731. struct listnode *node, *nnode;
  732. struct ospf_opaque_functab *functab;
  733. int rc = -1;
  734. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  735. if (functab->del_if_hook != NULL)
  736. if ((* functab->del_if_hook)(ifp) != 0)
  737. goto out;
  738. rc = 0;
  739. out:
  740. return rc;
  741. }
  742. static void
  743. opaque_lsa_ism_change_callback (struct list *funclist,
  744. struct ospf_interface *oi, int old_status)
  745. {
  746. struct listnode *node, *nnode;
  747. struct ospf_opaque_functab *functab;
  748. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  749. if (functab->ism_change_hook != NULL)
  750. (* functab->ism_change_hook)(oi, old_status);
  751. return;
  752. }
  753. static void
  754. opaque_lsa_nsm_change_callback (struct list *funclist,
  755. struct ospf_neighbor *nbr, int old_status)
  756. {
  757. struct listnode *node, *nnode;
  758. struct ospf_opaque_functab *functab;
  759. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  760. if (functab->nsm_change_hook != NULL)
  761. (* functab->nsm_change_hook)(nbr, old_status);
  762. return;
  763. }
  764. static void
  765. opaque_lsa_config_write_router_callback (struct list *funclist,
  766. struct vty *vty)
  767. {
  768. struct listnode *node, *nnode;
  769. struct ospf_opaque_functab *functab;
  770. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  771. if (functab->config_write_router != NULL)
  772. (* functab->config_write_router)(vty);
  773. return;
  774. }
  775. static void
  776. opaque_lsa_config_write_if_callback (struct list *funclist,
  777. struct vty *vty, struct interface *ifp)
  778. {
  779. struct listnode *node, *nnode;
  780. struct ospf_opaque_functab *functab;
  781. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  782. if (functab->config_write_if != NULL)
  783. (* functab->config_write_if)(vty, ifp);
  784. return;
  785. }
  786. static void
  787. opaque_lsa_config_write_debug_callback (struct list *funclist, struct vty *vty)
  788. {
  789. struct listnode *node, *nnode;
  790. struct ospf_opaque_functab *functab;
  791. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  792. if (functab->config_write_debug != NULL)
  793. (* functab->config_write_debug)(vty);
  794. return;
  795. }
  796. static int
  797. opaque_lsa_originate_callback (struct list *funclist, void *lsa_type_dependent)
  798. {
  799. struct listnode *node, *nnode;
  800. struct ospf_opaque_functab *functab;
  801. int rc = -1;
  802. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  803. if (functab->lsa_originator != NULL)
  804. if ((* functab->lsa_originator)(lsa_type_dependent) != 0)
  805. goto out;
  806. rc = 0;
  807. out:
  808. return rc;
  809. }
  810. static int
  811. new_lsa_callback (struct list *funclist, struct ospf_lsa *lsa)
  812. {
  813. struct listnode *node, *nnode;
  814. struct ospf_opaque_functab *functab;
  815. int rc = -1;
  816. /* This function handles ALL types of LSAs, not only opaque ones. */
  817. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  818. if (functab->new_lsa_hook != NULL)
  819. if ((* functab->new_lsa_hook)(lsa) != 0)
  820. goto out;
  821. rc = 0;
  822. out:
  823. return rc;
  824. }
  825. static int
  826. del_lsa_callback (struct list *funclist, struct ospf_lsa *lsa)
  827. {
  828. struct listnode *node, *nnode;
  829. struct ospf_opaque_functab *functab;
  830. int rc = -1;
  831. /* This function handles ALL types of LSAs, not only opaque ones. */
  832. for (ALL_LIST_ELEMENTS (funclist, node, nnode, functab))
  833. if (functab->del_lsa_hook != NULL)
  834. if ((* functab->del_lsa_hook)(lsa) != 0)
  835. goto out;
  836. rc = 0;
  837. out:
  838. return rc;
  839. }
  840. /*------------------------------------------------------------------------*
  841. * Followings are glue functions to call Opaque-LSA specific processing.
  842. *------------------------------------------------------------------------*/
  843. int
  844. ospf_opaque_new_if (struct interface *ifp)
  845. {
  846. struct list *funclist;
  847. int rc = -1;
  848. funclist = ospf_opaque_wildcard_funclist;
  849. if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
  850. goto out;
  851. funclist = ospf_opaque_type9_funclist;
  852. if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
  853. goto out;
  854. funclist = ospf_opaque_type10_funclist;
  855. if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
  856. goto out;
  857. funclist = ospf_opaque_type11_funclist;
  858. if (opaque_lsa_new_if_callback (funclist, ifp) != 0)
  859. goto out;
  860. rc = 0;
  861. out:
  862. return rc;
  863. }
  864. int
  865. ospf_opaque_del_if (struct interface *ifp)
  866. {
  867. struct list *funclist;
  868. int rc = -1;
  869. funclist = ospf_opaque_wildcard_funclist;
  870. if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
  871. goto out;
  872. funclist = ospf_opaque_type9_funclist;
  873. if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
  874. goto out;
  875. funclist = ospf_opaque_type10_funclist;
  876. if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
  877. goto out;
  878. funclist = ospf_opaque_type11_funclist;
  879. if (opaque_lsa_del_if_callback (funclist, ifp) != 0)
  880. goto out;
  881. rc = 0;
  882. out:
  883. return rc;
  884. }
  885. void
  886. ospf_opaque_ism_change (struct ospf_interface *oi, int old_status)
  887. {
  888. struct list *funclist;
  889. funclist = ospf_opaque_wildcard_funclist;
  890. opaque_lsa_ism_change_callback (funclist, oi, old_status);
  891. funclist = ospf_opaque_type9_funclist;
  892. opaque_lsa_ism_change_callback (funclist, oi, old_status);
  893. funclist = ospf_opaque_type10_funclist;
  894. opaque_lsa_ism_change_callback (funclist, oi, old_status);
  895. funclist = ospf_opaque_type11_funclist;
  896. opaque_lsa_ism_change_callback (funclist, oi, old_status);
  897. return;
  898. }
  899. void
  900. ospf_opaque_nsm_change (struct ospf_neighbor *nbr, int old_state)
  901. {
  902. struct ospf *top;
  903. struct list *funclist;
  904. if ((top = oi_to_top (nbr->oi)) == NULL)
  905. goto out;
  906. if (old_state != NSM_Full && nbr->state == NSM_Full)
  907. {
  908. if (CHECK_FLAG (nbr->options, OSPF_OPTION_O))
  909. {
  910. if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
  911. {
  912. if (IS_DEBUG_OSPF_EVENT)
  913. zlog_debug ("Opaque-LSA: Now get operational!");
  914. SET_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT);
  915. }
  916. ospf_opaque_lsa_originate_schedule (nbr->oi, NULL);
  917. }
  918. }
  919. else
  920. if (old_state == NSM_Full && nbr->state != NSM_Full)
  921. {
  922. #ifdef NOTYET
  923. /*
  924. * If no more opaque-capable full-state neighbor remains in the
  925. * flooding scope which corresponds to Opaque-LSA type, periodic
  926. * LS flooding should be stopped.
  927. */
  928. #endif /* NOTYET */
  929. ;
  930. }
  931. funclist = ospf_opaque_wildcard_funclist;
  932. opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
  933. funclist = ospf_opaque_type9_funclist;
  934. opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
  935. funclist = ospf_opaque_type10_funclist;
  936. opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
  937. funclist = ospf_opaque_type11_funclist;
  938. opaque_lsa_nsm_change_callback (funclist, nbr, old_state);
  939. out:
  940. return;
  941. }
  942. void
  943. ospf_opaque_config_write_router (struct vty *vty, struct ospf *ospf)
  944. {
  945. struct list *funclist;
  946. if (CHECK_FLAG (ospf->config, OSPF_OPAQUE_CAPABLE))
  947. vty_out (vty, " capability opaque%s", VTY_NEWLINE);
  948. funclist = ospf_opaque_wildcard_funclist;
  949. opaque_lsa_config_write_router_callback (funclist, vty);
  950. funclist = ospf_opaque_type9_funclist;
  951. opaque_lsa_config_write_router_callback (funclist, vty);
  952. funclist = ospf_opaque_type10_funclist;
  953. opaque_lsa_config_write_router_callback (funclist, vty);
  954. funclist = ospf_opaque_type11_funclist;
  955. opaque_lsa_config_write_router_callback (funclist, vty);
  956. return;
  957. }
  958. void
  959. ospf_opaque_config_write_if (struct vty *vty, struct interface *ifp)
  960. {
  961. struct list *funclist;
  962. funclist = ospf_opaque_wildcard_funclist;
  963. opaque_lsa_config_write_if_callback (funclist, vty, ifp);
  964. funclist = ospf_opaque_type9_funclist;
  965. opaque_lsa_config_write_if_callback (funclist, vty, ifp);
  966. funclist = ospf_opaque_type10_funclist;
  967. opaque_lsa_config_write_if_callback (funclist, vty, ifp);
  968. funclist = ospf_opaque_type11_funclist;
  969. opaque_lsa_config_write_if_callback (funclist, vty, ifp);
  970. return;
  971. }
  972. void
  973. ospf_opaque_config_write_debug (struct vty *vty)
  974. {
  975. struct list *funclist;
  976. funclist = ospf_opaque_wildcard_funclist;
  977. opaque_lsa_config_write_debug_callback (funclist, vty);
  978. funclist = ospf_opaque_type9_funclist;
  979. opaque_lsa_config_write_debug_callback (funclist, vty);
  980. funclist = ospf_opaque_type10_funclist;
  981. opaque_lsa_config_write_debug_callback (funclist, vty);
  982. funclist = ospf_opaque_type11_funclist;
  983. opaque_lsa_config_write_debug_callback (funclist, vty);
  984. return;
  985. }
  986. void
  987. show_opaque_info_detail (struct vty *vty, struct ospf_lsa *lsa)
  988. {
  989. struct lsa_header *lsah = (struct lsa_header *) lsa->data;
  990. u_int32_t lsid = ntohl (lsah->id.s_addr);
  991. u_char opaque_type = GET_OPAQUE_TYPE (lsid);
  992. u_int32_t opaque_id = GET_OPAQUE_ID (lsid);
  993. struct ospf_opaque_functab *functab;
  994. /* Switch output functionality by vty address. */
  995. if (vty != NULL)
  996. {
  997. vty_out (vty, " Opaque-Type %u (%s)%s", opaque_type,
  998. ospf_opaque_type_name (opaque_type), VTY_NEWLINE);
  999. vty_out (vty, " Opaque-ID 0x%x%s", opaque_id, VTY_NEWLINE);
  1000. vty_out (vty, " Opaque-Info: %u octets of data%s%s",
  1001. ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE,
  1002. VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)",
  1003. VTY_NEWLINE);
  1004. }
  1005. else
  1006. {
  1007. zlog_debug (" Opaque-Type %u (%s)", opaque_type,
  1008. ospf_opaque_type_name (opaque_type));
  1009. zlog_debug (" Opaque-ID 0x%x", opaque_id);
  1010. zlog_debug (" Opaque-Info: %u octets of data%s",
  1011. ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE,
  1012. VALID_OPAQUE_INFO_LEN(lsah) ? "" : "(Invalid length?)");
  1013. }
  1014. /* Call individual output functions. */
  1015. if ((functab = ospf_opaque_functab_lookup (lsa)) != NULL)
  1016. if (functab->show_opaque_info != NULL)
  1017. (* functab->show_opaque_info)(vty, lsa);
  1018. return;
  1019. }
  1020. void
  1021. ospf_opaque_lsa_dump (struct stream *s, u_int16_t length)
  1022. {
  1023. struct ospf_lsa lsa;
  1024. lsa.data = (struct lsa_header *) STREAM_PNT (s);
  1025. show_opaque_info_detail (NULL, &lsa);
  1026. return;
  1027. }
  1028. static int
  1029. ospf_opaque_lsa_install_hook (struct ospf_lsa *lsa)
  1030. {
  1031. struct list *funclist;
  1032. int rc = -1;
  1033. /*
  1034. * Some Opaque-LSA user may want to monitor every LSA installation
  1035. * into the LSDB, regardless with target LSA type.
  1036. */
  1037. funclist = ospf_opaque_wildcard_funclist;
  1038. if (new_lsa_callback (funclist, lsa) != 0)
  1039. goto out;
  1040. funclist = ospf_opaque_type9_funclist;
  1041. if (new_lsa_callback (funclist, lsa) != 0)
  1042. goto out;
  1043. funclist = ospf_opaque_type10_funclist;
  1044. if (new_lsa_callback (funclist, lsa) != 0)
  1045. goto out;
  1046. funclist = ospf_opaque_type11_funclist;
  1047. if (new_lsa_callback (funclist, lsa) != 0)
  1048. goto out;
  1049. rc = 0;
  1050. out:
  1051. return rc;
  1052. }
  1053. static int
  1054. ospf_opaque_lsa_delete_hook (struct ospf_lsa *lsa)
  1055. {
  1056. struct list *funclist;
  1057. int rc = -1;
  1058. /*
  1059. * Some Opaque-LSA user may want to monitor every LSA deletion
  1060. * from the LSDB, regardless with target LSA type.
  1061. */
  1062. funclist = ospf_opaque_wildcard_funclist;
  1063. if (del_lsa_callback (funclist, lsa) != 0)
  1064. goto out;
  1065. funclist = ospf_opaque_type9_funclist;
  1066. if (del_lsa_callback (funclist, lsa) != 0)
  1067. goto out;
  1068. funclist = ospf_opaque_type10_funclist;
  1069. if (del_lsa_callback (funclist, lsa) != 0)
  1070. goto out;
  1071. funclist = ospf_opaque_type11_funclist;
  1072. if (del_lsa_callback (funclist, lsa) != 0)
  1073. goto out;
  1074. rc = 0;
  1075. out:
  1076. return rc;
  1077. }
  1078. /*------------------------------------------------------------------------*
  1079. * Followings are Opaque-LSA origination/refresh management functions.
  1080. *------------------------------------------------------------------------*/
  1081. static int ospf_opaque_type9_lsa_originate (struct thread *t);
  1082. static int ospf_opaque_type10_lsa_originate (struct thread *t);
  1083. static int ospf_opaque_type11_lsa_originate (struct thread *t);
  1084. static void ospf_opaque_lsa_reoriginate_resume (struct list *listtop, void *arg);
  1085. void
  1086. ospf_opaque_lsa_originate_schedule (struct ospf_interface *oi, int *delay0)
  1087. {
  1088. struct ospf *top;
  1089. struct ospf_area *area;
  1090. struct listnode *node, *nnode;
  1091. struct opaque_info_per_type *oipt;
  1092. int delay = 0;
  1093. if ((top = oi_to_top (oi)) == NULL || (area = oi->area) == NULL)
  1094. {
  1095. zlog_warn ("ospf_opaque_lsa_originate_schedule: Invalid argument?");
  1096. goto out;
  1097. }
  1098. /* It may not a right time to schedule origination now. */
  1099. if (! CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
  1100. {
  1101. if (IS_DEBUG_OSPF_EVENT)
  1102. zlog_debug ("ospf_opaque_lsa_originate_schedule: Not operational.");
  1103. goto out; /* This is not an error. */
  1104. }
  1105. if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
  1106. {
  1107. if (IS_DEBUG_OSPF_EVENT)
  1108. zlog_debug ("ospf_opaque_lsa_originate_schedule: Under blockade.");
  1109. goto out; /* This is not an error, too. */
  1110. }
  1111. if (delay0 != NULL)
  1112. delay = *delay0;
  1113. /*
  1114. * There might be some entries that have been waiting for triggering
  1115. * of per opaque-type re-origination get resumed.
  1116. */
  1117. ospf_opaque_lsa_reoriginate_resume ( oi->opaque_lsa_self, (void *) oi);
  1118. ospf_opaque_lsa_reoriginate_resume (area->opaque_lsa_self, (void *) area);
  1119. ospf_opaque_lsa_reoriginate_resume ( top->opaque_lsa_self, (void *) top);
  1120. /*
  1121. * Now, schedule origination of all Opaque-LSAs per opaque-type.
  1122. */
  1123. if (! list_isempty (ospf_opaque_type9_funclist)
  1124. && list_isempty (oi->opaque_lsa_self)
  1125. && oi->t_opaque_lsa_self == NULL)
  1126. {
  1127. if (IS_DEBUG_OSPF_EVENT)
  1128. zlog_debug ("Schedule Type-9 Opaque-LSA origination in %d sec later.", delay);
  1129. oi->t_opaque_lsa_self =
  1130. thread_add_timer (master, ospf_opaque_type9_lsa_originate, oi, delay);
  1131. delay += OSPF_MIN_LS_INTERVAL;
  1132. }
  1133. if (! list_isempty (ospf_opaque_type10_funclist)
  1134. && list_isempty (area->opaque_lsa_self)
  1135. && area->t_opaque_lsa_self == NULL)
  1136. {
  1137. /*
  1138. * One AREA may contain multiple OIs, but above 2nd and 3rd
  1139. * conditions prevent from scheduling the originate function
  1140. * again and again.
  1141. */
  1142. if (IS_DEBUG_OSPF_EVENT)
  1143. zlog_debug ("Schedule Type-10 Opaque-LSA origination in %d sec later.", delay);
  1144. area->t_opaque_lsa_self =
  1145. thread_add_timer (master, ospf_opaque_type10_lsa_originate,
  1146. area, delay);
  1147. delay += OSPF_MIN_LS_INTERVAL;
  1148. }
  1149. if (! list_isempty (ospf_opaque_type11_funclist)
  1150. && list_isempty (top->opaque_lsa_self)
  1151. && top->t_opaque_lsa_self == NULL)
  1152. {
  1153. /*
  1154. * One OSPF may contain multiple AREAs, but above 2nd and 3rd
  1155. * conditions prevent from scheduling the originate function
  1156. * again and again.
  1157. */
  1158. if (IS_DEBUG_OSPF_EVENT)
  1159. zlog_debug ("Schedule Type-11 Opaque-LSA origination in %d sec later.", delay);
  1160. top->t_opaque_lsa_self =
  1161. thread_add_timer (master, ospf_opaque_type11_lsa_originate,
  1162. top, delay);
  1163. delay += OSPF_MIN_LS_INTERVAL;
  1164. }
  1165. /*
  1166. * Following section treats a special situation that this node's
  1167. * opaque capability has changed as "ON -> OFF -> ON".
  1168. */
  1169. if (! list_isempty (ospf_opaque_type9_funclist)
  1170. && ! list_isempty (oi->opaque_lsa_self))
  1171. {
  1172. for (ALL_LIST_ELEMENTS (oi->opaque_lsa_self, node, nnode, oipt))
  1173. {
  1174. /*
  1175. * removed the test for
  1176. * (! list_isempty (oipt->id_list)) * Handler is already active. *
  1177. * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
  1178. * not being empty.
  1179. */
  1180. if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
  1181. || oipt->status == PROC_SUSPEND) /* Cannot originate now. */
  1182. continue;
  1183. ospf_opaque_lsa_reoriginate_schedule ((void *) oi,
  1184. OSPF_OPAQUE_LINK_LSA, oipt->opaque_type);
  1185. }
  1186. }
  1187. if (! list_isempty (ospf_opaque_type10_funclist)
  1188. && ! list_isempty (area->opaque_lsa_self))
  1189. {
  1190. for (ALL_LIST_ELEMENTS (area->opaque_lsa_self, node, nnode, oipt))
  1191. {
  1192. /*
  1193. * removed the test for
  1194. * (! list_isempty (oipt->id_list)) * Handler is already active. *
  1195. * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
  1196. * not being empty.
  1197. */
  1198. if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
  1199. || oipt->status == PROC_SUSPEND) /* Cannot originate now. */
  1200. continue;
  1201. ospf_opaque_lsa_reoriginate_schedule ((void *) area,
  1202. OSPF_OPAQUE_AREA_LSA, oipt->opaque_type);
  1203. }
  1204. }
  1205. if (! list_isempty (ospf_opaque_type11_funclist)
  1206. && ! list_isempty (top->opaque_lsa_self))
  1207. {
  1208. for (ALL_LIST_ELEMENTS (top->opaque_lsa_self, node, nnode, oipt))
  1209. {
  1210. /*
  1211. * removed the test for
  1212. * (! list_isempty (oipt->id_list)) * Handler is already active. *
  1213. * because opaque cababilities ON -> OFF -> ON result in list_isempty (oipt->id_list)
  1214. * not being empty.
  1215. */
  1216. if (oipt->t_opaque_lsa_self != NULL /* Waiting for a thread call. */
  1217. || oipt->status == PROC_SUSPEND) /* Cannot originate now. */
  1218. continue;
  1219. ospf_opaque_lsa_reoriginate_schedule ((void *) top,
  1220. OSPF_OPAQUE_AS_LSA, oipt->opaque_type);
  1221. }
  1222. }
  1223. if (delay0 != NULL)
  1224. *delay0 = delay;
  1225. out:
  1226. return;
  1227. }
  1228. static int
  1229. ospf_opaque_type9_lsa_originate (struct thread *t)
  1230. {
  1231. struct ospf_interface *oi;
  1232. int rc;
  1233. oi = THREAD_ARG (t);
  1234. oi->t_opaque_lsa_self = NULL;
  1235. if (IS_DEBUG_OSPF_EVENT)
  1236. zlog_debug ("Timer[Type9-LSA]: Originate Opaque-LSAs for OI %s",
  1237. IF_NAME (oi));
  1238. rc = opaque_lsa_originate_callback (ospf_opaque_type9_funclist, oi);
  1239. return rc;
  1240. }
  1241. static int
  1242. ospf_opaque_type10_lsa_originate (struct thread *t)
  1243. {
  1244. struct ospf_area *area;
  1245. int rc;
  1246. area = THREAD_ARG (t);
  1247. area->t_opaque_lsa_self = NULL;
  1248. if (IS_DEBUG_OSPF_EVENT)
  1249. zlog_debug ("Timer[Type10-LSA]: Originate Opaque-LSAs for Area %s",
  1250. inet_ntoa (area->area_id));
  1251. rc = opaque_lsa_originate_callback (ospf_opaque_type10_funclist, area);
  1252. return rc;
  1253. }
  1254. static int
  1255. ospf_opaque_type11_lsa_originate (struct thread *t)
  1256. {
  1257. struct ospf *top;
  1258. int rc;
  1259. top = THREAD_ARG (t);
  1260. top->t_opaque_lsa_self = NULL;
  1261. if (IS_DEBUG_OSPF_EVENT)
  1262. zlog_debug ("Timer[Type11-LSA]: Originate AS-External Opaque-LSAs");
  1263. rc = opaque_lsa_originate_callback (ospf_opaque_type11_funclist, top);
  1264. return rc;
  1265. }
  1266. static void
  1267. ospf_opaque_lsa_reoriginate_resume (struct list *listtop, void *arg)
  1268. {
  1269. struct listnode *node, *nnode;
  1270. struct opaque_info_per_type *oipt;
  1271. struct ospf_opaque_functab *functab;
  1272. if (listtop == NULL)
  1273. goto out;
  1274. /*
  1275. * Pickup oipt entries those which in SUSPEND status, and give
  1276. * them a chance to start re-origination now.
  1277. */
  1278. for (ALL_LIST_ELEMENTS (listtop, node, nnode, oipt))
  1279. {
  1280. if (oipt->status != PROC_SUSPEND)
  1281. continue;
  1282. oipt->status = PROC_NORMAL;
  1283. if ((functab = oipt->functab) == NULL
  1284. || functab->lsa_originator == NULL)
  1285. continue;
  1286. if ((* functab->lsa_originator)(arg) != 0)
  1287. {
  1288. zlog_warn ("ospf_opaque_lsa_reoriginate_resume: Failed (opaque-type=%u)", oipt->opaque_type);
  1289. continue;
  1290. }
  1291. }
  1292. out:
  1293. return;
  1294. }
  1295. struct ospf_lsa *
  1296. ospf_opaque_lsa_install (struct ospf_lsa *lsa, int rt_recalc)
  1297. {
  1298. struct ospf_lsa *new = NULL;
  1299. struct opaque_info_per_type *oipt;
  1300. struct opaque_info_per_id *oipi;
  1301. struct ospf *top;
  1302. /* Don't take "rt_recalc" into consideration for now. *//* XXX */
  1303. if (! IS_LSA_SELF (lsa))
  1304. {
  1305. new = lsa; /* Don't touch this LSA. */
  1306. goto out;
  1307. }
  1308. if (IS_DEBUG_OSPF (lsa, LSA_INSTALL))
  1309. zlog_debug ("Install Type-%u Opaque-LSA: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
  1310. /* Replace the existing lsa with the new one. */
  1311. if ((oipt = lookup_opaque_info_by_type (lsa)) != NULL
  1312. && (oipi = lookup_opaque_info_by_id (oipt, lsa)) != NULL)
  1313. {
  1314. ospf_lsa_unlock (&oipi->lsa);
  1315. oipi->lsa = ospf_lsa_lock (lsa);
  1316. }
  1317. /* Register the new lsa entry and get its control info. */
  1318. else
  1319. if ((oipi = register_opaque_lsa (lsa)) == NULL)
  1320. {
  1321. zlog_warn ("ospf_opaque_lsa_install: register_opaque_lsa() ?");
  1322. goto out;
  1323. }
  1324. /*
  1325. * Make use of a common mechanism (ospf_lsa_refresh_walker)
  1326. * for periodic refresh of self-originated Opaque-LSAs.
  1327. */
  1328. switch (lsa->data->type)
  1329. {
  1330. case OSPF_OPAQUE_LINK_LSA:
  1331. if ((top = oi_to_top (lsa->oi)) == NULL)
  1332. {
  1333. /* Above conditions must have passed. */
  1334. zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
  1335. goto out;
  1336. }
  1337. break;
  1338. case OSPF_OPAQUE_AREA_LSA:
  1339. if (lsa->area == NULL || (top = lsa->area->ospf) == NULL)
  1340. {
  1341. /* Above conditions must have passed. */
  1342. zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
  1343. goto out;
  1344. }
  1345. break;
  1346. case OSPF_OPAQUE_AS_LSA:
  1347. top = ospf_lookup ();
  1348. if (lsa->area != NULL && (top = lsa->area->ospf) == NULL)
  1349. {
  1350. /* Above conditions must have passed. */
  1351. zlog_warn ("ospf_opaque_lsa_install: Sonmething wrong?");
  1352. goto out;
  1353. }
  1354. break;
  1355. default:
  1356. zlog_warn ("ospf_opaque_lsa_install: Unexpected LSA-type(%u)", lsa->data->type);
  1357. goto out;
  1358. }
  1359. ospf_refresher_register_lsa (top, lsa);
  1360. new = lsa;
  1361. out:
  1362. return new;
  1363. }
  1364. struct ospf_lsa *
  1365. ospf_opaque_lsa_refresh (struct ospf_lsa *lsa)
  1366. {
  1367. struct ospf *ospf;
  1368. struct ospf_opaque_functab *functab;
  1369. struct ospf_lsa *new = NULL;
  1370. ospf = ospf_lookup ();
  1371. if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL
  1372. || functab->lsa_refresher == NULL)
  1373. {
  1374. /*
  1375. * Though this LSA seems to have originated on this node, the
  1376. * handling module for this "lsa-type and opaque-type" was
  1377. * already deleted sometime ago.
  1378. * Anyway, this node still has a responsibility to flush this
  1379. * LSA from the routing domain.
  1380. */
  1381. if (IS_DEBUG_OSPF_EVENT)
  1382. zlog_debug ("LSA[Type%d:%s]: Flush stray Opaque-LSA", lsa->data->type, inet_ntoa (lsa->data->id));
  1383. lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
  1384. ospf_lsa_flush (ospf, lsa);
  1385. }
  1386. else
  1387. new = (* functab->lsa_refresher)(lsa);
  1388. return new;
  1389. }
  1390. /*------------------------------------------------------------------------*
  1391. * Followings are re-origination/refresh/flush operations of Opaque-LSAs,
  1392. * triggered by external interventions (vty session, signaling, etc).
  1393. *------------------------------------------------------------------------*/
  1394. #define OSPF_OPAQUE_TIMER_ON(T,F,L,V) \
  1395. if (!(T)) \
  1396. (T) = thread_add_timer (master, (F), (L), (V))
  1397. static struct ospf_lsa *pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area, u_char lsa_type, u_char opaque_type);
  1398. static int ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t);
  1399. static int ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t);
  1400. static int ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t);
  1401. static int ospf_opaque_lsa_refresh_timer (struct thread *t);
  1402. void
  1403. ospf_opaque_lsa_reoriginate_schedule (void *lsa_type_dependent,
  1404. u_char lsa_type, u_char opaque_type)
  1405. {
  1406. struct ospf *top;
  1407. struct ospf_area dummy, *area = NULL;
  1408. struct ospf_interface *oi = NULL;
  1409. struct ospf_lsa *lsa;
  1410. struct opaque_info_per_type *oipt;
  1411. int (*func) (struct thread * t) = NULL;
  1412. int delay;
  1413. switch (lsa_type)
  1414. {
  1415. case OSPF_OPAQUE_LINK_LSA:
  1416. if ((oi = (struct ospf_interface *) lsa_type_dependent) == NULL)
  1417. {
  1418. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1419. " Type-9 Opaque-LSA: Invalid parameter?");
  1420. goto out;
  1421. }
  1422. if ((top = oi_to_top (oi)) == NULL)
  1423. {
  1424. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule: OI(%s) -> TOP?",
  1425. IF_NAME (oi));
  1426. goto out;
  1427. }
  1428. if (!list_isempty (ospf_opaque_type9_funclist)
  1429. && list_isempty (oi->opaque_lsa_self)
  1430. && oi->t_opaque_lsa_self != NULL)
  1431. {
  1432. zlog_warn ("Type-9 Opaque-LSA (opaque_type=%u):"
  1433. " Common origination for OI(%s) has already started",
  1434. opaque_type, IF_NAME (oi));
  1435. goto out;
  1436. }
  1437. func = ospf_opaque_type9_lsa_reoriginate_timer;
  1438. break;
  1439. case OSPF_OPAQUE_AREA_LSA:
  1440. if ((area = (struct ospf_area *) lsa_type_dependent) == NULL)
  1441. {
  1442. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1443. " Type-10 Opaque-LSA: Invalid parameter?");
  1444. goto out;
  1445. }
  1446. if ((top = area->ospf) == NULL)
  1447. {
  1448. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1449. " AREA(%s) -> TOP?", inet_ntoa (area->area_id));
  1450. goto out;
  1451. }
  1452. if (!list_isempty (ospf_opaque_type10_funclist)
  1453. && list_isempty (area->opaque_lsa_self)
  1454. && area->t_opaque_lsa_self != NULL)
  1455. {
  1456. zlog_warn ("Type-10 Opaque-LSA (opaque_type=%u):"
  1457. " Common origination for AREA(%s) has already started",
  1458. opaque_type, inet_ntoa (area->area_id));
  1459. goto out;
  1460. }
  1461. func = ospf_opaque_type10_lsa_reoriginate_timer;
  1462. break;
  1463. case OSPF_OPAQUE_AS_LSA:
  1464. if ((top = (struct ospf *) lsa_type_dependent) == NULL)
  1465. {
  1466. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1467. " Type-11 Opaque-LSA: Invalid parameter?");
  1468. goto out;
  1469. }
  1470. if (!list_isempty (ospf_opaque_type11_funclist)
  1471. && list_isempty (top->opaque_lsa_self)
  1472. && top->t_opaque_lsa_self != NULL)
  1473. {
  1474. zlog_warn ("Type-11 Opaque-LSA (opaque_type=%u):"
  1475. " Common origination has already started", opaque_type);
  1476. goto out;
  1477. }
  1478. /* Fake "area" to pass "ospf" to a lookup function later. */
  1479. dummy.ospf = top;
  1480. area = &dummy;
  1481. func = ospf_opaque_type11_lsa_reoriginate_timer;
  1482. break;
  1483. default:
  1484. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1485. " Unexpected LSA-type(%u)",
  1486. lsa_type);
  1487. goto out;
  1488. }
  1489. /* It may not a right time to schedule reorigination now. */
  1490. if (!CHECK_FLAG (top->opaque, OPAQUE_OPERATION_READY_BIT))
  1491. {
  1492. if (IS_DEBUG_OSPF_EVENT)
  1493. zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Not operational.");
  1494. goto out; /* This is not an error. */
  1495. }
  1496. if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
  1497. {
  1498. if (IS_DEBUG_OSPF_EVENT)
  1499. zlog_debug ("ospf_opaque_lsa_reoriginate_schedule: Under blockade.");
  1500. goto out; /* This is not an error, too. */
  1501. }
  1502. /* Generate a dummy lsa to be passed for a lookup function. */
  1503. lsa = pseudo_lsa (oi, area, lsa_type, opaque_type);
  1504. if ((oipt = lookup_opaque_info_by_type (lsa)) == NULL)
  1505. {
  1506. struct ospf_opaque_functab *functab;
  1507. if ((functab = ospf_opaque_functab_lookup (lsa)) == NULL)
  1508. {
  1509. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1510. " No associated function?: lsa_type(%u),"
  1511. " opaque_type(%u)",
  1512. lsa_type, opaque_type);
  1513. goto out;
  1514. }
  1515. if ((oipt = register_opaque_info_per_type (functab, lsa)) == NULL)
  1516. {
  1517. zlog_warn ("ospf_opaque_lsa_reoriginate_schedule:"
  1518. " Cannot get a control info?: lsa_type(%u),"
  1519. " opaque_type(%u)",
  1520. lsa_type, opaque_type);
  1521. goto out;
  1522. }
  1523. }
  1524. if (oipt->t_opaque_lsa_self != NULL)
  1525. {
  1526. if (IS_DEBUG_OSPF_EVENT)
  1527. zlog_debug ("Type-%u Opaque-LSA has already scheduled to"
  1528. " RE-ORIGINATE: [opaque-type=%u]",
  1529. lsa_type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));
  1530. goto out;
  1531. }
  1532. /*
  1533. * Different from initial origination time, in which various conditions
  1534. * (opaque capability, neighbor status etc) are assured by caller of
  1535. * the originating function "ospf_opaque_lsa_originate_schedule ()",
  1536. * it is highly possible that these conditions might not be satisfied
  1537. * at the time of re-origination function is to be called.
  1538. */
  1539. delay = OSPF_MIN_LS_INTERVAL; /* XXX */
  1540. if (IS_DEBUG_OSPF_EVENT)
  1541. zlog_debug ("Schedule Type-%u Opaque-LSA to RE-ORIGINATE in %d"
  1542. " sec later: [opaque-type=%u]",
  1543. lsa_type, delay,
  1544. GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)));
  1545. OSPF_OPAQUE_TIMER_ON (oipt->t_opaque_lsa_self, func, oipt, delay);
  1546. out:
  1547. return;
  1548. }
  1549. static struct ospf_lsa *
  1550. pseudo_lsa (struct ospf_interface *oi, struct ospf_area *area,
  1551. u_char lsa_type, u_char opaque_type)
  1552. {
  1553. static struct ospf_lsa lsa = { 0 };
  1554. static struct lsa_header lsah = { 0 };
  1555. u_int32_t tmp;
  1556. lsa.oi = oi;
  1557. lsa.area = area;
  1558. lsa.data = &lsah;
  1559. lsah.type = lsa_type;
  1560. tmp = SET_OPAQUE_LSID (opaque_type, 0); /* Opaque-ID is unused here. */
  1561. lsah.id.s_addr = htonl (tmp);
  1562. return &lsa;
  1563. }
  1564. static int
  1565. ospf_opaque_type9_lsa_reoriginate_timer (struct thread *t)
  1566. {
  1567. struct opaque_info_per_type *oipt;
  1568. struct ospf_opaque_functab *functab;
  1569. struct ospf *top;
  1570. struct ospf_interface *oi;
  1571. int rc = -1;
  1572. oipt = THREAD_ARG (t);
  1573. oipt->t_opaque_lsa_self = NULL;
  1574. if ((functab = oipt->functab) == NULL
  1575. || functab->lsa_originator == NULL)
  1576. {
  1577. zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: No associated function?");
  1578. goto out;
  1579. }
  1580. oi = (struct ospf_interface *) oipt->owner;
  1581. if ((top = oi_to_top (oi)) == NULL)
  1582. {
  1583. zlog_warn ("ospf_opaque_type9_lsa_reoriginate_timer: Something wrong?");
  1584. goto out;
  1585. }
  1586. if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE)
  1587. || ! ospf_if_is_enable (oi)
  1588. || ospf_nbr_count_opaque_capable (oi) == 0)
  1589. {
  1590. if (IS_DEBUG_OSPF_EVENT)
  1591. zlog_debug ("Suspend re-origination of Type-9 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
  1592. oipt->status = PROC_SUSPEND;
  1593. rc = 0;
  1594. goto out;
  1595. }
  1596. if (IS_DEBUG_OSPF_EVENT)
  1597. zlog_debug ("Timer[Type9-LSA]: Re-originate Opaque-LSAs (opaque-type=%u) for OI (%s)", oipt->opaque_type, IF_NAME (oi));
  1598. rc = (* functab->lsa_originator)(oi);
  1599. out:
  1600. return rc;
  1601. }
  1602. static int
  1603. ospf_opaque_type10_lsa_reoriginate_timer (struct thread *t)
  1604. {
  1605. struct opaque_info_per_type *oipt;
  1606. struct ospf_opaque_functab *functab;
  1607. struct listnode *node, *nnode;
  1608. struct ospf *top;
  1609. struct ospf_area *area;
  1610. struct ospf_interface *oi;
  1611. int n, rc = -1;
  1612. oipt = THREAD_ARG (t);
  1613. oipt->t_opaque_lsa_self = NULL;
  1614. if ((functab = oipt->functab) == NULL
  1615. || functab->lsa_originator == NULL)
  1616. {
  1617. zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: No associated function?");
  1618. goto out;
  1619. }
  1620. area = (struct ospf_area *) oipt->owner;
  1621. if (area == NULL || (top = area->ospf) == NULL)
  1622. {
  1623. zlog_warn ("ospf_opaque_type10_lsa_reoriginate_timer: Something wrong?");
  1624. goto out;
  1625. }
  1626. /* There must be at least one "opaque-capable, full-state" neighbor. */
  1627. n = 0;
  1628. for (ALL_LIST_ELEMENTS (area->oiflist, node, nnode, oi))
  1629. {
  1630. if ((n = ospf_nbr_count_opaque_capable (oi)) > 0)
  1631. break;
  1632. }
  1633. if (n == 0 || ! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
  1634. {
  1635. if (IS_DEBUG_OSPF_EVENT)
  1636. zlog_debug ("Suspend re-origination of Type-10 Opaque-LSAs"
  1637. " (opaque-type=%u) for a while...",
  1638. oipt->opaque_type);
  1639. oipt->status = PROC_SUSPEND;
  1640. rc = 0;
  1641. goto out;
  1642. }
  1643. if (IS_DEBUG_OSPF_EVENT)
  1644. zlog_debug ("Timer[Type10-LSA]: Re-originate Opaque-LSAs"
  1645. " (opaque-type=%u) for Area %s",
  1646. oipt->opaque_type, inet_ntoa (area->area_id));
  1647. rc = (* functab->lsa_originator)(area);
  1648. out:
  1649. return rc;
  1650. }
  1651. static int
  1652. ospf_opaque_type11_lsa_reoriginate_timer (struct thread *t)
  1653. {
  1654. struct opaque_info_per_type *oipt;
  1655. struct ospf_opaque_functab *functab;
  1656. struct ospf *top;
  1657. int rc = -1;
  1658. oipt = THREAD_ARG (t);
  1659. oipt->t_opaque_lsa_self = NULL;
  1660. if ((functab = oipt->functab) == NULL
  1661. || functab->lsa_originator == NULL)
  1662. {
  1663. zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer:"
  1664. " No associated function?");
  1665. goto out;
  1666. }
  1667. if ((top = (struct ospf *) oipt->owner) == NULL)
  1668. {
  1669. zlog_warn ("ospf_opaque_type11_lsa_reoriginate_timer: Something wrong?");
  1670. goto out;
  1671. }
  1672. if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
  1673. {
  1674. if (IS_DEBUG_OSPF_EVENT)
  1675. zlog_debug ("Suspend re-origination of Type-11 Opaque-LSAs (opaque-type=%u) for a while...", oipt->opaque_type);
  1676. oipt->status = PROC_SUSPEND;
  1677. rc = 0;
  1678. goto out;
  1679. }
  1680. if (IS_DEBUG_OSPF_EVENT)
  1681. zlog_debug ("Timer[Type11-LSA]: Re-originate Opaque-LSAs (opaque-type=%u).", oipt->opaque_type);
  1682. rc = (* functab->lsa_originator)(top);
  1683. out:
  1684. return rc;
  1685. }
  1686. void
  1687. ospf_opaque_lsa_refresh_schedule (struct ospf_lsa *lsa0)
  1688. {
  1689. struct opaque_info_per_type *oipt;
  1690. struct opaque_info_per_id *oipi;
  1691. struct ospf_lsa *lsa;
  1692. int delay;
  1693. if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
  1694. || (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
  1695. {
  1696. zlog_warn ("ospf_opaque_lsa_refresh_schedule: Invalid parameter?");
  1697. goto out;
  1698. }
  1699. /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
  1700. if ((lsa = oipi->lsa) == NULL)
  1701. {
  1702. zlog_warn ("ospf_opaque_lsa_refresh_schedule: Something wrong?");
  1703. goto out;
  1704. }
  1705. if (oipi->t_opaque_lsa_self != NULL)
  1706. {
  1707. if (IS_DEBUG_OSPF_EVENT)
  1708. zlog_debug ("Type-%u Opaque-LSA has already scheduled to REFRESH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
  1709. goto out;
  1710. }
  1711. /* Delete this lsa from neighbor retransmit-list. */
  1712. switch (lsa->data->type)
  1713. {
  1714. case OSPF_OPAQUE_LINK_LSA:
  1715. case OSPF_OPAQUE_AREA_LSA:
  1716. ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
  1717. break;
  1718. case OSPF_OPAQUE_AS_LSA:
  1719. ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa);
  1720. break;
  1721. default:
  1722. zlog_warn ("ospf_opaque_lsa_refresh_schedule: Unexpected LSA-type(%u)", lsa->data->type);
  1723. goto out;
  1724. }
  1725. delay = ospf_lsa_refresh_delay (lsa);
  1726. if (IS_DEBUG_OSPF_EVENT)
  1727. zlog_debug ("Schedule Type-%u Opaque-LSA to REFRESH in %d sec later: [opaque-type=%u, opaque-id=%x]", lsa->data->type, delay, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
  1728. OSPF_OPAQUE_TIMER_ON (oipi->t_opaque_lsa_self,
  1729. ospf_opaque_lsa_refresh_timer, oipi, delay);
  1730. out:
  1731. return;
  1732. }
  1733. static int
  1734. ospf_opaque_lsa_refresh_timer (struct thread *t)
  1735. {
  1736. struct opaque_info_per_id *oipi;
  1737. struct ospf_opaque_functab *functab;
  1738. struct ospf_lsa *lsa;
  1739. if (IS_DEBUG_OSPF_EVENT)
  1740. zlog_debug ("Timer[Opaque-LSA]: (Opaque-LSA Refresh expire)");
  1741. oipi = THREAD_ARG (t);
  1742. oipi->t_opaque_lsa_self = NULL;
  1743. if ((lsa = oipi->lsa) != NULL)
  1744. if ((functab = oipi->opqctl_type->functab) != NULL)
  1745. if (functab->lsa_refresher != NULL)
  1746. (* functab->lsa_refresher)(lsa);
  1747. return 0;
  1748. }
  1749. void
  1750. ospf_opaque_lsa_flush_schedule (struct ospf_lsa *lsa0)
  1751. {
  1752. struct opaque_info_per_type *oipt;
  1753. struct opaque_info_per_id *oipi;
  1754. struct ospf_lsa *lsa;
  1755. if ((oipt = lookup_opaque_info_by_type (lsa0)) == NULL
  1756. || (oipi = lookup_opaque_info_by_id (oipt, lsa0)) == NULL)
  1757. {
  1758. zlog_warn ("ospf_opaque_lsa_flush_schedule: Invalid parameter?");
  1759. goto out;
  1760. }
  1761. /* Given "lsa0" and current "oipi->lsa" may different, but harmless. */
  1762. if ((lsa = oipi->lsa) == NULL)
  1763. {
  1764. zlog_warn ("ospf_opaque_lsa_flush_schedule: Something wrong?");
  1765. goto out;
  1766. }
  1767. /* Delete this lsa from neighbor retransmit-list. */
  1768. switch (lsa->data->type)
  1769. {
  1770. case OSPF_OPAQUE_LINK_LSA:
  1771. case OSPF_OPAQUE_AREA_LSA:
  1772. ospf_ls_retransmit_delete_nbr_area (lsa->area, lsa);
  1773. break;
  1774. case OSPF_OPAQUE_AS_LSA:
  1775. ospf_ls_retransmit_delete_nbr_as (lsa0->area->ospf, lsa);
  1776. break;
  1777. default:
  1778. zlog_warn ("ospf_opaque_lsa_flush_schedule: Unexpected LSA-type(%u)", lsa->data->type);
  1779. goto out;
  1780. }
  1781. /* Dequeue listnode entry from the list. */
  1782. listnode_delete (oipt->id_list, oipi);
  1783. /* Avoid misjudgement in the next lookup. */
  1784. if (listcount (oipt->id_list) == 0)
  1785. oipt->id_list->head = oipt->id_list->tail = NULL;
  1786. /* Disassociate internal control information with the given lsa. */
  1787. free_opaque_info_per_id ((void *) oipi);
  1788. /* Force given lsa's age to MaxAge. */
  1789. lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
  1790. if (IS_DEBUG_OSPF_EVENT)
  1791. zlog_debug ("Schedule Type-%u Opaque-LSA to FLUSH: [opaque-type=%u, opaque-id=%x]", lsa->data->type, GET_OPAQUE_TYPE (ntohl (lsa->data->id.s_addr)), GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr)));
  1792. /* This lsa will be flushed and removed eventually. */
  1793. ospf_lsa_flush (lsa0->area->ospf, lsa);
  1794. out:
  1795. return;
  1796. }
  1797. /*------------------------------------------------------------------------*
  1798. * Followings are control functions to block origination after restart.
  1799. *------------------------------------------------------------------------*/
  1800. static void ospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs, struct ospf_neighbor *inbr, struct ospf_lsa *lsa);
  1801. #ifdef BUGGY_UNLOCK
  1802. static void ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi);
  1803. static void ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area);
  1804. static void ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top);
  1805. static unsigned long ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type);
  1806. #endif /* BUGGY_UNLOCK */
  1807. void
  1808. ospf_opaque_adjust_lsreq (struct ospf_neighbor *nbr, struct list *lsas)
  1809. {
  1810. struct ospf *top;
  1811. struct ospf_area *area;
  1812. struct ospf_interface *oi;
  1813. struct listnode *node1, *nnode1;
  1814. struct listnode *node2, *nnode2;
  1815. struct ospf_lsa *lsa;
  1816. if ((top = oi_to_top (nbr->oi)) == NULL)
  1817. goto out;
  1818. /*
  1819. * If an instance of self-originated Opaque-LSA is found in the given
  1820. * LSA list, and it is not installed to LSDB yet, exclude it from the
  1821. * list "nbr->ls_req". In this way, it is assured that an LSReq message,
  1822. * which might be sent in the process of flooding, will not request for
  1823. * the LSA to be flushed immediately; otherwise, depending on timing,
  1824. * an LSUpd message will carry instances of target LSAs with MaxAge,
  1825. * while other LSUpd message might carry old LSA instances (non-MaxAge).
  1826. * Obviously, the latter would trigger miserable situations that repeat
  1827. * installation and removal of unwanted LSAs indefinitely.
  1828. */
  1829. for (ALL_LIST_ELEMENTS (lsas, node1, nnode1, lsa))
  1830. {
  1831. /* Filter out unwanted LSAs. */
  1832. if (! IS_OPAQUE_LSA (lsa->data->type))
  1833. continue;
  1834. if (! IPV4_ADDR_SAME (&lsa->data->adv_router, &top->router_id))
  1835. continue;
  1836. /*
  1837. * Don't touch an LSA which has MaxAge; two possible cases.
  1838. *
  1839. * 1) This LSA has originally flushed by myself (received LSUpd
  1840. * message's router-id is equal to my router-id), and flooded
  1841. * back by an opaque-capable router.
  1842. *
  1843. * 2) This LSA has expired in an opaque-capable router and thus
  1844. * flushed by the router.
  1845. */
  1846. if (IS_LSA_MAXAGE (lsa))
  1847. continue;
  1848. /* If the LSA has installed in the LSDB, nothing to do here. */
  1849. if (ospf_lsa_lookup_by_header (nbr->oi->area, lsa->data) != NULL)
  1850. continue;
  1851. /* Ok, here we go. */
  1852. switch (lsa->data->type)
  1853. {
  1854. case OSPF_OPAQUE_LINK_LSA:
  1855. oi = nbr->oi;
  1856. ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);
  1857. break;
  1858. case OSPF_OPAQUE_AREA_LSA:
  1859. area = nbr->oi->area;
  1860. for (ALL_LIST_ELEMENTS (area->oiflist, node2, nnode2, oi))
  1861. ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);
  1862. break;
  1863. case OSPF_OPAQUE_AS_LSA:
  1864. for (ALL_LIST_ELEMENTS (top->oiflist, node2, nnode2, oi))
  1865. ospf_opaque_exclude_lsa_from_lsreq (oi->nbrs, nbr, lsa);
  1866. break;
  1867. default:
  1868. break;
  1869. }
  1870. }
  1871. out:
  1872. return;
  1873. }
  1874. static void
  1875. ospf_opaque_exclude_lsa_from_lsreq (struct route_table *nbrs,
  1876. struct ospf_neighbor *inbr,
  1877. struct ospf_lsa *lsa)
  1878. {
  1879. struct route_node *rn;
  1880. struct ospf_neighbor *onbr;
  1881. struct ospf_lsa *ls_req;
  1882. for (rn = route_top (nbrs); rn; rn = route_next (rn))
  1883. {
  1884. if ((onbr = rn->info) == NULL)
  1885. continue;
  1886. if (onbr == inbr)
  1887. continue;
  1888. if ((ls_req = ospf_ls_request_lookup (onbr, lsa)) == NULL)
  1889. continue;
  1890. if (IS_DEBUG_OSPF_EVENT)
  1891. zlog_debug ("LSA[%s]: Exclude this entry from LSReq to send.", dump_lsa_key (lsa));
  1892. ospf_ls_request_delete (onbr, ls_req);
  1893. /* ospf_check_nbr_loading (onbr);*//* XXX */
  1894. }
  1895. return;
  1896. }
  1897. void
  1898. ospf_opaque_self_originated_lsa_received (struct ospf_neighbor *nbr,
  1899. struct ospf_lsa *lsa)
  1900. {
  1901. struct ospf *top;
  1902. u_char before;
  1903. if ((top = oi_to_top (nbr->oi)) == NULL)
  1904. return;
  1905. before = IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque);
  1906. /*
  1907. * Since these LSA entries are not yet installed into corresponding
  1908. * LSDB, just flush them without calling ospf_ls_maxage() afterward.
  1909. */
  1910. lsa->data->ls_age = htons (OSPF_LSA_MAXAGE);
  1911. switch (lsa->data->type)
  1912. {
  1913. case OSPF_OPAQUE_LINK_LSA:
  1914. SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
  1915. ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);
  1916. break;
  1917. case OSPF_OPAQUE_AREA_LSA:
  1918. SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
  1919. ospf_flood_through_area (nbr->oi->area, NULL/*inbr*/, lsa);
  1920. break;
  1921. case OSPF_OPAQUE_AS_LSA:
  1922. SET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT);
  1923. ospf_flood_through_as (top, NULL/*inbr*/, lsa);
  1924. break;
  1925. default:
  1926. zlog_warn ("ospf_opaque_self_originated_lsa_received: Unexpected LSA-type(%u)", lsa->data->type);
  1927. return;
  1928. }
  1929. ospf_lsa_discard (lsa); /* List "lsas" will be deleted by caller. */
  1930. if (before == 0 && IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
  1931. {
  1932. if (IS_DEBUG_OSPF_EVENT)
  1933. zlog_debug ("Block Opaque-LSA origination: OFF -> ON");
  1934. }
  1935. }
  1936. void
  1937. ospf_opaque_ls_ack_received (struct ospf_neighbor *nbr, struct ospf_lsa *lsa)
  1938. {
  1939. struct ospf *top;
  1940. int delay;
  1941. struct ospf_interface *oi;
  1942. struct listnode *node, *nnode;
  1943. if ((top = oi_to_top (nbr->oi)) == NULL)
  1944. return;
  1945. if (!IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
  1946. return;
  1947. switch (lsa->data->type)
  1948. {
  1949. case OSPF_OPAQUE_LINK_LSA:
  1950. if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT))
  1951. UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
  1952. /* BUGGY_UNLOCK: ospf_opaque_type9_lsa_rxmt_nbr_check (nbr->oi); */
  1953. /* Callback function... */
  1954. break;
  1955. case OSPF_OPAQUE_AREA_LSA:
  1956. if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT))
  1957. UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
  1958. /* BUGGY_UNLOCK: ospf_opaque_type10_lsa_rxmt_nbr_check (nbr->oi->area); */
  1959. /* Callback function... */
  1960. break;
  1961. case OSPF_OPAQUE_AS_LSA:
  1962. if (CHECK_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT))
  1963. UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT);
  1964. /* BUGGY_UNLOCK: ospf_opaque_type11_lsa_rxmt_nbr_check (top); */
  1965. /* Callback function... */
  1966. break;
  1967. default:
  1968. zlog_warn ("ospf_opaque_ls_ack_received: Unexpected LSA-type(%u)", lsa->data->type);
  1969. return;
  1970. }
  1971. if (IS_OPAQUE_LSA_ORIGINATION_BLOCKED (top->opaque))
  1972. return; /* Blocking still in progress. */
  1973. if (IS_DEBUG_OSPF_EVENT)
  1974. zlog_debug ("Block Opaque-LSA origination: ON -> OFF");
  1975. if (! CHECK_FLAG (top->config, OSPF_OPAQUE_CAPABLE))
  1976. return; /* Opaque capability condition must have changed. */
  1977. /* Ok, let's start origination of Opaque-LSAs. */
  1978. delay = OSPF_MIN_LS_INTERVAL;
  1979. for (ALL_LIST_ELEMENTS (top->oiflist, node, nnode, oi))
  1980. {
  1981. if (! ospf_if_is_enable (oi)
  1982. || ospf_nbr_count_opaque_capable (oi) == 0)
  1983. continue;
  1984. ospf_opaque_lsa_originate_schedule (oi, &delay);
  1985. }
  1986. return;
  1987. }
  1988. #ifdef BUGGY_UNLOCK
  1989. static void
  1990. ospf_opaque_type9_lsa_rxmt_nbr_check (struct ospf_interface *oi)
  1991. {
  1992. unsigned long n;
  1993. n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_LINK_LSA);
  1994. if (n == 0)
  1995. {
  1996. if (IS_DEBUG_OSPF_EVENT)
  1997. zlog_debug ("Self-originated type-9 Opaque-LSAs: OI(%s): Flush completed", IF_NAME (oi));
  1998. UNSET_FLAG (oi->area->ospf->opaque, OPAQUE_BLOCK_TYPE_09_LSA_BIT);
  1999. }
  2000. return;
  2001. }
  2002. static void
  2003. ospf_opaque_type10_lsa_rxmt_nbr_check (struct ospf_area *area)
  2004. {
  2005. struct listnode *node;
  2006. struct ospf_interface *oi;
  2007. unsigned long n = 0;
  2008. for (ALL_LIST_ELEMENTS_RO (area->oiflist, node, oi))
  2009. {
  2010. if (area->area_id.s_addr != OSPF_AREA_BACKBONE
  2011. && oi->type == OSPF_IFTYPE_VIRTUALLINK)
  2012. continue;
  2013. n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AREA_LSA);
  2014. if (n > 0)
  2015. break;
  2016. }
  2017. if (n == 0)
  2018. {
  2019. if (IS_DEBUG_OSPF_EVENT)
  2020. zlog_debug ("Self-originated type-10 Opaque-LSAs: AREA(%s): Flush completed", inet_ntoa (area->area_id));
  2021. UNSET_FLAG (area->ospf->opaque, OPAQUE_BLOCK_TYPE_10_LSA_BIT);
  2022. }
  2023. return;
  2024. }
  2025. static void
  2026. ospf_opaque_type11_lsa_rxmt_nbr_check (struct ospf *top)
  2027. {
  2028. struct listnode *node;
  2029. struct ospf_interface *oi;
  2030. unsigned long n = 0;
  2031. for (ALL_LIST_ELEMENTS_RO (top->oiflist, node, oi))
  2032. {
  2033. switch (oi->type)
  2034. {
  2035. case OSPF_IFTYPE_VIRTUALLINK:
  2036. continue;
  2037. default:
  2038. break;
  2039. }
  2040. n = ospf_opaque_nrxmt_self (oi->nbrs, OSPF_OPAQUE_AS_LSA);
  2041. if (n > 0)
  2042. goto out;
  2043. }
  2044. if (n == 0)
  2045. {
  2046. if (IS_DEBUG_OSPF_EVENT)
  2047. zlog_debug ("Self-originated type-11 Opaque-LSAs: Flush completed");
  2048. UNSET_FLAG (top->opaque, OPAQUE_BLOCK_TYPE_11_LSA_BIT);
  2049. }
  2050. out:
  2051. return;
  2052. }
  2053. static unsigned long
  2054. ospf_opaque_nrxmt_self (struct route_table *nbrs, int lsa_type)
  2055. {
  2056. struct route_node *rn;
  2057. struct ospf_neighbor *nbr;
  2058. struct ospf *top;
  2059. unsigned long n = 0;
  2060. for (rn = route_top (nbrs); rn; rn = route_next (rn))
  2061. {
  2062. if ((nbr = rn->info) == NULL)
  2063. continue;
  2064. if ((top = oi_to_top (nbr->oi)) == NULL)
  2065. continue;
  2066. if (IPV4_ADDR_SAME (&nbr->router_id, &top->router_id))
  2067. continue;
  2068. n += ospf_ls_retransmit_count_self (nbr, lsa_type);
  2069. }
  2070. return n;
  2071. }
  2072. #endif /* BUGGY_UNLOCK */
  2073. /*------------------------------------------------------------------------*
  2074. * Followings are util functions; probably be used by Opaque-LSAs only...
  2075. *------------------------------------------------------------------------*/
  2076. void
  2077. htonf (float *src, float *dst)
  2078. {
  2079. u_int32_t lu1, lu2;
  2080. memcpy (&lu1, src, sizeof (u_int32_t));
  2081. lu2 = htonl (lu1);
  2082. memcpy (dst, &lu2, sizeof (u_int32_t));
  2083. return;
  2084. }
  2085. void
  2086. ntohf (float *src, float *dst)
  2087. {
  2088. u_int32_t lu1, lu2;
  2089. memcpy (&lu1, src, sizeof (u_int32_t));
  2090. lu2 = ntohl (lu1);
  2091. memcpy (dst, &lu2, sizeof (u_int32_t));
  2092. return;
  2093. }
  2094. struct ospf *
  2095. oi_to_top (struct ospf_interface *oi)
  2096. {
  2097. struct ospf *top = NULL;
  2098. struct ospf_area *area;
  2099. if (oi == NULL || (area = oi->area) == NULL || (top = area->ospf) == NULL)
  2100. zlog_warn ("Broken relationship for \"OI -> AREA -> OSPF\"?");
  2101. return top;
  2102. }
  2103. #endif /* HAVE_OPAQUE_LSA */