zebra_routemap.c 18 KB

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