ospf6_asbr.c 43 KB

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