ospf_te.c 51 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903
  1. /*
  2. * This is an implementation of draft-katz-yeung-ospf-traffic-06.txt
  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 definition is not reflected to "memory.h" yet. *****/
  24. #define MTYPE_OSPF_MPLS_TE_LINKPARAMS MTYPE_TMP
  25. #include <zebra.h>
  26. #include "linklist.h"
  27. #include "prefix.h"
  28. #include "if.h"
  29. #include "table.h"
  30. #include "memory.h"
  31. #include "command.h"
  32. #include "vty.h"
  33. #include "stream.h"
  34. #include "log.h"
  35. #include "thread.h"
  36. #include "hash.h"
  37. #include "sockunion.h" /* for inet_aton() */
  38. #include "network.h"
  39. #include "ospfd/ospfd.h"
  40. #include "ospfd/ospf_interface.h"
  41. #include "ospfd/ospf_ism.h"
  42. #include "ospfd/ospf_asbr.h"
  43. #include "ospfd/ospf_lsa.h"
  44. #include "ospfd/ospf_lsdb.h"
  45. #include "ospfd/ospf_neighbor.h"
  46. #include "ospfd/ospf_nsm.h"
  47. #include "ospfd/ospf_flood.h"
  48. #include "ospfd/ospf_packet.h"
  49. #include "ospfd/ospf_spf.h"
  50. #include "ospfd/ospf_dump.h"
  51. #include "ospfd/ospf_route.h"
  52. #include "ospfd/ospf_ase.h"
  53. #include "ospfd/ospf_zebra.h"
  54. #include "ospfd/ospf_te.h"
  55. /* Following structure are internal use only. */
  56. struct ospf_mpls_te
  57. {
  58. enum { disabled, enabled } status;
  59. /* List elements are zebra-interfaces (ifp), not ospf-interfaces (oi). */
  60. struct list *iflist;
  61. /* Store Router-TLV in network byte order. */
  62. struct te_tlv_router_addr router_addr;
  63. };
  64. struct mpls_te_link
  65. {
  66. /*
  67. * According to MPLS-TE (draft) specification, 24-bit Opaque-ID field
  68. * is subdivided into 8-bit "unused" field and 16-bit "instance" field.
  69. * In this implementation, each Link-TLV has its own instance.
  70. */
  71. u_int32_t instance;
  72. /* Reference pointer to a Zebra-interface. */
  73. struct interface *ifp;
  74. /* Area info in which this MPLS-TE link belongs to. */
  75. struct ospf_area *area;
  76. /* Flags to manage this link parameters. */
  77. u_int32_t flags;
  78. #define LPFLG_LOOKUP_DONE 0x1
  79. #define LPFLG_LSA_ENGAGED 0x2
  80. #define LPFLG_LSA_FORCED_REFRESH 0x4
  81. /* Store Link-TLV in network byte order. */
  82. struct te_tlv_link link_header;
  83. struct te_link_subtlv_link_type link_type;
  84. struct te_link_subtlv_link_id link_id;
  85. struct te_link_subtlv_lclif_ipaddr *lclif_ipaddr;
  86. struct te_link_subtlv_rmtif_ipaddr *rmtif_ipaddr;
  87. struct te_link_subtlv_te_metric te_metric;
  88. struct te_link_subtlv_max_bw max_bw;
  89. struct te_link_subtlv_max_rsv_bw max_rsv_bw;
  90. struct te_link_subtlv_unrsv_bw unrsv_bw;
  91. struct te_link_subtlv_rsc_clsclr rsc_clsclr;
  92. };
  93. /*
  94. * Global variable to manage Opaque-LSA/MPLS-TE on this node.
  95. * Note that all parameter values are stored in network byte order.
  96. */
  97. static struct ospf_mpls_te OspfMplsTE;
  98. enum oifstate {
  99. OI_ANY, OI_DOWN, OI_UP
  100. };
  101. enum sched_opcode {
  102. REORIGINATE_PER_AREA, REFRESH_THIS_LSA, FLUSH_THIS_LSA
  103. };
  104. /*------------------------------------------------------------------------*
  105. * Followings are initialize/terminate functions for MPLS-TE handling.
  106. *------------------------------------------------------------------------*/
  107. static int ospf_mpls_te_new_if (struct interface *ifp);
  108. static int ospf_mpls_te_del_if (struct interface *ifp);
  109. static void ospf_mpls_te_ism_change (struct ospf_interface *oi, int old_status);
  110. static void ospf_mpls_te_nsm_change (struct ospf_neighbor *nbr, int old_status);
  111. static void ospf_mpls_te_config_write_router (struct vty *vty);
  112. static void ospf_mpls_te_config_write_if (struct vty *vty, struct interface *ifp);
  113. static void ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa);
  114. static int ospf_mpls_te_lsa_originate (void *arg);
  115. static struct ospf_lsa *ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa);
  116. static void ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp, enum sched_opcode);
  117. static void del_mpls_te_link (void *val);
  118. static void ospf_mpls_te_register_vty (void);
  119. int
  120. ospf_mpls_te_init (void)
  121. {
  122. int rc;
  123. rc = ospf_register_opaque_functab (
  124. OSPF_OPAQUE_AREA_LSA,
  125. OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA,
  126. ospf_mpls_te_new_if,
  127. ospf_mpls_te_del_if,
  128. ospf_mpls_te_ism_change,
  129. ospf_mpls_te_nsm_change,
  130. ospf_mpls_te_config_write_router,
  131. ospf_mpls_te_config_write_if,
  132. NULL,/* ospf_mpls_te_config_write_debug */
  133. ospf_mpls_te_show_info,
  134. ospf_mpls_te_lsa_originate,
  135. ospf_mpls_te_lsa_refresh,
  136. NULL,/* ospf_mpls_te_new_lsa_hook */
  137. NULL /* ospf_mpls_te_del_lsa_hook */);
  138. if (rc != 0)
  139. {
  140. zlog_warn ("ospf_mpls_te_init: Failed to register functions");
  141. goto out;
  142. }
  143. memset (&OspfMplsTE, 0, sizeof (struct ospf_mpls_te));
  144. OspfMplsTE.status = disabled;
  145. OspfMplsTE.iflist = list_new ();
  146. OspfMplsTE.iflist->del = del_mpls_te_link;
  147. ospf_mpls_te_register_vty ();
  148. out:
  149. return rc;
  150. }
  151. void
  152. ospf_mpls_te_term (void)
  153. {
  154. list_delete (OspfMplsTE.iflist);
  155. OspfMplsTE.iflist = NULL;
  156. OspfMplsTE.status = disabled;
  157. ospf_delete_opaque_functab (OSPF_OPAQUE_AREA_LSA,
  158. OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);
  159. return;
  160. }
  161. /*------------------------------------------------------------------------*
  162. * Followings are control functions for MPLS-TE parameters management.
  163. *------------------------------------------------------------------------*/
  164. static void
  165. del_mpls_te_link (void *val)
  166. {
  167. XFREE (MTYPE_OSPF_MPLS_TE_LINKPARAMS, val);
  168. return;
  169. }
  170. static u_int32_t
  171. get_mpls_te_instance_value (void)
  172. {
  173. static u_int32_t seqno = 0;
  174. if (seqno < MAX_LEGAL_TE_INSTANCE_NUM )
  175. seqno += 1;
  176. else
  177. seqno = 1; /* Avoid zero. */
  178. return seqno;
  179. }
  180. static struct ospf_interface *
  181. lookup_oi_by_ifp (struct interface *ifp,
  182. struct ospf_area *area, enum oifstate oifstate)
  183. {
  184. struct ospf_interface *oi = NULL;
  185. struct route_node *rn;
  186. for (rn = route_top (IF_OIFS (ifp)); rn; rn = route_next (rn))
  187. {
  188. if ((oi = rn->info) == NULL)
  189. continue;
  190. switch (oifstate)
  191. {
  192. case OI_ANY:
  193. break;
  194. case OI_DOWN:
  195. if (ospf_if_is_enable (oi))
  196. continue;
  197. break;
  198. case OI_UP:
  199. if (! ospf_if_is_enable (oi))
  200. continue;
  201. break;
  202. default:
  203. zlog_warn ("lookup_oi_by_ifp: Unknown oifstate: %x", oifstate);
  204. goto out;
  205. }
  206. if (area == NULL || oi->area == area)
  207. return oi;
  208. }
  209. out:
  210. return NULL;
  211. }
  212. static struct mpls_te_link *
  213. lookup_linkparams_by_ifp (struct interface *ifp)
  214. {
  215. struct listnode *node, *nnode;
  216. struct mpls_te_link *lp;
  217. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  218. if (lp->ifp == ifp)
  219. return lp;
  220. return NULL;
  221. }
  222. static struct mpls_te_link *
  223. lookup_linkparams_by_instance (struct ospf_lsa *lsa)
  224. {
  225. struct listnode *node;
  226. struct mpls_te_link *lp;
  227. unsigned int key = GET_OPAQUE_ID (ntohl (lsa->data->id.s_addr));
  228. for (ALL_LIST_ELEMENTS_RO (OspfMplsTE.iflist, node, lp))
  229. if (lp->instance == key)
  230. return lp;
  231. zlog_warn ("lookup_linkparams_by_instance: Entry not found: key(%x)", key);
  232. return NULL;
  233. }
  234. static void
  235. ospf_mpls_te_foreach_area (
  236. void (*func)(struct mpls_te_link *lp, enum sched_opcode),
  237. enum sched_opcode sched_opcode)
  238. {
  239. struct listnode *node, *nnode;
  240. struct listnode *node2;
  241. struct mpls_te_link *lp;
  242. struct ospf_area *area;
  243. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  244. {
  245. if ((area = lp->area) == NULL)
  246. continue;
  247. if (lp->flags & LPFLG_LOOKUP_DONE)
  248. continue;
  249. if (func != NULL)
  250. (* func)(lp, sched_opcode);
  251. for (node2 = listnextnode (node); node2; node2 = listnextnode (node2))
  252. if ((lp = listgetdata (node2)) != NULL)
  253. if (lp->area != NULL)
  254. if (IPV4_ADDR_SAME (&lp->area->area_id, &area->area_id))
  255. lp->flags |= LPFLG_LOOKUP_DONE;
  256. }
  257. for (ALL_LIST_ELEMENTS_RO (OspfMplsTE.iflist, node, lp))
  258. if (lp->area != NULL)
  259. lp->flags &= ~LPFLG_LOOKUP_DONE;
  260. return;
  261. }
  262. static void
  263. set_mpls_te_router_addr (struct in_addr ipv4)
  264. {
  265. OspfMplsTE.router_addr.header.type = htons (TE_TLV_ROUTER_ADDR);
  266. OspfMplsTE.router_addr.header.length = htons (sizeof (ipv4));
  267. OspfMplsTE.router_addr.value = ipv4;
  268. return;
  269. }
  270. static void
  271. set_linkparams_link_header (struct mpls_te_link *lp)
  272. {
  273. struct te_tlv_header *tlvh;
  274. u_int16_t length = 0;
  275. /* TE_LINK_SUBTLV_LINK_TYPE */
  276. if (ntohs (lp->link_type.header.type) != 0)
  277. length += TLV_SIZE (&lp->link_type.header);
  278. /* TE_LINK_SUBTLV_LINK_ID */
  279. if (ntohs (lp->link_id.header.type) != 0)
  280. length += TLV_SIZE (&lp->link_id.header);
  281. /* TE_LINK_SUBTLV_LCLIF_IPADDR */
  282. if ((tlvh = (struct te_tlv_header *) lp->lclif_ipaddr) != NULL
  283. && ntohs (tlvh->type) != 0)
  284. length += TLV_SIZE (tlvh);
  285. /* TE_LINK_SUBTLV_RMTIF_IPADDR */
  286. if ((tlvh = (struct te_tlv_header *) lp->rmtif_ipaddr) != NULL
  287. && ntohs (tlvh->type) != 0)
  288. length += TLV_SIZE (tlvh);
  289. /* TE_LINK_SUBTLV_TE_METRIC */
  290. if (ntohs (lp->te_metric.header.type) != 0)
  291. length += TLV_SIZE (&lp->te_metric.header);
  292. /* TE_LINK_SUBTLV_MAX_BW */
  293. if (ntohs (lp->max_bw.header.type) != 0)
  294. length += TLV_SIZE (&lp->max_bw.header);
  295. /* TE_LINK_SUBTLV_MAX_RSV_BW */
  296. if (ntohs (lp->max_rsv_bw.header.type) != 0)
  297. length += TLV_SIZE (&lp->max_rsv_bw.header);
  298. /* TE_LINK_SUBTLV_UNRSV_BW */
  299. if (ntohs (lp->unrsv_bw.header.type) != 0)
  300. length += TLV_SIZE (&lp->unrsv_bw.header);
  301. /* TE_LINK_SUBTLV_RSC_CLSCLR */
  302. if (ntohs (lp->rsc_clsclr.header.type) != 0)
  303. length += TLV_SIZE (&lp->rsc_clsclr.header);
  304. lp->link_header.header.type = htons (TE_TLV_LINK);
  305. lp->link_header.header.length = htons (length);
  306. return;
  307. }
  308. static void
  309. set_linkparams_link_type (struct ospf_interface *oi, struct mpls_te_link *lp)
  310. {
  311. lp->link_type.header.type = htons (TE_LINK_SUBTLV_LINK_TYPE);
  312. lp->link_type.header.length = htons (sizeof (lp->link_type.link_type.value));
  313. switch (oi->type)
  314. {
  315. case OSPF_IFTYPE_POINTOPOINT:
  316. lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_PTP;
  317. break;
  318. case OSPF_IFTYPE_BROADCAST:
  319. case OSPF_IFTYPE_NBMA:
  320. lp->link_type.link_type.value = LINK_TYPE_SUBTLV_VALUE_MA;
  321. break;
  322. default:
  323. /* Not supported yet. *//* XXX */
  324. lp->link_type.header.type = htons (0);
  325. break;
  326. }
  327. return;
  328. }
  329. static void
  330. set_linkparams_link_id (struct ospf_interface *oi, struct mpls_te_link *lp)
  331. {
  332. struct ospf_neighbor *nbr;
  333. int done = 0;
  334. lp->link_id.header.type = htons (TE_LINK_SUBTLV_LINK_ID);
  335. lp->link_id.header.length = htons (sizeof (lp->link_id.value));
  336. /*
  337. * The Link ID is identical to the contents of the Link ID field
  338. * in the Router LSA for these link types.
  339. */
  340. switch (oi->type)
  341. {
  342. case OSPF_IFTYPE_POINTOPOINT:
  343. /* Take the router ID of the neighbor. */
  344. if ((nbr = ospf_nbr_lookup_ptop (oi))
  345. && nbr->state == NSM_Full)
  346. {
  347. lp->link_id.value = nbr->router_id;
  348. done = 1;
  349. }
  350. break;
  351. case OSPF_IFTYPE_BROADCAST:
  352. case OSPF_IFTYPE_NBMA:
  353. /* Take the interface address of the designated router. */
  354. if ((nbr = ospf_nbr_lookup_by_addr (oi->nbrs, &DR (oi))) == NULL)
  355. break;
  356. if (nbr->state == NSM_Full
  357. || (IPV4_ADDR_SAME (&oi->address->u.prefix4, &DR (oi))
  358. && ospf_nbr_count (oi, NSM_Full) > 0))
  359. {
  360. lp->link_id.value = DR (oi);
  361. done = 1;
  362. }
  363. break;
  364. default:
  365. /* Not supported yet. *//* XXX */
  366. lp->link_id.header.type = htons (0);
  367. break;
  368. }
  369. if (! done)
  370. {
  371. struct in_addr mask;
  372. masklen2ip (oi->address->prefixlen, &mask);
  373. lp->link_id.value.s_addr = oi->address->u.prefix4.s_addr & mask.s_addr;
  374. }
  375. return;
  376. }
  377. static void
  378. set_linkparams_te_metric (struct mpls_te_link *lp, u_int32_t te_metric)
  379. {
  380. lp->te_metric.header.type = htons (TE_LINK_SUBTLV_TE_METRIC);
  381. lp->te_metric.header.length = htons (sizeof (lp->te_metric.value));
  382. lp->te_metric.value = htonl (te_metric);
  383. return;
  384. }
  385. static void
  386. set_linkparams_max_bw (struct mpls_te_link *lp, float fp)
  387. {
  388. lp->max_bw.header.type = htons (TE_LINK_SUBTLV_MAX_BW);
  389. lp->max_bw.header.length = htons (sizeof (lp->max_bw.value));
  390. lp->max_bw.value = htonf (fp);
  391. return;
  392. }
  393. static void
  394. set_linkparams_max_rsv_bw (struct mpls_te_link *lp, float fp)
  395. {
  396. lp->max_rsv_bw.header.type = htons (TE_LINK_SUBTLV_MAX_RSV_BW);
  397. lp->max_rsv_bw.header.length = htons (sizeof (lp->max_rsv_bw.value));
  398. lp->max_rsv_bw.value = htonf (fp);
  399. return;
  400. }
  401. static void
  402. set_linkparams_unrsv_bw (struct mpls_te_link *lp, int priority, float fp)
  403. {
  404. /* Note that TLV-length field is the size of array. */
  405. lp->unrsv_bw.header.type = htons (TE_LINK_SUBTLV_UNRSV_BW);
  406. lp->unrsv_bw.header.length = htons (sizeof (lp->unrsv_bw.value));
  407. lp->unrsv_bw.value [priority] = htonf (fp);
  408. return;
  409. }
  410. static void
  411. set_linkparams_rsc_clsclr (struct mpls_te_link *lp, u_int32_t classcolor)
  412. {
  413. lp->rsc_clsclr.header.type = htons (TE_LINK_SUBTLV_RSC_CLSCLR);
  414. lp->rsc_clsclr.header.length = htons (sizeof (lp->rsc_clsclr.value));
  415. lp->rsc_clsclr.value = htonl (classcolor);
  416. return;
  417. }
  418. static void
  419. initialize_linkparams (struct mpls_te_link *lp)
  420. {
  421. struct interface *ifp = lp->ifp;
  422. struct ospf_interface *oi;
  423. float fval;
  424. int i;
  425. if ((oi = lookup_oi_by_ifp (ifp, NULL, OI_ANY)) == NULL)
  426. return;
  427. /*
  428. * Try to set initial values those can be derived from
  429. * zebra-interface information.
  430. */
  431. set_linkparams_link_type (oi, lp);
  432. /*
  433. * Linux and *BSD kernel holds bandwidth parameter as an "int" type.
  434. * We may have to reconsider, if "ifp->bandwidth" type changes to float.
  435. */
  436. fval = (float)((ifp->bandwidth ? ifp->bandwidth
  437. : OSPF_DEFAULT_BANDWIDTH) * 1000 / 8);
  438. set_linkparams_max_bw (lp, fval);
  439. set_linkparams_max_rsv_bw (lp, fval);
  440. for (i = 0; i < 8; i++)
  441. set_linkparams_unrsv_bw (lp, i, fval);
  442. return;
  443. }
  444. static int
  445. is_mandated_params_set (struct mpls_te_link *lp)
  446. {
  447. int rc = 0;
  448. if (ntohs (OspfMplsTE.router_addr.header.type) == 0)
  449. goto out;
  450. if (ntohs (lp->link_type.header.type) == 0)
  451. goto out;
  452. if (ntohs (lp->link_id.header.type) == 0)
  453. goto out;
  454. rc = 1;
  455. out:
  456. return rc;
  457. }
  458. /*------------------------------------------------------------------------*
  459. * Followings are callback functions against generic Opaque-LSAs handling.
  460. *------------------------------------------------------------------------*/
  461. static int
  462. ospf_mpls_te_new_if (struct interface *ifp)
  463. {
  464. struct mpls_te_link *new;
  465. int rc = -1;
  466. if (lookup_linkparams_by_ifp (ifp) != NULL)
  467. {
  468. zlog_warn ("ospf_mpls_te_new_if: ifp(%p) already in use?", (void *)ifp);
  469. rc = 0; /* Do nothing here. */
  470. goto out;
  471. }
  472. new = XCALLOC (MTYPE_OSPF_MPLS_TE_LINKPARAMS,
  473. sizeof (struct mpls_te_link));
  474. if (new == NULL)
  475. {
  476. zlog_warn ("ospf_mpls_te_new_if: XMALLOC: %s", safe_strerror (errno));
  477. goto out;
  478. }
  479. new->area = NULL;
  480. new->flags = 0;
  481. new->instance = get_mpls_te_instance_value ();
  482. new->ifp = ifp;
  483. initialize_linkparams (new);
  484. listnode_add (OspfMplsTE.iflist, new);
  485. /* Schedule Opaque-LSA refresh. *//* XXX */
  486. rc = 0;
  487. out:
  488. return rc;
  489. }
  490. static int
  491. ospf_mpls_te_del_if (struct interface *ifp)
  492. {
  493. struct mpls_te_link *lp;
  494. int rc = -1;
  495. if ((lp = lookup_linkparams_by_ifp (ifp)) != NULL)
  496. {
  497. struct list *iflist = OspfMplsTE.iflist;
  498. /* Dequeue listnode entry from the list. */
  499. listnode_delete (iflist, lp);
  500. /* Avoid misjudgement in the next lookup. */
  501. if (listcount (iflist) == 0)
  502. iflist->head = iflist->tail = NULL;
  503. XFREE (MTYPE_OSPF_MPLS_TE_LINKPARAMS, lp);
  504. }
  505. /* Schedule Opaque-LSA refresh. *//* XXX */
  506. rc = 0;
  507. /*out:*/
  508. return rc;
  509. }
  510. static void
  511. ospf_mpls_te_ism_change (struct ospf_interface *oi, int old_state)
  512. {
  513. struct te_link_subtlv_link_type old_type;
  514. struct te_link_subtlv_link_id old_id;
  515. struct mpls_te_link *lp;
  516. if ((lp = lookup_linkparams_by_ifp (oi->ifp)) == NULL)
  517. {
  518. zlog_warn ("ospf_mpls_te_ism_change: Cannot get linkparams from OI(%s)?", IF_NAME (oi));
  519. goto out;
  520. }
  521. if (oi->area == NULL || oi->area->ospf == NULL)
  522. {
  523. zlog_warn ("ospf_mpls_te_ism_change: Cannot refer to OSPF from OI(%s)?",
  524. IF_NAME (oi));
  525. goto out;
  526. }
  527. #ifdef notyet
  528. if ((lp->area != NULL
  529. && ! IPV4_ADDR_SAME (&lp->area->area_id, &oi->area->area_id))
  530. || (lp->area != NULL && oi->area == NULL))
  531. {
  532. /* How should we consider this case? */
  533. zlog_warn ("MPLS-TE: Area for OI(%s) has changed to [%s], flush previous LSAs", IF_NAME (oi), oi->area ? inet_ntoa (oi->area->area_id) : "N/A");
  534. ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA);
  535. }
  536. #endif
  537. /* Keep Area information in conbination with linkparams. */
  538. lp->area = oi->area;
  539. switch (oi->state)
  540. {
  541. case ISM_PointToPoint:
  542. case ISM_DROther:
  543. case ISM_Backup:
  544. case ISM_DR:
  545. old_type = lp->link_type;
  546. old_id = lp->link_id;
  547. set_linkparams_link_type (oi, lp);
  548. set_linkparams_link_id (oi, lp);
  549. if ((ntohs (old_type.header.type) != ntohs (lp->link_type.header.type)
  550. || old_type.link_type.value != lp->link_type.link_type.value)
  551. || (ntohs (old_id.header.type) != ntohs (lp->link_id.header.type)
  552. || ntohl (old_id.value.s_addr) != ntohl (lp->link_id.value.s_addr)))
  553. {
  554. if (lp->flags & LPFLG_LSA_ENGAGED)
  555. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  556. else
  557. ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);
  558. }
  559. break;
  560. default:
  561. lp->link_type.header.type = htons (0);
  562. lp->link_id.header.type = htons (0);
  563. if (lp->flags & LPFLG_LSA_ENGAGED)
  564. ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA);
  565. break;
  566. }
  567. out:
  568. return;
  569. }
  570. static void
  571. ospf_mpls_te_nsm_change (struct ospf_neighbor *nbr, int old_state)
  572. {
  573. /* So far, nothing to do here. */
  574. return;
  575. }
  576. /*------------------------------------------------------------------------*
  577. * Followings are OSPF protocol processing functions for MPLS-TE.
  578. *------------------------------------------------------------------------*/
  579. static void
  580. build_tlv_header (struct stream *s, struct te_tlv_header *tlvh)
  581. {
  582. stream_put (s, tlvh, sizeof (struct te_tlv_header));
  583. return;
  584. }
  585. static void
  586. build_router_tlv (struct stream *s)
  587. {
  588. struct te_tlv_header *tlvh = &OspfMplsTE.router_addr.header;
  589. if (ntohs (tlvh->type) != 0)
  590. {
  591. build_tlv_header (s, tlvh);
  592. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  593. }
  594. return;
  595. }
  596. static void
  597. build_link_subtlv_link_type (struct stream *s, struct mpls_te_link *lp)
  598. {
  599. struct te_tlv_header *tlvh = &lp->link_type.header;
  600. if (ntohs (tlvh->type) != 0)
  601. {
  602. build_tlv_header (s, tlvh);
  603. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  604. }
  605. return;
  606. }
  607. static void
  608. build_link_subtlv_link_id (struct stream *s, struct mpls_te_link *lp)
  609. {
  610. struct te_tlv_header *tlvh = &lp->link_id.header;
  611. if (ntohs (tlvh->type) != 0)
  612. {
  613. build_tlv_header (s, tlvh);
  614. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  615. }
  616. return;
  617. }
  618. static void
  619. build_link_subtlv_lclif_ipaddr (struct stream *s, struct mpls_te_link *lp)
  620. {
  621. struct te_tlv_header *tlvh = (struct te_tlv_header *) lp->lclif_ipaddr;
  622. if (tlvh != NULL && ntohs (tlvh->type) != 0)
  623. {
  624. build_tlv_header (s, tlvh);
  625. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  626. }
  627. return;
  628. }
  629. static void
  630. build_link_subtlv_rmtif_ipaddr (struct stream *s, struct mpls_te_link *lp)
  631. {
  632. struct te_tlv_header *tlvh = (struct te_tlv_header *) lp->rmtif_ipaddr;
  633. if (tlvh != NULL && ntohs (tlvh->type) != 0)
  634. {
  635. build_tlv_header (s, tlvh);
  636. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  637. }
  638. return;
  639. }
  640. static void
  641. build_link_subtlv_te_metric (struct stream *s, struct mpls_te_link *lp)
  642. {
  643. struct te_tlv_header *tlvh = &lp->te_metric.header;
  644. if (ntohs (tlvh->type) != 0)
  645. {
  646. build_tlv_header (s, tlvh);
  647. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  648. }
  649. return;
  650. }
  651. static void
  652. build_link_subtlv_max_bw (struct stream *s, struct mpls_te_link *lp)
  653. {
  654. struct te_tlv_header *tlvh = &lp->max_bw.header;
  655. if (ntohs (tlvh->type) != 0)
  656. {
  657. build_tlv_header (s, tlvh);
  658. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  659. }
  660. return;
  661. }
  662. static void
  663. build_link_subtlv_max_rsv_bw (struct stream *s, struct mpls_te_link *lp)
  664. {
  665. struct te_tlv_header *tlvh = &lp->max_rsv_bw.header;
  666. if (ntohs (tlvh->type) != 0)
  667. {
  668. build_tlv_header (s, tlvh);
  669. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  670. }
  671. return;
  672. }
  673. static void
  674. build_link_subtlv_unrsv_bw (struct stream *s, struct mpls_te_link *lp)
  675. {
  676. struct te_tlv_header *tlvh = &lp->unrsv_bw.header;
  677. if (ntohs (tlvh->type) != 0)
  678. {
  679. build_tlv_header (s, tlvh);
  680. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  681. }
  682. return;
  683. }
  684. static void
  685. build_link_subtlv_rsc_clsclr (struct stream *s, struct mpls_te_link *lp)
  686. {
  687. struct te_tlv_header *tlvh = &lp->rsc_clsclr.header;
  688. if (ntohs (tlvh->type) != 0)
  689. {
  690. build_tlv_header (s, tlvh);
  691. stream_put (s, tlvh+1, TLV_BODY_SIZE (tlvh));
  692. }
  693. return;
  694. }
  695. static void
  696. build_link_tlv (struct stream *s, struct mpls_te_link *lp)
  697. {
  698. set_linkparams_link_header (lp);
  699. build_tlv_header (s, &lp->link_header.header);
  700. build_link_subtlv_link_type (s, lp);
  701. build_link_subtlv_link_id (s, lp);
  702. build_link_subtlv_lclif_ipaddr (s, lp);
  703. build_link_subtlv_rmtif_ipaddr (s, lp);
  704. build_link_subtlv_te_metric (s, lp);
  705. build_link_subtlv_max_bw (s, lp);
  706. build_link_subtlv_max_rsv_bw (s, lp);
  707. build_link_subtlv_unrsv_bw (s, lp);
  708. build_link_subtlv_rsc_clsclr (s, lp);
  709. return;
  710. }
  711. static void
  712. ospf_mpls_te_lsa_body_set (struct stream *s, struct mpls_te_link *lp)
  713. {
  714. /*
  715. * The router address TLV is type 1, and ...
  716. * It must appear in exactly one
  717. * Traffic Engineering LSA originated by a router.
  718. */
  719. build_router_tlv (s);
  720. /*
  721. * Only one Link TLV shall be carried in each LSA, allowing for fine
  722. * granularity changes in topology.
  723. */
  724. build_link_tlv (s, lp);
  725. return;
  726. }
  727. /* Create new opaque-LSA. */
  728. static struct ospf_lsa *
  729. ospf_mpls_te_lsa_new (struct ospf_area *area, struct mpls_te_link *lp)
  730. {
  731. struct stream *s;
  732. struct lsa_header *lsah;
  733. struct ospf_lsa *new = NULL;
  734. u_char options, lsa_type;
  735. struct in_addr lsa_id;
  736. u_int32_t tmp;
  737. u_int16_t length;
  738. /* Create a stream for LSA. */
  739. if ((s = stream_new (OSPF_MAX_LSA_SIZE)) == NULL)
  740. {
  741. zlog_warn ("ospf_mpls_te_lsa_new: stream_new() ?");
  742. goto out;
  743. }
  744. lsah = (struct lsa_header *) STREAM_DATA (s);
  745. options = LSA_OPTIONS_GET (area);
  746. options |= LSA_OPTIONS_NSSA_GET (area);
  747. options |= OSPF_OPTION_O; /* Don't forget this :-) */
  748. lsa_type = OSPF_OPAQUE_AREA_LSA;
  749. tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, lp->instance);
  750. lsa_id.s_addr = htonl (tmp);
  751. if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
  752. zlog_debug ("LSA[Type%d:%s]: Create an Opaque-LSA/MPLS-TE instance", lsa_type, inet_ntoa (lsa_id));
  753. /* Set opaque-LSA header fields. */
  754. lsa_header_set (s, options, lsa_type, lsa_id, area->ospf->router_id);
  755. /* Set opaque-LSA body fields. */
  756. ospf_mpls_te_lsa_body_set (s, lp);
  757. /* Set length. */
  758. length = stream_get_endp (s);
  759. lsah->length = htons (length);
  760. /* Now, create an OSPF LSA instance. */
  761. if ((new = ospf_lsa_new ()) == NULL)
  762. {
  763. zlog_warn ("ospf_mpls_te_lsa_new: ospf_lsa_new() ?");
  764. stream_free (s);
  765. goto out;
  766. }
  767. if ((new->data = ospf_lsa_data_new (length)) == NULL)
  768. {
  769. zlog_warn ("ospf_mpls_te_lsa_new: ospf_lsa_data_new() ?");
  770. ospf_lsa_unlock (&new);
  771. new = NULL;
  772. stream_free (s);
  773. goto out;
  774. }
  775. new->area = area;
  776. SET_FLAG (new->flags, OSPF_LSA_SELF);
  777. memcpy (new->data, lsah, length);
  778. stream_free (s);
  779. out:
  780. return new;
  781. }
  782. static int
  783. ospf_mpls_te_lsa_originate1 (struct ospf_area *area, struct mpls_te_link *lp)
  784. {
  785. struct ospf_lsa *new;
  786. int rc = -1;
  787. /* Create new Opaque-LSA/MPLS-TE instance. */
  788. if ((new = ospf_mpls_te_lsa_new (area, lp)) == NULL)
  789. {
  790. zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_mpls_te_lsa_new() ?");
  791. goto out;
  792. }
  793. /* Install this LSA into LSDB. */
  794. if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL)
  795. {
  796. zlog_warn ("ospf_mpls_te_lsa_originate1: ospf_lsa_install() ?");
  797. ospf_lsa_unlock (&new);
  798. goto out;
  799. }
  800. /* Now this linkparameter entry has associated LSA. */
  801. lp->flags |= LPFLG_LSA_ENGAGED;
  802. /* Update new LSA origination count. */
  803. area->ospf->lsa_originate_count++;
  804. /* Flood new LSA through area. */
  805. ospf_flood_through_area (area, NULL/*nbr*/, new);
  806. if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
  807. {
  808. char area_id[INET_ADDRSTRLEN];
  809. strcpy (area_id, inet_ntoa (area->area_id));
  810. zlog_debug ("LSA[Type%d:%s]: Originate Opaque-LSA/MPLS-TE: Area(%s), Link(%s)", new->data->type, inet_ntoa (new->data->id), area_id, lp->ifp->name);
  811. ospf_lsa_header_dump (new->data);
  812. }
  813. rc = 0;
  814. out:
  815. return rc;
  816. }
  817. static int
  818. ospf_mpls_te_lsa_originate (void *arg)
  819. {
  820. struct ospf_area *area = (struct ospf_area *) arg;
  821. struct listnode *node, *nnode;
  822. struct mpls_te_link *lp;
  823. int rc = -1;
  824. if (OspfMplsTE.status == disabled)
  825. {
  826. zlog_info ("ospf_mpls_te_lsa_originate: MPLS-TE is disabled now.");
  827. rc = 0; /* This is not an error case. */
  828. goto out;
  829. }
  830. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  831. {
  832. if (lp->area == NULL)
  833. continue;
  834. if (! IPV4_ADDR_SAME (&lp->area->area_id, &area->area_id))
  835. continue;
  836. if (lp->flags & LPFLG_LSA_ENGAGED)
  837. {
  838. if (lp->flags & LPFLG_LSA_FORCED_REFRESH)
  839. {
  840. lp->flags &= ~LPFLG_LSA_FORCED_REFRESH;
  841. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  842. }
  843. continue;
  844. }
  845. if (! is_mandated_params_set (lp))
  846. {
  847. zlog_warn ("ospf_mpls_te_lsa_originate: Link(%s) lacks some mandated MPLS-TE parameters.", lp->ifp ? lp->ifp->name : "?");
  848. continue;
  849. }
  850. /* Ok, let's try to originate an LSA for this area and Link. */
  851. if (ospf_mpls_te_lsa_originate1 (area, lp) != 0)
  852. goto out;
  853. }
  854. rc = 0;
  855. out:
  856. return rc;
  857. }
  858. static struct ospf_lsa *
  859. ospf_mpls_te_lsa_refresh (struct ospf_lsa *lsa)
  860. {
  861. struct mpls_te_link *lp;
  862. struct ospf_area *area = lsa->area;
  863. struct ospf_lsa *new = NULL;
  864. if (OspfMplsTE.status == disabled)
  865. {
  866. /*
  867. * This LSA must have flushed before due to MPLS-TE status change.
  868. * It seems a slip among routers in the routing domain.
  869. */
  870. zlog_info ("ospf_mpls_te_lsa_refresh: MPLS-TE is disabled now.");
  871. lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */
  872. }
  873. /* At first, resolve lsa/lp relationship. */
  874. if ((lp = lookup_linkparams_by_instance (lsa)) == NULL)
  875. {
  876. zlog_warn ("ospf_mpls_te_lsa_refresh: Invalid parameter?");
  877. lsa->data->ls_age = htons (OSPF_LSA_MAXAGE); /* Flush it anyway. */
  878. }
  879. /* If the lsa's age reached to MaxAge, start flushing procedure. */
  880. if (IS_LSA_MAXAGE (lsa))
  881. {
  882. if (lp)
  883. lp->flags &= ~LPFLG_LSA_ENGAGED;
  884. ospf_opaque_lsa_flush_schedule (lsa);
  885. goto out;
  886. }
  887. /* Create new Opaque-LSA/MPLS-TE instance. */
  888. if ((new = ospf_mpls_te_lsa_new (area, lp)) == NULL)
  889. {
  890. zlog_warn ("ospf_mpls_te_lsa_refresh: ospf_mpls_te_lsa_new() ?");
  891. goto out;
  892. }
  893. new->data->ls_seqnum = lsa_seqnum_increment (lsa);
  894. /* Install this LSA into LSDB. */
  895. /* Given "lsa" will be freed in the next function. */
  896. if (ospf_lsa_install (area->ospf, NULL/*oi*/, new) == NULL)
  897. {
  898. zlog_warn ("ospf_mpls_te_lsa_refresh: ospf_lsa_install() ?");
  899. ospf_lsa_unlock (&new);
  900. goto out;
  901. }
  902. /* Flood updated LSA through area. */
  903. ospf_flood_through_area (area, NULL/*nbr*/, new);
  904. /* Debug logging. */
  905. if (IS_DEBUG_OSPF (lsa, LSA_GENERATE))
  906. {
  907. zlog_debug ("LSA[Type%d:%s]: Refresh Opaque-LSA/MPLS-TE",
  908. new->data->type, inet_ntoa (new->data->id));
  909. ospf_lsa_header_dump (new->data);
  910. }
  911. out:
  912. return new;
  913. }
  914. static void
  915. ospf_mpls_te_lsa_schedule (struct mpls_te_link *lp,
  916. enum sched_opcode opcode)
  917. {
  918. struct ospf_lsa lsa;
  919. struct lsa_header lsah;
  920. u_int32_t tmp;
  921. memset (&lsa, 0, sizeof (lsa));
  922. memset (&lsah, 0, sizeof (lsah));
  923. lsa.area = lp->area;
  924. lsa.data = &lsah;
  925. lsah.type = OSPF_OPAQUE_AREA_LSA;
  926. tmp = SET_OPAQUE_LSID (OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA, lp->instance);
  927. lsah.id.s_addr = htonl (tmp);
  928. switch (opcode)
  929. {
  930. case REORIGINATE_PER_AREA:
  931. ospf_opaque_lsa_reoriginate_schedule ((void *) lp->area,
  932. OSPF_OPAQUE_AREA_LSA, OPAQUE_TYPE_TRAFFIC_ENGINEERING_LSA);
  933. break;
  934. case REFRESH_THIS_LSA:
  935. ospf_opaque_lsa_refresh_schedule (&lsa);
  936. break;
  937. case FLUSH_THIS_LSA:
  938. lp->flags &= ~LPFLG_LSA_ENGAGED;
  939. ospf_opaque_lsa_flush_schedule (&lsa);
  940. break;
  941. default:
  942. zlog_warn ("ospf_mpls_te_lsa_schedule: Unknown opcode (%u)", opcode);
  943. break;
  944. }
  945. return;
  946. }
  947. /*------------------------------------------------------------------------*
  948. * Followings are vty session control functions.
  949. *------------------------------------------------------------------------*/
  950. static u_int16_t
  951. show_vty_router_addr (struct vty *vty, struct te_tlv_header *tlvh)
  952. {
  953. struct te_tlv_router_addr *top = (struct te_tlv_router_addr *) tlvh;
  954. if (vty != NULL)
  955. vty_out (vty, " Router-Address: %s%s", inet_ntoa (top->value), VTY_NEWLINE);
  956. else
  957. zlog_debug (" Router-Address: %s", inet_ntoa (top->value));
  958. return TLV_SIZE (tlvh);
  959. }
  960. static u_int16_t
  961. show_vty_link_header (struct vty *vty, struct te_tlv_header *tlvh)
  962. {
  963. struct te_tlv_link *top = (struct te_tlv_link *) tlvh;
  964. if (vty != NULL)
  965. vty_out (vty, " Link: %u octets of data%s", ntohs (top->header.length), VTY_NEWLINE);
  966. else
  967. zlog_debug (" Link: %u octets of data", ntohs (top->header.length));
  968. return TLV_HDR_SIZE; /* Here is special, not "TLV_SIZE". */
  969. }
  970. static u_int16_t
  971. show_vty_link_subtlv_link_type (struct vty *vty, struct te_tlv_header *tlvh)
  972. {
  973. struct te_link_subtlv_link_type *top;
  974. const char *cp = "Unknown";
  975. top = (struct te_link_subtlv_link_type *) tlvh;
  976. switch (top->link_type.value)
  977. {
  978. case LINK_TYPE_SUBTLV_VALUE_PTP:
  979. cp = "Point-to-point";
  980. break;
  981. case LINK_TYPE_SUBTLV_VALUE_MA:
  982. cp = "Multiaccess";
  983. break;
  984. default:
  985. break;
  986. }
  987. if (vty != NULL)
  988. vty_out (vty, " Link-Type: %s (%u)%s", cp, top->link_type.value, VTY_NEWLINE);
  989. else
  990. zlog_debug (" Link-Type: %s (%u)", cp, top->link_type.value);
  991. return TLV_SIZE (tlvh);
  992. }
  993. static u_int16_t
  994. show_vty_link_subtlv_link_id (struct vty *vty, struct te_tlv_header *tlvh)
  995. {
  996. struct te_link_subtlv_link_id *top;
  997. top = (struct te_link_subtlv_link_id *) tlvh;
  998. if (vty != NULL)
  999. vty_out (vty, " Link-ID: %s%s", inet_ntoa (top->value), VTY_NEWLINE);
  1000. else
  1001. zlog_debug (" Link-ID: %s", inet_ntoa (top->value));
  1002. return TLV_SIZE (tlvh);
  1003. }
  1004. static u_int16_t
  1005. show_vty_link_subtlv_lclif_ipaddr (struct vty *vty, struct te_tlv_header *tlvh)
  1006. {
  1007. struct te_link_subtlv_lclif_ipaddr *top;
  1008. int i, n;
  1009. top = (struct te_link_subtlv_lclif_ipaddr *) tlvh;
  1010. n = ntohs (tlvh->length) / sizeof (top->value[0]);
  1011. if (vty != NULL)
  1012. vty_out (vty, " Local Interface IP Address(es): %d%s", n, VTY_NEWLINE);
  1013. else
  1014. zlog_debug (" Local Interface IP Address(es): %d", n);
  1015. for (i = 0; i < n; i++)
  1016. {
  1017. if (vty != NULL)
  1018. vty_out (vty, " #%d: %s%s", i, inet_ntoa (top->value[i]), VTY_NEWLINE);
  1019. else
  1020. zlog_debug (" #%d: %s", i, inet_ntoa (top->value[i]));
  1021. }
  1022. return TLV_SIZE (tlvh);
  1023. }
  1024. static u_int16_t
  1025. show_vty_link_subtlv_rmtif_ipaddr (struct vty *vty, struct te_tlv_header *tlvh)
  1026. {
  1027. struct te_link_subtlv_rmtif_ipaddr *top;
  1028. int i, n;
  1029. top = (struct te_link_subtlv_rmtif_ipaddr *) tlvh;
  1030. n = ntohs (tlvh->length) / sizeof (top->value[0]);
  1031. if (vty != NULL)
  1032. vty_out (vty, " Remote Interface IP Address(es): %d%s", n, VTY_NEWLINE);
  1033. else
  1034. zlog_debug (" Remote Interface IP Address(es): %d", n);
  1035. for (i = 0; i < n; i++)
  1036. {
  1037. if (vty != NULL)
  1038. vty_out (vty, " #%d: %s%s", i, inet_ntoa (top->value[i]), VTY_NEWLINE);
  1039. else
  1040. zlog_debug (" #%d: %s", i, inet_ntoa (top->value[i]));
  1041. }
  1042. return TLV_SIZE (tlvh);
  1043. }
  1044. static u_int16_t
  1045. show_vty_link_subtlv_te_metric (struct vty *vty, struct te_tlv_header *tlvh)
  1046. {
  1047. struct te_link_subtlv_te_metric *top;
  1048. top = (struct te_link_subtlv_te_metric *) tlvh;
  1049. if (vty != NULL)
  1050. vty_out (vty, " Traffic Engineering Metric: %u%s", (u_int32_t) ntohl (top->value), VTY_NEWLINE);
  1051. else
  1052. zlog_debug (" Traffic Engineering Metric: %u", (u_int32_t) ntohl (top->value));
  1053. return TLV_SIZE (tlvh);
  1054. }
  1055. static u_int16_t
  1056. show_vty_link_subtlv_max_bw (struct vty *vty, struct te_tlv_header *tlvh)
  1057. {
  1058. struct te_link_subtlv_max_bw *top;
  1059. float fval;
  1060. top = (struct te_link_subtlv_max_bw *) tlvh;
  1061. fval = ntohf (top->value);
  1062. if (vty != NULL)
  1063. vty_out (vty, " Maximum Bandwidth: %g (Bytes/sec)%s", fval, VTY_NEWLINE);
  1064. else
  1065. zlog_debug (" Maximum Bandwidth: %g (Bytes/sec)", fval);
  1066. return TLV_SIZE (tlvh);
  1067. }
  1068. static u_int16_t
  1069. show_vty_link_subtlv_max_rsv_bw (struct vty *vty, struct te_tlv_header *tlvh)
  1070. {
  1071. struct te_link_subtlv_max_rsv_bw *top;
  1072. float fval;
  1073. top = (struct te_link_subtlv_max_rsv_bw *) tlvh;
  1074. fval = ntohf (top->value);
  1075. if (vty != NULL)
  1076. vty_out (vty, " Maximum Reservable Bandwidth: %g (Bytes/sec)%s", fval, VTY_NEWLINE);
  1077. else
  1078. zlog_debug (" Maximum Reservable Bandwidth: %g (Bytes/sec)", fval);
  1079. return TLV_SIZE (tlvh);
  1080. }
  1081. static u_int16_t
  1082. show_vty_link_subtlv_unrsv_bw (struct vty *vty, struct te_tlv_header *tlvh)
  1083. {
  1084. struct te_link_subtlv_unrsv_bw *top;
  1085. float fval;
  1086. int i;
  1087. top = (struct te_link_subtlv_unrsv_bw *) tlvh;
  1088. for (i = 0; i < 8; i++)
  1089. {
  1090. fval = ntohf (top->value[i]);
  1091. if (vty != NULL)
  1092. vty_out (vty, " Unreserved Bandwidth (pri %d): %g (Bytes/sec)%s", i, fval, VTY_NEWLINE);
  1093. else
  1094. zlog_debug (" Unreserved Bandwidth (pri %d): %g (Bytes/sec)", i, fval);
  1095. }
  1096. return TLV_SIZE (tlvh);
  1097. }
  1098. static u_int16_t
  1099. show_vty_link_subtlv_rsc_clsclr (struct vty *vty, struct te_tlv_header *tlvh)
  1100. {
  1101. struct te_link_subtlv_rsc_clsclr *top;
  1102. top = (struct te_link_subtlv_rsc_clsclr *) tlvh;
  1103. if (vty != NULL)
  1104. vty_out (vty, " Resource class/color: 0x%x%s", (u_int32_t) ntohl (top->value), VTY_NEWLINE);
  1105. else
  1106. zlog_debug (" Resource Class/Color: 0x%x", (u_int32_t) ntohl (top->value));
  1107. return TLV_SIZE (tlvh);
  1108. }
  1109. static u_int16_t
  1110. show_vty_unknown_tlv (struct vty *vty, struct te_tlv_header *tlvh)
  1111. {
  1112. if (vty != NULL)
  1113. vty_out (vty, " Unknown TLV: [type(0x%x), length(0x%x)]%s", ntohs (tlvh->type), ntohs (tlvh->length), VTY_NEWLINE);
  1114. else
  1115. zlog_debug (" Unknown TLV: [type(0x%x), length(0x%x)]", ntohs (tlvh->type), ntohs (tlvh->length));
  1116. return TLV_SIZE (tlvh);
  1117. }
  1118. static u_int16_t
  1119. ospf_mpls_te_show_link_subtlv (struct vty *vty, struct te_tlv_header *tlvh0,
  1120. u_int16_t subtotal, u_int16_t total)
  1121. {
  1122. struct te_tlv_header *tlvh, *next;
  1123. u_int16_t sum = subtotal;
  1124. for (tlvh = tlvh0; sum < total; tlvh = (next ? next : TLV_HDR_NEXT (tlvh)))
  1125. {
  1126. next = NULL;
  1127. switch (ntohs (tlvh->type))
  1128. {
  1129. case TE_LINK_SUBTLV_LINK_TYPE:
  1130. sum += show_vty_link_subtlv_link_type (vty, tlvh);
  1131. break;
  1132. case TE_LINK_SUBTLV_LINK_ID:
  1133. sum += show_vty_link_subtlv_link_id (vty, tlvh);
  1134. break;
  1135. case TE_LINK_SUBTLV_LCLIF_IPADDR:
  1136. sum += show_vty_link_subtlv_lclif_ipaddr (vty, tlvh);
  1137. break;
  1138. case TE_LINK_SUBTLV_RMTIF_IPADDR:
  1139. sum += show_vty_link_subtlv_rmtif_ipaddr (vty, tlvh);
  1140. break;
  1141. case TE_LINK_SUBTLV_TE_METRIC:
  1142. sum += show_vty_link_subtlv_te_metric (vty, tlvh);
  1143. break;
  1144. case TE_LINK_SUBTLV_MAX_BW:
  1145. sum += show_vty_link_subtlv_max_bw (vty, tlvh);
  1146. break;
  1147. case TE_LINK_SUBTLV_MAX_RSV_BW:
  1148. sum += show_vty_link_subtlv_max_rsv_bw (vty, tlvh);
  1149. break;
  1150. case TE_LINK_SUBTLV_UNRSV_BW:
  1151. sum += show_vty_link_subtlv_unrsv_bw (vty, tlvh);
  1152. break;
  1153. case TE_LINK_SUBTLV_RSC_CLSCLR:
  1154. sum += show_vty_link_subtlv_rsc_clsclr (vty, tlvh);
  1155. break;
  1156. default:
  1157. sum += show_vty_unknown_tlv (vty, tlvh);
  1158. break;
  1159. }
  1160. }
  1161. return sum;
  1162. }
  1163. static void
  1164. ospf_mpls_te_show_info (struct vty *vty, struct ospf_lsa *lsa)
  1165. {
  1166. struct lsa_header *lsah = (struct lsa_header *) lsa->data;
  1167. struct te_tlv_header *tlvh, *next;
  1168. u_int16_t sum, total;
  1169. u_int16_t (* subfunc)(struct vty *vty, struct te_tlv_header *tlvh,
  1170. u_int16_t subtotal, u_int16_t total) = NULL;
  1171. sum = 0;
  1172. total = ntohs (lsah->length) - OSPF_LSA_HEADER_SIZE;
  1173. for (tlvh = TLV_HDR_TOP (lsah); sum < total;
  1174. tlvh = (next ? next : TLV_HDR_NEXT (tlvh)))
  1175. {
  1176. if (subfunc != NULL)
  1177. {
  1178. sum = (* subfunc)(vty, tlvh, sum, total);
  1179. next = (struct te_tlv_header *)((char *) tlvh + sum);
  1180. subfunc = NULL;
  1181. continue;
  1182. }
  1183. next = NULL;
  1184. switch (ntohs (tlvh->type))
  1185. {
  1186. case TE_TLV_ROUTER_ADDR:
  1187. sum += show_vty_router_addr (vty, tlvh);
  1188. break;
  1189. case TE_TLV_LINK:
  1190. sum += show_vty_link_header (vty, tlvh);
  1191. subfunc = ospf_mpls_te_show_link_subtlv;
  1192. next = tlvh + 1;
  1193. break;
  1194. default:
  1195. sum += show_vty_unknown_tlv (vty, tlvh);
  1196. break;
  1197. }
  1198. }
  1199. return;
  1200. }
  1201. static void
  1202. ospf_mpls_te_config_write_router (struct vty *vty)
  1203. {
  1204. if (OspfMplsTE.status == enabled)
  1205. {
  1206. vty_out (vty, " mpls-te%s", VTY_NEWLINE);
  1207. vty_out (vty, " mpls-te router-address %s%s",
  1208. inet_ntoa (OspfMplsTE.router_addr.value), VTY_NEWLINE);
  1209. }
  1210. return;
  1211. }
  1212. static void
  1213. ospf_mpls_te_config_write_if (struct vty *vty, struct interface *ifp)
  1214. {
  1215. struct mpls_te_link *lp;
  1216. if ((OspfMplsTE.status == enabled)
  1217. && (! if_is_loopback (ifp) && if_is_up (ifp) && ospf_oi_count (ifp) > 0)
  1218. && ((lp = lookup_linkparams_by_ifp (ifp)) != NULL))
  1219. {
  1220. float fval;
  1221. int i;
  1222. vty_out (vty, " mpls-te link metric %u%s",
  1223. (u_int32_t) ntohl (lp->te_metric.value), VTY_NEWLINE);
  1224. fval = ntohf (lp->max_bw.value);
  1225. if (fval >= MPLS_TE_MINIMUM_BANDWIDTH)
  1226. vty_out (vty, " mpls-te link max-bw %g%s", fval, VTY_NEWLINE);
  1227. fval = ntohf (lp->max_rsv_bw.value);
  1228. if (fval >= MPLS_TE_MINIMUM_BANDWIDTH)
  1229. vty_out (vty, " mpls-te link max-rsv-bw %g%s", fval, VTY_NEWLINE);
  1230. for (i = 0; i < 8; i++)
  1231. {
  1232. fval = ntohf (lp->unrsv_bw.value[i]);
  1233. if (fval >= MPLS_TE_MINIMUM_BANDWIDTH)
  1234. vty_out (vty, " mpls-te link unrsv-bw %d %g%s",
  1235. i, fval, VTY_NEWLINE);
  1236. }
  1237. vty_out (vty, " mpls-te link rsc-clsclr 0x%x%s",
  1238. (u_int32_t) ntohl (lp->rsc_clsclr.value), VTY_NEWLINE);
  1239. }
  1240. return;
  1241. }
  1242. /*------------------------------------------------------------------------*
  1243. * Followings are vty command functions.
  1244. *------------------------------------------------------------------------*/
  1245. DEFUN (mpls_te,
  1246. mpls_te_cmd,
  1247. "mpls-te",
  1248. "Configure MPLS-TE parameters\n"
  1249. "Enable the MPLS-TE functionality\n")
  1250. {
  1251. struct listnode *node, *nnode;
  1252. struct mpls_te_link *lp;
  1253. if (OspfMplsTE.status == enabled)
  1254. return CMD_SUCCESS;
  1255. if (IS_DEBUG_OSPF_EVENT)
  1256. zlog_debug ("MPLS-TE: OFF -> ON");
  1257. OspfMplsTE.status = enabled;
  1258. /*
  1259. * Following code is intended to handle two cases;
  1260. *
  1261. * 1) MPLS-TE was disabled at startup time, but now become enabled.
  1262. * 2) MPLS-TE was once enabled then disabled, and now enabled again.
  1263. */
  1264. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  1265. initialize_linkparams (lp);
  1266. ospf_mpls_te_foreach_area (ospf_mpls_te_lsa_schedule, REORIGINATE_PER_AREA);
  1267. return CMD_SUCCESS;
  1268. }
  1269. ALIAS (mpls_te,
  1270. mpls_te_on_cmd,
  1271. "mpls-te on",
  1272. "Configure MPLS-TE parameters\n"
  1273. "Enable the MPLS-TE functionality\n")
  1274. DEFUN (no_mpls_te,
  1275. no_mpls_te_cmd,
  1276. "no mpls-te",
  1277. NO_STR
  1278. "Configure MPLS-TE parameters\n"
  1279. "Disable the MPLS-TE functionality\n")
  1280. {
  1281. struct listnode *node, *nnode;
  1282. struct mpls_te_link *lp;
  1283. if (OspfMplsTE.status == disabled)
  1284. return CMD_SUCCESS;
  1285. if (IS_DEBUG_OSPF_EVENT)
  1286. zlog_debug ("MPLS-TE: ON -> OFF");
  1287. OspfMplsTE.status = disabled;
  1288. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  1289. if (lp->area != NULL)
  1290. if (lp->flags & LPFLG_LSA_ENGAGED)
  1291. ospf_mpls_te_lsa_schedule (lp, FLUSH_THIS_LSA);
  1292. return CMD_SUCCESS;
  1293. }
  1294. DEFUN (mpls_te_router_addr,
  1295. mpls_te_router_addr_cmd,
  1296. "mpls-te router-address A.B.C.D",
  1297. "MPLS-TE specific commands\n"
  1298. "Stable IP address of the advertising router\n"
  1299. "MPLS-TE router address in IPv4 address format\n")
  1300. {
  1301. struct te_tlv_router_addr *ra = &OspfMplsTE.router_addr;
  1302. struct in_addr value;
  1303. if (! inet_aton (argv[0], &value))
  1304. {
  1305. vty_out (vty, "Please specify Router-Addr by A.B.C.D%s", VTY_NEWLINE);
  1306. return CMD_WARNING;
  1307. }
  1308. if (ntohs (ra->header.type) == 0
  1309. || ntohl (ra->value.s_addr) != ntohl (value.s_addr))
  1310. {
  1311. struct listnode *node, *nnode;
  1312. struct mpls_te_link *lp;
  1313. int need_to_reoriginate = 0;
  1314. set_mpls_te_router_addr (value);
  1315. if (OspfMplsTE.status == disabled)
  1316. goto out;
  1317. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  1318. {
  1319. if (lp->area == NULL)
  1320. continue;
  1321. if ((lp->flags & LPFLG_LSA_ENGAGED) == 0)
  1322. {
  1323. need_to_reoriginate = 1;
  1324. break;
  1325. }
  1326. }
  1327. for (ALL_LIST_ELEMENTS (OspfMplsTE.iflist, node, nnode, lp))
  1328. {
  1329. if (lp->area == NULL)
  1330. continue;
  1331. if (need_to_reoriginate)
  1332. lp->flags |= LPFLG_LSA_FORCED_REFRESH;
  1333. else
  1334. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  1335. }
  1336. if (need_to_reoriginate)
  1337. ospf_mpls_te_foreach_area (
  1338. ospf_mpls_te_lsa_schedule, REORIGINATE_PER_AREA);
  1339. }
  1340. out:
  1341. return CMD_SUCCESS;
  1342. }
  1343. DEFUN (mpls_te_link_metric,
  1344. mpls_te_link_metric_cmd,
  1345. "mpls-te link metric <0-4294967295>",
  1346. "MPLS-TE specific commands\n"
  1347. "Configure MPLS-TE link parameters\n"
  1348. "Link metric for MPLS-TE purpose\n"
  1349. "Metric\n")
  1350. {
  1351. struct interface *ifp = (struct interface *) vty->index;
  1352. struct mpls_te_link *lp;
  1353. u_int32_t value;
  1354. if ((lp = lookup_linkparams_by_ifp (ifp)) == NULL)
  1355. {
  1356. vty_out (vty, "mpls_te_link_metric: Something wrong!%s", VTY_NEWLINE);
  1357. return CMD_WARNING;
  1358. }
  1359. value = strtoul (argv[0], NULL, 10);
  1360. if (ntohs (lp->te_metric.header.type) == 0
  1361. || ntohl (lp->te_metric.value) != value)
  1362. {
  1363. set_linkparams_te_metric (lp, value);
  1364. if (OspfMplsTE.status == enabled)
  1365. if (lp->area != NULL)
  1366. {
  1367. if (lp->flags & LPFLG_LSA_ENGAGED)
  1368. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  1369. else
  1370. ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);
  1371. }
  1372. }
  1373. return CMD_SUCCESS;
  1374. }
  1375. DEFUN (mpls_te_link_maxbw,
  1376. mpls_te_link_maxbw_cmd,
  1377. "mpls-te link max-bw BANDWIDTH",
  1378. "MPLS-TE specific commands\n"
  1379. "Configure MPLS-TE link parameters\n"
  1380. "Maximum bandwidth that can be used\n"
  1381. "Bytes/second (IEEE floating point format)\n")
  1382. {
  1383. struct interface *ifp = (struct interface *) vty->index;
  1384. struct mpls_te_link *lp;
  1385. float f1, f2;
  1386. if ((lp = lookup_linkparams_by_ifp (ifp)) == NULL)
  1387. {
  1388. vty_out (vty, "mpls_te_link_maxbw: Something wrong!%s", VTY_NEWLINE);
  1389. return CMD_WARNING;
  1390. }
  1391. f1 = ntohf (lp->max_bw.value);
  1392. if (sscanf (argv[0], "%g", &f2) != 1)
  1393. {
  1394. vty_out (vty, "mpls_te_link_maxbw: fscanf: %s%s", safe_strerror (errno), VTY_NEWLINE);
  1395. return CMD_WARNING;
  1396. }
  1397. if (ntohs (lp->max_bw.header.type) == 0
  1398. || f1 != f2)
  1399. {
  1400. set_linkparams_max_bw (lp, f2);
  1401. if (OspfMplsTE.status == enabled)
  1402. if (lp->area != NULL)
  1403. {
  1404. if (lp->flags & LPFLG_LSA_ENGAGED)
  1405. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  1406. else
  1407. ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);
  1408. }
  1409. }
  1410. return CMD_SUCCESS;
  1411. }
  1412. DEFUN (mpls_te_link_max_rsv_bw,
  1413. mpls_te_link_max_rsv_bw_cmd,
  1414. "mpls-te link max-rsv-bw BANDWIDTH",
  1415. "MPLS-TE specific commands\n"
  1416. "Configure MPLS-TE link parameters\n"
  1417. "Maximum bandwidth that may be reserved\n"
  1418. "Bytes/second (IEEE floating point format)\n")
  1419. {
  1420. struct interface *ifp = (struct interface *) vty->index;
  1421. struct mpls_te_link *lp;
  1422. float f1, f2;
  1423. if ((lp = lookup_linkparams_by_ifp (ifp)) == NULL)
  1424. {
  1425. vty_out (vty, "mpls_te_link_max_rsv_bw: Something wrong!%s", VTY_NEWLINE);
  1426. return CMD_WARNING;
  1427. }
  1428. f1 = ntohf (lp->max_rsv_bw.value);
  1429. if (sscanf (argv[0], "%g", &f2) != 1)
  1430. {
  1431. vty_out (vty, "mpls_te_link_max_rsv_bw: fscanf: %s%s", safe_strerror (errno), VTY_NEWLINE);
  1432. return CMD_WARNING;
  1433. }
  1434. if (ntohs (lp->max_rsv_bw.header.type) == 0
  1435. || f1 != f2)
  1436. {
  1437. set_linkparams_max_rsv_bw (lp, f2);
  1438. if (OspfMplsTE.status == enabled)
  1439. if (lp->area != NULL)
  1440. {
  1441. if (lp->flags & LPFLG_LSA_ENGAGED)
  1442. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  1443. else
  1444. ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);
  1445. }
  1446. }
  1447. return CMD_SUCCESS;
  1448. }
  1449. DEFUN (mpls_te_link_unrsv_bw,
  1450. mpls_te_link_unrsv_bw_cmd,
  1451. "mpls-te link unrsv-bw <0-7> BANDWIDTH",
  1452. "MPLS-TE specific commands\n"
  1453. "Configure MPLS-TE link parameters\n"
  1454. "Unreserved bandwidth at each priority level\n"
  1455. "Priority\n"
  1456. "Bytes/second (IEEE floating point format)\n")
  1457. {
  1458. struct interface *ifp = (struct interface *) vty->index;
  1459. struct mpls_te_link *lp;
  1460. int priority;
  1461. float f1, f2;
  1462. if ((lp = lookup_linkparams_by_ifp (ifp)) == NULL)
  1463. {
  1464. vty_out (vty, "mpls_te_link_unrsv_bw: Something wrong!%s", VTY_NEWLINE);
  1465. return CMD_WARNING;
  1466. }
  1467. /* We don't have to consider about range check here. */
  1468. if (sscanf (argv[0], "%d", &priority) != 1)
  1469. {
  1470. vty_out (vty, "mpls_te_link_unrsv_bw: fscanf: %s%s", safe_strerror (errno), VTY_NEWLINE);
  1471. return CMD_WARNING;
  1472. }
  1473. f1 = ntohf (lp->unrsv_bw.value [priority]);
  1474. if (sscanf (argv[1], "%g", &f2) != 1)
  1475. {
  1476. vty_out (vty, "mpls_te_link_unrsv_bw: fscanf: %s%s", safe_strerror (errno), VTY_NEWLINE);
  1477. return CMD_WARNING;
  1478. }
  1479. if (ntohs (lp->unrsv_bw.header.type) == 0
  1480. || f1 != f2)
  1481. {
  1482. set_linkparams_unrsv_bw (lp, priority, f2);
  1483. if (OspfMplsTE.status == enabled)
  1484. if (lp->area != NULL)
  1485. {
  1486. if (lp->flags & LPFLG_LSA_ENGAGED)
  1487. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  1488. else
  1489. ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);
  1490. }
  1491. }
  1492. return CMD_SUCCESS;
  1493. }
  1494. DEFUN (mpls_te_link_rsc_clsclr,
  1495. mpls_te_link_rsc_clsclr_cmd,
  1496. "mpls-te link rsc-clsclr BITPATTERN",
  1497. "MPLS-TE specific commands\n"
  1498. "Configure MPLS-TE link parameters\n"
  1499. "Administrative group membership\n"
  1500. "32-bit Hexadecimal value (ex. 0xa1)\n")
  1501. {
  1502. struct interface *ifp = (struct interface *) vty->index;
  1503. struct mpls_te_link *lp;
  1504. unsigned long value;
  1505. if ((lp = lookup_linkparams_by_ifp (ifp)) == NULL)
  1506. {
  1507. vty_out (vty, "mpls_te_link_rsc_clsclr: Something wrong!%s", VTY_NEWLINE);
  1508. return CMD_WARNING;
  1509. }
  1510. if (sscanf (argv[0], "0x%lx", &value) != 1)
  1511. {
  1512. vty_out (vty, "mpls_te_link_rsc_clsclr: fscanf: %s%s", safe_strerror (errno), VTY_NEWLINE);
  1513. return CMD_WARNING;
  1514. }
  1515. if (ntohs (lp->rsc_clsclr.header.type) == 0
  1516. || ntohl (lp->rsc_clsclr.value) != value)
  1517. {
  1518. set_linkparams_rsc_clsclr (lp, value);
  1519. if (OspfMplsTE.status == enabled)
  1520. if (lp->area != NULL)
  1521. {
  1522. if (lp->flags & LPFLG_LSA_ENGAGED)
  1523. ospf_mpls_te_lsa_schedule (lp, REFRESH_THIS_LSA);
  1524. else
  1525. ospf_mpls_te_lsa_schedule (lp, REORIGINATE_PER_AREA);
  1526. }
  1527. }
  1528. return CMD_SUCCESS;
  1529. }
  1530. DEFUN (show_mpls_te_router,
  1531. show_mpls_te_router_cmd,
  1532. "show mpls-te router",
  1533. SHOW_STR
  1534. "MPLS-TE information\n"
  1535. "Router information\n")
  1536. {
  1537. if (OspfMplsTE.status == enabled)
  1538. {
  1539. vty_out (vty, "--- MPLS-TE router parameters ---%s",
  1540. VTY_NEWLINE);
  1541. if (ntohs (OspfMplsTE.router_addr.header.type) != 0)
  1542. show_vty_router_addr (vty, &OspfMplsTE.router_addr.header);
  1543. else if (vty != NULL)
  1544. vty_out (vty, " N/A%s", VTY_NEWLINE);
  1545. }
  1546. return CMD_SUCCESS;
  1547. }
  1548. static void
  1549. show_mpls_te_link_sub (struct vty *vty, struct interface *ifp)
  1550. {
  1551. struct mpls_te_link *lp;
  1552. struct te_tlv_header *tlvh;
  1553. if ((OspfMplsTE.status == enabled)
  1554. && (! if_is_loopback (ifp) && if_is_up (ifp) && ospf_oi_count (ifp) > 0)
  1555. && ((lp = lookup_linkparams_by_ifp (ifp)) != NULL))
  1556. {
  1557. vty_out (vty, "-- MPLS-TE link parameters for %s --%s",
  1558. ifp->name, VTY_NEWLINE);
  1559. show_vty_link_subtlv_link_type (vty, &lp->link_type.header);
  1560. show_vty_link_subtlv_link_id (vty, &lp->link_id.header);
  1561. if ((tlvh = (struct te_tlv_header *) lp->lclif_ipaddr) != NULL)
  1562. show_vty_link_subtlv_lclif_ipaddr (vty, tlvh);
  1563. if ((tlvh = (struct te_tlv_header *) lp->rmtif_ipaddr) != NULL)
  1564. show_vty_link_subtlv_rmtif_ipaddr (vty, tlvh);
  1565. show_vty_link_subtlv_te_metric (vty, &lp->te_metric.header);
  1566. show_vty_link_subtlv_max_bw (vty, &lp->max_bw.header);
  1567. show_vty_link_subtlv_max_rsv_bw (vty, &lp->max_rsv_bw.header);
  1568. show_vty_link_subtlv_unrsv_bw (vty, &lp->unrsv_bw.header);
  1569. show_vty_link_subtlv_rsc_clsclr (vty, &lp->rsc_clsclr.header);
  1570. }
  1571. else
  1572. {
  1573. vty_out (vty, " %s: MPLS-TE is disabled on this interface%s",
  1574. ifp->name, VTY_NEWLINE);
  1575. }
  1576. return;
  1577. }
  1578. DEFUN (show_mpls_te_link,
  1579. show_mpls_te_link_cmd,
  1580. "show mpls-te interface [INTERFACE]",
  1581. SHOW_STR
  1582. "MPLS-TE information\n"
  1583. "Interface information\n"
  1584. "Interface name\n")
  1585. {
  1586. struct interface *ifp;
  1587. struct listnode *node, *nnode;
  1588. /* Show All Interfaces. */
  1589. if (argc == 0)
  1590. {
  1591. for (ALL_LIST_ELEMENTS (iflist, node, nnode, ifp))
  1592. show_mpls_te_link_sub (vty, ifp);
  1593. }
  1594. /* Interface name is specified. */
  1595. else
  1596. {
  1597. if ((ifp = if_lookup_by_name (argv[0])) == NULL)
  1598. vty_out (vty, "No such interface name%s", VTY_NEWLINE);
  1599. else
  1600. show_mpls_te_link_sub (vty, ifp);
  1601. }
  1602. return CMD_SUCCESS;
  1603. }
  1604. static void
  1605. ospf_mpls_te_register_vty (void)
  1606. {
  1607. install_element (VIEW_NODE, &show_mpls_te_router_cmd);
  1608. install_element (VIEW_NODE, &show_mpls_te_link_cmd);
  1609. install_element (OSPF_NODE, &mpls_te_cmd);
  1610. install_element (OSPF_NODE, &no_mpls_te_cmd);
  1611. install_element (OSPF_NODE, &mpls_te_on_cmd);
  1612. install_element (OSPF_NODE, &mpls_te_router_addr_cmd);
  1613. install_element (INTERFACE_NODE, &mpls_te_link_metric_cmd);
  1614. install_element (INTERFACE_NODE, &mpls_te_link_maxbw_cmd);
  1615. install_element (INTERFACE_NODE, &mpls_te_link_max_rsv_bw_cmd);
  1616. install_element (INTERFACE_NODE, &mpls_te_link_unrsv_bw_cmd);
  1617. install_element (INTERFACE_NODE, &mpls_te_link_rsc_clsclr_cmd);
  1618. return;
  1619. }