ospf6_asbr.c 38 KB

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