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