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
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
32 #include "zebra/zserv.h"
34 /* Add zebra route map rule */
36 zebra_route_match_add(struct vty
*vty
, struct route_map_index
*index
,
37 const char *command
, const char *arg
)
41 ret
= route_map_add_match (index
, command
, arg
);
46 case RMAP_RULE_MISSING
:
47 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
49 case RMAP_COMPILE_ERROR
:
50 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
57 /* Delete zebra route map rule. */
59 zebra_route_match_delete (struct vty
*vty
, struct route_map_index
*index
,
60 const char *command
, const char *arg
)
64 ret
= route_map_delete_match (index
, command
, arg
);
69 case RMAP_RULE_MISSING
:
70 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
72 case RMAP_COMPILE_ERROR
:
73 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
80 /* Add zebra route map rule. */
82 zebra_route_set_add (struct vty
*vty
, struct route_map_index
*index
,
83 const char *command
, const char *arg
)
87 ret
= route_map_add_set (index
, command
, arg
);
92 case RMAP_RULE_MISSING
:
93 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
95 case RMAP_COMPILE_ERROR
:
96 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
103 /* Delete zebra route map rule. */
105 zebra_route_set_delete (struct vty
*vty
, struct route_map_index
*index
,
106 const char *command
, const char *arg
)
110 ret
= route_map_delete_set (index
, command
, arg
);
115 case RMAP_RULE_MISSING
:
116 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
118 case RMAP_COMPILE_ERROR
:
119 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
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
;
135 unsigned int ifindex
;
137 if (type
== RMAP_ZEBRA
)
139 if (strcasecmp(ifname
, "any") == 0)
141 ifindex
= ifname2ifindex(ifname
);
147 if (nexthop
->ifindex
== ifindex
)
153 /* Route map `match interface' match statement. `arg' is IFNAME value */
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. */
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
=
171 route_match_interface
,
172 route_match_interface_compile
,
173 route_match_interface_free
176 DEFUN (match_interface
,
178 "match interface WORD",
180 "match first hop interface of route\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",
191 "Match first hop interface of route\n")
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",
204 "Match first hop interface of route\n"
207 DEFUN (match_ip_next_hop
,
208 match_ip_next_hop_cmd
,
209 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
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",
226 "Match next-hop address of route\n")
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)",
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",
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",
263 "Match next-hop address of route\n"
264 "Match entries of prefix-lists\n")
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",
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)",
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",
302 "Match address of route\n")
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)",
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",
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",
339 "Match address of route\n"
340 "Match entries of prefix-lists\n")
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",
354 "Match address of route\n"
355 "Match entries of prefix-lists\n"
356 "IP prefix-list name\n")
364 "src address for route\n"
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
);
376 pif
= if_lookup_exact_address (src
);
379 vty_out (vty
, "%% not a local address%s", VTY_NEWLINE
);
382 return zebra_route_set_add (vty
, vty
->index
, "src", argv
[0]);
390 "Source address for route\n")
393 return zebra_route_set_delete (vty
, vty
->index
, "src", NULL
);
395 return zebra_route_set_delete (vty
, vty
->index
, "src", argv
[0]);
400 "no set src (A.B.C.D)",
403 "src address for route\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
)
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
)
430 p
.prefix
= nexthop
->rgate
.ipv4
;
431 p
.prefixlen
= IPV4_MAX_BITLEN
;
433 case NEXTHOP_TYPE_IPV4
:
435 p
.prefix
= nexthop
->gate
.ipv4
;
436 p
.prefixlen
= IPV4_MAX_BITLEN
;
441 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
445 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
446 RMAP_NOMATCH
: RMAP_MATCH
);
451 /* Route map `ip next-hop' match statement. `arg' should be
454 route_match_ip_next_hop_compile (const char *arg
)
456 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
459 /* Free route map's compiled `. */
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
=
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
)
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
)
496 p
.prefix
= nexthop
->rgate
.ipv4
;
497 p
.prefixlen
= IPV4_MAX_BITLEN
;
499 case NEXTHOP_TYPE_IPV4
:
501 p
.prefix
= nexthop
->gate
.ipv4
;
502 p
.prefixlen
= IPV4_MAX_BITLEN
;
507 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
511 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
512 RMAP_NOMATCH
: RMAP_MATCH
);
518 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
520 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
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
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
);
553 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
554 RMAP_NOMATCH
: RMAP_MATCH
);
559 /* Route map `ip address' match statement. `arg' should be
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. */
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
=
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
);
597 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
598 RMAP_NOMATCH
: RMAP_MATCH
);
604 route_match_ip_address_prefix_list_compile (const char *arg
)
606 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
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' */
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
;
636 nexthop
->src
= *(union g_addr
*)rule
;
641 /* set src compilation. */
643 route_set_src_compile (const char *arg
)
646 union g_addr src
, *psrc
;
648 if (inet_pton(AF_INET
, arg
, &src
.ipv4
) > 0)
651 else if (inet_pton(AF_INET6
, arg
, &src
.ipv6
) > 0)
653 #endif /* HAVE_IPV6 */
657 psrc
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (union g_addr
));
663 /* Free route map's compiled `set src' value. */
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
=
675 route_set_src_compile
,
680 zebra_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
);
691 route_map_install_set (&route_set_src_cmd
);
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
);
709 install_element (RMAP_NODE
, &set_src_cmd
);
710 install_element (RMAP_NODE
, &no_set_src_cmd
);