zebra_routemap.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
  1. /* zebra routemap.
  2. * Copyright (C) 2006 IBM Corporation
  3. *
  4. * This file is part of GNU Zebra.
  5. *
  6. * GNU Zebra is free software; you can redistribute it and/or modify it
  7. * under the terms of the GNU General Public License as published by the
  8. * Free Software Foundation; either version 2, or (at your option) any
  9. * later version.
  10. *
  11. * GNU Zebra is distributed in the hope that it will be useful, but
  12. * WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  14. * General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with GNU Zebra; see the file COPYING. If not, write to the Free
  18. * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
  19. * 02111-1307, USA.
  20. */
  21. #include <zebra.h>
  22. #include "memory.h"
  23. #include "prefix.h"
  24. #include "rib.h"
  25. #include "routemap.h"
  26. #include "command.h"
  27. #include "filter.h"
  28. #include "plist.h"
  29. #include "zebra/zserv.h"
  30. /* Add zebra route map rule */
  31. static int
  32. zebra_route_match_add(struct vty *vty, struct route_map_index *index,
  33. const char *command, const char *arg)
  34. {
  35. int ret;
  36. ret = route_map_add_match (index, command, arg);
  37. if (ret)
  38. {
  39. switch (ret)
  40. {
  41. case RMAP_RULE_MISSING:
  42. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  43. return CMD_WARNING;
  44. case RMAP_COMPILE_ERROR:
  45. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  46. return CMD_WARNING;
  47. }
  48. }
  49. return CMD_SUCCESS;
  50. }
  51. /* Delete zebra route map rule. */
  52. static int
  53. zebra_route_match_delete (struct vty *vty, struct route_map_index *index,
  54. const char *command, const char *arg)
  55. {
  56. int ret;
  57. ret = route_map_delete_match (index, command, arg);
  58. if (ret)
  59. {
  60. switch (ret)
  61. {
  62. case RMAP_RULE_MISSING:
  63. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  64. return CMD_WARNING;
  65. case RMAP_COMPILE_ERROR:
  66. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  67. return CMD_WARNING;
  68. }
  69. }
  70. return CMD_SUCCESS;
  71. }
  72. /* Add zebra route map rule. */
  73. static int
  74. zebra_route_set_add (struct vty *vty, struct route_map_index *index,
  75. const char *command, const char *arg)
  76. {
  77. int ret;
  78. ret = route_map_add_set (index, command, arg);
  79. if (ret)
  80. {
  81. switch (ret)
  82. {
  83. case RMAP_RULE_MISSING:
  84. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  85. return CMD_WARNING;
  86. case RMAP_COMPILE_ERROR:
  87. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  88. return CMD_WARNING;
  89. }
  90. }
  91. return CMD_SUCCESS;
  92. }
  93. /* Delete zebra route map rule. */
  94. static int
  95. zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
  96. const char *command, const char *arg)
  97. {
  98. int ret;
  99. ret = route_map_delete_set (index, command, arg);
  100. if (ret)
  101. {
  102. switch (ret)
  103. {
  104. case RMAP_RULE_MISSING:
  105. vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
  106. return CMD_WARNING;
  107. case RMAP_COMPILE_ERROR:
  108. vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
  109. return CMD_WARNING;
  110. }
  111. }
  112. return CMD_SUCCESS;
  113. }
  114. /* `match interface IFNAME' */
  115. /* Match function return 1 if match is success else return zero. */
  116. static route_map_result_t
  117. route_match_interface (void *rule, struct prefix *prefix,
  118. route_map_object_t type, void *object)
  119. {
  120. struct nexthop *nexthop;
  121. char *ifname = rule;
  122. unsigned int ifindex;
  123. if (type == RMAP_ZEBRA)
  124. {
  125. if (strcasecmp(ifname, "any") == 0)
  126. return RMAP_MATCH;
  127. ifindex = ifname2ifindex(ifname);
  128. if (ifindex == 0)
  129. return RMAP_NOMATCH;
  130. nexthop = object;
  131. if (!nexthop)
  132. return RMAP_NOMATCH;
  133. if (nexthop->ifindex == ifindex)
  134. return RMAP_MATCH;
  135. }
  136. return RMAP_NOMATCH;
  137. }
  138. /* Route map `match interface' match statement. `arg' is IFNAME value */
  139. static void *
  140. route_match_interface_compile (const char *arg)
  141. {
  142. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  143. }
  144. /* Free route map's compiled `match interface' value. */
  145. static void
  146. route_match_interface_free (void *rule)
  147. {
  148. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  149. }
  150. /* Route map commands for interface matching */
  151. struct route_map_rule_cmd route_match_interface_cmd =
  152. {
  153. "interface",
  154. route_match_interface,
  155. route_match_interface_compile,
  156. route_match_interface_free
  157. };
  158. DEFUN (match_interface,
  159. match_interface_cmd,
  160. "match interface WORD",
  161. MATCH_STR
  162. "match first hop interface of route\n"
  163. "Interface name\n")
  164. {
  165. return zebra_route_match_add (vty, vty->index, "interface", argv[0]);
  166. }
  167. DEFUN (no_match_interface,
  168. no_match_interface_cmd,
  169. "no match interface",
  170. NO_STR
  171. MATCH_STR
  172. "Match first hop interface of route\n")
  173. {
  174. if (argc == 0)
  175. return zebra_route_match_delete (vty, vty->index, "interface", NULL);
  176. return zebra_route_match_delete (vty, vty->index, "interface", argv[0]);
  177. }
  178. ALIAS (no_match_interface,
  179. no_match_interface_val_cmd,
  180. "no match interface WORD",
  181. NO_STR
  182. MATCH_STR
  183. "Match first hop interface of route\n"
  184. "Interface name\n")
  185. DEFUN (match_ip_next_hop,
  186. match_ip_next_hop_cmd,
  187. "match ip next-hop (<1-199>|<1300-2699>|WORD)",
  188. MATCH_STR
  189. IP_STR
  190. "Match next-hop address of route\n"
  191. "IP access-list number\n"
  192. "IP access-list number (expanded range)\n"
  193. "IP Access-list name\n")
  194. {
  195. return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
  196. }
  197. DEFUN (no_match_ip_next_hop,
  198. no_match_ip_next_hop_cmd,
  199. "no match ip next-hop",
  200. NO_STR
  201. MATCH_STR
  202. IP_STR
  203. "Match next-hop address of route\n")
  204. {
  205. if (argc == 0)
  206. return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL);
  207. return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
  208. }
  209. ALIAS (no_match_ip_next_hop,
  210. no_match_ip_next_hop_val_cmd,
  211. "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
  212. NO_STR
  213. MATCH_STR
  214. IP_STR
  215. "Match next-hop address of route\n"
  216. "IP access-list number\n"
  217. "IP access-list number (expanded range)\n"
  218. "IP Access-list name\n")
  219. DEFUN (match_ip_next_hop_prefix_list,
  220. match_ip_next_hop_prefix_list_cmd,
  221. "match ip next-hop prefix-list WORD",
  222. MATCH_STR
  223. IP_STR
  224. "Match next-hop address of route\n"
  225. "Match entries of prefix-lists\n"
  226. "IP prefix-list name\n")
  227. {
  228. return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  229. }
  230. DEFUN (no_match_ip_next_hop_prefix_list,
  231. no_match_ip_next_hop_prefix_list_cmd,
  232. "no match ip next-hop prefix-list",
  233. NO_STR
  234. MATCH_STR
  235. IP_STR
  236. "Match next-hop address of route\n"
  237. "Match entries of prefix-lists\n")
  238. {
  239. if (argc == 0)
  240. return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
  241. return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
  242. }
  243. ALIAS (no_match_ip_next_hop_prefix_list,
  244. no_match_ip_next_hop_prefix_list_val_cmd,
  245. "no match ip next-hop prefix-list WORD",
  246. NO_STR
  247. MATCH_STR
  248. IP_STR
  249. "Match next-hop address of route\n"
  250. "Match entries of prefix-lists\n"
  251. "IP prefix-list name\n")
  252. DEFUN (match_ip_address,
  253. match_ip_address_cmd,
  254. "match ip address (<1-199>|<1300-2699>|WORD)",
  255. MATCH_STR
  256. IP_STR
  257. "Match address of route\n"
  258. "IP access-list number\n"
  259. "IP access-list number (expanded range)\n"
  260. "IP Access-list name\n")
  261. {
  262. return zebra_route_match_add (vty, vty->index, "ip address", argv[0]);
  263. }
  264. DEFUN (no_match_ip_address,
  265. no_match_ip_address_cmd,
  266. "no match ip address",
  267. NO_STR
  268. MATCH_STR
  269. IP_STR
  270. "Match address of route\n")
  271. {
  272. if (argc == 0)
  273. return zebra_route_match_delete (vty, vty->index, "ip address", NULL);
  274. return zebra_route_match_delete (vty, vty->index, "ip address", argv[0]);
  275. }
  276. ALIAS (no_match_ip_address,
  277. no_match_ip_address_val_cmd,
  278. "no match ip address (<1-199>|<1300-2699>|WORD)",
  279. NO_STR
  280. MATCH_STR
  281. IP_STR
  282. "Match address of route\n"
  283. "IP access-list number\n"
  284. "IP access-list number (expanded range)\n"
  285. "IP Access-list name\n")
  286. DEFUN (match_ip_address_prefix_list,
  287. match_ip_address_prefix_list_cmd,
  288. "match ip address prefix-list WORD",
  289. MATCH_STR
  290. IP_STR
  291. "Match address of route\n"
  292. "Match entries of prefix-lists\n"
  293. "IP prefix-list name\n")
  294. {
  295. return zebra_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
  296. }
  297. DEFUN (no_match_ip_address_prefix_list,
  298. no_match_ip_address_prefix_list_cmd,
  299. "no match ip address prefix-list",
  300. NO_STR
  301. MATCH_STR
  302. IP_STR
  303. "Match address of route\n"
  304. "Match entries of prefix-lists\n")
  305. {
  306. if (argc == 0)
  307. return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
  308. return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
  309. }
  310. ALIAS (no_match_ip_address_prefix_list,
  311. no_match_ip_address_prefix_list_val_cmd,
  312. "no match ip address prefix-list WORD",
  313. NO_STR
  314. MATCH_STR
  315. IP_STR
  316. "Match address of route\n"
  317. "Match entries of prefix-lists\n"
  318. "IP prefix-list name\n")
  319. /* set functions */
  320. DEFUN (set_src,
  321. set_src_cmd,
  322. "set src A.B.C.D",
  323. SET_STR
  324. "src address for route\n"
  325. "src address\n")
  326. {
  327. struct in_addr src;
  328. struct interface *pif;
  329. if (inet_pton(AF_INET, argv[0], &src) <= 0)
  330. {
  331. vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
  332. return CMD_WARNING;
  333. }
  334. pif = if_lookup_exact_address (src);
  335. if (!pif)
  336. {
  337. vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
  338. return CMD_WARNING;
  339. }
  340. return zebra_route_set_add (vty, vty->index, "src", argv[0]);
  341. }
  342. DEFUN (no_set_src,
  343. no_set_src_cmd,
  344. "no set src",
  345. NO_STR
  346. SET_STR
  347. "Source address for route\n")
  348. {
  349. if (argc == 0)
  350. return zebra_route_set_delete (vty, vty->index, "src", NULL);
  351. return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
  352. }
  353. ALIAS (no_set_src,
  354. no_set_src_val_cmd,
  355. "no set src (A.B.C.D)",
  356. NO_STR
  357. SET_STR
  358. "src address for route\n"
  359. "src address\n")
  360. /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
  361. /* `match ip next-hop IP_ACCESS_LIST' */
  362. /* Match function return 1 if match is success else return zero. */
  363. static route_map_result_t
  364. route_match_ip_next_hop (void *rule, struct prefix *prefix,
  365. route_map_object_t type, void *object)
  366. {
  367. struct access_list *alist;
  368. struct nexthop *nexthop;
  369. struct prefix_ipv4 p;
  370. if (type == RMAP_ZEBRA)
  371. {
  372. nexthop = object;
  373. switch (nexthop->type) {
  374. case NEXTHOP_TYPE_IFINDEX:
  375. case NEXTHOP_TYPE_IFNAME:
  376. /* Interface routes can't match ip next-hop */
  377. return RMAP_NOMATCH;
  378. case NEXTHOP_TYPE_IPV4_IFINDEX:
  379. case NEXTHOP_TYPE_IPV4_IFNAME:
  380. case NEXTHOP_TYPE_IPV4:
  381. p.family = AF_INET;
  382. p.prefix = nexthop->gate.ipv4;
  383. p.prefixlen = IPV4_MAX_BITLEN;
  384. break;
  385. default:
  386. return RMAP_NOMATCH;
  387. }
  388. alist = access_list_lookup (AFI_IP, (char *) rule);
  389. if (alist == NULL)
  390. return RMAP_NOMATCH;
  391. return (access_list_apply (alist, &p) == FILTER_DENY ?
  392. RMAP_NOMATCH : RMAP_MATCH);
  393. }
  394. return RMAP_NOMATCH;
  395. }
  396. /* Route map `ip next-hop' match statement. `arg' should be
  397. access-list name. */
  398. static void *
  399. route_match_ip_next_hop_compile (const char *arg)
  400. {
  401. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  402. }
  403. /* Free route map's compiled `. */
  404. static void
  405. route_match_ip_next_hop_free (void *rule)
  406. {
  407. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  408. }
  409. /* Route map commands for ip next-hop matching. */
  410. static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
  411. {
  412. "ip next-hop",
  413. route_match_ip_next_hop,
  414. route_match_ip_next_hop_compile,
  415. route_match_ip_next_hop_free
  416. };
  417. /* `match ip next-hop prefix-list PREFIX_LIST' */
  418. static route_map_result_t
  419. route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
  420. route_map_object_t type, void *object)
  421. {
  422. struct prefix_list *plist;
  423. struct nexthop *nexthop;
  424. struct prefix_ipv4 p;
  425. if (type == RMAP_ZEBRA)
  426. {
  427. nexthop = object;
  428. switch (nexthop->type) {
  429. case NEXTHOP_TYPE_IFINDEX:
  430. case NEXTHOP_TYPE_IFNAME:
  431. /* Interface routes can't match ip next-hop */
  432. return RMAP_NOMATCH;
  433. case NEXTHOP_TYPE_IPV4_IFINDEX:
  434. case NEXTHOP_TYPE_IPV4_IFNAME:
  435. case NEXTHOP_TYPE_IPV4:
  436. p.family = AF_INET;
  437. p.prefix = nexthop->gate.ipv4;
  438. p.prefixlen = IPV4_MAX_BITLEN;
  439. break;
  440. default:
  441. return RMAP_NOMATCH;
  442. }
  443. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  444. if (plist == NULL)
  445. return RMAP_NOMATCH;
  446. return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
  447. RMAP_NOMATCH : RMAP_MATCH);
  448. }
  449. return RMAP_NOMATCH;
  450. }
  451. static void *
  452. route_match_ip_next_hop_prefix_list_compile (const char *arg)
  453. {
  454. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  455. }
  456. static void
  457. route_match_ip_next_hop_prefix_list_free (void *rule)
  458. {
  459. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  460. }
  461. static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
  462. {
  463. "ip next-hop prefix-list",
  464. route_match_ip_next_hop_prefix_list,
  465. route_match_ip_next_hop_prefix_list_compile,
  466. route_match_ip_next_hop_prefix_list_free
  467. };
  468. /* `match ip address IP_ACCESS_LIST' */
  469. /* Match function should return 1 if match is success else return
  470. zero. */
  471. static route_map_result_t
  472. route_match_ip_address (void *rule, struct prefix *prefix,
  473. route_map_object_t type, void *object)
  474. {
  475. struct access_list *alist;
  476. if (type == RMAP_ZEBRA)
  477. {
  478. alist = access_list_lookup (AFI_IP, (char *) rule);
  479. if (alist == NULL)
  480. return RMAP_NOMATCH;
  481. return (access_list_apply (alist, prefix) == FILTER_DENY ?
  482. RMAP_NOMATCH : RMAP_MATCH);
  483. }
  484. return RMAP_NOMATCH;
  485. }
  486. /* Route map `ip address' match statement. `arg' should be
  487. access-list name. */
  488. static void *
  489. route_match_ip_address_compile (const char *arg)
  490. {
  491. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  492. }
  493. /* Free route map's compiled `ip address' value. */
  494. static void
  495. route_match_ip_address_free (void *rule)
  496. {
  497. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  498. }
  499. /* Route map commands for ip address matching. */
  500. static struct route_map_rule_cmd route_match_ip_address_cmd =
  501. {
  502. "ip address",
  503. route_match_ip_address,
  504. route_match_ip_address_compile,
  505. route_match_ip_address_free
  506. };
  507. /* `match ip address prefix-list PREFIX_LIST' */
  508. static route_map_result_t
  509. route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
  510. route_map_object_t type, void *object)
  511. {
  512. struct prefix_list *plist;
  513. if (type == RMAP_ZEBRA)
  514. {
  515. plist = prefix_list_lookup (AFI_IP, (char *) rule);
  516. if (plist == NULL)
  517. return RMAP_NOMATCH;
  518. return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
  519. RMAP_NOMATCH : RMAP_MATCH);
  520. }
  521. return RMAP_NOMATCH;
  522. }
  523. static void *
  524. route_match_ip_address_prefix_list_compile (const char *arg)
  525. {
  526. return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
  527. }
  528. static void
  529. route_match_ip_address_prefix_list_free (void *rule)
  530. {
  531. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  532. }
  533. static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
  534. {
  535. "ip address prefix-list",
  536. route_match_ip_address_prefix_list,
  537. route_match_ip_address_prefix_list_compile,
  538. route_match_ip_address_prefix_list_free
  539. };
  540. /* `set src A.B.C.D' */
  541. /* Set src. */
  542. static route_map_result_t
  543. route_set_src (void *rule, struct prefix *prefix,
  544. route_map_object_t type, void *object)
  545. {
  546. if (type == RMAP_ZEBRA)
  547. {
  548. struct nexthop *nexthop;
  549. nexthop = object;
  550. nexthop->src = *(union g_addr *)rule;
  551. }
  552. return RMAP_OKAY;
  553. }
  554. /* set src compilation. */
  555. static void *
  556. route_set_src_compile (const char *arg)
  557. {
  558. union g_addr src, *psrc;
  559. if (inet_pton(AF_INET, arg, &src.ipv4) != 1
  560. #ifdef HAVE_IPV6
  561. && inet_pton(AF_INET6, arg, &src.ipv6) != 1
  562. #endif /* HAVE_IPV6 */
  563. )
  564. return NULL;
  565. psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
  566. *psrc = src;
  567. return psrc;
  568. }
  569. /* Free route map's compiled `set src' value. */
  570. static void
  571. route_set_src_free (void *rule)
  572. {
  573. XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
  574. }
  575. /* Set src rule structure. */
  576. static struct route_map_rule_cmd route_set_src_cmd =
  577. {
  578. "src",
  579. route_set_src,
  580. route_set_src_compile,
  581. route_set_src_free,
  582. };
  583. void
  584. zebra_route_map_init ()
  585. {
  586. route_map_init ();
  587. route_map_init_vty ();
  588. route_map_install_match (&route_match_interface_cmd);
  589. route_map_install_match (&route_match_ip_next_hop_cmd);
  590. route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
  591. route_map_install_match (&route_match_ip_address_cmd);
  592. route_map_install_match (&route_match_ip_address_prefix_list_cmd);
  593. /* */
  594. route_map_install_set (&route_set_src_cmd);
  595. /* */
  596. install_element (RMAP_NODE, &match_interface_cmd);
  597. install_element (RMAP_NODE, &no_match_interface_cmd);
  598. install_element (RMAP_NODE, &no_match_interface_val_cmd);
  599. install_element (RMAP_NODE, &match_ip_next_hop_cmd);
  600. install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
  601. install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
  602. install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
  603. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
  604. install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
  605. install_element (RMAP_NODE, &match_ip_address_cmd);
  606. install_element (RMAP_NODE, &no_match_ip_address_cmd);
  607. install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
  608. install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
  609. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
  610. install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
  611. /* */
  612. install_element (RMAP_NODE, &set_src_cmd);
  613. install_element (RMAP_NODE, &no_set_src_cmd);
  614. }