rip_routemap.c 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144
  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 (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>|<+/-metric>)",
  859. NO_STR
  860. SET_STR
  861. "Metric value for destination routing protocol\n"
  862. "Metric value\n"
  863. "Add or subtract metric\n")
  864. DEFUN (set_ip_nexthop,
  865. set_ip_nexthop_cmd,
  866. "set ip next-hop A.B.C.D",
  867. SET_STR
  868. IP_STR
  869. "Next hop address\n"
  870. "IP address of next hop\n")
  871. {
  872. union sockunion su;
  873. int ret;
  874. ret = str2sockunion (argv[0], &su);
  875. if (ret < 0)
  876. {
  877. vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
  878. return CMD_WARNING;
  879. }
  880. return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
  881. }
  882. DEFUN (no_set_ip_nexthop,
  883. no_set_ip_nexthop_cmd,
  884. "no set ip next-hop",
  885. NO_STR
  886. SET_STR
  887. IP_STR
  888. "Next hop address\n")
  889. {
  890. if (argc == 0)
  891. return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
  892. return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
  893. }
  894. ALIAS (no_set_ip_nexthop,
  895. no_set_ip_nexthop_val_cmd,
  896. "no set ip next-hop A.B.C.D",
  897. NO_STR
  898. SET_STR
  899. IP_STR
  900. "Next hop address\n"
  901. "IP address of next hop\n")
  902. DEFUN (set_tag,
  903. set_tag_cmd,
  904. "set tag <0-65535>",
  905. SET_STR
  906. "Tag value for routing protocol\n"
  907. "Tag value\n")
  908. {
  909. return rip_route_set_add (vty, vty->index, "tag", argv[0]);
  910. }
  911. DEFUN (no_set_tag,
  912. no_set_tag_cmd,
  913. "no set tag",
  914. NO_STR
  915. SET_STR
  916. "Tag value for routing protocol\n")
  917. {
  918. if (argc == 0)
  919. return rip_route_set_delete (vty, vty->index, "tag", NULL);
  920. return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
  921. }
  922. ALIAS (no_set_tag,
  923. no_set_tag_val_cmd,
  924. "no set tag <0-65535>",
  925. NO_STR
  926. SET_STR
  927. "Tag value for routing protocol\n"
  928. "Tag value\n")
  929. void
  930. rip_route_map_reset ()
  931. {
  932. ;
  933. }
  934. /* Route-map init */
  935. void
  936. rip_route_map_init ()
  937. {
  938. route_map_init ();
  939. route_map_init_vty ();
  940. route_map_add_hook (rip_route_map_update);
  941. route_map_delete_hook (rip_route_map_update);
  942. route_map_install_match (&route_match_metric_cmd);
  943. route_map_install_match (&route_match_interface_cmd);
  944. route_map_install_match (&route_match_ip_next_hop_cmd);
  945. route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  946. route_map_install_match (&route_match_ip_address_cmd);
  947. route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  948. route_map_install_match (&route_match_tag_cmd);
  949. route_map_install_set (&route_set_metric_cmd);
  950. route_map_install_set (&route_set_ip_nexthop_cmd);
  951. route_map_install_set (&route_set_tag_cmd);
  952. install_element (RMAP_NODE, &match_metric_cmd);
  953. install_element (RMAP_NODE, &no_match_metric_cmd);
  954. install_element (RMAP_NODE, &no_match_metric_val_cmd);
  955. install_element (RMAP_NODE, &match_interface_cmd);
  956. install_element (RMAP_NODE, &no_match_interface_cmd);
  957. install_element (RMAP_NODE, &no_match_interface_val_cmd);
  958. install_element (RMAP_NODE, &match_ip_next_hop_cmd);
  959. install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
  960. install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
  961. install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  962. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  963. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  964. install_element (RMAP_NODE, &match_ip_address_cmd);
  965. install_element (RMAP_NODE, &no_match_ip_address_cmd);
  966. install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  967. install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  968. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  969. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  970. install_element (RMAP_NODE, &match_tag_cmd);
  971. install_element (RMAP_NODE, &no_match_tag_cmd);
  972. install_element (RMAP_NODE, &no_match_tag_val_cmd);
  973. install_element (RMAP_NODE, &set_metric_cmd);
  974. install_element (RMAP_NODE, &set_metric_addsub_cmd);
  975. install_element (RMAP_NODE, &no_set_metric_cmd);
  976. install_element (RMAP_NODE, &no_set_metric_val_cmd);
  977. install_element (RMAP_NODE, &set_ip_nexthop_cmd);
  978. install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
  979. install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
  980. install_element (RMAP_NODE, &set_tag_cmd);
  981. install_element (RMAP_NODE, &no_set_tag_cmd);
  982. install_element (RMAP_NODE, &no_set_tag_val_cmd);
  983. }