ospf_opaque.c 71 KB

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