zebra: make declaration const in rtm_flag_dump()
[jleu-quagga.git] / zebra / zebra_routemap.c
blob808dcf745927202c5dd324ad8ae02a19bc4eca63
1 /* zebra routemap.
2 * Copyright (C) 2006 IBM Corporation
4 * This file is part of GNU Zebra.
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.
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.
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.
22 #include <zebra.h>
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"
32 #include "zebra/zserv.h"
34 /* Add zebra route map rule */
35 static int
36 zebra_route_match_add(struct vty *vty, struct route_map_index *index,
37 const char *command, const char *arg)
39 int ret;
41 ret = route_map_add_match (index, command, arg);
42 if (ret)
44 switch (ret)
46 case RMAP_RULE_MISSING:
47 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
48 return CMD_WARNING;
49 case RMAP_COMPILE_ERROR:
50 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
51 return CMD_WARNING;
54 return CMD_SUCCESS;
57 /* Delete zebra route map rule. */
58 static int
59 zebra_route_match_delete (struct vty *vty, struct route_map_index *index,
60 const char *command, const char *arg)
62 int ret;
64 ret = route_map_delete_match (index, command, arg);
65 if (ret)
67 switch (ret)
69 case RMAP_RULE_MISSING:
70 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
71 return CMD_WARNING;
72 case RMAP_COMPILE_ERROR:
73 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
74 return CMD_WARNING;
77 return CMD_SUCCESS;
80 /* Add zebra route map rule. */
81 static int
82 zebra_route_set_add (struct vty *vty, struct route_map_index *index,
83 const char *command, const char *arg)
85 int ret;
87 ret = route_map_add_set (index, command, arg);
88 if (ret)
90 switch (ret)
92 case RMAP_RULE_MISSING:
93 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
94 return CMD_WARNING;
95 case RMAP_COMPILE_ERROR:
96 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
97 return CMD_WARNING;
100 return CMD_SUCCESS;
103 /* Delete zebra route map rule. */
104 static int
105 zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
106 const char *command, const char *arg)
108 int ret;
110 ret = route_map_delete_set (index, command, arg);
111 if (ret)
113 switch (ret)
115 case RMAP_RULE_MISSING:
116 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
117 return CMD_WARNING;
118 case RMAP_COMPILE_ERROR:
119 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
120 return CMD_WARNING;
123 return CMD_SUCCESS;
127 /* `match interface IFNAME' */
128 /* Match function return 1 if match is success else return zero. */
129 static route_map_result_t
130 route_match_interface (void *rule, struct prefix *prefix,
131 route_map_object_t type, void *object)
133 struct nexthop *nexthop;
134 char *ifname = rule;
135 unsigned int ifindex;
137 if (type == RMAP_ZEBRA)
139 if (strcasecmp(ifname, "any") == 0)
140 return RMAP_MATCH;
141 ifindex = ifname2ifindex(ifname);
142 if (ifindex == 0)
143 return RMAP_NOMATCH;
144 nexthop = object;
145 if (!nexthop)
146 return RMAP_NOMATCH;
147 if (nexthop->ifindex == ifindex)
148 return RMAP_MATCH;
150 return RMAP_NOMATCH;
153 /* Route map `match interface' match statement. `arg' is IFNAME value */
154 static void *
155 route_match_interface_compile (const char *arg)
157 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
160 /* Free route map's compiled `match interface' value. */
161 static void
162 route_match_interface_free (void *rule)
164 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
167 /* Route map commands for interface matching */
168 struct route_map_rule_cmd route_match_interface_cmd =
170 "interface",
171 route_match_interface,
172 route_match_interface_compile,
173 route_match_interface_free
176 DEFUN (match_interface,
177 match_interface_cmd,
178 "match interface WORD",
179 MATCH_STR
180 "match first hop interface of route\n"
181 "Interface name\n")
183 return zebra_route_match_add (vty, vty->index, "interface", argv[0]);
186 DEFUN (no_match_interface,
187 no_match_interface_cmd,
188 "no match interface",
189 NO_STR
190 MATCH_STR
191 "Match first hop interface of route\n")
193 if (argc == 0)
194 return zebra_route_match_delete (vty, vty->index, "interface", NULL);
196 return zebra_route_match_delete (vty, vty->index, "interface", argv[0]);
199 ALIAS (no_match_interface,
200 no_match_interface_val_cmd,
201 "no match interface WORD",
202 NO_STR
203 MATCH_STR
204 "Match first hop interface of route\n"
205 "Interface name\n")
207 DEFUN (match_ip_next_hop,
208 match_ip_next_hop_cmd,
209 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
210 MATCH_STR
211 IP_STR
212 "Match next-hop address of route\n"
213 "IP access-list number\n"
214 "IP access-list number (expanded range)\n"
215 "IP Access-list name\n")
217 return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
220 DEFUN (no_match_ip_next_hop,
221 no_match_ip_next_hop_cmd,
222 "no match ip next-hop",
223 NO_STR
224 MATCH_STR
225 IP_STR
226 "Match next-hop address of route\n")
228 if (argc == 0)
229 return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL);
231 return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
234 ALIAS (no_match_ip_next_hop,
235 no_match_ip_next_hop_val_cmd,
236 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
237 NO_STR
238 MATCH_STR
239 IP_STR
240 "Match next-hop address of route\n"
241 "IP access-list number\n"
242 "IP access-list number (expanded range)\n"
243 "IP Access-list name\n")
245 DEFUN (match_ip_next_hop_prefix_list,
246 match_ip_next_hop_prefix_list_cmd,
247 "match ip next-hop prefix-list WORD",
248 MATCH_STR
249 IP_STR
250 "Match next-hop address of route\n"
251 "Match entries of prefix-lists\n"
252 "IP prefix-list name\n")
254 return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
257 DEFUN (no_match_ip_next_hop_prefix_list,
258 no_match_ip_next_hop_prefix_list_cmd,
259 "no match ip next-hop prefix-list",
260 NO_STR
261 MATCH_STR
262 IP_STR
263 "Match next-hop address of route\n"
264 "Match entries of prefix-lists\n")
266 if (argc == 0)
267 return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
269 return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
272 ALIAS (no_match_ip_next_hop_prefix_list,
273 no_match_ip_next_hop_prefix_list_val_cmd,
274 "no match ip next-hop prefix-list WORD",
275 NO_STR
276 MATCH_STR
277 IP_STR
278 "Match next-hop address of route\n"
279 "Match entries of prefix-lists\n"
280 "IP prefix-list name\n")
282 DEFUN (match_ip_address,
283 match_ip_address_cmd,
284 "match ip address (<1-199>|<1300-2699>|WORD)",
285 MATCH_STR
286 IP_STR
287 "Match address of route\n"
288 "IP access-list number\n"
289 "IP access-list number (expanded range)\n"
290 "IP Access-list name\n")
293 return zebra_route_match_add (vty, vty->index, "ip address", argv[0]);
296 DEFUN (no_match_ip_address,
297 no_match_ip_address_cmd,
298 "no match ip address",
299 NO_STR
300 MATCH_STR
301 IP_STR
302 "Match address of route\n")
304 if (argc == 0)
305 return zebra_route_match_delete (vty, vty->index, "ip address", NULL);
307 return zebra_route_match_delete (vty, vty->index, "ip address", argv[0]);
310 ALIAS (no_match_ip_address,
311 no_match_ip_address_val_cmd,
312 "no match ip address (<1-199>|<1300-2699>|WORD)",
313 NO_STR
314 MATCH_STR
315 IP_STR
316 "Match address of route\n"
317 "IP access-list number\n"
318 "IP access-list number (expanded range)\n"
319 "IP Access-list name\n")
321 DEFUN (match_ip_address_prefix_list,
322 match_ip_address_prefix_list_cmd,
323 "match ip address prefix-list WORD",
324 MATCH_STR
325 IP_STR
326 "Match address of route\n"
327 "Match entries of prefix-lists\n"
328 "IP prefix-list name\n")
330 return zebra_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
333 DEFUN (no_match_ip_address_prefix_list,
334 no_match_ip_address_prefix_list_cmd,
335 "no match ip address prefix-list",
336 NO_STR
337 MATCH_STR
338 IP_STR
339 "Match address of route\n"
340 "Match entries of prefix-lists\n")
342 if (argc == 0)
343 return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
345 return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
348 ALIAS (no_match_ip_address_prefix_list,
349 no_match_ip_address_prefix_list_val_cmd,
350 "no match ip address prefix-list WORD",
351 NO_STR
352 MATCH_STR
353 IP_STR
354 "Match address of route\n"
355 "Match entries of prefix-lists\n"
356 "IP prefix-list name\n")
358 /* set functions */
360 DEFUN (set_src,
361 set_src_cmd,
362 "set src A.B.C.D",
363 SET_STR
364 "src address for route\n"
365 "src address\n")
367 struct in_addr src;
368 struct interface *pif;
370 if (inet_pton(AF_INET, argv[0], &src) <= 0)
372 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
373 return CMD_WARNING;
376 pif = if_lookup_exact_address (src);
377 if (!pif)
379 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
380 return CMD_WARNING;
382 return zebra_route_set_add (vty, vty->index, "src", argv[0]);
385 DEFUN (no_set_src,
386 no_set_src_cmd,
387 "no set src",
388 NO_STR
389 SET_STR
390 "Source address for route\n")
392 if (argc == 0)
393 return zebra_route_set_delete (vty, vty->index, "src", NULL);
395 return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
398 ALIAS (no_set_src,
399 no_set_src_val_cmd,
400 "no set src (A.B.C.D)",
401 NO_STR
402 SET_STR
403 "src address for route\n"
404 "src address\n")
406 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
408 /* `match ip next-hop IP_ACCESS_LIST' */
410 /* Match function return 1 if match is success else return zero. */
411 static route_map_result_t
412 route_match_ip_next_hop (void *rule, struct prefix *prefix,
413 route_map_object_t type, void *object)
415 struct access_list *alist;
416 struct nexthop *nexthop;
417 struct prefix_ipv4 p;
419 if (type == RMAP_ZEBRA)
421 nexthop = object;
422 switch (nexthop->type) {
423 case NEXTHOP_TYPE_IFINDEX:
424 case NEXTHOP_TYPE_IFNAME:
425 case NEXTHOP_TYPE_IPV4_IFINDEX:
426 case NEXTHOP_TYPE_IPV4_IFNAME:
427 if (nexthop->rtype != NEXTHOP_TYPE_IPV4)
428 return RMAP_NOMATCH;
429 p.family = AF_INET;
430 p.prefix = nexthop->rgate.ipv4;
431 p.prefixlen = IPV4_MAX_BITLEN;
432 break;
433 case NEXTHOP_TYPE_IPV4:
434 p.family = AF_INET;
435 p.prefix = nexthop->gate.ipv4;
436 p.prefixlen = IPV4_MAX_BITLEN;
437 break;
438 default:
439 return RMAP_NOMATCH;
441 alist = access_list_lookup (AFI_IP, (char *) rule);
442 if (alist == NULL)
443 return RMAP_NOMATCH;
445 return (access_list_apply (alist, &p) == FILTER_DENY ?
446 RMAP_NOMATCH : RMAP_MATCH);
448 return RMAP_NOMATCH;
451 /* Route map `ip next-hop' match statement. `arg' should be
452 access-list name. */
453 static void *
454 route_match_ip_next_hop_compile (const char *arg)
456 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
459 /* Free route map's compiled `. */
460 static void
461 route_match_ip_next_hop_free (void *rule)
463 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
466 /* Route map commands for ip next-hop matching. */
467 static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
469 "ip next-hop",
470 route_match_ip_next_hop,
471 route_match_ip_next_hop_compile,
472 route_match_ip_next_hop_free
475 /* `match ip next-hop prefix-list PREFIX_LIST' */
477 static route_map_result_t
478 route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
479 route_map_object_t type, void *object)
481 struct prefix_list *plist;
482 struct nexthop *nexthop;
483 struct prefix_ipv4 p;
485 if (type == RMAP_ZEBRA)
487 nexthop = object;
488 switch (nexthop->type) {
489 case NEXTHOP_TYPE_IFINDEX:
490 case NEXTHOP_TYPE_IFNAME:
491 case NEXTHOP_TYPE_IPV4_IFINDEX:
492 case NEXTHOP_TYPE_IPV4_IFNAME:
493 if (nexthop->rtype != NEXTHOP_TYPE_IPV4)
494 return RMAP_NOMATCH;
495 p.family = AF_INET;
496 p.prefix = nexthop->rgate.ipv4;
497 p.prefixlen = IPV4_MAX_BITLEN;
498 break;
499 case NEXTHOP_TYPE_IPV4:
500 p.family = AF_INET;
501 p.prefix = nexthop->gate.ipv4;
502 p.prefixlen = IPV4_MAX_BITLEN;
503 break;
504 default:
505 return RMAP_NOMATCH;
507 plist = prefix_list_lookup (AFI_IP, (char *) rule);
508 if (plist == NULL)
509 return RMAP_NOMATCH;
511 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
512 RMAP_NOMATCH : RMAP_MATCH);
514 return RMAP_NOMATCH;
517 static void *
518 route_match_ip_next_hop_prefix_list_compile (const char *arg)
520 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
523 static void
524 route_match_ip_next_hop_prefix_list_free (void *rule)
526 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
529 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
531 "ip next-hop prefix-list",
532 route_match_ip_next_hop_prefix_list,
533 route_match_ip_next_hop_prefix_list_compile,
534 route_match_ip_next_hop_prefix_list_free
537 /* `match ip address IP_ACCESS_LIST' */
539 /* Match function should return 1 if match is success else return
540 zero. */
541 static route_map_result_t
542 route_match_ip_address (void *rule, struct prefix *prefix,
543 route_map_object_t type, void *object)
545 struct access_list *alist;
547 if (type == RMAP_ZEBRA)
549 alist = access_list_lookup (AFI_IP, (char *) rule);
550 if (alist == NULL)
551 return RMAP_NOMATCH;
553 return (access_list_apply (alist, prefix) == FILTER_DENY ?
554 RMAP_NOMATCH : RMAP_MATCH);
556 return RMAP_NOMATCH;
559 /* Route map `ip address' match statement. `arg' should be
560 access-list name. */
561 static void *
562 route_match_ip_address_compile (const char *arg)
564 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
567 /* Free route map's compiled `ip address' value. */
568 static void
569 route_match_ip_address_free (void *rule)
571 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
574 /* Route map commands for ip address matching. */
575 static struct route_map_rule_cmd route_match_ip_address_cmd =
577 "ip address",
578 route_match_ip_address,
579 route_match_ip_address_compile,
580 route_match_ip_address_free
583 /* `match ip address prefix-list PREFIX_LIST' */
585 static route_map_result_t
586 route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
587 route_map_object_t type, void *object)
589 struct prefix_list *plist;
591 if (type == RMAP_ZEBRA)
593 plist = prefix_list_lookup (AFI_IP, (char *) rule);
594 if (plist == NULL)
595 return RMAP_NOMATCH;
597 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
598 RMAP_NOMATCH : RMAP_MATCH);
600 return RMAP_NOMATCH;
603 static void *
604 route_match_ip_address_prefix_list_compile (const char *arg)
606 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
609 static void
610 route_match_ip_address_prefix_list_free (void *rule)
612 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
615 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
617 "ip address prefix-list",
618 route_match_ip_address_prefix_list,
619 route_match_ip_address_prefix_list_compile,
620 route_match_ip_address_prefix_list_free
624 /* `set src A.B.C.D' */
626 /* Set src. */
627 static route_map_result_t
628 route_set_src (void *rule, struct prefix *prefix,
629 route_map_object_t type, void *object)
631 if (type == RMAP_ZEBRA)
633 struct nexthop *nexthop;
635 nexthop = object;
636 nexthop->src = *(union g_addr *)rule;
638 return RMAP_OKAY;
641 /* set src compilation. */
642 static void *
643 route_set_src_compile (const char *arg)
645 sa_family_t family;
646 union g_addr src, *psrc;
648 if (inet_pton(AF_INET, arg, &src.ipv4) > 0)
649 family = AF_INET;
650 #ifdef HAVE_IPV6
651 else if (inet_pton(AF_INET6, arg, &src.ipv6) > 0)
652 family = AF_INET6;
653 #endif /* HAVE_IPV6 */
654 else
655 return NULL;
657 psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
658 *psrc = src;
660 return psrc;
663 /* Free route map's compiled `set src' value. */
664 static void
665 route_set_src_free (void *rule)
667 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
670 /* Set src rule structure. */
671 static struct route_map_rule_cmd route_set_src_cmd =
673 "src",
674 route_set_src,
675 route_set_src_compile,
676 route_set_src_free,
679 void
680 zebra_route_map_init ()
682 route_map_init ();
683 route_map_init_vty ();
685 route_map_install_match (&route_match_interface_cmd);
686 route_map_install_match (&route_match_ip_next_hop_cmd);
687 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
688 route_map_install_match (&route_match_ip_address_cmd);
689 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
690 /* */
691 route_map_install_set (&route_set_src_cmd);
692 /* */
693 install_element (RMAP_NODE, &match_interface_cmd);
694 install_element (RMAP_NODE, &no_match_interface_cmd);
695 install_element (RMAP_NODE, &no_match_interface_val_cmd);
696 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
697 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
698 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
699 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
700 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
701 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
702 install_element (RMAP_NODE, &match_ip_address_cmd);
703 install_element (RMAP_NODE, &no_match_ip_address_cmd);
704 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
705 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
706 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
707 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
708 /* */
709 install_element (RMAP_NODE, &set_src_cmd);
710 install_element (RMAP_NODE, &no_set_src_cmd);