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
34 #include "zebra/zserv.h"
36 /* Add zebra route map rule */
38 zebra_route_match_add(struct vty *vty, struct route_map_index *index,
39 const char *command, const char *arg)
43 ret = route_map_add_match (index, command, arg);
48 case RMAP_RULE_MISSING:
49 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
51 case RMAP_COMPILE_ERROR:
52 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
59 /* Delete zebra route map rule. */
61 zebra_route_match_delete (struct vty *vty, struct route_map_index *index,
62 const char *command, const char *arg)
66 ret = route_map_delete_match (index, command, arg);
71 case RMAP_RULE_MISSING:
72 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
74 case RMAP_COMPILE_ERROR:
75 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
82 /* Add zebra route map rule. */
84 zebra_route_set_add (struct vty *vty, struct route_map_index *index,
85 const char *command, const char *arg)
89 ret = route_map_add_set (index, command, arg);
94 case RMAP_RULE_MISSING:
95 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
97 case RMAP_COMPILE_ERROR:
98 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
105 /* Delete zebra route map rule. */
107 zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
108 const char *command, const char *arg)
112 ret = route_map_delete_set (index, command, arg);
117 case RMAP_RULE_MISSING:
118 vty_out (vty, "%% Zebra Can't find rule.%s", VTY_NEWLINE);
120 case RMAP_COMPILE_ERROR:
121 vty_out (vty, "%% Zebra Argument is malformed.%s", VTY_NEWLINE);
129 /* `match interface IFNAME' */
130 /* Match function return 1 if match is success else return zero. */
131 static route_map_result_t
132 route_match_interface (void *rule, struct prefix *prefix,
133 route_map_object_t type, void *object)
135 struct nexthop_vrfid *nh_vrf;
136 struct nexthop *nexthop;
140 if (type == RMAP_ZEBRA)
142 if (strcasecmp(ifname, "any") == 0)
147 ifindex = ifname2ifindex_vrf (ifname, nh_vrf->vrf_id);
150 nexthop = nh_vrf->nexthop;
153 if (nexthop->ifindex == ifindex)
159 /* Route map `match interface' match statement. `arg' is IFNAME value */
161 route_match_interface_compile (const char *arg)
163 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
166 /* Free route map's compiled `match interface' value. */
168 route_match_interface_free (void *rule)
170 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
173 /* Route map commands for interface matching */
174 struct route_map_rule_cmd route_match_interface_cmd =
177 route_match_interface,
178 route_match_interface_compile,
179 route_match_interface_free
182 DEFUN (match_interface,
184 "match interface WORD",
186 "match first hop interface of route\n"
189 return zebra_route_match_add (vty, vty->index, "interface", argv[0]);
192 DEFUN (no_match_interface,
193 no_match_interface_cmd,
194 "no match interface",
197 "Match first hop interface of route\n")
200 return zebra_route_match_delete (vty, vty->index, "interface", NULL);
202 return zebra_route_match_delete (vty, vty->index, "interface", argv[0]);
205 ALIAS (no_match_interface,
206 no_match_interface_val_cmd,
207 "no match interface WORD",
210 "Match first hop interface of route\n"
213 DEFUN (match_ip_next_hop,
214 match_ip_next_hop_cmd,
215 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
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")
223 return zebra_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
226 DEFUN (no_match_ip_next_hop,
227 no_match_ip_next_hop_cmd,
228 "no match ip next-hop",
232 "Match next-hop address of route\n")
235 return zebra_route_match_delete (vty, vty->index, "ip next-hop", NULL);
237 return zebra_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
240 ALIAS (no_match_ip_next_hop,
241 no_match_ip_next_hop_val_cmd,
242 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
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")
251 DEFUN (match_ip_next_hop_prefix_list,
252 match_ip_next_hop_prefix_list_cmd,
253 "match ip next-hop prefix-list WORD",
256 "Match next-hop address of route\n"
257 "Match entries of prefix-lists\n"
258 "IP prefix-list name\n")
260 return zebra_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
263 DEFUN (no_match_ip_next_hop_prefix_list,
264 no_match_ip_next_hop_prefix_list_cmd,
265 "no match ip next-hop prefix-list",
269 "Match next-hop address of route\n"
270 "Match entries of prefix-lists\n")
273 return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
275 return zebra_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
278 ALIAS (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",
284 "Match next-hop address of route\n"
285 "Match entries of prefix-lists\n"
286 "IP prefix-list name\n")
288 DEFUN (match_ip_address,
289 match_ip_address_cmd,
290 "match ip address (<1-199>|<1300-2699>|WORD)",
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")
299 return zebra_route_match_add (vty, vty->index, "ip address", argv[0]);
302 DEFUN (no_match_ip_address,
303 no_match_ip_address_cmd,
304 "no match ip address",
308 "Match address of route\n")
311 return zebra_route_match_delete (vty, vty->index, "ip address", NULL);
313 return zebra_route_match_delete (vty, vty->index, "ip address", argv[0]);
316 ALIAS (no_match_ip_address,
317 no_match_ip_address_val_cmd,
318 "no match ip address (<1-199>|<1300-2699>|WORD)",
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")
327 DEFUN (match_ip_address_prefix_list,
328 match_ip_address_prefix_list_cmd,
329 "match ip address prefix-list WORD",
332 "Match address of route\n"
333 "Match entries of prefix-lists\n"
334 "IP prefix-list name\n")
336 return zebra_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
339 DEFUN (no_match_ip_address_prefix_list,
340 no_match_ip_address_prefix_list_cmd,
341 "no match ip address prefix-list",
345 "Match address of route\n"
346 "Match entries of prefix-lists\n")
349 return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
351 return zebra_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
354 ALIAS (no_match_ip_address_prefix_list,
355 no_match_ip_address_prefix_list_val_cmd,
356 "no match ip address prefix-list WORD",
360 "Match address of route\n"
361 "Match entries of prefix-lists\n"
362 "IP prefix-list name\n")
370 "src address for route\n"
374 struct interface *pif = NULL;
377 if (inet_pton(AF_INET, argv[0], &src) <= 0)
379 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
383 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)
389 vty_out (vty, "%% not a local address%s", VTY_NEWLINE);
393 return zebra_route_set_add (vty, vty->index, "src", argv[0]);
401 "Source address for route\n")
404 return zebra_route_set_delete (vty, vty->index, "src", NULL);
406 return zebra_route_set_delete (vty, vty->index, "src", argv[0]);
411 "no set src (A.B.C.D)",
414 "src address for route\n"
417 /*XXXXXXXXXXXXXXXXXXXXXXXXXXXX*/
419 /* `match ip next-hop IP_ACCESS_LIST' */
421 /* Match function return 1 if match is success else return zero. */
422 static route_map_result_t
423 route_match_ip_next_hop (void *rule, struct prefix *prefix,
424 route_map_object_t type, void *object)
426 struct access_list *alist;
427 struct nexthop *nexthop;
428 struct nexthop_vrfid *nh_vrf;
429 struct prefix_ipv4 p;
431 if (type == RMAP_ZEBRA)
434 nexthop = nh_vrf->nexthop;
435 switch (nexthop->type) {
436 case NEXTHOP_TYPE_IFINDEX:
437 case NEXTHOP_TYPE_IFNAME:
438 /* Interface routes can't match ip next-hop */
440 case NEXTHOP_TYPE_IPV4_IFINDEX:
441 case NEXTHOP_TYPE_IPV4_IFNAME:
442 case NEXTHOP_TYPE_IPV4:
444 p.prefix = nexthop->gate.ipv4;
445 p.prefixlen = IPV4_MAX_BITLEN;
450 alist = access_list_lookup (AFI_IP, (char *) rule);
454 return (access_list_apply (alist, &p) == FILTER_DENY ?
455 RMAP_NOMATCH : RMAP_MATCH);
460 /* Route map `ip next-hop' match statement. `arg' should be
463 route_match_ip_next_hop_compile (const char *arg)
465 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
468 /* Free route map's compiled `. */
470 route_match_ip_next_hop_free (void *rule)
472 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
475 /* Route map commands for ip next-hop matching. */
476 static struct route_map_rule_cmd route_match_ip_next_hop_cmd =
479 route_match_ip_next_hop,
480 route_match_ip_next_hop_compile,
481 route_match_ip_next_hop_free
484 /* `match ip next-hop prefix-list PREFIX_LIST' */
486 static route_map_result_t
487 route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
488 route_map_object_t type, void *object)
490 struct prefix_list *plist;
491 struct nexthop *nexthop;
492 struct nexthop_vrfid *nh_vrf;
493 struct prefix_ipv4 p;
495 if (type == RMAP_ZEBRA)
498 nexthop = nh_vrf->nexthop;
499 switch (nexthop->type) {
500 case NEXTHOP_TYPE_IFINDEX:
501 case NEXTHOP_TYPE_IFNAME:
502 /* Interface routes can't match ip next-hop */
504 case NEXTHOP_TYPE_IPV4_IFINDEX:
505 case NEXTHOP_TYPE_IPV4_IFNAME:
506 case NEXTHOP_TYPE_IPV4:
508 p.prefix = nexthop->gate.ipv4;
509 p.prefixlen = IPV4_MAX_BITLEN;
514 plist = prefix_list_lookup (AFI_IP, (char *) rule);
518 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
519 RMAP_NOMATCH : RMAP_MATCH);
525 route_match_ip_next_hop_prefix_list_compile (const char *arg)
527 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
531 route_match_ip_next_hop_prefix_list_free (void *rule)
533 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
536 static struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
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
544 /* `match ip address IP_ACCESS_LIST' */
546 /* Match function should return 1 if match is success else return
548 static route_map_result_t
549 route_match_ip_address (void *rule, struct prefix *prefix,
550 route_map_object_t type, void *object)
552 struct access_list *alist;
554 if (type == RMAP_ZEBRA)
556 alist = access_list_lookup (AFI_IP, (char *) rule);
560 return (access_list_apply (alist, prefix) == FILTER_DENY ?
561 RMAP_NOMATCH : RMAP_MATCH);
566 /* Route map `ip address' match statement. `arg' should be
569 route_match_ip_address_compile (const char *arg)
571 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
574 /* Free route map's compiled `ip address' value. */
576 route_match_ip_address_free (void *rule)
578 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
581 /* Route map commands for ip address matching. */
582 static struct route_map_rule_cmd route_match_ip_address_cmd =
585 route_match_ip_address,
586 route_match_ip_address_compile,
587 route_match_ip_address_free
590 /* `match ip address prefix-list PREFIX_LIST' */
592 static route_map_result_t
593 route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
594 route_map_object_t type, void *object)
596 struct prefix_list *plist;
598 if (type == RMAP_ZEBRA)
600 plist = prefix_list_lookup (AFI_IP, (char *) rule);
604 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
605 RMAP_NOMATCH : RMAP_MATCH);
611 route_match_ip_address_prefix_list_compile (const char *arg)
613 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
617 route_match_ip_address_prefix_list_free (void *rule)
619 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
622 static struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
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
631 /* `set src A.B.C.D' */
634 static route_map_result_t
635 route_set_src (void *rule, struct prefix *prefix,
636 route_map_object_t type, void *object)
638 if (type == RMAP_ZEBRA)
640 struct nexthop_vrfid *nh_vrf;
643 nh_vrf->nexthop->src = *(union g_addr *)rule;
648 /* set src compilation. */
650 route_set_src_compile (const char *arg)
652 union g_addr src, *psrc;
654 if (inet_pton(AF_INET, arg, &src.ipv4) != 1
656 && inet_pton(AF_INET6, arg, &src.ipv6) != 1
657 #endif /* HAVE_IPV6 */
661 psrc = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (union g_addr));
667 /* Free route map's compiled `set src' value. */
669 route_set_src_free (void *rule)
671 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
674 /* Set src rule structure. */
675 static struct route_map_rule_cmd route_set_src_cmd =
679 route_set_src_compile,
684 zebra_route_map_init ()
687 route_map_init_vty ();
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);
695 route_map_install_set (&route_set_src_cmd);
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);
713 install_element (RMAP_NODE, &set_src_cmd);
714 install_element (RMAP_NODE, &no_set_src_cmd);