rip_routemap.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113
  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, "%% RIP Can't find rule.%s", VTY_NEWLINE);
  55. return CMD_WARNING;
  56. case RMAP_COMPILE_ERROR:
  57. vty_out (vty, "%% RIP 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, "%% RIP Can't find rule.%s", VTY_NEWLINE);
  76. return CMD_WARNING;
  77. case RMAP_COMPILE_ERROR:
  78. vty_out (vty, "%% RIP 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, "%% RIP 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, "%% RIP 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, "%% RIP Can't find rule.%s", VTY_NEWLINE);
  124. return CMD_WARNING;
  125. case RMAP_COMPILE_ERROR:
  126. vty_out (vty, "%% RIP 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. route_tag_t *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 commands for tag matching. */
  418. static struct route_map_rule_cmd route_match_tag_cmd =
  419. {
  420. "tag",
  421. route_match_tag,
  422. route_map_rule_tag_compile,
  423. route_map_rule_tag_free,
  424. };
  425. /* `set metric METRIC' */
  426. /* Set metric to attribute. */
  427. static route_map_result_t
  428. route_set_metric (void *rule, struct prefix *prefix,
  429. route_map_object_t type, void *object)
  430. {
  431. if (type == RMAP_RIP)
  432. {
  433. struct rip_metric_modifier *mod;
  434. struct rip_info *rinfo;
  435. mod = rule;
  436. rinfo = object;
  437. if (mod->type == metric_increment)
  438. rinfo->metric_out += mod->metric;
  439. else if (mod->type == metric_decrement)
  440. rinfo->metric_out -= mod->metric;
  441. else if (mod->type == metric_absolute)
  442. rinfo->metric_out = mod->metric;
  443. if ((signed int)rinfo->metric_out < 1)
  444. rinfo->metric_out = 1;
  445. if (rinfo->metric_out > RIP_METRIC_INFINITY)
  446. rinfo->metric_out = RIP_METRIC_INFINITY;
  447. rinfo->metric_set = 1;
  448. }
  449. return RMAP_OKAY;
  450. }
  451. /* set metric compilation. */
  452. static void *
  453. route_set_metric_compile (const char *arg)
  454. {
  455. int len;
  456. const char *pnt;
  457. int type;
  458. long metric;
  459. char *endptr = NULL;
  460. struct rip_metric_modifier *mod;
  461. len = strlen (arg);
  462. pnt = arg;
  463. if (len == 0)
  464. return NULL;
  465. /* Examine first character. */
  466. if (arg[0] == '+')
  467. {
  468. type = metric_increment;
  469. pnt++;
  470. }
  471. else if (arg[0] == '-')
  472. {
  473. type = metric_decrement;
  474. pnt++;
  475. }
  476. else
  477. type = metric_absolute;
  478. /* Check beginning with digit string. */
  479. if (*pnt < '0' || *pnt > '9')
  480. return NULL;
  481. /* Convert string to integer. */
  482. metric = strtol (pnt, &endptr, 10);
  483. if (metric == LONG_MAX || *endptr != '\0')
  484. return NULL;
  485. if (metric < 0 || metric > RIP_METRIC_INFINITY)
  486. return NULL;
  487. mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
  488. sizeof (struct rip_metric_modifier));
  489. mod->type = type;
  490. mod->metric = metric;
  491. return mod;
  492. }
  493. /* Free route map's compiled `set metric' value. */
  494. static void
  495. route_set_metric_free (void *rule)
  496. {
  497. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  498. }
  499. /* Set metric rule structure. */
  500. static struct route_map_rule_cmd route_set_metric_cmd =
  501. {
  502. "metric",
  503. route_set_metric,
  504. route_set_metric_compile,
  505. route_set_metric_free,
  506. };
  507. /* `set ip next-hop IP_ADDRESS' */
  508. /* Set nexthop to object. ojbect must be pointer to struct attr. */
  509. static route_map_result_t
  510. route_set_ip_nexthop (void *rule, struct prefix *prefix,
  511. route_map_object_t type, void *object)
  512. {
  513. struct in_addr *address;
  514. struct rip_info *rinfo;
  515. if(type == RMAP_RIP)
  516. {
  517. /* Fetch routemap's rule information. */
  518. address = rule;
  519. rinfo = object;
  520. /* Set next hop value. */
  521. rinfo->nexthop_out = *address;
  522. }
  523. return RMAP_OKAY;
  524. }
  525. /* Route map `ip nexthop' compile function. Given string is converted
  526. to struct in_addr structure. */
  527. static void *
  528. route_set_ip_nexthop_compile (const char *arg)
  529. {
  530. int ret;
  531. struct in_addr *address;
  532. address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
  533. ret = inet_aton (arg, address);
  534. if (ret == 0)
  535. {
  536. XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
  537. return NULL;
  538. }
  539. return address;
  540. }
  541. /* Free route map's compiled `ip nexthop' value. */
  542. static void
  543. route_set_ip_nexthop_free (void *rule)
  544. {
  545. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  546. }
  547. /* Route map commands for ip nexthop set. */
  548. static struct route_map_rule_cmd route_set_ip_nexthop_cmd =
  549. {
  550. "ip next-hop",
  551. route_set_ip_nexthop,
  552. route_set_ip_nexthop_compile,
  553. route_set_ip_nexthop_free
  554. };
  555. /* `set tag TAG' */
  556. /* Set tag to object. ojbect must be pointer to struct attr. */
  557. static route_map_result_t
  558. route_set_tag (void *rule, struct prefix *prefix,
  559. route_map_object_t type, void *object)
  560. {
  561. route_tag_t *tag;
  562. struct rip_info *rinfo;
  563. if(type == RMAP_RIP)
  564. {
  565. /* Fetch routemap's rule information. */
  566. tag = rule;
  567. rinfo = object;
  568. /* Set next hop value. */
  569. rinfo->tag_out = *tag;
  570. }
  571. return RMAP_OKAY;
  572. }
  573. /* Route map commands for tag set. */
  574. static struct route_map_rule_cmd route_set_tag_cmd =
  575. {
  576. "tag",
  577. route_set_tag,
  578. route_map_rule_tag_compile,
  579. route_map_rule_tag_free
  580. };
  581. #define MATCH_STR "Match values from routing table\n"
  582. #define SET_STR "Set values in destination routing protocol\n"
  583. DEFUN (match_metric,
  584. match_metric_cmd,
  585. "match metric <0-4294967295>",
  586. MATCH_STR
  587. "Match metric of route\n"
  588. "Metric value\n")
  589. {
  590. return rip_route_match_add (vty, vty->index, "metric", argv[0]);
  591. }
  592. DEFUN (no_match_metric,
  593. no_match_metric_cmd,
  594. "no match metric",
  595. NO_STR
  596. MATCH_STR
  597. "Match metric of route\n")
  598. {
  599. if (argc == 0)
  600. return rip_route_match_delete (vty, vty->index, "metric", NULL);
  601. return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
  602. }
  603. ALIAS (no_match_metric,
  604. no_match_metric_val_cmd,
  605. "no match metric <0-4294967295>",
  606. NO_STR
  607. MATCH_STR
  608. "Match metric of route\n"
  609. "Metric value\n")
  610. DEFUN (match_interface,
  611. match_interface_cmd,
  612. "match interface WORD",
  613. MATCH_STR
  614. "Match first hop interface of route\n"
  615. "Interface name\n")
  616. {
  617. return rip_route_match_add (vty, vty->index, "interface", argv[0]);
  618. }
  619. DEFUN (no_match_interface,
  620. no_match_interface_cmd,
  621. "no match interface",
  622. NO_STR
  623. MATCH_STR
  624. "Match first hop interface of route\n")
  625. {
  626. if (argc == 0)
  627. return rip_route_match_delete (vty, vty->index, "interface", NULL);
  628. return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
  629. }
  630. ALIAS (no_match_interface,
  631. no_match_interface_val_cmd,
  632. "no match interface WORD",
  633. NO_STR
  634. MATCH_STR
  635. "Match first hop interface of route\n"
  636. "Interface name\n")
  637. DEFUN (match_ip_next_hop,
  638. match_ip_next_hop_cmd,
  639. "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  640. MATCH_STR
  641. IP_STR
  642. "Match next-hop address of route\n"
  643. "IP access-list number\n"
  644. "IP access-list number (expanded range)\n"
  645. "IP Access-list name\n")
  646. {
  647. return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  648. }
  649. DEFUN (no_match_ip_next_hop,
  650. no_match_ip_next_hop_cmd,
  651. "no match ip next-hop",
  652. NO_STR
  653. MATCH_STR
  654. IP_STR
  655. "Match next-hop address of route\n")
  656. {
  657. if (argc == 0)
  658. return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  659. return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  660. }
  661. ALIAS (no_match_ip_next_hop,
  662. no_match_ip_next_hop_val_cmd,
  663. "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  664. NO_STR
  665. MATCH_STR
  666. IP_STR
  667. "Match next-hop address of route\n"
  668. "IP access-list number\n"
  669. "IP access-list number (expanded range)\n"
  670. "IP Access-list name\n")
  671. DEFUN (match_ip_next_hop_prefix_list,
  672. match_ip_next_hop_prefix_list_cmd,
  673. "match ip next-hop prefix-list WORD",
  674. MATCH_STR
  675. IP_STR
  676. "Match next-hop address of route\n"
  677. "Match entries of prefix-lists\n"
  678. "IP prefix-list name\n")
  679. {
  680. return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  681. }
  682. DEFUN (no_match_ip_next_hop_prefix_list,
  683. no_match_ip_next_hop_prefix_list_cmd,
  684. "no match ip next-hop prefix-list",
  685. NO_STR
  686. MATCH_STR
  687. IP_STR
  688. "Match next-hop address of route\n"
  689. "Match entries of prefix-lists\n")
  690. {
  691. if (argc == 0)
  692. return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  693. return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  694. }
  695. ALIAS (no_match_ip_next_hop_prefix_list,
  696. no_match_ip_next_hop_prefix_list_val_cmd,
  697. "no match ip next-hop prefix-list WORD",
  698. NO_STR
  699. MATCH_STR
  700. IP_STR
  701. "Match next-hop address of route\n"
  702. "Match entries of prefix-lists\n"
  703. "IP prefix-list name\n")
  704. DEFUN (match_ip_address,
  705. match_ip_address_cmd,
  706. "match ip address (<1-199>|<1300-2699>|WORD)",
  707. MATCH_STR
  708. IP_STR
  709. "Match address of route\n"
  710. "IP access-list number\n"
  711. "IP access-list number (expanded range)\n"
  712. "IP Access-list name\n")
  713. {
  714. return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
  715. }
  716. DEFUN (no_match_ip_address,
  717. no_match_ip_address_cmd,
  718. "no match ip address",
  719. NO_STR
  720. MATCH_STR
  721. IP_STR
  722. "Match address of route\n")
  723. {
  724. if (argc == 0)
  725. return rip_route_match_delete (vty, vty->index, "ip address", NULL);
  726. return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
  727. }
  728. ALIAS (no_match_ip_address,
  729. no_match_ip_address_val_cmd,
  730. "no match ip address (<1-199>|<1300-2699>|WORD)",
  731. NO_STR
  732. MATCH_STR
  733. IP_STR
  734. "Match address of route\n"
  735. "IP access-list number\n"
  736. "IP access-list number (expanded range)\n"
  737. "IP Access-list name\n")
  738. DEFUN (match_ip_address_prefix_list,
  739. match_ip_address_prefix_list_cmd,
  740. "match ip address prefix-list WORD",
  741. MATCH_STR
  742. IP_STR
  743. "Match address of route\n"
  744. "Match entries of prefix-lists\n"
  745. "IP prefix-list name\n")
  746. {
  747. return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  748. }
  749. DEFUN (no_match_ip_address_prefix_list,
  750. no_match_ip_address_prefix_list_cmd,
  751. "no match ip address prefix-list",
  752. NO_STR
  753. MATCH_STR
  754. IP_STR
  755. "Match address of route\n"
  756. "Match entries of prefix-lists\n")
  757. {
  758. if (argc == 0)
  759. return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  760. return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  761. }
  762. ALIAS (no_match_ip_address_prefix_list,
  763. no_match_ip_address_prefix_list_val_cmd,
  764. "no match ip address prefix-list WORD",
  765. NO_STR
  766. MATCH_STR
  767. IP_STR
  768. "Match address of route\n"
  769. "Match entries of prefix-lists\n"
  770. "IP prefix-list name\n")
  771. DEFUN (match_tag,
  772. match_tag_cmd,
  773. "match tag <1-4294967295>",
  774. MATCH_STR
  775. "Match tag of route\n"
  776. "Metric value\n")
  777. {
  778. return rip_route_match_add (vty, vty->index, "tag", argv[0]);
  779. }
  780. DEFUN (no_match_tag,
  781. no_match_tag_cmd,
  782. "no match tag",
  783. NO_STR
  784. MATCH_STR
  785. "Match tag of route\n")
  786. {
  787. if (argc == 0)
  788. return rip_route_match_delete (vty, vty->index, "tag", NULL);
  789. return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
  790. }
  791. ALIAS (no_match_tag,
  792. no_match_tag_val_cmd,
  793. "no match tag <1-4294967295>",
  794. NO_STR
  795. MATCH_STR
  796. "Match tag of route\n"
  797. "Metric value\n")
  798. /* set functions */
  799. DEFUN (set_metric,
  800. set_metric_cmd,
  801. "set metric <0-4294967295>",
  802. SET_STR
  803. "Metric value for destination routing protocol\n"
  804. "Metric value\n")
  805. {
  806. return rip_route_set_add (vty, vty->index, "metric", argv[0]);
  807. }
  808. ALIAS (set_metric,
  809. set_metric_addsub_cmd,
  810. "set metric <+/-metric>",
  811. SET_STR
  812. "Metric value for destination routing protocol\n"
  813. "Add or subtract metric\n")
  814. DEFUN (no_set_metric,
  815. no_set_metric_cmd,
  816. "no set metric",
  817. NO_STR
  818. SET_STR
  819. "Metric value for destination routing protocol\n")
  820. {
  821. if (argc == 0)
  822. return rip_route_set_delete (vty, vty->index, "metric", NULL);
  823. return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
  824. }
  825. ALIAS (no_set_metric,
  826. no_set_metric_val_cmd,
  827. "no set metric <0-4294967295>",
  828. NO_STR
  829. SET_STR
  830. "Metric value for destination routing protocol\n"
  831. "Metric value\n")
  832. ALIAS (no_set_metric,
  833. no_set_metric_addsub_cmd,
  834. "no set metric <+/-metric>",
  835. NO_STR
  836. SET_STR
  837. "Metric value for destination routing protocol\n"
  838. "Add or subtract metric\n")
  839. DEFUN (set_ip_nexthop,
  840. set_ip_nexthop_cmd,
  841. "set ip next-hop A.B.C.D",
  842. SET_STR
  843. IP_STR
  844. "Next hop address\n"
  845. "IP address of next hop\n")
  846. {
  847. union sockunion su;
  848. int ret;
  849. ret = str2sockunion (argv[0], &su);
  850. if (ret < 0)
  851. {
  852. vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
  853. return CMD_WARNING;
  854. }
  855. return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
  856. }
  857. DEFUN (no_set_ip_nexthop,
  858. no_set_ip_nexthop_cmd,
  859. "no set ip next-hop",
  860. NO_STR
  861. SET_STR
  862. IP_STR
  863. "Next hop address\n")
  864. {
  865. if (argc == 0)
  866. return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
  867. return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
  868. }
  869. ALIAS (no_set_ip_nexthop,
  870. no_set_ip_nexthop_val_cmd,
  871. "no set ip next-hop A.B.C.D",
  872. NO_STR
  873. SET_STR
  874. IP_STR
  875. "Next hop address\n"
  876. "IP address of next hop\n")
  877. DEFUN (set_tag,
  878. set_tag_cmd,
  879. "set tag <1-4294967295>",
  880. SET_STR
  881. "Tag value for routing protocol\n"
  882. "Tag value\n")
  883. {
  884. return rip_route_set_add (vty, vty->index, "tag", argv[0]);
  885. }
  886. DEFUN (no_set_tag,
  887. no_set_tag_cmd,
  888. "no set tag",
  889. NO_STR
  890. SET_STR
  891. "Tag value for routing protocol\n")
  892. {
  893. if (argc == 0)
  894. return rip_route_set_delete (vty, vty->index, "tag", NULL);
  895. return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
  896. }
  897. ALIAS (no_set_tag,
  898. no_set_tag_val_cmd,
  899. "no set tag <1-4294967295>",
  900. NO_STR
  901. SET_STR
  902. "Tag value for routing protocol\n"
  903. "Tag value\n")
  904. void
  905. rip_route_map_reset ()
  906. {
  907. ;
  908. }
  909. /* Route-map init */
  910. void
  911. rip_route_map_init ()
  912. {
  913. route_map_init ();
  914. route_map_init_vty ();
  915. route_map_add_hook (rip_route_map_update);
  916. route_map_delete_hook (rip_route_map_update);
  917. route_map_install_match (&route_match_metric_cmd);
  918. route_map_install_match (&route_match_interface_cmd);
  919. route_map_install_match (&route_match_ip_next_hop_cmd);
  920. route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  921. route_map_install_match (&route_match_ip_address_cmd);
  922. route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  923. route_map_install_match (&route_match_tag_cmd);
  924. route_map_install_set (&route_set_metric_cmd);
  925. route_map_install_set (&route_set_ip_nexthop_cmd);
  926. route_map_install_set (&route_set_tag_cmd);
  927. install_element (RMAP_NODE, &match_metric_cmd);
  928. install_element (RMAP_NODE, &no_match_metric_cmd);
  929. install_element (RMAP_NODE, &no_match_metric_val_cmd);
  930. install_element (RMAP_NODE, &match_interface_cmd);
  931. install_element (RMAP_NODE, &no_match_interface_cmd);
  932. install_element (RMAP_NODE, &no_match_interface_val_cmd);
  933. install_element (RMAP_NODE, &match_ip_next_hop_cmd);
  934. install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
  935. install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
  936. install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  937. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  938. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  939. install_element (RMAP_NODE, &match_ip_address_cmd);
  940. install_element (RMAP_NODE, &no_match_ip_address_cmd);
  941. install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  942. install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  943. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  944. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  945. install_element (RMAP_NODE, &match_tag_cmd);
  946. install_element (RMAP_NODE, &no_match_tag_cmd);
  947. install_element (RMAP_NODE, &no_match_tag_val_cmd);
  948. install_element (RMAP_NODE, &set_metric_cmd);
  949. install_element (RMAP_NODE, &set_metric_addsub_cmd);
  950. install_element (RMAP_NODE, &no_set_metric_cmd);
  951. install_element (RMAP_NODE, &no_set_metric_val_cmd);
  952. install_element (RMAP_NODE, &no_set_metric_addsub_cmd);
  953. install_element (RMAP_NODE, &set_ip_nexthop_cmd);
  954. install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
  955. install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
  956. install_element (RMAP_NODE, &set_tag_cmd);
  957. install_element (RMAP_NODE, &no_set_tag_cmd);
  958. install_element (RMAP_NODE, &no_set_tag_val_cmd);
  959. }