ospf6_asbr.c 36 KB

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