2 * Route map function of ospfd.
3 * Copyright (C) 2000 IP Infusion Inc.
5 * Written by Toshiaki Takada.
7 * This file is part of GNU Zebra.
9 * GNU Zebra is free software; you can redistribute it and/or modify it
10 * under the terms of the GNU General Public License as published by the
11 * Free Software Foundation; either version 2, or (at your option) any
14 * GNU Zebra is distributed in the hope that it will be useful, but
15 * WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
17 * General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with GNU Zebra; see the file COPYING. If not, write to the Free
21 * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
35 #include "ospfd/ospfd.h"
36 #include "ospfd/ospf_asbr.h"
37 #include "ospfd/ospf_interface.h"
38 #include "ospfd/ospf_lsa.h"
39 #include "ospfd/ospf_route.h"
40 #include "ospfd/ospf_zebra.h"
42 /* Hook function for updating route_map assignment. */
44 ospf_route_map_update (const char *name
)
49 /* If OSPF instatnce does not exist, return right now. */
50 ospf
= ospf_lookup ();
54 /* Update route-map */
55 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++)
57 if (ROUTEMAP_NAME (ospf
, type
)
58 && strcmp (ROUTEMAP_NAME (ospf
, type
), name
) == 0)
60 /* Keep old route-map. */
61 struct route_map
*old
= ROUTEMAP (ospf
, type
);
63 /* Update route-map. */
64 ROUTEMAP (ospf
, type
) =
65 route_map_lookup_by_name (ROUTEMAP_NAME (ospf
, type
));
67 /* No update for this distribute type. */
68 if (old
== NULL
&& ROUTEMAP (ospf
, type
) == NULL
)
71 ospf_distribute_list_update (ospf
, type
);
77 ospf_route_map_event (route_map_event_t event
, const char *name
)
82 /* If OSPF instatnce does not exist, return right now. */
83 ospf
= ospf_lookup ();
87 /* Update route-map. */
88 for (type
= 0; type
<= ZEBRA_ROUTE_MAX
; type
++)
90 if (ROUTEMAP_NAME (ospf
, type
) && ROUTEMAP (ospf
, type
)
91 && !strcmp (ROUTEMAP_NAME (ospf
, type
), name
))
93 ospf_distribute_list_update (ospf
, type
);
98 /* Delete rip route map rule. */
100 ospf_route_match_delete (struct vty
*vty
, struct route_map_index
*index
,
101 const char *command
, const char *arg
)
105 ret
= route_map_delete_match (index
, command
, arg
);
110 case RMAP_RULE_MISSING
:
111 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
114 case RMAP_COMPILE_ERROR
:
115 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
125 ospf_route_match_add (struct vty
*vty
, struct route_map_index
*index
,
126 const char *command
, const char *arg
)
130 ret
= route_map_add_match (index
, command
, arg
);
135 case RMAP_RULE_MISSING
:
136 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
139 case RMAP_COMPILE_ERROR
:
140 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
150 ospf_route_set_add (struct vty
*vty
, struct route_map_index
*index
,
151 const char *command
, const char *arg
)
155 ret
= route_map_add_set (index
, command
, arg
);
160 case RMAP_RULE_MISSING
:
161 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
164 case RMAP_COMPILE_ERROR
:
165 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
174 /* Delete rip route map rule. */
176 ospf_route_set_delete (struct vty
*vty
, struct route_map_index
*index
,
177 const char *command
, const char *arg
)
181 ret
= route_map_delete_set (index
, command
, arg
);
186 case RMAP_RULE_MISSING
:
187 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
190 case RMAP_COMPILE_ERROR
:
191 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
200 /* `match ip netxthop ' */
201 /* Match function return 1 if match is success else return zero. */
203 route_match_ip_nexthop (void *rule
, struct prefix
*prefix
,
204 route_map_object_t type
, void *object
)
206 struct access_list
*alist
;
207 struct external_info
*ei
= object
;
208 struct prefix_ipv4 p
;
210 if (type
== RMAP_OSPF
)
213 p
.prefix
= ei
->nexthop
;
214 p
.prefixlen
= IPV4_MAX_BITLEN
;
216 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
220 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
221 RMAP_NOMATCH
: RMAP_MATCH
);
226 /* Route map `ip next-hop' match statement. `arg' should be
229 route_match_ip_nexthop_compile (const char *arg
)
231 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
234 /* Free route map's compiled `ip address' value. */
236 route_match_ip_nexthop_free (void *rule
)
238 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
241 /* Route map commands for metric matching. */
242 struct route_map_rule_cmd route_match_ip_nexthop_cmd
=
245 route_match_ip_nexthop
,
246 route_match_ip_nexthop_compile
,
247 route_match_ip_nexthop_free
250 /* `match ip next-hop prefix-list PREFIX_LIST' */
253 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
254 route_map_object_t type
, void *object
)
256 struct prefix_list
*plist
;
257 struct external_info
*ei
= object
;
258 struct prefix_ipv4 p
;
260 if (type
== RMAP_OSPF
)
263 p
.prefix
= ei
->nexthop
;
264 p
.prefixlen
= IPV4_MAX_BITLEN
;
266 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
270 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
271 RMAP_NOMATCH
: RMAP_MATCH
);
277 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
279 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
283 route_match_ip_next_hop_prefix_list_free (void *rule
)
285 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
288 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
290 "ip next-hop prefix-list",
291 route_match_ip_next_hop_prefix_list
,
292 route_match_ip_next_hop_prefix_list_compile
,
293 route_match_ip_next_hop_prefix_list_free
296 /* `match ip address IP_ACCESS_LIST' */
297 /* Match function should return 1 if match is success else return
300 route_match_ip_address (void *rule
, struct prefix
*prefix
,
301 route_map_object_t type
, void *object
)
303 struct access_list
*alist
;
304 /* struct prefix_ipv4 match; */
306 if (type
== RMAP_OSPF
)
308 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
312 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
313 RMAP_NOMATCH
: RMAP_MATCH
);
318 /* Route map `ip address' match statement. `arg' should be
321 route_match_ip_address_compile (const char *arg
)
323 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
326 /* Free route map's compiled `ip address' value. */
328 route_match_ip_address_free (void *rule
)
330 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
333 /* Route map commands for ip address matching. */
334 struct route_map_rule_cmd route_match_ip_address_cmd
=
337 route_match_ip_address
,
338 route_match_ip_address_compile
,
339 route_match_ip_address_free
342 /* `match ip address prefix-list PREFIX_LIST' */
344 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
345 route_map_object_t type
, void *object
)
347 struct prefix_list
*plist
;
349 if (type
== RMAP_OSPF
)
351 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
355 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
356 RMAP_NOMATCH
: RMAP_MATCH
);
362 route_match_ip_address_prefix_list_compile (const char *arg
)
364 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
368 route_match_ip_address_prefix_list_free (void *rule
)
370 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
373 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
375 "ip address prefix-list",
376 route_match_ip_address_prefix_list
,
377 route_match_ip_address_prefix_list_compile
,
378 route_match_ip_address_prefix_list_free
381 /* `match interface IFNAME' */
382 /* Match function should return 1 if match is success else return
385 route_match_interface (void *rule
, struct prefix
*prefix
,
386 route_map_object_t type
, void *object
)
388 struct interface
*ifp
;
389 struct external_info
*ei
;
391 if (type
== RMAP_OSPF
)
394 ifp
= if_lookup_by_name ((char *)rule
);
396 if (ifp
== NULL
|| ifp
->ifindex
!= ei
->ifindex
)
404 /* Route map `interface' match statement. `arg' should be
407 route_match_interface_compile (const char *arg
)
409 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
412 /* Free route map's compiled `interface' value. */
414 route_match_interface_free (void *rule
)
416 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
419 /* Route map commands for ip address matching. */
420 struct route_map_rule_cmd route_match_interface_cmd
=
423 route_match_interface
,
424 route_match_interface_compile
,
425 route_match_interface_free
428 /* `set metric METRIC' */
429 /* Set metric to attribute. */
431 route_set_metric (void *rule
, struct prefix
*prefix
,
432 route_map_object_t type
, void *object
)
435 struct external_info
*ei
;
437 if (type
== RMAP_OSPF
)
439 /* Fetch routemap's rule information. */
443 /* Set metric out value. */
444 ei
->route_map_set
.metric
= *metric
;
449 /* set metric compilation. */
451 route_set_metric_compile (const char *arg
)
455 metric
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
456 *metric
= atoi (arg
);
461 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric
);
465 /* Free route map's compiled `set metric' value. */
467 route_set_metric_free (void *rule
)
469 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
472 /* Set metric rule structure. */
473 struct route_map_rule_cmd route_set_metric_cmd
=
477 route_set_metric_compile
,
478 route_set_metric_free
,
481 /* `set metric-type TYPE' */
482 /* Set metric-type to attribute. */
484 route_set_metric_type (void *rule
, struct prefix
*prefix
,
485 route_map_object_t type
, void *object
)
487 u_int32_t
*metric_type
;
488 struct external_info
*ei
;
490 if (type
== RMAP_OSPF
)
492 /* Fetch routemap's rule information. */
496 /* Set metric out value. */
497 ei
->route_map_set
.metric_type
= *metric_type
;
502 /* set metric-type compilation. */
504 route_set_metric_type_compile (const char *arg
)
506 u_int32_t
*metric_type
;
508 metric_type
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
509 if (strcmp (arg
, "type-1") == 0)
510 *metric_type
= EXTERNAL_METRIC_TYPE_1
;
511 else if (strcmp (arg
, "type-2") == 0)
512 *metric_type
= EXTERNAL_METRIC_TYPE_2
;
514 if (*metric_type
== EXTERNAL_METRIC_TYPE_1
||
515 *metric_type
== EXTERNAL_METRIC_TYPE_2
)
518 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric_type
);
522 /* Free route map's compiled `set metric-type' value. */
524 route_set_metric_type_free (void *rule
)
526 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
529 /* Set metric rule structure. */
530 struct route_map_rule_cmd route_set_metric_type_cmd
=
533 route_set_metric_type
,
534 route_set_metric_type_compile
,
535 route_set_metric_type_free
,
538 DEFUN (match_ip_nexthop
,
539 match_ip_nexthop_cmd
,
540 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
543 "Match next-hop address of route\n"
544 "IP access-list number\n"
545 "IP access-list number (expanded range)\n"
546 "IP access-list name\n")
548 return ospf_route_match_add (vty
, vty
->index
, "ip next-hop", argv
[0]);
551 DEFUN (no_match_ip_nexthop
,
552 no_match_ip_nexthop_cmd
,
553 "no match ip next-hop",
557 "Match next-hop address of route\n")
560 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop", NULL
);
562 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop", argv
[0]);
565 ALIAS (no_match_ip_nexthop
,
566 no_match_ip_nexthop_val_cmd
,
567 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
571 "Match next-hop address of route\n"
572 "IP access-list number\n"
573 "IP access-list number (expanded range)\n"
574 "IP access-list name\n")
576 DEFUN (match_ip_next_hop_prefix_list
,
577 match_ip_next_hop_prefix_list_cmd
,
578 "match ip next-hop prefix-list WORD",
581 "Match next-hop address of route\n"
582 "Match entries of prefix-lists\n"
583 "IP prefix-list name\n")
585 return ospf_route_match_add (vty
, vty
->index
, "ip next-hop prefix-list",
589 DEFUN (no_match_ip_next_hop_prefix_list
,
590 no_match_ip_next_hop_prefix_list_cmd
,
591 "no match ip next-hop prefix-list",
595 "Match next-hop address of route\n"
596 "Match entries of prefix-lists\n")
599 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list",
601 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list",
605 ALIAS (no_match_ip_next_hop_prefix_list
,
606 no_match_ip_next_hop_prefix_list_val_cmd
,
607 "no match ip next-hop prefix-list WORD",
611 "Match next-hop address of route\n"
612 "Match entries of prefix-lists\n"
613 "IP prefix-list name\n")
615 DEFUN (match_ip_address
,
616 match_ip_address_cmd
,
617 "match ip address (<1-199>|<1300-2699>|WORD)",
620 "Match address of route\n"
621 "IP access-list number\n"
622 "IP access-list number (expanded range)\n"
623 "IP access-list name\n")
625 return ospf_route_match_add (vty
, vty
->index
, "ip address", argv
[0]);
628 DEFUN (no_match_ip_address
,
629 no_match_ip_address_cmd
,
630 "no match ip address",
634 "Match address of route\n")
637 return ospf_route_match_delete (vty
, vty
->index
, "ip address", NULL
);
639 return ospf_route_match_delete (vty
, vty
->index
, "ip address", argv
[0]);
642 ALIAS (no_match_ip_address
,
643 no_match_ip_address_val_cmd
,
644 "no match ip address (<1-199>|<1300-2699>|WORD)",
648 "Match address of route\n"
649 "IP access-list number\n"
650 "IP access-list number (expanded range)\n"
651 "IP access-list name\n")
653 DEFUN (match_ip_address_prefix_list
,
654 match_ip_address_prefix_list_cmd
,
655 "match ip address prefix-list WORD",
658 "Match address of route\n"
659 "Match entries of prefix-lists\n"
660 "IP prefix-list name\n")
662 return ospf_route_match_add (vty
, vty
->index
, "ip address prefix-list",
666 DEFUN (no_match_ip_address_prefix_list
,
667 no_match_ip_address_prefix_list_cmd
,
668 "no match ip address prefix-list",
672 "Match address of route\n"
673 "Match entries of prefix-lists\n")
676 return ospf_route_match_delete (vty
, vty
->index
, "ip address prefix-list",
678 return ospf_route_match_delete (vty
, vty
->index
, "ip address prefix-list",
682 ALIAS (no_match_ip_address_prefix_list
,
683 no_match_ip_address_prefix_list_val_cmd
,
684 "no match ip address prefix-list WORD",
688 "Match address of route\n"
689 "Match entries of prefix-lists\n"
690 "IP prefix-list name\n")
692 DEFUN (match_interface
,
694 "match interface WORD",
696 "Match first hop interface of route\n"
699 return ospf_route_match_add (vty
, vty
->index
, "interface", argv
[0]);
702 DEFUN (no_match_interface
,
703 no_match_interface_cmd
,
704 "no match interface",
707 "Match first hop interface of route\n")
710 return ospf_route_match_delete (vty
, vty
->index
, "interface", NULL
);
712 return ospf_route_match_delete (vty
, vty
->index
, "interface", argv
[0]);
715 ALIAS (no_match_interface
,
716 no_match_interface_val_cmd
,
717 "no match interface WORD",
720 "Match first hop interface of route\n"
725 "set metric <0-4294967295>",
727 "Metric value for destination routing protocol\n"
730 return ospf_route_set_add (vty
, vty
->index
, "metric", argv
[0]);
733 DEFUN (no_set_metric
,
738 "Metric value for destination routing protocol\n")
741 return ospf_route_set_delete (vty
, vty
->index
, "metric", NULL
);
743 return ospf_route_set_delete (vty
, vty
->index
, "metric", argv
[0]);
746 ALIAS (no_set_metric
,
747 no_set_metric_val_cmd
,
748 "no set metric <0-4294967295>",
751 "Metric value for destination routing protocol\n"
754 DEFUN (set_metric_type
,
756 "set metric-type (type-1|type-2)",
758 "Type of metric for destination routing protocol\n"
759 "OSPF[6] external type 1 metric\n"
760 "OSPF[6] external type 2 metric\n")
762 if (strcmp (argv
[0], "1") == 0)
763 return ospf_route_set_add (vty
, vty
->index
, "metric-type",
765 if (strcmp (argv
[0], "2") == 0)
766 return ospf_route_set_add (vty
, vty
->index
, "metric-type",
769 return ospf_route_set_add (vty
, vty
->index
, "metric-type", argv
[0]);
772 DEFUN (no_set_metric_type
,
773 no_set_metric_type_cmd
,
774 "no set metric-type",
777 "Type of metric for destination routing protocol\n")
780 return ospf_route_set_delete (vty
, vty
->index
, "metric-type", NULL
);
782 return ospf_route_set_delete (vty
, vty
->index
, "metric-type", argv
[0]);
785 ALIAS (no_set_metric_type
,
786 no_set_metric_type_val_cmd
,
787 "no set metric-type (type-1|type-2)",
790 "Type of metric for destination routing protocol\n"
791 "OSPF[6] external type 1 metric\n"
792 "OSPF[6] external type 2 metric\n")
796 ospf_route_map_init (void)
799 route_map_init_vty ();
801 route_map_add_hook (ospf_route_map_update
);
802 route_map_delete_hook (ospf_route_map_update
);
803 route_map_event_hook (ospf_route_map_event
);
805 route_map_install_match (&route_match_ip_nexthop_cmd
);
806 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
807 route_map_install_match (&route_match_ip_address_cmd
);
808 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
809 route_map_install_match (&route_match_interface_cmd
);
811 route_map_install_set (&route_set_metric_cmd
);
812 route_map_install_set (&route_set_metric_type_cmd
);
814 install_element (RMAP_NODE
, &match_ip_nexthop_cmd
);
815 install_element (RMAP_NODE
, &no_match_ip_nexthop_cmd
);
816 install_element (RMAP_NODE
, &no_match_ip_nexthop_val_cmd
);
817 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
818 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
819 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_val_cmd
);
820 install_element (RMAP_NODE
, &match_ip_address_cmd
);
821 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
822 install_element (RMAP_NODE
, &no_match_ip_address_val_cmd
);
823 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
824 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
825 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_val_cmd
);
826 install_element (RMAP_NODE
, &match_interface_cmd
);
827 install_element (RMAP_NODE
, &no_match_interface_cmd
);
828 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
830 install_element (RMAP_NODE
, &set_metric_cmd
);
831 install_element (RMAP_NODE
, &no_set_metric_cmd
);
832 install_element (RMAP_NODE
, &no_set_metric_val_cmd
);
833 install_element (RMAP_NODE
, &set_metric_type_cmd
);
834 install_element (RMAP_NODE
, &no_set_metric_type_cmd
);
835 install_element (RMAP_NODE
, &no_set_metric_type_val_cmd
);