rip_routemap.c 28 KB

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