ospf6_asbr.c 35 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282
  1. /*
  2. * Copyright (C) 2003 Yasuhiro Ohara
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the
  18. * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
  19. * Boston, MA 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "log.h"
  23. #include "memory.h"
  24. #include "prefix.h"
  25. #include "command.h"
  26. #include "vty.h"
  27. #include "routemap.h"
  28. #include "table.h"
  29. #include "plist.h"
  30. #include "thread.h"
  31. #include "linklist.h"
  32. #include "ospf6_proto.h"
  33. #include "ospf6_lsa.h"
  34. #include "ospf6_lsdb.h"
  35. #include "ospf6_route.h"
  36. #include "ospf6_zebra.h"
  37. #include "ospf6_message.h"
  38. #include "ospf6_top.h"
  39. #include "ospf6_area.h"
  40. #include "ospf6_interface.h"
  41. #include "ospf6_neighbor.h"
  42. #include "ospf6_asbr.h"
  43. #include "ospf6_intra.h"
  44. #include "ospf6_flood.h"
  45. #include "ospf6d.h"
  46. unsigned char conf_debug_ospf6_asbr = 0;
  47. #define ZROUTE_NAME(x) zebra_route_string(x)
  48. /* AS External LSA origination */
  49. void
  50. ospf6_as_external_lsa_originate (struct ospf6_route *route)
  51. {
  52. char buffer[OSPF6_MAX_LSASIZE];
  53. struct ospf6_lsa_header *lsa_header;
  54. struct ospf6_lsa *old, *lsa;
  55. struct ospf6_as_external_lsa *as_external_lsa;
  56. char buf[64];
  57. caddr_t p;
  58. /* find previous LSA */
  59. old = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
  60. route->path.origin.id, ospf6->router_id,
  61. ospf6->lsdb);
  62. if (IS_OSPF6_DEBUG_ASBR || IS_OSPF6_DEBUG_ORIGINATE (AS_EXTERNAL))
  63. {
  64. prefix2str (&route->prefix, buf, sizeof (buf));
  65. zlog_debug ("Originate AS-External-LSA for %s", buf);
  66. }
  67. /* prepare buffer */
  68. memset (buffer, 0, sizeof (buffer));
  69. lsa_header = (struct ospf6_lsa_header *) buffer;
  70. as_external_lsa = (struct ospf6_as_external_lsa *)
  71. ((caddr_t) lsa_header + sizeof (struct ospf6_lsa_header));
  72. p = (caddr_t)
  73. ((caddr_t) as_external_lsa + sizeof (struct ospf6_as_external_lsa));
  74. /* Fill AS-External-LSA */
  75. /* Metric type */
  76. if (route->path.metric_type == 2)
  77. SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
  78. else
  79. UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_E);
  80. /* forwarding address */
  81. if (! IN6_IS_ADDR_UNSPECIFIED (&route->nexthop[0].address))
  82. SET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
  83. else
  84. UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F);
  85. /* external route tag */
  86. UNSET_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T);
  87. /* Set metric */
  88. OSPF6_ASBR_METRIC_SET (as_external_lsa, route->path.cost);
  89. /* prefixlen */
  90. as_external_lsa->prefix.prefix_length = route->prefix.prefixlen;
  91. /* PrefixOptions */
  92. as_external_lsa->prefix.prefix_options = route->path.prefix_options;
  93. /* don't use refer LS-type */
  94. as_external_lsa->prefix.prefix_refer_lstype = htons (0);
  95. /* set Prefix */
  96. memcpy (p, &route->prefix.u.prefix6,
  97. OSPF6_PREFIX_SPACE (route->prefix.prefixlen));
  98. ospf6_prefix_apply_mask (&as_external_lsa->prefix);
  99. p += OSPF6_PREFIX_SPACE (route->prefix.prefixlen);
  100. /* Forwarding address */
  101. if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_F))
  102. {
  103. memcpy (p, &route->nexthop[0].address, sizeof (struct in6_addr));
  104. p += sizeof (struct in6_addr);
  105. }
  106. /* External Route Tag */
  107. if (CHECK_FLAG (as_external_lsa->bits_metric, OSPF6_ASBR_BIT_T))
  108. {
  109. /* xxx */
  110. }
  111. /* Fill LSA Header */
  112. lsa_header->age = 0;
  113. lsa_header->type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
  114. lsa_header->id = route->path.origin.id;
  115. lsa_header->adv_router = ospf6->router_id;
  116. lsa_header->seqnum =
  117. ospf6_new_ls_seqnum (lsa_header->type, lsa_header->id,
  118. lsa_header->adv_router, ospf6->lsdb);
  119. lsa_header->length = htons ((caddr_t) p - (caddr_t) lsa_header);
  120. /* LSA checksum */
  121. ospf6_lsa_checksum (lsa_header);
  122. /* create LSA */
  123. lsa = ospf6_lsa_create (lsa_header);
  124. /* Originate */
  125. ospf6_lsa_originate_process (lsa, ospf6);
  126. }
  127. void
  128. ospf6_asbr_lsa_add (struct ospf6_lsa *lsa)
  129. {
  130. struct ospf6_as_external_lsa *external;
  131. struct prefix asbr_id;
  132. struct ospf6_route *asbr_entry, *route;
  133. char buf[64];
  134. int i;
  135. external = (struct ospf6_as_external_lsa *)
  136. OSPF6_LSA_HEADER_END (lsa->header);
  137. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  138. zlog_debug ("Calculate AS-External route for %s", lsa->name);
  139. if (lsa->header->adv_router == ospf6->router_id)
  140. {
  141. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  142. zlog_debug ("Ignore self-originated AS-External-LSA");
  143. return;
  144. }
  145. if (OSPF6_ASBR_METRIC (external) == LS_INFINITY)
  146. {
  147. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  148. zlog_debug ("Ignore LSA with LSInfinity Metric");
  149. return;
  150. }
  151. ospf6_linkstate_prefix (lsa->header->adv_router, htonl (0), &asbr_id);
  152. asbr_entry = ospf6_route_lookup (&asbr_id, ospf6->brouter_table);
  153. if (asbr_entry == NULL ||
  154. ! CHECK_FLAG (asbr_entry->path.router_bits, OSPF6_ROUTER_BIT_E))
  155. {
  156. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  157. {
  158. prefix2str (&asbr_id, buf, sizeof (buf));
  159. zlog_debug ("ASBR entry not found: %s", buf);
  160. }
  161. return;
  162. }
  163. route = ospf6_route_create ();
  164. route->type = OSPF6_DEST_TYPE_NETWORK;
  165. route->prefix.family = AF_INET6;
  166. route->prefix.prefixlen = external->prefix.prefix_length;
  167. ospf6_prefix_in6_addr (&route->prefix.u.prefix6, &external->prefix);
  168. route->path.area_id = asbr_entry->path.area_id;
  169. route->path.origin.type = lsa->header->type;
  170. route->path.origin.id = lsa->header->id;
  171. route->path.origin.adv_router = lsa->header->adv_router;
  172. route->path.prefix_options = external->prefix.prefix_options;
  173. if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E))
  174. {
  175. route->path.type = OSPF6_PATH_TYPE_EXTERNAL2;
  176. route->path.metric_type = 2;
  177. route->path.cost = asbr_entry->path.cost;
  178. route->path.cost_e2 = OSPF6_ASBR_METRIC (external);
  179. }
  180. else
  181. {
  182. route->path.type = OSPF6_PATH_TYPE_EXTERNAL1;
  183. route->path.metric_type = 1;
  184. route->path.cost = asbr_entry->path.cost + OSPF6_ASBR_METRIC (external);
  185. route->path.cost_e2 = 0;
  186. }
  187. for (i = 0; i < OSPF6_MULTI_PATH_LIMIT; i++)
  188. ospf6_nexthop_copy (&route->nexthop[i], &asbr_entry->nexthop[i]);
  189. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  190. {
  191. prefix2str (&route->prefix, buf, sizeof (buf));
  192. zlog_debug ("AS-External route add: %s", buf);
  193. }
  194. ospf6_route_add (route, ospf6->route_table);
  195. }
  196. void
  197. ospf6_asbr_lsa_remove (struct ospf6_lsa *lsa)
  198. {
  199. struct ospf6_as_external_lsa *external;
  200. struct prefix prefix;
  201. struct ospf6_route *route;
  202. char buf[64];
  203. external = (struct ospf6_as_external_lsa *)
  204. OSPF6_LSA_HEADER_END (lsa->header);
  205. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  206. zlog_debug ("Withdraw AS-External route for %s", lsa->name);
  207. if (lsa->header->adv_router == ospf6->router_id)
  208. {
  209. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  210. zlog_debug ("Ignore self-originated AS-External-LSA");
  211. return;
  212. }
  213. memset (&prefix, 0, sizeof (struct prefix));
  214. prefix.family = AF_INET6;
  215. prefix.prefixlen = external->prefix.prefix_length;
  216. ospf6_prefix_in6_addr (&prefix.u.prefix6, &external->prefix);
  217. route = ospf6_route_lookup (&prefix, ospf6->route_table);
  218. if (route == NULL)
  219. {
  220. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  221. {
  222. prefix2str (&prefix, buf, sizeof (buf));
  223. zlog_debug ("AS-External route %s not found", buf);
  224. }
  225. return;
  226. }
  227. for (ospf6_route_lock (route);
  228. route && ospf6_route_is_prefix (&prefix, route);
  229. route = ospf6_route_next (route))
  230. {
  231. if (route->type != OSPF6_DEST_TYPE_NETWORK)
  232. continue;
  233. if (route->path.origin.type != lsa->header->type)
  234. continue;
  235. if (route->path.origin.id != lsa->header->id)
  236. continue;
  237. if (route->path.origin.adv_router != lsa->header->adv_router)
  238. continue;
  239. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  240. {
  241. prefix2str (&route->prefix, buf, sizeof (buf));
  242. zlog_debug ("AS-External route remove: %s", buf);
  243. }
  244. ospf6_route_remove (route, ospf6->route_table);
  245. }
  246. }
  247. void
  248. ospf6_asbr_lsentry_add (struct ospf6_route *asbr_entry)
  249. {
  250. char buf[64];
  251. struct ospf6_lsa *lsa;
  252. u_int16_t type;
  253. u_int32_t router;
  254. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  255. {
  256. ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
  257. zlog_debug ("New ASBR %s found", buf);
  258. }
  259. type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
  260. router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
  261. for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
  262. lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
  263. {
  264. if (! OSPF6_LSA_IS_MAXAGE (lsa))
  265. ospf6_asbr_lsa_add (lsa);
  266. }
  267. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  268. {
  269. ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
  270. zlog_debug ("Calculation for new ASBR %s done", buf);
  271. }
  272. }
  273. void
  274. ospf6_asbr_lsentry_remove (struct ospf6_route *asbr_entry)
  275. {
  276. char buf[64];
  277. struct ospf6_lsa *lsa;
  278. u_int16_t type;
  279. u_int32_t router;
  280. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  281. {
  282. ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
  283. zlog_debug ("ASBR %s disappeared", buf);
  284. }
  285. type = htons (OSPF6_LSTYPE_AS_EXTERNAL);
  286. router = ospf6_linkstate_prefix_adv_router (&asbr_entry->prefix);
  287. for (lsa = ospf6_lsdb_type_router_head (type, router, ospf6->lsdb);
  288. lsa; lsa = ospf6_lsdb_type_router_next (type, router, lsa))
  289. ospf6_asbr_lsa_remove (lsa);
  290. if (IS_OSPF6_DEBUG_EXAMIN (AS_EXTERNAL))
  291. {
  292. ospf6_linkstate_prefix2str (&asbr_entry->prefix, buf, sizeof (buf));
  293. zlog_debug ("Calculation for old ASBR %s done", buf);
  294. }
  295. }
  296. /* redistribute function */
  297. void
  298. ospf6_asbr_routemap_set (int type, const char *mapname)
  299. {
  300. if (ospf6->rmap[type].name)
  301. free (ospf6->rmap[type].name);
  302. ospf6->rmap[type].name = strdup (mapname);
  303. ospf6->rmap[type].map = route_map_lookup_by_name (mapname);
  304. }
  305. void
  306. ospf6_asbr_routemap_unset (int type)
  307. {
  308. if (ospf6->rmap[type].name)
  309. free (ospf6->rmap[type].name);
  310. ospf6->rmap[type].name = NULL;
  311. ospf6->rmap[type].map = NULL;
  312. }
  313. void
  314. ospf6_asbr_routemap_update (const char *mapname)
  315. {
  316. int type;
  317. if (ospf6 == NULL)
  318. return;
  319. for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  320. {
  321. if (ospf6->rmap[type].name)
  322. ospf6->rmap[type].map =
  323. route_map_lookup_by_name (ospf6->rmap[type].name);
  324. else
  325. ospf6->rmap[type].map = NULL;
  326. }
  327. }
  328. int
  329. ospf6_asbr_is_asbr (struct ospf6 *o)
  330. {
  331. return o->external_table->count;
  332. }
  333. void
  334. ospf6_asbr_redistribute_set (int type)
  335. {
  336. ospf6_zebra_redistribute (type);
  337. }
  338. void
  339. ospf6_asbr_redistribute_unset (int type)
  340. {
  341. struct ospf6_route *route;
  342. struct ospf6_external_info *info;
  343. ospf6_zebra_no_redistribute (type);
  344. for (route = ospf6_route_head (ospf6->external_table); route;
  345. route = ospf6_route_next (route))
  346. {
  347. info = route->route_option;
  348. if (info->type != type)
  349. continue;
  350. ospf6_asbr_redistribute_remove (info->type, route->nexthop[0].ifindex,
  351. &route->prefix);
  352. }
  353. }
  354. void
  355. ospf6_asbr_redistribute_add (int type, int ifindex, struct prefix *prefix,
  356. u_int nexthop_num, struct in6_addr *nexthop)
  357. {
  358. int ret;
  359. struct ospf6_route troute;
  360. struct ospf6_external_info tinfo;
  361. struct ospf6_route *route, *match;
  362. struct ospf6_external_info *info;
  363. struct prefix prefix_id;
  364. struct route_node *node;
  365. char pbuf[64], ibuf[16];
  366. struct listnode *lnode, *lnnode;
  367. struct ospf6_area *oa;
  368. if (! ospf6_zebra_is_redistribute (type))
  369. return;
  370. if (IS_OSPF6_DEBUG_ASBR)
  371. {
  372. prefix2str (prefix, pbuf, sizeof (pbuf));
  373. zlog_debug ("Redistribute %s (%s)", pbuf, ZROUTE_NAME (type));
  374. }
  375. /* if route-map was specified but not found, do not advertise */
  376. if (ospf6->rmap[type].name)
  377. {
  378. if (ospf6->rmap[type].map == NULL)
  379. ospf6_asbr_routemap_update (NULL);
  380. if (ospf6->rmap[type].map == NULL)
  381. {
  382. zlog_warn ("route-map \"%s\" not found, suppress redistributing",
  383. ospf6->rmap[type].name);
  384. return;
  385. }
  386. }
  387. /* apply route-map */
  388. if (ospf6->rmap[type].map)
  389. {
  390. memset (&troute, 0, sizeof (troute));
  391. memset (&tinfo, 0, sizeof (tinfo));
  392. troute.route_option = &tinfo;
  393. ret = route_map_apply (ospf6->rmap[type].map, prefix,
  394. RMAP_OSPF6, &troute);
  395. if (ret == RMAP_DENYMATCH)
  396. {
  397. if (IS_OSPF6_DEBUG_ASBR)
  398. zlog_debug ("Denied by route-map \"%s\"", ospf6->rmap[type].name);
  399. return;
  400. }
  401. }
  402. match = ospf6_route_lookup (prefix, ospf6->external_table);
  403. if (match)
  404. {
  405. info = match->route_option;
  406. /* copy result of route-map */
  407. if (ospf6->rmap[type].map)
  408. {
  409. if (troute.path.metric_type)
  410. match->path.metric_type = troute.path.metric_type;
  411. if (troute.path.cost)
  412. match->path.cost = troute.path.cost;
  413. if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
  414. memcpy (&info->forwarding, &tinfo.forwarding,
  415. sizeof (struct in6_addr));
  416. }
  417. info->type = type;
  418. match->nexthop[0].ifindex = ifindex;
  419. if (nexthop_num && nexthop)
  420. memcpy (&match->nexthop[0].address, nexthop, sizeof (struct in6_addr));
  421. /* create/update binding in external_id_table */
  422. prefix_id.family = AF_INET;
  423. prefix_id.prefixlen = 32;
  424. prefix_id.u.prefix4.s_addr = htonl (info->id);
  425. node = route_node_get (ospf6->external_id_table, &prefix_id);
  426. node->info = match;
  427. if (IS_OSPF6_DEBUG_ASBR)
  428. {
  429. inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
  430. zlog_debug ("Advertise as AS-External Id:%s", ibuf);
  431. }
  432. match->path.origin.id = htonl (info->id);
  433. ospf6_as_external_lsa_originate (match);
  434. return;
  435. }
  436. /* create new entry */
  437. route = ospf6_route_create ();
  438. route->type = OSPF6_DEST_TYPE_NETWORK;
  439. memcpy (&route->prefix, prefix, sizeof (struct prefix));
  440. info = (struct ospf6_external_info *)
  441. XMALLOC (MTYPE_OSPF6_EXTERNAL_INFO, sizeof (struct ospf6_external_info));
  442. memset (info, 0, sizeof (struct ospf6_external_info));
  443. route->route_option = info;
  444. info->id = ospf6->external_id++;
  445. /* copy result of route-map */
  446. if (ospf6->rmap[type].map)
  447. {
  448. if (troute.path.metric_type)
  449. route->path.metric_type = troute.path.metric_type;
  450. if (troute.path.cost)
  451. route->path.cost = troute.path.cost;
  452. if (! IN6_IS_ADDR_UNSPECIFIED (&tinfo.forwarding))
  453. memcpy (&info->forwarding, &tinfo.forwarding,
  454. sizeof (struct in6_addr));
  455. }
  456. info->type = type;
  457. route->nexthop[0].ifindex = ifindex;
  458. if (nexthop_num && nexthop)
  459. memcpy (&route->nexthop[0].address, nexthop, sizeof (struct in6_addr));
  460. /* create/update binding in external_id_table */
  461. prefix_id.family = AF_INET;
  462. prefix_id.prefixlen = 32;
  463. prefix_id.u.prefix4.s_addr = htonl (info->id);
  464. node = route_node_get (ospf6->external_id_table, &prefix_id);
  465. node->info = route;
  466. route = ospf6_route_add (route, ospf6->external_table);
  467. route->route_option = info;
  468. if (IS_OSPF6_DEBUG_ASBR)
  469. {
  470. inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
  471. zlog_debug ("Advertise as AS-External Id:%s", ibuf);
  472. }
  473. route->path.origin.id = htonl (info->id);
  474. ospf6_as_external_lsa_originate (route);
  475. /* Router-Bit (ASBR Flag) may have to be updated */
  476. for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
  477. OSPF6_ROUTER_LSA_SCHEDULE (oa);
  478. }
  479. void
  480. ospf6_asbr_redistribute_remove (int type, int ifindex, struct prefix *prefix)
  481. {
  482. struct ospf6_route *match;
  483. struct ospf6_external_info *info = NULL;
  484. struct route_node *node;
  485. struct ospf6_lsa *lsa;
  486. struct prefix prefix_id;
  487. char pbuf[64], ibuf[16];
  488. struct listnode *lnode, *lnnode;
  489. struct ospf6_area *oa;
  490. match = ospf6_route_lookup (prefix, ospf6->external_table);
  491. if (match == NULL)
  492. {
  493. if (IS_OSPF6_DEBUG_ASBR)
  494. {
  495. prefix2str (prefix, pbuf, sizeof (pbuf));
  496. zlog_debug ("No such route %s to withdraw", pbuf);
  497. }
  498. return;
  499. }
  500. info = match->route_option;
  501. assert (info);
  502. if (info->type != type)
  503. {
  504. if (IS_OSPF6_DEBUG_ASBR)
  505. {
  506. prefix2str (prefix, pbuf, sizeof (pbuf));
  507. zlog_debug ("Original protocol mismatch: %s", pbuf);
  508. }
  509. return;
  510. }
  511. if (IS_OSPF6_DEBUG_ASBR)
  512. {
  513. prefix2str (prefix, pbuf, sizeof (pbuf));
  514. inet_ntop (AF_INET, &prefix_id.u.prefix4, ibuf, sizeof (ibuf));
  515. zlog_debug ("Withdraw %s (AS-External Id:%s)", pbuf, ibuf);
  516. }
  517. lsa = ospf6_lsdb_lookup (htons (OSPF6_LSTYPE_AS_EXTERNAL),
  518. htonl (info->id), ospf6->router_id, ospf6->lsdb);
  519. if (lsa)
  520. ospf6_lsa_purge (lsa);
  521. /* remove binding in external_id_table */
  522. prefix_id.family = AF_INET;
  523. prefix_id.prefixlen = 32;
  524. prefix_id.u.prefix4.s_addr = htonl (info->id);
  525. node = route_node_lookup (ospf6->external_id_table, &prefix_id);
  526. assert (node);
  527. node->info = NULL;
  528. route_unlock_node (node);
  529. ospf6_route_remove (match, ospf6->external_table);
  530. XFREE (MTYPE_OSPF6_EXTERNAL_INFO, info);
  531. /* Router-Bit (ASBR Flag) may have to be updated */
  532. for (ALL_LIST_ELEMENTS (ospf6->area_list, lnode, lnnode, oa))
  533. OSPF6_ROUTER_LSA_SCHEDULE (oa);
  534. }
  535. DEFUN (ospf6_redistribute,
  536. ospf6_redistribute_cmd,
  537. "redistribute (static|kernel|connected|ripng|bgp)",
  538. "Redistribute\n"
  539. "Static route\n"
  540. "Kernel route\n"
  541. "Connected route\n"
  542. "RIPng route\n"
  543. "BGP route\n"
  544. )
  545. {
  546. int type = 0;
  547. if (strncmp (argv[0], "sta", 3) == 0)
  548. type = ZEBRA_ROUTE_STATIC;
  549. else if (strncmp (argv[0], "ker", 3) == 0)
  550. type = ZEBRA_ROUTE_KERNEL;
  551. else if (strncmp (argv[0], "con", 3) == 0)
  552. type = ZEBRA_ROUTE_CONNECT;
  553. else if (strncmp (argv[0], "rip", 3) == 0)
  554. type = ZEBRA_ROUTE_RIPNG;
  555. else if (strncmp (argv[0], "bgp", 3) == 0)
  556. type = ZEBRA_ROUTE_BGP;
  557. ospf6_asbr_redistribute_unset (type);
  558. ospf6_asbr_routemap_unset (type);
  559. ospf6_asbr_redistribute_set (type);
  560. return CMD_SUCCESS;
  561. }
  562. DEFUN (ospf6_redistribute_routemap,
  563. ospf6_redistribute_routemap_cmd,
  564. "redistribute (static|kernel|connected|ripng|bgp) route-map WORD",
  565. "Redistribute\n"
  566. "Static routes\n"
  567. "Kernel route\n"
  568. "Connected route\n"
  569. "RIPng route\n"
  570. "BGP route\n"
  571. "Route map reference\n"
  572. "Route map name\n"
  573. )
  574. {
  575. int type = 0;
  576. if (strncmp (argv[0], "sta", 3) == 0)
  577. type = ZEBRA_ROUTE_STATIC;
  578. else if (strncmp (argv[0], "ker", 3) == 0)
  579. type = ZEBRA_ROUTE_KERNEL;
  580. else if (strncmp (argv[0], "con", 3) == 0)
  581. type = ZEBRA_ROUTE_CONNECT;
  582. else if (strncmp (argv[0], "rip", 3) == 0)
  583. type = ZEBRA_ROUTE_RIPNG;
  584. else if (strncmp (argv[0], "bgp", 3) == 0)
  585. type = ZEBRA_ROUTE_BGP;
  586. ospf6_asbr_redistribute_unset (type);
  587. ospf6_asbr_routemap_set (type, argv[1]);
  588. ospf6_asbr_redistribute_set (type);
  589. return CMD_SUCCESS;
  590. }
  591. DEFUN (no_ospf6_redistribute,
  592. no_ospf6_redistribute_cmd,
  593. "no redistribute (static|kernel|connected|ripng|bgp)",
  594. NO_STR
  595. "Redistribute\n"
  596. "Static route\n"
  597. "Kernel route\n"
  598. "Connected route\n"
  599. "RIPng route\n"
  600. "BGP route\n"
  601. )
  602. {
  603. int type = 0;
  604. if (strncmp (argv[0], "sta", 3) == 0)
  605. type = ZEBRA_ROUTE_STATIC;
  606. else if (strncmp (argv[0], "ker", 3) == 0)
  607. type = ZEBRA_ROUTE_KERNEL;
  608. else if (strncmp (argv[0], "con", 3) == 0)
  609. type = ZEBRA_ROUTE_CONNECT;
  610. else if (strncmp (argv[0], "rip", 3) == 0)
  611. type = ZEBRA_ROUTE_RIPNG;
  612. else if (strncmp (argv[0], "bgp", 3) == 0)
  613. type = ZEBRA_ROUTE_BGP;
  614. ospf6_asbr_redistribute_unset (type);
  615. ospf6_asbr_routemap_unset (type);
  616. return CMD_SUCCESS;
  617. }
  618. int
  619. ospf6_redistribute_config_write (struct vty *vty)
  620. {
  621. int type;
  622. for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  623. {
  624. if (type == ZEBRA_ROUTE_OSPF6)
  625. continue;
  626. if (! ospf6_zebra_is_redistribute (type))
  627. continue;
  628. if (ospf6->rmap[type].name)
  629. vty_out (vty, " redistribute %s route-map %s%s",
  630. ZROUTE_NAME (type), ospf6->rmap[type].name, VNL);
  631. else
  632. vty_out (vty, " redistribute %s%s",
  633. ZROUTE_NAME (type), VNL);
  634. }
  635. return 0;
  636. }
  637. void
  638. ospf6_redistribute_show_config (struct vty *vty)
  639. {
  640. int type;
  641. int nroute[ZEBRA_ROUTE_MAX];
  642. int total;
  643. struct ospf6_route *route;
  644. struct ospf6_external_info *info;
  645. total = 0;
  646. for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  647. nroute[type] = 0;
  648. for (route = ospf6_route_head (ospf6->external_table); route;
  649. route = ospf6_route_next (route))
  650. {
  651. info = route->route_option;
  652. nroute[info->type]++;
  653. total++;
  654. }
  655. vty_out (vty, "Redistributing External Routes from:%s", VNL);
  656. for (type = 0; type < ZEBRA_ROUTE_MAX; type++)
  657. {
  658. if (type == ZEBRA_ROUTE_OSPF6)
  659. continue;
  660. if (! ospf6_zebra_is_redistribute (type))
  661. continue;
  662. if (ospf6->rmap[type].name)
  663. vty_out (vty, " %d: %s with route-map \"%s\"%s%s", nroute[type],
  664. ZROUTE_NAME (type), ospf6->rmap[type].name,
  665. (ospf6->rmap[type].map ? "" : " (not found !)"),
  666. VNL);
  667. else
  668. vty_out (vty, " %d: %s%s", nroute[type],
  669. ZROUTE_NAME (type), VNL);
  670. }
  671. vty_out (vty, "Total %d routes%s", total, VNL);
  672. }
  673. /* Routemap Functions */
  674. route_map_result_t
  675. ospf6_routemap_rule_match_address_prefixlist (void *rule,
  676. struct prefix *prefix,
  677. route_map_object_t type,
  678. void *object)
  679. {
  680. struct prefix_list *plist;
  681. if (type != RMAP_OSPF6)
  682. return RMAP_NOMATCH;
  683. plist = prefix_list_lookup (AFI_IP6, (char *) rule);
  684. if (plist == NULL)
  685. return RMAP_NOMATCH;
  686. return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  687. RMAP_NOMATCH : RMAP_MATCH);
  688. }
  689. void *
  690. ospf6_routemap_rule_match_address_prefixlist_compile (const char *arg)
  691. {
  692. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  693. }
  694. void
  695. ospf6_routemap_rule_match_address_prefixlist_free (void *rule)
  696. {
  697. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  698. }
  699. struct route_map_rule_cmd
  700. ospf6_routemap_rule_match_address_prefixlist_cmd =
  701. {
  702. "ipv6 address prefix-list",
  703. ospf6_routemap_rule_match_address_prefixlist,
  704. ospf6_routemap_rule_match_address_prefixlist_compile,
  705. ospf6_routemap_rule_match_address_prefixlist_free,
  706. };
  707. route_map_result_t
  708. ospf6_routemap_rule_set_metric_type (void *rule, struct prefix *prefix,
  709. route_map_object_t type, void *object)
  710. {
  711. char *metric_type = rule;
  712. struct ospf6_route *route = object;
  713. if (type != RMAP_OSPF6)
  714. return RMAP_OKAY;
  715. if (strcmp (metric_type, "type-2") == 0)
  716. route->path.metric_type = 2;
  717. else
  718. route->path.metric_type = 1;
  719. return RMAP_OKAY;
  720. }
  721. void *
  722. ospf6_routemap_rule_set_metric_type_compile (const char *arg)
  723. {
  724. if (strcmp (arg, "type-2") && strcmp (arg, "type-1"))
  725. return NULL;
  726. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  727. }
  728. void
  729. ospf6_routemap_rule_set_metric_type_free (void *rule)
  730. {
  731. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  732. }
  733. struct route_map_rule_cmd
  734. ospf6_routemap_rule_set_metric_type_cmd =
  735. {
  736. "metric-type",
  737. ospf6_routemap_rule_set_metric_type,
  738. ospf6_routemap_rule_set_metric_type_compile,
  739. ospf6_routemap_rule_set_metric_type_free,
  740. };
  741. route_map_result_t
  742. ospf6_routemap_rule_set_metric (void *rule, struct prefix *prefix,
  743. route_map_object_t type, void *object)
  744. {
  745. char *metric = rule;
  746. struct ospf6_route *route = object;
  747. if (type != RMAP_OSPF6)
  748. return RMAP_OKAY;
  749. route->path.cost = atoi (metric);
  750. return RMAP_OKAY;
  751. }
  752. void *
  753. ospf6_routemap_rule_set_metric_compile (const char *arg)
  754. {
  755. u_int32_t metric;
  756. char *endp;
  757. metric = strtoul (arg, &endp, 0);
  758. if (metric > LS_INFINITY || *endp != '\0')
  759. return NULL;
  760. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  761. }
  762. void
  763. ospf6_routemap_rule_set_metric_free (void *rule)
  764. {
  765. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  766. }
  767. struct route_map_rule_cmd
  768. ospf6_routemap_rule_set_metric_cmd =
  769. {
  770. "metric",
  771. ospf6_routemap_rule_set_metric,
  772. ospf6_routemap_rule_set_metric_compile,
  773. ospf6_routemap_rule_set_metric_free,
  774. };
  775. route_map_result_t
  776. ospf6_routemap_rule_set_forwarding (void *rule, struct prefix *prefix,
  777. route_map_object_t type, void *object)
  778. {
  779. char *forwarding = rule;
  780. struct ospf6_route *route = object;
  781. struct ospf6_external_info *info = route->route_option;
  782. if (type != RMAP_OSPF6)
  783. return RMAP_OKAY;
  784. if (inet_pton (AF_INET6, forwarding, &info->forwarding) != 1)
  785. {
  786. memset (&info->forwarding, 0, sizeof (struct in6_addr));
  787. return RMAP_ERROR;
  788. }
  789. return RMAP_OKAY;
  790. }
  791. void *
  792. ospf6_routemap_rule_set_forwarding_compile (const char *arg)
  793. {
  794. struct in6_addr a;
  795. if (inet_pton (AF_INET6, arg, &a) != 1)
  796. return NULL;
  797. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  798. }
  799. void
  800. ospf6_routemap_rule_set_forwarding_free (void *rule)
  801. {
  802. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  803. }
  804. struct route_map_rule_cmd
  805. ospf6_routemap_rule_set_forwarding_cmd =
  806. {
  807. "forwarding-address",
  808. ospf6_routemap_rule_set_forwarding,
  809. ospf6_routemap_rule_set_forwarding_compile,
  810. ospf6_routemap_rule_set_forwarding_free,
  811. };
  812. int
  813. route_map_command_status (struct vty *vty, int ret)
  814. {
  815. if (! ret)
  816. return CMD_SUCCESS;
  817. switch (ret)
  818. {
  819. case RMAP_RULE_MISSING:
  820. vty_out (vty, "Can't find rule.%s", VNL);
  821. break;
  822. case RMAP_COMPILE_ERROR:
  823. vty_out (vty, "Argument is malformed.%s", VNL);
  824. break;
  825. default:
  826. vty_out (vty, "route-map add set failed.%s", VNL);
  827. break;
  828. }
  829. return CMD_WARNING;
  830. }
  831. /* add "match address" */
  832. DEFUN (ospf6_routemap_match_address_prefixlist,
  833. ospf6_routemap_match_address_prefixlist_cmd,
  834. "match ipv6 address prefix-list WORD",
  835. "Match values\n"
  836. IPV6_STR
  837. "Match address of route\n"
  838. "Match entries of prefix-lists\n"
  839. "IPv6 prefix-list name\n")
  840. {
  841. int ret = route_map_add_match ((struct route_map_index *) vty->index,
  842. "ipv6 address prefix-list", argv[0]);
  843. return route_map_command_status (vty, ret);
  844. }
  845. /* delete "match address" */
  846. DEFUN (ospf6_routemap_no_match_address_prefixlist,
  847. ospf6_routemap_no_match_address_prefixlist_cmd,
  848. "no match ipv6 address prefix-list WORD",
  849. NO_STR
  850. "Match values\n"
  851. IPV6_STR
  852. "Match address of route\n"
  853. "Match entries of prefix-lists\n"
  854. "IPv6 prefix-list name\n")
  855. {
  856. int ret = route_map_delete_match ((struct route_map_index *) vty->index,
  857. "ipv6 address prefix-list", argv[0]);
  858. return route_map_command_status (vty, ret);
  859. }
  860. /* add "set metric-type" */
  861. DEFUN (ospf6_routemap_set_metric_type,
  862. ospf6_routemap_set_metric_type_cmd,
  863. "set metric-type (type-1|type-2)",
  864. "Set value\n"
  865. "Type of metric\n"
  866. "OSPF6 external type 1 metric\n"
  867. "OSPF6 external type 2 metric\n")
  868. {
  869. int ret = route_map_add_set ((struct route_map_index *) vty->index,
  870. "metric-type", argv[0]);
  871. return route_map_command_status (vty, ret);
  872. }
  873. /* delete "set metric-type" */
  874. DEFUN (ospf6_routemap_no_set_metric_type,
  875. ospf6_routemap_no_set_metric_type_cmd,
  876. "no set metric-type (type-1|type-2)",
  877. NO_STR
  878. "Set value\n"
  879. "Type of metric\n"
  880. "OSPF6 external type 1 metric\n"
  881. "OSPF6 external type 2 metric\n")
  882. {
  883. int ret = route_map_delete_set ((struct route_map_index *) vty->index,
  884. "metric-type", argv[0]);
  885. return route_map_command_status (vty, ret);
  886. }
  887. /* add "set metric" */
  888. DEFUN (set_metric,
  889. set_metric_cmd,
  890. "set metric <0-4294967295>",
  891. "Set value\n"
  892. "Metric value\n"
  893. "Metric value\n")
  894. {
  895. int ret = route_map_add_set ((struct route_map_index *) vty->index,
  896. "metric", argv[0]);
  897. return route_map_command_status (vty, ret);
  898. }
  899. /* delete "set metric" */
  900. DEFUN (no_set_metric,
  901. no_set_metric_cmd,
  902. "no set metric <0-4294967295>",
  903. NO_STR
  904. "Set value\n"
  905. "Metric\n"
  906. "METRIC value\n")
  907. {
  908. int ret = route_map_delete_set ((struct route_map_index *) vty->index,
  909. "metric", argv[0]);
  910. return route_map_command_status (vty, ret);
  911. }
  912. /* add "set forwarding-address" */
  913. DEFUN (ospf6_routemap_set_forwarding,
  914. ospf6_routemap_set_forwarding_cmd,
  915. "set forwarding-address X:X::X:X",
  916. "Set value\n"
  917. "Forwarding Address\n"
  918. "IPv6 Address\n")
  919. {
  920. int ret = route_map_add_set ((struct route_map_index *) vty->index,
  921. "forwarding-address", argv[0]);
  922. return route_map_command_status (vty, ret);
  923. }
  924. /* delete "set forwarding-address" */
  925. DEFUN (ospf6_routemap_no_set_forwarding,
  926. ospf6_routemap_no_set_forwarding_cmd,
  927. "no set forwarding-address X:X::X:X",
  928. NO_STR
  929. "Set value\n"
  930. "Forwarding Address\n"
  931. "IPv6 Address\n")
  932. {
  933. int ret = route_map_delete_set ((struct route_map_index *) vty->index,
  934. "forwarding-address", argv[0]);
  935. return route_map_command_status (vty, ret);
  936. }
  937. void
  938. ospf6_routemap_init ()
  939. {
  940. route_map_init ();
  941. route_map_init_vty ();
  942. route_map_add_hook (ospf6_asbr_routemap_update);
  943. route_map_delete_hook (ospf6_asbr_routemap_update);
  944. route_map_install_match (&ospf6_routemap_rule_match_address_prefixlist_cmd);
  945. route_map_install_set (&ospf6_routemap_rule_set_metric_type_cmd);
  946. route_map_install_set (&ospf6_routemap_rule_set_metric_cmd);
  947. route_map_install_set (&ospf6_routemap_rule_set_forwarding_cmd);
  948. /* Match address prefix-list */
  949. install_element (RMAP_NODE, &ospf6_routemap_match_address_prefixlist_cmd);
  950. install_element (RMAP_NODE, &ospf6_routemap_no_match_address_prefixlist_cmd);
  951. /* ASE Metric Type (e.g. Type-1/Type-2) */
  952. install_element (RMAP_NODE, &ospf6_routemap_set_metric_type_cmd);
  953. install_element (RMAP_NODE, &ospf6_routemap_no_set_metric_type_cmd);
  954. /* ASE Metric */
  955. install_element (RMAP_NODE, &set_metric_cmd);
  956. install_element (RMAP_NODE, &no_set_metric_cmd);
  957. /* ASE Metric */
  958. install_element (RMAP_NODE, &ospf6_routemap_set_forwarding_cmd);
  959. install_element (RMAP_NODE, &ospf6_routemap_no_set_forwarding_cmd);
  960. }
  961. /* Display functions */
  962. int
  963. ospf6_as_external_lsa_show (struct vty *vty, struct ospf6_lsa *lsa)
  964. {
  965. struct ospf6_as_external_lsa *external;
  966. char buf[64];
  967. struct in6_addr in6, *forwarding;
  968. assert (lsa->header);
  969. external = (struct ospf6_as_external_lsa *)
  970. OSPF6_LSA_HEADER_END (lsa->header);
  971. /* bits */
  972. snprintf (buf, sizeof (buf), "%c%c%c",
  973. (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_E) ? 'E' : '-'),
  974. (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F) ? 'F' : '-'),
  975. (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_T) ? 'T' : '-'));
  976. vty_out (vty, " Bits: %s%s", buf, VNL);
  977. vty_out (vty, " Metric: %5lu%s", (u_long) OSPF6_ASBR_METRIC (external),
  978. VNL);
  979. ospf6_prefix_options_printbuf (external->prefix.prefix_options,
  980. buf, sizeof (buf));
  981. vty_out (vty, " Prefix Options: %s%s", buf,
  982. VNL);
  983. vty_out (vty, " Referenced LSType: %d%s",
  984. ntohs (external->prefix.prefix_refer_lstype),
  985. VNL);
  986. ospf6_prefix_in6_addr (&in6, &external->prefix);
  987. inet_ntop (AF_INET6, &in6, buf, sizeof (buf));
  988. vty_out (vty, " Prefix: %s/%d%s", buf,
  989. external->prefix.prefix_length, VNL);
  990. /* Forwarding-Address */
  991. if (CHECK_FLAG (external->bits_metric, OSPF6_ASBR_BIT_F))
  992. {
  993. forwarding = (struct in6_addr *)
  994. ((caddr_t) external + sizeof (struct ospf6_as_external_lsa) +
  995. OSPF6_PREFIX_SPACE (external->prefix.prefix_length));
  996. inet_ntop (AF_INET6, forwarding, buf, sizeof (buf));
  997. vty_out (vty, " Forwarding-Address: %s%s", buf, VNL);
  998. }
  999. return 0;
  1000. }
  1001. void
  1002. ospf6_asbr_external_route_show (struct vty *vty, struct ospf6_route *route)
  1003. {
  1004. struct ospf6_external_info *info = route->route_option;
  1005. char prefix[64], id[16], forwarding[64];
  1006. u_int32_t tmp_id;
  1007. prefix2str (&route->prefix, prefix, sizeof (prefix));
  1008. tmp_id = ntohl (info->id);
  1009. inet_ntop (AF_INET, &tmp_id, id, sizeof (id));
  1010. if (! IN6_IS_ADDR_UNSPECIFIED (&info->forwarding))
  1011. inet_ntop (AF_INET6, &info->forwarding, forwarding, sizeof (forwarding));
  1012. else
  1013. snprintf (forwarding, sizeof (forwarding), ":: (ifindex %d)",
  1014. route->nexthop[0].ifindex);
  1015. vty_out (vty, "%c %-32s %-15s type-%d %5lu %s%s",
  1016. zebra_route_char(info->type),
  1017. prefix, id, route->path.metric_type,
  1018. (u_long) (route->path.metric_type == 2 ?
  1019. route->path.cost_e2 : route->path.cost),
  1020. forwarding, VNL);
  1021. }
  1022. DEFUN (show_ipv6_ospf6_redistribute,
  1023. show_ipv6_ospf6_redistribute_cmd,
  1024. "show ipv6 ospf6 redistribute",
  1025. SHOW_STR
  1026. IP6_STR
  1027. OSPF6_STR
  1028. "redistributing External information\n"
  1029. )
  1030. {
  1031. struct ospf6_route *route;
  1032. ospf6_redistribute_show_config (vty);
  1033. for (route = ospf6_route_head (ospf6->external_table); route;
  1034. route = ospf6_route_next (route))
  1035. ospf6_asbr_external_route_show (vty, route);
  1036. return CMD_SUCCESS;
  1037. }
  1038. struct ospf6_lsa_handler as_external_handler =
  1039. {
  1040. OSPF6_LSTYPE_AS_EXTERNAL,
  1041. "AS-External",
  1042. ospf6_as_external_lsa_show
  1043. };
  1044. void
  1045. ospf6_asbr_init ()
  1046. {
  1047. ospf6_routemap_init ();
  1048. ospf6_install_lsa_handler (&as_external_handler);
  1049. install_element (VIEW_NODE, &show_ipv6_ospf6_redistribute_cmd);
  1050. install_element (ENABLE_NODE, &show_ipv6_ospf6_redistribute_cmd);
  1051. install_element (OSPF6_NODE, &ospf6_redistribute_cmd);
  1052. install_element (OSPF6_NODE, &ospf6_redistribute_routemap_cmd);
  1053. install_element (OSPF6_NODE, &no_ospf6_redistribute_cmd);
  1054. }
  1055. DEFUN (debug_ospf6_asbr,
  1056. debug_ospf6_asbr_cmd,
  1057. "debug ospf6 asbr",
  1058. DEBUG_STR
  1059. OSPF6_STR
  1060. "Debug OSPFv3 ASBR function\n"
  1061. )
  1062. {
  1063. OSPF6_DEBUG_ASBR_ON ();
  1064. return CMD_SUCCESS;
  1065. }
  1066. DEFUN (no_debug_ospf6_asbr,
  1067. no_debug_ospf6_asbr_cmd,
  1068. "no debug ospf6 asbr",
  1069. NO_STR
  1070. DEBUG_STR
  1071. OSPF6_STR
  1072. "Debug OSPFv3 ASBR function\n"
  1073. )
  1074. {
  1075. OSPF6_DEBUG_ASBR_OFF ();
  1076. return CMD_SUCCESS;
  1077. }
  1078. int
  1079. config_write_ospf6_debug_asbr (struct vty *vty)
  1080. {
  1081. if (IS_OSPF6_DEBUG_ASBR)
  1082. vty_out (vty, "debug ospf6 asbr%s", VNL);
  1083. return 0;
  1084. }
  1085. void
  1086. install_element_ospf6_debug_asbr ()
  1087. {
  1088. install_element (ENABLE_NODE, &debug_ospf6_asbr_cmd);
  1089. install_element (ENABLE_NODE, &no_debug_ospf6_asbr_cmd);
  1090. install_element (CONFIG_NODE, &debug_ospf6_asbr_cmd);
  1091. install_element (CONFIG_NODE, &no_debug_ospf6_asbr_cmd);
  1092. }