rip_routemap.c 28 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152
  1. /* RIPv2 routemap.
  2. * Copyright (C) 2005 6WIND <alain.ritoux@6wind.com>
  3. * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
  4. *
  5. * This file is part of GNU Zebra.
  6. *
  7. * GNU Zebra is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU General Public License as published by the
  9. * Free Software Foundation; either version 2, or (at your option) any
  10. * later version.
  11. *
  12. * GNU Zebra is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU General Public License
  18. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  19. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  20. * 02111-1307, USA.
  21. */
  22. #include <zebra.h>
  23. #include "memory.h"
  24. #include "prefix.h"
  25. #include "routemap.h"
  26. #include "command.h"
  27. #include "filter.h"
  28. #include "log.h"
  29. #include "sockunion.h" /* for inet_aton () */
  30. #include "plist.h"
  31. #include "ripd/ripd.h"
  32. struct rip_metric_modifier
  33. {
  34. enum
  35. {
  36. metric_increment,
  37. metric_decrement,
  38. metric_absolute
  39. } type;
  40. u_char metric;
  41. };
  42. /* Add rip route map rule. */
  43. static int
  44. rip_route_match_add (struct vty *vty, struct route_map_index *index,
  45. const char *command, const char *arg)
  46. {
  47. int ret;
  48. ret = route_map_add_match (index, command, arg);
  49. if (ret)
  50. {
  51. switch (ret)
  52. {
  53. case RMAP_RULE_MISSING:
  54. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  55. return CMD_WARNING;
  56. case RMAP_COMPILE_ERROR:
  57. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  58. return CMD_WARNING;
  59. }
  60. }
  61. return CMD_SUCCESS;
  62. }
  63. /* Delete rip route map rule. */
  64. static int
  65. rip_route_match_delete (struct vty *vty, struct route_map_index *index,
  66. const char *command, const char *arg)
  67. {
  68. int ret;
  69. ret = route_map_delete_match (index, command, arg);
  70. if (ret)
  71. {
  72. switch (ret)
  73. {
  74. case RMAP_RULE_MISSING:
  75. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  76. return CMD_WARNING;
  77. case RMAP_COMPILE_ERROR:
  78. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  79. return CMD_WARNING;
  80. }
  81. }
  82. return CMD_SUCCESS;
  83. }
  84. /* Add rip route map rule. */
  85. static int
  86. rip_route_set_add (struct vty *vty, struct route_map_index *index,
  87. const char *command, const char *arg)
  88. {
  89. int ret;
  90. ret = route_map_add_set (index, command, arg);
  91. if (ret)
  92. {
  93. switch (ret)
  94. {
  95. case RMAP_RULE_MISSING:
  96. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  97. return CMD_WARNING;
  98. case RMAP_COMPILE_ERROR:
  99. /* rip, ripng and other protocols share the set metric command
  100. but only values from 0 to 16 are valid for rip and ripng
  101. if metric is out of range for rip and ripng, it is not for
  102. other protocols. Do not return an error */
  103. if (strcmp(command, "metric")) {
  104. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  105. return CMD_WARNING;
  106. }
  107. }
  108. }
  109. return CMD_SUCCESS;
  110. }
  111. /* Delete rip route map rule. */
  112. static int
  113. rip_route_set_delete (struct vty *vty, struct route_map_index *index,
  114. const char *command, const char *arg)
  115. {
  116. int ret;
  117. ret = route_map_delete_set (index, command, arg);
  118. if (ret)
  119. {
  120. switch (ret)
  121. {
  122. case RMAP_RULE_MISSING:
  123. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  124. return CMD_WARNING;
  125. case RMAP_COMPILE_ERROR:
  126. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  127. return CMD_WARNING;
  128. }
  129. }
  130. return CMD_SUCCESS;
  131. }
  132. /* Hook function for updating route_map assignment. */
  133. /* ARGSUSED */
  134. static void
  135. rip_route_map_update (const char *notused)
  136. {
  137. int i;
  138. if (rip)
  139. {
  140. for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
  141. {
  142. if (rip->route_map[i].name)
  143. rip->route_map[i].map =
  144. route_map_lookup_by_name (rip->route_map[i].name);
  145. }
  146. }
  147. }
  148. /* `match metric METRIC' */
  149. /* Match function return 1 if match is success else return zero. */
  150. static route_map_result_t
  151. route_match_metric (void *rule, struct prefix *prefix,
  152. route_map_object_t type, void *object)
  153. {
  154. u_int32_t *metric;
  155. u_int32_t check;
  156. struct rip_info *rinfo;
  157. if (type == RMAP_RIP)
  158. {
  159. metric = rule;
  160. rinfo = object;
  161. /* If external metric is available, the route-map should
  162. work on this one (for redistribute purpose) */
  163. check = (rinfo->external_metric) ? rinfo->external_metric :
  164. rinfo->metric;
  165. if (check == *metric)
  166. return RMAP_MATCH;
  167. else
  168. return RMAP_NOMATCH;
  169. }
  170. return RMAP_NOMATCH;
  171. }
  172. /* Route map `match metric' match statement. `arg' is METRIC value */
  173. static void *
  174. route_match_metric_compile (const char *arg)
  175. {
  176. u_int32_t *metric;
  177. metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
  178. *metric = atoi (arg);
  179. if(*metric > 0)
  180. return metric;
  181. XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
  182. return NULL;
  183. }
  184. /* Free route map's compiled `match metric' value. */
  185. static void
  186. route_match_metric_free (void *rule)
  187. {
  188. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  189. }
  190. /* Route map commands for metric matching. */
  191. struct route_map_rule_cmd route_match_metric_cmd =
  192. {
  193. "metric",
  194. route_match_metric,
  195. route_match_metric_compile,
  196. route_match_metric_free
  197. };
  198. /* `match interface IFNAME' */
  199. /* Match function return 1 if match is success else return zero. */
  200. static route_map_result_t
  201. route_match_interface (void *rule, struct prefix *prefix,
  202. route_map_object_t type, void *object)
  203. {
  204. struct rip_info *rinfo;
  205. struct interface *ifp;
  206. char *ifname;
  207. if (type == RMAP_RIP)
  208. {
  209. ifname = rule;
  210. ifp = if_lookup_by_name(ifname);
  211. if (!ifp)
  212. return RMAP_NOMATCH;
  213. rinfo = object;
  214. if (rinfo->ifindex_out == ifp->ifindex || rinfo->ifindex == ifp->ifindex)
  215. return RMAP_MATCH;
  216. else
  217. return RMAP_NOMATCH;
  218. }
  219. return RMAP_NOMATCH;
  220. }
  221. /* Route map `match interface' match statement. `arg' is IFNAME value */
  222. /* XXX I don`t know if I need to check does interface exist? */
  223. static void *
  224. route_match_interface_compile (const char *arg)
  225. {
  226. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  227. }
  228. /* Free route map's compiled `match interface' value. */
  229. static void
  230. route_match_interface_free (void *rule)
  231. {
  232. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  233. }
  234. /* Route map commands for interface matching. */
  235. struct route_map_rule_cmd route_match_interface_cmd =
  236. {
  237. "interface",
  238. route_match_interface,
  239. route_match_interface_compile,
  240. route_match_interface_free
  241. };
  242. /* `match ip next-hop IP_ACCESS_LIST' */
  243. /* Match function return 1 if match is success else return zero. */
  244. static route_map_result_t
  245. route_match_ip_next_hop (void *rule, struct prefix *prefix,
  246. route_map_object_t type, void *object)
  247. {
  248. struct access_list *alist;
  249. struct rip_info *rinfo;
  250. struct prefix_ipv4 p;
  251. if (type == RMAP_RIP)
  252. {
  253. rinfo = object;
  254. p.family = AF_INET;
  255. p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
  256. p.prefixlen = IPV4_MAX_BITLEN;
  257. alist = access_list_lookup (AFI_IP, (char *) rule);
  258. if (alist == NULL)
  259. return RMAP_NOMATCH;
  260. return (access_list_apply (alist, &p) == FILTER_DENY ?
  261. RMAP_NOMATCH : RMAP_MATCH);
  262. }
  263. return RMAP_NOMATCH;
  264. }
  265. /* Route map `ip next-hop' match statement. `arg' should be
  266. access-list name. */
  267. static void *
  268. route_match_ip_next_hop_compile (const char *arg)
  269. {
  270. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  271. }
  272. /* Free route map's compiled `. */
  273. static void
  274. route_match_ip_next_hop_free (void *rule)
  275. {
  276. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  277. }
  278. /* Route map commands for ip next-hop matching. */
  279. static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
  280. {
  281. "ip next-hop",
  282. route_match_ip_next_hop,
  283. route_match_ip_next_hop_compile,
  284. route_match_ip_next_hop_free
  285. };
  286. /* `match ip next-hop prefix-list PREFIX_LIST' */
  287. static route_map_result_t
  288. route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
  289. route_map_object_t type, void *object)
  290. {
  291. struct prefix_list *plist;
  292. struct rip_info *rinfo;
  293. struct prefix_ipv4 p;
  294. if (type == RMAP_RIP)
  295. {
  296. rinfo = object;
  297. p.family = AF_INET;
  298. p.prefix = (rinfo->nexthop.s_addr) ? rinfo->nexthop : rinfo->from;
  299. p.prefixlen = IPV4_MAX_BITLEN;
  300. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  301. if (plist == NULL)
  302. return RMAP_NOMATCH;
  303. return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  304. RMAP_NOMATCH : RMAP_MATCH);
  305. }
  306. return RMAP_NOMATCH;
  307. }
  308. static void *
  309. route_match_ip_next_hop_prefix_list_compile (const char *arg)
  310. {
  311. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  312. }
  313. static void
  314. route_match_ip_next_hop_prefix_list_free (void *rule)
  315. {
  316. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  317. }
  318. static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  319. {
  320. "ip next-hop prefix-list",
  321. route_match_ip_next_hop_prefix_list,
  322. route_match_ip_next_hop_prefix_list_compile,
  323. route_match_ip_next_hop_prefix_list_free
  324. };
  325. /* `match ip address IP_ACCESS_LIST' */
  326. /* Match function should return 1 if match is success else return
  327. zero. */
  328. static route_map_result_t
  329. route_match_ip_address (void *rule, struct prefix *prefix,
  330. route_map_object_t type, void *object)
  331. {
  332. struct access_list *alist;
  333. if (type == RMAP_RIP)
  334. {
  335. alist = access_list_lookup (AFI_IP, (char *) rule);
  336. if (alist == NULL)
  337. return RMAP_NOMATCH;
  338. return (access_list_apply (alist, prefix) == FILTER_DENY ?
  339. RMAP_NOMATCH : RMAP_MATCH);
  340. }
  341. return RMAP_NOMATCH;
  342. }
  343. /* Route map `ip address' match statement. `arg' should be
  344. access-list name. */
  345. static void *
  346. route_match_ip_address_compile (const char *arg)
  347. {
  348. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  349. }
  350. /* Free route map's compiled `ip address' value. */
  351. static void
  352. route_match_ip_address_free (void *rule)
  353. {
  354. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  355. }
  356. /* Route map commands for ip address matching. */
  357. static struct route_map_rule_cmd route_match_ip_address_cmd =
  358. {
  359. "ip address",
  360. route_match_ip_address,
  361. route_match_ip_address_compile,
  362. route_match_ip_address_free
  363. };
  364. /* `match ip address prefix-list PREFIX_LIST' */
  365. static route_map_result_t
  366. route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
  367. route_map_object_t type, void *object)
  368. {
  369. struct prefix_list *plist;
  370. if (type == RMAP_RIP)
  371. {
  372. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  373. if (plist == NULL)
  374. return RMAP_NOMATCH;
  375. return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  376. RMAP_NOMATCH : RMAP_MATCH);
  377. }
  378. return RMAP_NOMATCH;
  379. }
  380. static void *
  381. route_match_ip_address_prefix_list_compile (const char *arg)
  382. {
  383. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  384. }
  385. static void
  386. route_match_ip_address_prefix_list_free (void *rule)
  387. {
  388. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  389. }
  390. static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  391. {
  392. "ip address prefix-list",
  393. route_match_ip_address_prefix_list,
  394. route_match_ip_address_prefix_list_compile,
  395. route_match_ip_address_prefix_list_free
  396. };
  397. /* `match tag TAG' */
  398. /* Match function return 1 if match is success else return zero. */
  399. static route_map_result_t
  400. route_match_tag (void *rule, struct prefix *prefix,
  401. route_map_object_t type, void *object)
  402. {
  403. u_short *tag;
  404. struct rip_info *rinfo;
  405. if (type == RMAP_RIP)
  406. {
  407. tag = rule;
  408. rinfo = object;
  409. /* The information stored by rinfo is host ordered. */
  410. if (rinfo->tag == *tag)
  411. return RMAP_MATCH;
  412. else
  413. return RMAP_NOMATCH;
  414. }
  415. return RMAP_NOMATCH;
  416. }
  417. /* Route map `match tag' match statement. `arg' is TAG value */
  418. static void *
  419. route_match_tag_compile (const char *arg)
  420. {
  421. u_short *tag;
  422. tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
  423. *tag = atoi (arg);
  424. return tag;
  425. }
  426. /* Free route map's compiled `match tag' value. */
  427. static void
  428. route_match_tag_free (void *rule)
  429. {
  430. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  431. }
  432. /* Route map commands for tag matching. */
  433. struct route_map_rule_cmd route_match_tag_cmd =
  434. {
  435. "tag",
  436. route_match_tag,
  437. route_match_tag_compile,
  438. route_match_tag_free
  439. };
  440. /* `set metric METRIC' */
  441. /* Set metric to attribute. */
  442. static route_map_result_t
  443. route_set_metric (void *rule, struct prefix *prefix,
  444. route_map_object_t type, void *object)
  445. {
  446. if (type == RMAP_RIP)
  447. {
  448. struct rip_metric_modifier *mod;
  449. struct rip_info *rinfo;
  450. mod = rule;
  451. rinfo = object;
  452. if (mod->type == metric_increment)
  453. rinfo->metric_out += mod->metric;
  454. else if (mod->type == metric_decrement)
  455. rinfo->metric_out -= mod->metric;
  456. else if (mod->type == metric_absolute)
  457. rinfo->metric_out = mod->metric;
  458. if ((signed int)rinfo->metric_out < 1)
  459. rinfo->metric_out = 1;
  460. if (rinfo->metric_out > RIP_METRIC_INFINITY)
  461. rinfo->metric_out = RIP_METRIC_INFINITY;
  462. rinfo->metric_set = 1;
  463. }
  464. return RMAP_OKAY;
  465. }
  466. /* set metric compilation. */
  467. static void *
  468. route_set_metric_compile (const char *arg)
  469. {
  470. int len;
  471. const char *pnt;
  472. int type;
  473. long metric;
  474. char *endptr = NULL;
  475. struct rip_metric_modifier *mod;
  476. len = strlen (arg);
  477. pnt = arg;
  478. if (len == 0)
  479. return NULL;
  480. /* Examine first character. */
  481. if (arg[0] == '+')
  482. {
  483. type = metric_increment;
  484. pnt++;
  485. }
  486. else if (arg[0] == '-')
  487. {
  488. type = metric_decrement;
  489. pnt++;
  490. }
  491. else
  492. type = metric_absolute;
  493. /* Check beginning with digit string. */
  494. if (*pnt < '0' || *pnt > '9')
  495. return NULL;
  496. /* Convert string to integer. */
  497. metric = strtol (pnt, &endptr, 10);
  498. if (metric == LONG_MAX || *endptr != '\0')
  499. return NULL;
  500. if (metric < 0 || metric > RIP_METRIC_INFINITY)
  501. return NULL;
  502. mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  503. sizeof (struct rip_metric_modifier));
  504. mod->type = type;
  505. mod->metric = metric;
  506. return mod;
  507. }
  508. /* Free route map's compiled `set metric' value. */
  509. static void
  510. route_set_metric_free (void *rule)
  511. {
  512. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  513. }
  514. /* Set metric rule structure. */
  515. static struct route_map_rule_cmd route_set_metric_cmd =
  516. {
  517. "metric",
  518. route_set_metric,
  519. route_set_metric_compile,
  520. route_set_metric_free,
  521. };
  522. /* `set ip next-hop IP_ADDRESS' */
  523. /* Set nexthop to object. ojbect must be pointer to struct attr. */
  524. static route_map_result_t
  525. route_set_ip_nexthop (void *rule, struct prefix *prefix,
  526. route_map_object_t type, void *object)
  527. {
  528. struct in_addr *address;
  529. struct rip_info *rinfo;
  530. if(type == RMAP_RIP)
  531. {
  532. /* Fetch routemap's rule information. */
  533. address = rule;
  534. rinfo = object;
  535. /* Set next hop value. */
  536. rinfo->nexthop_out = *address;
  537. }
  538. return RMAP_OKAY;
  539. }
  540. /* Route map `ip nexthop' compile function. Given string is converted
  541. to struct in_addr structure. */
  542. static void *
  543. route_set_ip_nexthop_compile (const char *arg)
  544. {
  545. int ret;
  546. struct in_addr *address;
  547. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  548. ret = inet_aton (arg, address);
  549. if (ret == 0)
  550. {
  551. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  552. return NULL;
  553. }
  554. return address;
  555. }
  556. /* Free route map's compiled `ip nexthop' value. */
  557. static void
  558. route_set_ip_nexthop_free (void *rule)
  559. {
  560. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  561. }
  562. /* Route map commands for ip nexthop set. */
  563. static struct route_map_rule_cmd route_set_ip_nexthop_cmd =
  564. {
  565. "ip next-hop",
  566. route_set_ip_nexthop,
  567. route_set_ip_nexthop_compile,
  568. route_set_ip_nexthop_free
  569. };
  570. /* `set tag TAG' */
  571. /* Set tag to object. ojbect must be pointer to struct attr. */
  572. static route_map_result_t
  573. route_set_tag (void *rule, struct prefix *prefix,
  574. route_map_object_t type, void *object)
  575. {
  576. u_short *tag;
  577. struct rip_info *rinfo;
  578. if(type == RMAP_RIP)
  579. {
  580. /* Fetch routemap's rule information. */
  581. tag = rule;
  582. rinfo = object;
  583. /* Set next hop value. */
  584. rinfo->tag_out = *tag;
  585. }
  586. return RMAP_OKAY;
  587. }
  588. /* Route map `tag' compile function. Given string is converted
  589. to u_short. */
  590. static void *
  591. route_set_tag_compile (const char *arg)
  592. {
  593. u_short *tag;
  594. tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
  595. *tag = atoi (arg);
  596. return tag;
  597. }
  598. /* Free route map's compiled `ip nexthop' value. */
  599. static void
  600. route_set_tag_free (void *rule)
  601. {
  602. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  603. }
  604. /* Route map commands for tag set. */
  605. static struct route_map_rule_cmd route_set_tag_cmd =
  606. {
  607. "tag",
  608. route_set_tag,
  609. route_set_tag_compile,
  610. route_set_tag_free
  611. };
  612. #define MATCH_STR "Match values from routing table\n"
  613. #define SET_STR "Set values in destination routing protocol\n"
  614. DEFUN (match_metric,
  615. match_metric_cmd,
  616. "match metric <0-4294967295>",
  617. MATCH_STR
  618. "Match metric of route\n"
  619. "Metric value\n")
  620. {
  621. return rip_route_match_add (vty, vty->index, "metric", argv[0]);
  622. }
  623. DEFUN (no_match_metric,
  624. no_match_metric_cmd,
  625. "no match metric",
  626. NO_STR
  627. MATCH_STR
  628. "Match metric of route\n")
  629. {
  630. if (argc == 0)
  631. return rip_route_match_delete (vty, vty->index, "metric", NULL);
  632. return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
  633. }
  634. ALIAS (no_match_metric,
  635. no_match_metric_val_cmd,
  636. "no match metric <0-4294967295>",
  637. NO_STR
  638. MATCH_STR
  639. "Match metric of route\n"
  640. "Metric value\n")
  641. DEFUN (match_interface,
  642. match_interface_cmd,
  643. "match interface WORD",
  644. MATCH_STR
  645. "Match first hop interface of route\n"
  646. "Interface name\n")
  647. {
  648. return rip_route_match_add (vty, vty->index, "interface", argv[0]);
  649. }
  650. DEFUN (no_match_interface,
  651. no_match_interface_cmd,
  652. "no match interface",
  653. NO_STR
  654. MATCH_STR
  655. "Match first hop interface of route\n")
  656. {
  657. if (argc == 0)
  658. return rip_route_match_delete (vty, vty->index, "interface", NULL);
  659. return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
  660. }
  661. ALIAS (no_match_interface,
  662. no_match_interface_val_cmd,
  663. "no match interface WORD",
  664. NO_STR
  665. MATCH_STR
  666. "Match first hop interface of route\n"
  667. "Interface name\n")
  668. DEFUN (match_ip_next_hop,
  669. match_ip_next_hop_cmd,
  670. "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  671. MATCH_STR
  672. IP_STR
  673. "Match next-hop address of route\n"
  674. "IP access-list number\n"
  675. "IP access-list number (expanded range)\n"
  676. "IP Access-list name\n")
  677. {
  678. return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  679. }
  680. DEFUN (no_match_ip_next_hop,
  681. no_match_ip_next_hop_cmd,
  682. "no match ip next-hop",
  683. NO_STR
  684. MATCH_STR
  685. IP_STR
  686. "Match next-hop address of route\n")
  687. {
  688. if (argc == 0)
  689. return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  690. return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  691. }
  692. ALIAS (no_match_ip_next_hop,
  693. no_match_ip_next_hop_val_cmd,
  694. "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  695. NO_STR
  696. MATCH_STR
  697. IP_STR
  698. "Match next-hop address of route\n"
  699. "IP access-list number\n"
  700. "IP access-list number (expanded range)\n"
  701. "IP Access-list name\n")
  702. DEFUN (match_ip_next_hop_prefix_list,
  703. match_ip_next_hop_prefix_list_cmd,
  704. "match ip next-hop prefix-list WORD",
  705. MATCH_STR
  706. IP_STR
  707. "Match next-hop address of route\n"
  708. "Match entries of prefix-lists\n"
  709. "IP prefix-list name\n")
  710. {
  711. return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  712. }
  713. DEFUN (no_match_ip_next_hop_prefix_list,
  714. no_match_ip_next_hop_prefix_list_cmd,
  715. "no match ip next-hop prefix-list",
  716. NO_STR
  717. MATCH_STR
  718. IP_STR
  719. "Match next-hop address of route\n"
  720. "Match entries of prefix-lists\n")
  721. {
  722. if (argc == 0)
  723. return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  724. return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  725. }
  726. ALIAS (no_match_ip_next_hop_prefix_list,
  727. no_match_ip_next_hop_prefix_list_val_cmd,
  728. "no match ip next-hop prefix-list WORD",
  729. NO_STR
  730. MATCH_STR
  731. IP_STR
  732. "Match next-hop address of route\n"
  733. "Match entries of prefix-lists\n"
  734. "IP prefix-list name\n")
  735. DEFUN (match_ip_address,
  736. match_ip_address_cmd,
  737. "match ip address (<1-199>|<1300-2699>|WORD)",
  738. MATCH_STR
  739. IP_STR
  740. "Match address of route\n"
  741. "IP access-list number\n"
  742. "IP access-list number (expanded range)\n"
  743. "IP Access-list name\n")
  744. {
  745. return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
  746. }
  747. DEFUN (no_match_ip_address,
  748. no_match_ip_address_cmd,
  749. "no match ip address",
  750. NO_STR
  751. MATCH_STR
  752. IP_STR
  753. "Match address of route\n")
  754. {
  755. if (argc == 0)
  756. return rip_route_match_delete (vty, vty->index, "ip address", NULL);
  757. return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
  758. }
  759. ALIAS (no_match_ip_address,
  760. no_match_ip_address_val_cmd,
  761. "no match ip address (<1-199>|<1300-2699>|WORD)",
  762. NO_STR
  763. MATCH_STR
  764. IP_STR
  765. "Match address of route\n"
  766. "IP access-list number\n"
  767. "IP access-list number (expanded range)\n"
  768. "IP Access-list name\n")
  769. DEFUN (match_ip_address_prefix_list,
  770. match_ip_address_prefix_list_cmd,
  771. "match ip address prefix-list WORD",
  772. MATCH_STR
  773. IP_STR
  774. "Match address of route\n"
  775. "Match entries of prefix-lists\n"
  776. "IP prefix-list name\n")
  777. {
  778. return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  779. }
  780. DEFUN (no_match_ip_address_prefix_list,
  781. no_match_ip_address_prefix_list_cmd,
  782. "no match ip address prefix-list",
  783. NO_STR
  784. MATCH_STR
  785. IP_STR
  786. "Match address of route\n"
  787. "Match entries of prefix-lists\n")
  788. {
  789. if (argc == 0)
  790. return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  791. return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  792. }
  793. ALIAS (no_match_ip_address_prefix_list,
  794. no_match_ip_address_prefix_list_val_cmd,
  795. "no match ip address prefix-list WORD",
  796. NO_STR
  797. MATCH_STR
  798. IP_STR
  799. "Match address of route\n"
  800. "Match entries of prefix-lists\n"
  801. "IP prefix-list name\n")
  802. DEFUN (match_tag,
  803. match_tag_cmd,
  804. "match tag <0-65535>",
  805. MATCH_STR
  806. "Match tag of route\n"
  807. "Metric value\n")
  808. {
  809. return rip_route_match_add (vty, vty->index, "tag", argv[0]);
  810. }
  811. DEFUN (no_match_tag,
  812. no_match_tag_cmd,
  813. "no match tag",
  814. NO_STR
  815. MATCH_STR
  816. "Match tag of route\n")
  817. {
  818. if (argc == 0)
  819. return rip_route_match_delete (vty, vty->index, "tag", NULL);
  820. return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
  821. }
  822. ALIAS (no_match_tag,
  823. no_match_tag_val_cmd,
  824. "no match tag <0-65535>",
  825. NO_STR
  826. MATCH_STR
  827. "Match tag of route\n"
  828. "Metric value\n")
  829. /* set functions */
  830. DEFUN (set_metric,
  831. set_metric_cmd,
  832. "set metric <0-4294967295>",
  833. SET_STR
  834. "Metric value for destination routing protocol\n"
  835. "Metric value\n")
  836. {
  837. return rip_route_set_add (vty, vty->index, "metric", argv[0]);
  838. }
  839. ALIAS (set_metric,
  840. set_metric_addsub_cmd,
  841. "set metric <+/-metric>",
  842. SET_STR
  843. "Metric value for destination routing protocol\n"
  844. "Add or subtract metric\n")
  845. DEFUN (no_set_metric,
  846. no_set_metric_cmd,
  847. "no set metric",
  848. NO_STR
  849. SET_STR
  850. "Metric value for destination routing protocol\n")
  851. {
  852. if (argc == 0)
  853. return rip_route_set_delete (vty, vty->index, "metric", NULL);
  854. return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
  855. }
  856. ALIAS (no_set_metric,
  857. no_set_metric_val_cmd,
  858. "no set metric <0-4294967295>",
  859. NO_STR
  860. SET_STR
  861. "Metric value for destination routing protocol\n"
  862. "Metric value\n")
  863. ALIAS (no_set_metric,
  864. no_set_metric_addsub_cmd,
  865. "no set metric <+/-metric>",
  866. NO_STR
  867. SET_STR
  868. "Metric value for destination routing protocol\n"
  869. "Add or subtract metric\n")
  870. DEFUN (set_ip_nexthop,
  871. set_ip_nexthop_cmd,
  872. "set ip next-hop A.B.C.D",
  873. SET_STR
  874. IP_STR
  875. "Next hop address\n"
  876. "IP address of next hop\n")
  877. {
  878. union sockunion su;
  879. int ret;
  880. ret = str2sockunion (argv[0], &su);
  881. if (ret < 0)
  882. {
  883. vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
  884. return CMD_WARNING;
  885. }
  886. return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
  887. }
  888. DEFUN (no_set_ip_nexthop,
  889. no_set_ip_nexthop_cmd,
  890. "no set ip next-hop",
  891. NO_STR
  892. SET_STR
  893. IP_STR
  894. "Next hop address\n")
  895. {
  896. if (argc == 0)
  897. return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
  898. return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
  899. }
  900. ALIAS (no_set_ip_nexthop,
  901. no_set_ip_nexthop_val_cmd,
  902. "no set ip next-hop A.B.C.D",
  903. NO_STR
  904. SET_STR
  905. IP_STR
  906. "Next hop address\n"
  907. "IP address of next hop\n")
  908. DEFUN (set_tag,
  909. set_tag_cmd,
  910. "set tag <0-65535>",
  911. SET_STR
  912. "Tag value for routing protocol\n"
  913. "Tag value\n")
  914. {
  915. return rip_route_set_add (vty, vty->index, "tag", argv[0]);
  916. }
  917. DEFUN (no_set_tag,
  918. no_set_tag_cmd,
  919. "no set tag",
  920. NO_STR
  921. SET_STR
  922. "Tag value for routing protocol\n")
  923. {
  924. if (argc == 0)
  925. return rip_route_set_delete (vty, vty->index, "tag", NULL);
  926. return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
  927. }
  928. ALIAS (no_set_tag,
  929. no_set_tag_val_cmd,
  930. "no set tag <0-65535>",
  931. NO_STR
  932. SET_STR
  933. "Tag value for routing protocol\n"
  934. "Tag value\n")
  935. void
  936. rip_route_map_reset ()
  937. {
  938. ;
  939. }
  940. /* Route-map init */
  941. void
  942. rip_route_map_init ()
  943. {
  944. route_map_init ();
  945. route_map_init_vty ();
  946. route_map_add_hook (rip_route_map_update);
  947. route_map_delete_hook (rip_route_map_update);
  948. route_map_install_match (&route_match_metric_cmd);
  949. route_map_install_match (&route_match_interface_cmd);
  950. route_map_install_match (&route_match_ip_next_hop_cmd);
  951. route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  952. route_map_install_match (&route_match_ip_address_cmd);
  953. route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  954. route_map_install_match (&route_match_tag_cmd);
  955. route_map_install_set (&route_set_metric_cmd);
  956. route_map_install_set (&route_set_ip_nexthop_cmd);
  957. route_map_install_set (&route_set_tag_cmd);
  958. install_element (RMAP_NODE, &match_metric_cmd);
  959. install_element (RMAP_NODE, &no_match_metric_cmd);
  960. install_element (RMAP_NODE, &no_match_metric_val_cmd);
  961. install_element (RMAP_NODE, &match_interface_cmd);
  962. install_element (RMAP_NODE, &no_match_interface_cmd);
  963. install_element (RMAP_NODE, &no_match_interface_val_cmd);
  964. install_element (RMAP_NODE, &match_ip_next_hop_cmd);
  965. install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
  966. install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
  967. install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  968. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  969. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  970. install_element (RMAP_NODE, &match_ip_address_cmd);
  971. install_element (RMAP_NODE, &no_match_ip_address_cmd);
  972. install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  973. install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  974. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  975. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  976. install_element (RMAP_NODE, &match_tag_cmd);
  977. install_element (RMAP_NODE, &no_match_tag_cmd);
  978. install_element (RMAP_NODE, &no_match_tag_val_cmd);
  979. install_element (RMAP_NODE, &set_metric_cmd);
  980. install_element (RMAP_NODE, &set_metric_addsub_cmd);
  981. install_element (RMAP_NODE, &no_set_metric_cmd);
  982. install_element (RMAP_NODE, &no_set_metric_val_cmd);
  983. install_element (RMAP_NODE, &no_set_metric_addsub_cmd);
  984. install_element (RMAP_NODE, &set_ip_nexthop_cmd);
  985. install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
  986. install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
  987. install_element (RMAP_NODE, &set_tag_cmd);
  988. install_element (RMAP_NODE, &no_set_tag_cmd);
  989. install_element (RMAP_NODE, &no_set_tag_val_cmd);
  990. }