ospf6_asbr.c 38 KB

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