blob: 49feccd0632e9301e721fa7417254ff4633070da [file] [log] [blame]
Paul Jakma5921ef92007-05-04 20:13:20 +00001/* 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
22#include <zebra.h>
23
24#include "memory.h"
25#include "prefix.h"
26#include "rib.h"
27#include "routemap.h"
28#include "command.h"
29#include "filter.h"
30#include "plist.h"
Feng Lu8970f742015-05-22 11:40:05 +020031#include "vrf.h"
Paul Jakma5921ef92007-05-04 20:13:20 +000032
33#include "zebra/zserv.h"
34
35/* Add zebra route map rule */
36static int
37zebra_route_match_add(struct vty *vty, struct route_map_index *index,
38 const char *command, const char *arg)
39{
40 int ret;
41
42 ret = route_map_add_match (index, command, arg);
43 if (ret)
44 {
45 switch (ret)
46 {
47 case RMAP_RULE_MISSING:
48 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
49 return CMD_WARNING;
50 case RMAP_COMPILE_ERROR:
51 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
52 return CMD_WARNING;
53 }
54 }
55 return CMD_SUCCESS;
56}
57
58/* Delete zebra route map rule. */
59static int
60zebra_route_match_delete (struct vty *vty, struct route_map_index *index,
61 const char *command, const char *arg)
62{
63 int ret;
64
65 ret = route_map_delete_match (index, command, arg);
66 if (ret)
67 {
68 switch (ret)
69 {
70 case RMAP_RULE_MISSING:
71 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
72 return CMD_WARNING;
73 case RMAP_COMPILE_ERROR:
74 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
75 return CMD_WARNING;
76 }
77 }
78 return CMD_SUCCESS;
79}
80
81/* Add zebra route map rule. */
82static int
83zebra_route_set_add (struct vty *vty, struct route_map_index *index,
84 const char *command, const char *arg)
85{
86 int ret;
87
88 ret = route_map_add_set (index, command, arg);
89 if (ret)
90 {
91 switch (ret)
92 {
93 case RMAP_RULE_MISSING:
94 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
95 return CMD_WARNING;
96 case RMAP_COMPILE_ERROR:
97 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
98 return CMD_WARNING;
99 }
100 }
101 return CMD_SUCCESS;
102}
103
104/* Delete zebra route map rule. */
105static int
106zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
107 const char *command, const char *arg)
108{
109 int ret;
110
111 ret = route_map_delete_set (index, command, arg);
112 if (ret)
113 {
114 switch (ret)
115 {
116 case RMAP_RULE_MISSING:
117 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
118 return CMD_WARNING;
119 case RMAP_COMPILE_ERROR:
120 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
121 return CMD_WARNING;
122 }
123 }
124 return CMD_SUCCESS;
125}
126
David Lamparter6b0655a2014-06-04 06:53:35 +0200127
Paul Jakma5921ef92007-05-04 20:13:20 +0000128/* `match interface IFNAME' */
129/* Match function return 1 if match is success else return zero. */
130static route_map_result_t
131route_match_interface (void *rule, struct prefix *prefix,
132 route_map_object_t type, void *object)
133{
Feng Lu1885d0a2015-05-22 11:40:04 +0200134 struct nexthop_vrfid *nh_vrf;
Paul Jakma5921ef92007-05-04 20:13:20 +0000135 struct nexthop *nexthop;
136 char *ifname = rule;
Paul Jakma9099f9b2016-01-18 10:12:10 +0000137 ifindex_t ifindex;
Paul Jakma5921ef92007-05-04 20:13:20 +0000138
139 if (type == RMAP_ZEBRA)
140 {
141 if (strcasecmp(ifname, "any") == 0)
142 return RMAP_MATCH;
Feng Lu1885d0a2015-05-22 11:40:04 +0200143 nh_vrf = object;
144 if (!nh_vrf)
145 return RMAP_NOMATCH;
146 ifindex = ifname2ifindex_vrf (ifname, nh_vrf->vrf_id);
Paul Jakma5921ef92007-05-04 20:13:20 +0000147 if (ifindex == 0)
148 return RMAP_NOMATCH;
Feng Lu1885d0a2015-05-22 11:40:04 +0200149 nexthop = nh_vrf->nexthop;
Paul Jakma5921ef92007-05-04 20:13:20 +0000150 if (!nexthop)
151 return RMAP_NOMATCH;
152 if (nexthop->ifindex == ifindex)
153 return RMAP_MATCH;
154 }
155 return RMAP_NOMATCH;
156}
157
158/* Route map `match interface' match statement. `arg' is IFNAME value */
159static void *
160route_match_interface_compile (const char *arg)
161{
162 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
163}
164
165/* Free route map's compiled `match interface' value. */
166static void
167route_match_interface_free (void *rule)
168{
169 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
170}
171
172/* Route map commands for interface matching */
173struct route_map_rule_cmd route_match_interface_cmd =
174{
175 "interface",
176 route_match_interface,
177 route_match_interface_compile,
178 route_match_interface_free
179};
180
181DEFUN (match_interface,
182 match_interface_cmd,
183 "match interface WORD",
184 MATCH_STR
185 "match first hop interface of route\n"
186 "Interface name\n")
187{
188 return zebra_route_match_add (vty, vty->index, "interface", argv[0]);
189}
190
191DEFUN (no_match_interface,
192 no_match_interface_cmd,
193 "no match interface",
194 NO_STR
195 MATCH_STR
196 "Match first hop interface of route\n")
197{
198 if (argc == 0)
199 return zebra_route_match_delete (vty, vty->index, "interface", NULL);
200
201 return zebra_route_match_delete (vty, vty->index, "interface", argv[0]);
202}
203
204ALIAS (no_match_interface,
205 no_match_interface_val_cmd,
206 "no match interface WORD",
207 NO_STR
208 MATCH_STR
209 "Match first hop interface of route\n"
210 "Interface name\n")
211
212DEFUN (match_ip_next_hop,
213 match_ip_next_hop_cmd,
214 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
215 MATCH_STR
216 IP_STR
217 "Match next-hop address of route\n"
218 "IP access-list number\n"
219 "IP access-list number (expanded range)\n"
220 "IP Access-list name\n")
221{
222 return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
223}
224
225DEFUN (no_match_ip_next_hop,
226 no_match_ip_next_hop_cmd,
227 "no match ip next-hop",
228 NO_STR
229 MATCH_STR
230 IP_STR
231 "Match next-hop address of route\n")
232{
233 if (argc == 0)
234 return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL);
235
236 return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
237}
238
239ALIAS (no_match_ip_next_hop,
240 no_match_ip_next_hop_val_cmd,
241 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
242 NO_STR
243 MATCH_STR
244 IP_STR
245 "Match next-hop address of route\n"
246 "IP access-list number\n"
247 "IP access-list number (expanded range)\n"
248 "IP Access-list name\n")
249
250DEFUN (match_ip_next_hop_prefix_list,
251 match_ip_next_hop_prefix_list_cmd,
252 "match ip next-hop prefix-list WORD",
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{
259 return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
260}
261
262DEFUN (no_match_ip_next_hop_prefix_list,
263 no_match_ip_next_hop_prefix_list_cmd,
264 "no match ip next-hop prefix-list",
265 NO_STR
266 MATCH_STR
267 IP_STR
268 "Match next-hop address of route\n"
269 "Match entries of prefix-lists\n")
270{
271 if (argc == 0)
272 return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
273
274 return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
275}
276
277ALIAS (no_match_ip_next_hop_prefix_list,
278 no_match_ip_next_hop_prefix_list_val_cmd,
279 "no match ip next-hop prefix-list WORD",
280 NO_STR
281 MATCH_STR
282 IP_STR
283 "Match next-hop address of route\n"
284 "Match entries of prefix-lists\n"
285 "IP prefix-list name\n")
286
287DEFUN (match_ip_address,
288 match_ip_address_cmd,
289 "match ip address (<1-199>|<1300-2699>|WORD)",
290 MATCH_STR
291 IP_STR
292 "Match address of route\n"
293 "IP access-list number\n"
294 "IP access-list number (expanded range)\n"
295 "IP Access-list name\n")
296
297{
298 return zebra_route_match_add (vty, vty->index, "ip address", argv[0]);
299}
300
301DEFUN (no_match_ip_address,
302 no_match_ip_address_cmd,
303 "no match ip address",
304 NO_STR
305 MATCH_STR
306 IP_STR
307 "Match address of route\n")
308{
309 if (argc == 0)
310 return zebra_route_match_delete (vty, vty->index, "ip address", NULL);
311
312 return zebra_route_match_delete (vty, vty->index, "ip address", argv[0]);
313}
314
315ALIAS (no_match_ip_address,
316 no_match_ip_address_val_cmd,
317 "no match ip address (<1-199>|<1300-2699>|WORD)",
318 NO_STR
319 MATCH_STR
320 IP_STR
321 "Match address of route\n"
322 "IP access-list number\n"
323 "IP access-list number (expanded range)\n"
324 "IP Access-list name\n")
325
326DEFUN (match_ip_address_prefix_list,
327 match_ip_address_prefix_list_cmd,
328 "match ip address prefix-list WORD",
329 MATCH_STR
330 IP_STR
331 "Match address of route\n"
332 "Match entries of prefix-lists\n"
333 "IP prefix-list name\n")
334{
335 return zebra_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
336}
337
338DEFUN (no_match_ip_address_prefix_list,
339 no_match_ip_address_prefix_list_cmd,
340 "no match ip address prefix-list",
341 NO_STR
342 MATCH_STR
343 IP_STR
344 "Match address of route\n"
345 "Match entries of prefix-lists\n")
346{
347 if (argc == 0)
348 return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
349
350 return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
351}
352
353ALIAS (no_match_ip_address_prefix_list,
354 no_match_ip_address_prefix_list_val_cmd,
355 "no match ip address prefix-list WORD",
356 NO_STR
357 MATCH_STR
358 IP_STR
359 "Match address of route\n"
360 "Match entries of prefix-lists\n"
361 "IP prefix-list name\n")
362
363/* set functions */
364
365DEFUN (set_src,
366 set_src_cmd,
367 "set src A.B.C.D",
368 SET_STR
369 "src address for route\n"
370 "src address\n")
371{
372 struct in_addr src;
Feng Lu8970f742015-05-22 11:40:05 +0200373 struct interface *pif = NULL;
374 vrf_iter_t iter;
Paul Jakma5921ef92007-05-04 20:13:20 +0000375
376 if (inet_pton(AF_INET, argv[0], &src) <= 0)
377 {
378 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
379 return CMD_WARNING;
380 }
381
Feng Lu8970f742015-05-22 11:40:05 +0200382 for (iter = vrf_first (); iter != VRF_ITER_INVALID; iter = vrf_next (iter))
383 if ((pif = if_lookup_exact_address_vrf (src, vrf_iter2id (iter))) != NULL)
384 break;
385
386 if (!pif)
387 {
388 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
389 return CMD_WARNING;
390 }
391
Paul Jakma5921ef92007-05-04 20:13:20 +0000392 return zebra_route_set_add (vty, vty->index, "src", argv[0]);
393}
394
395DEFUN (no_set_src,
396 no_set_src_cmd,
397 "no set src",
398 NO_STR
399 SET_STR
400 "Source address for route\n")
401{
402 if (argc == 0)
403 return zebra_route_set_delete (vty, vty->index, "src", NULL);
404
405 return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
406}
407
408ALIAS (no_set_src,
409 no_set_src_val_cmd,
410 "no set src (A.B.C.D)",
411 NO_STR
412 SET_STR
413 "src address for route\n"
414 "src address\n")
415
416/*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
417
418/* `match ip next-hop IP_ACCESS_LIST' */
419
420/* Match function return 1 if match is success else return zero. */
421static route_map_result_t
422route_match_ip_next_hop (void *rule, struct prefix *prefix,
423 route_map_object_t type, void *object)
424{
425 struct access_list *alist;
426 struct nexthop *nexthop;
Stas Nichiporovichaef46502016-04-26 08:14:36 +0000427 struct nexthop_vrfid *nh_vrf;
Paul Jakma5921ef92007-05-04 20:13:20 +0000428 struct prefix_ipv4 p;
429
430 if (type == RMAP_ZEBRA)
431 {
Stas Nichiporovichaef46502016-04-26 08:14:36 +0000432 nh_vrf = object;
433 nexthop = nh_vrf->nexthop;
Paul Jakma5921ef92007-05-04 20:13:20 +0000434 switch (nexthop->type) {
435 case NEXTHOP_TYPE_IFINDEX:
436 case NEXTHOP_TYPE_IFNAME:
Christian Frankefa713d92013-07-05 15:35:37 +0000437 /* Interface routes can't match ip next-hop */
438 return RMAP_NOMATCH;
Paul Jakma5921ef92007-05-04 20:13:20 +0000439 case NEXTHOP_TYPE_IPV4_IFINDEX:
440 case NEXTHOP_TYPE_IPV4_IFNAME:
Paul Jakma5921ef92007-05-04 20:13:20 +0000441 case NEXTHOP_TYPE_IPV4:
442 p.family = AF_INET;
443 p.prefix = nexthop->gate.ipv4;
444 p.prefixlen = IPV4_MAX_BITLEN;
445 break;
446 default:
447 return RMAP_NOMATCH;
448 }
449 alist = access_list_lookup (AFI_IP, (char *) rule);
450 if (alist == NULL)
451 return RMAP_NOMATCH;
452
453 return (access_list_apply (alist, &p) == FILTER_DENY ?
454 RMAP_NOMATCH : RMAP_MATCH);
455 }
456 return RMAP_NOMATCH;
457}
458
459/* Route map `ip next-hop' match statement. `arg' should be
460 access-list name. */
461static void *
462route_match_ip_next_hop_compile (const char *arg)
463{
464 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
465}
466
467/* Free route map's compiled `. */
468static void
469route_match_ip_next_hop_free (void *rule)
470{
471 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
472}
473
474/* Route map commands for ip next-hop matching. */
475static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
476{
477 "ip next-hop",
478 route_match_ip_next_hop,
479 route_match_ip_next_hop_compile,
480 route_match_ip_next_hop_free
481};
David Lamparter6b0655a2014-06-04 06:53:35 +0200482
Paul Jakma5921ef92007-05-04 20:13:20 +0000483/* `match ip next-hop prefix-list PREFIX_LIST' */
484
485static route_map_result_t
486route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
487 route_map_object_t type, void *object)
488{
489 struct prefix_list *plist;
490 struct nexthop *nexthop;
Stas Nichiporovichaef46502016-04-26 08:14:36 +0000491 struct nexthop_vrfid *nh_vrf;
Paul Jakma5921ef92007-05-04 20:13:20 +0000492 struct prefix_ipv4 p;
493
494 if (type == RMAP_ZEBRA)
495 {
Stas Nichiporovichaef46502016-04-26 08:14:36 +0000496 nh_vrf = object;
497 nexthop = nh_vrf->nexthop;
Paul Jakma5921ef92007-05-04 20:13:20 +0000498 switch (nexthop->type) {
499 case NEXTHOP_TYPE_IFINDEX:
500 case NEXTHOP_TYPE_IFNAME:
Christian Frankefa713d92013-07-05 15:35:37 +0000501 /* Interface routes can't match ip next-hop */
502 return RMAP_NOMATCH;
Paul Jakma5921ef92007-05-04 20:13:20 +0000503 case NEXTHOP_TYPE_IPV4_IFINDEX:
504 case NEXTHOP_TYPE_IPV4_IFNAME:
Paul Jakma5921ef92007-05-04 20:13:20 +0000505 case NEXTHOP_TYPE_IPV4:
506 p.family = AF_INET;
507 p.prefix = nexthop->gate.ipv4;
508 p.prefixlen = IPV4_MAX_BITLEN;
509 break;
510 default:
511 return RMAP_NOMATCH;
512 }
513 plist = prefix_list_lookup (AFI_IP, (char *) rule);
514 if (plist == NULL)
515 return RMAP_NOMATCH;
516
517 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
518 RMAP_NOMATCH : RMAP_MATCH);
519 }
520 return RMAP_NOMATCH;
521}
522
523static void *
524route_match_ip_next_hop_prefix_list_compile (const char *arg)
525{
526 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
527}
528
529static void
530route_match_ip_next_hop_prefix_list_free (void *rule)
531{
532 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
533}
534
535static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
536{
537 "ip next-hop prefix-list",
538 route_match_ip_next_hop_prefix_list,
539 route_match_ip_next_hop_prefix_list_compile,
540 route_match_ip_next_hop_prefix_list_free
541};
David Lamparter6b0655a2014-06-04 06:53:35 +0200542
Paul Jakma5921ef92007-05-04 20:13:20 +0000543/* `match ip address IP_ACCESS_LIST' */
544
545/* Match function should return 1 if match is success else return
546 zero. */
547static route_map_result_t
548route_match_ip_address (void *rule, struct prefix *prefix,
549 route_map_object_t type, void *object)
550{
551 struct access_list *alist;
552
553 if (type == RMAP_ZEBRA)
554 {
555 alist = access_list_lookup (AFI_IP, (char *) rule);
556 if (alist == NULL)
557 return RMAP_NOMATCH;
558
559 return (access_list_apply (alist, prefix) == FILTER_DENY ?
560 RMAP_NOMATCH : RMAP_MATCH);
561 }
562 return RMAP_NOMATCH;
563}
564
565/* Route map `ip address' match statement. `arg' should be
566 access-list name. */
567static void *
568route_match_ip_address_compile (const char *arg)
569{
570 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
571}
572
573/* Free route map's compiled `ip address' value. */
574static void
575route_match_ip_address_free (void *rule)
576{
577 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
578}
579
580/* Route map commands for ip address matching. */
581static struct route_map_rule_cmd route_match_ip_address_cmd =
582{
583 "ip address",
584 route_match_ip_address,
585 route_match_ip_address_compile,
586 route_match_ip_address_free
587};
David Lamparter6b0655a2014-06-04 06:53:35 +0200588
Paul Jakma5921ef92007-05-04 20:13:20 +0000589/* `match ip address prefix-list PREFIX_LIST' */
590
591static route_map_result_t
592route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
593 route_map_object_t type, void *object)
594{
595 struct prefix_list *plist;
596
597 if (type == RMAP_ZEBRA)
598 {
599 plist = prefix_list_lookup (AFI_IP, (char *) rule);
600 if (plist == NULL)
601 return RMAP_NOMATCH;
602
603 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
604 RMAP_NOMATCH : RMAP_MATCH);
605 }
606 return RMAP_NOMATCH;
607}
608
609static void *
610route_match_ip_address_prefix_list_compile (const char *arg)
611{
612 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
613}
614
615static void
616route_match_ip_address_prefix_list_free (void *rule)
617{
618 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
619}
620
621static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
622{
623 "ip address prefix-list",
624 route_match_ip_address_prefix_list,
625 route_match_ip_address_prefix_list_compile,
626 route_match_ip_address_prefix_list_free
627};
628
David Lamparter6b0655a2014-06-04 06:53:35 +0200629
Paul Jakma5921ef92007-05-04 20:13:20 +0000630/* `set src A.B.C.D' */
631
632/* Set src. */
633static route_map_result_t
634route_set_src (void *rule, struct prefix *prefix,
635 route_map_object_t type, void *object)
636{
637 if (type == RMAP_ZEBRA)
638 {
Stas Nichiporovichaef46502016-04-26 08:14:36 +0000639 struct nexthop_vrfid *nh_vrf;
Paul Jakma5921ef92007-05-04 20:13:20 +0000640
Stas Nichiporovichaef46502016-04-26 08:14:36 +0000641 nh_vrf = object;
642 nh_vrf->nexthop->src = *(union g_addr *)rule;
Paul Jakma5921ef92007-05-04 20:13:20 +0000643 }
644 return RMAP_OKAY;
645}
646
647/* set src compilation. */
648static void *
649route_set_src_compile (const char *arg)
650{
Paul Jakma5921ef92007-05-04 20:13:20 +0000651 union g_addr src, *psrc;
652
Paul Jakma8dd1a8d2011-04-11 16:33:20 +0100653 if (inet_pton(AF_INET, arg, &src.ipv4) != 1
Andrew J. Schorr09303312007-05-30 20:10:34 +0000654#ifdef HAVE_IPV6
Paul Jakma8dd1a8d2011-04-11 16:33:20 +0100655 && inet_pton(AF_INET6, arg, &src.ipv6) != 1
Andrew J. Schorr09303312007-05-30 20:10:34 +0000656#endif /* HAVE_IPV6 */
Paul Jakma8dd1a8d2011-04-11 16:33:20 +0100657 )
658 return NULL;
Paul Jakma5921ef92007-05-04 20:13:20 +0000659
660 psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
661 *psrc = src;
662
663 return psrc;
664}
665
666/* Free route map's compiled `set src' value. */
667static void
668route_set_src_free (void *rule)
669{
670 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
671}
672
673/* Set src rule structure. */
674static struct route_map_rule_cmd route_set_src_cmd =
675{
676 "src",
677 route_set_src,
678 route_set_src_compile,
679 route_set_src_free,
680};
681
682void
683zebra_route_map_init ()
684{
685 route_map_init ();
686 route_map_init_vty ();
687
688 route_map_install_match (&route_match_interface_cmd);
689 route_map_install_match (&route_match_ip_next_hop_cmd);
690 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
691 route_map_install_match (&route_match_ip_address_cmd);
692 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
693/* */
694 route_map_install_set (&route_set_src_cmd);
695/* */
696 install_element (RMAP_NODE, &match_interface_cmd);
697 install_element (RMAP_NODE, &no_match_interface_cmd);
698 install_element (RMAP_NODE, &no_match_interface_val_cmd);
699 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
700 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
701 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
702 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
703 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
704 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
705 install_element (RMAP_NODE, &match_ip_address_cmd);
706 install_element (RMAP_NODE, &no_match_ip_address_cmd);
707 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
708 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
709 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
710 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
711/* */
712 install_element (RMAP_NODE, &set_src_cmd);
713 install_element (RMAP_NODE, &no_set_src_cmd);
714}