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
);
113 case RMAP_COMPILE_ERROR
:
114 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
123 ospf_route_match_add (struct vty
*vty
, struct route_map_index
*index
,
124 const char *command
, const char *arg
)
128 ret
= route_map_add_match (index
, command
, arg
);
133 case RMAP_RULE_MISSING
:
134 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
136 case RMAP_COMPILE_ERROR
:
137 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
146 ospf_route_set_add (struct vty
*vty
, struct route_map_index
*index
,
147 const char *command
, const char *arg
)
151 ret
= route_map_add_set (index
, command
, arg
);
156 case RMAP_RULE_MISSING
:
157 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
159 case RMAP_COMPILE_ERROR
:
160 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
168 /* Delete rip route map rule. */
170 ospf_route_set_delete (struct vty
*vty
, struct route_map_index
*index
,
171 const char *command
, const char *arg
)
175 ret
= route_map_delete_set (index
, command
, arg
);
180 case RMAP_RULE_MISSING
:
181 vty_out (vty
, "%% Can't find rule.%s", VTY_NEWLINE
);
183 case RMAP_COMPILE_ERROR
:
184 vty_out (vty
, "%% Argument is malformed.%s", VTY_NEWLINE
);
192 /* `match ip netxthop ' */
193 /* Match function return 1 if match is success else return zero. */
194 static route_map_result_t
195 route_match_ip_nexthop (void *rule
, struct prefix
*prefix
,
196 route_map_object_t type
, void *object
)
198 struct access_list
*alist
;
199 struct external_info
*ei
= object
;
200 struct prefix_ipv4 p
;
202 if (type
== RMAP_OSPF
)
205 p
.prefix
= ei
->nexthop
;
206 p
.prefixlen
= IPV4_MAX_BITLEN
;
208 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
212 return (access_list_apply (alist
, &p
) == FILTER_DENY
?
213 RMAP_NOMATCH
: RMAP_MATCH
);
218 /* Route map `ip next-hop' match statement. `arg' should be
221 route_match_ip_nexthop_compile (const char *arg
)
223 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
226 /* Free route map's compiled `ip address' value. */
228 route_match_ip_nexthop_free (void *rule
)
230 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
233 /* Route map commands for metric matching. */
234 struct route_map_rule_cmd route_match_ip_nexthop_cmd
=
237 route_match_ip_nexthop
,
238 route_match_ip_nexthop_compile
,
239 route_match_ip_nexthop_free
242 /* `match ip next-hop prefix-list PREFIX_LIST' */
244 static route_map_result_t
245 route_match_ip_next_hop_prefix_list (void *rule
, struct prefix
*prefix
,
246 route_map_object_t type
, void *object
)
248 struct prefix_list
*plist
;
249 struct external_info
*ei
= object
;
250 struct prefix_ipv4 p
;
252 if (type
== RMAP_OSPF
)
255 p
.prefix
= ei
->nexthop
;
256 p
.prefixlen
= IPV4_MAX_BITLEN
;
258 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
262 return (prefix_list_apply (plist
, &p
) == PREFIX_DENY
?
263 RMAP_NOMATCH
: RMAP_MATCH
);
269 route_match_ip_next_hop_prefix_list_compile (const char *arg
)
271 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
275 route_match_ip_next_hop_prefix_list_free (void *rule
)
277 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
280 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd
=
282 "ip next-hop prefix-list",
283 route_match_ip_next_hop_prefix_list
,
284 route_match_ip_next_hop_prefix_list_compile
,
285 route_match_ip_next_hop_prefix_list_free
288 /* `match ip address IP_ACCESS_LIST' */
289 /* Match function should return 1 if match is success else return
291 static route_map_result_t
292 route_match_ip_address (void *rule
, struct prefix
*prefix
,
293 route_map_object_t type
, void *object
)
295 struct access_list
*alist
;
296 /* struct prefix_ipv4 match; */
298 if (type
== RMAP_OSPF
)
300 alist
= access_list_lookup (AFI_IP
, (char *) rule
);
304 return (access_list_apply (alist
, prefix
) == FILTER_DENY
?
305 RMAP_NOMATCH
: RMAP_MATCH
);
310 /* Route map `ip address' match statement. `arg' should be
313 route_match_ip_address_compile (const char *arg
)
315 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
318 /* Free route map's compiled `ip address' value. */
320 route_match_ip_address_free (void *rule
)
322 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
325 /* Route map commands for ip address matching. */
326 struct route_map_rule_cmd route_match_ip_address_cmd
=
329 route_match_ip_address
,
330 route_match_ip_address_compile
,
331 route_match_ip_address_free
334 /* `match ip address prefix-list PREFIX_LIST' */
335 static route_map_result_t
336 route_match_ip_address_prefix_list (void *rule
, struct prefix
*prefix
,
337 route_map_object_t type
, void *object
)
339 struct prefix_list
*plist
;
341 if (type
== RMAP_OSPF
)
343 plist
= prefix_list_lookup (AFI_IP
, (char *) rule
);
347 return (prefix_list_apply (plist
, prefix
) == PREFIX_DENY
?
348 RMAP_NOMATCH
: RMAP_MATCH
);
354 route_match_ip_address_prefix_list_compile (const char *arg
)
356 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
360 route_match_ip_address_prefix_list_free (void *rule
)
362 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
365 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd
=
367 "ip address prefix-list",
368 route_match_ip_address_prefix_list
,
369 route_match_ip_address_prefix_list_compile
,
370 route_match_ip_address_prefix_list_free
373 /* `match interface IFNAME' */
374 /* Match function should return 1 if match is success else return
376 static route_map_result_t
377 route_match_interface (void *rule
, struct prefix
*prefix
,
378 route_map_object_t type
, void *object
)
380 struct interface
*ifp
;
381 struct external_info
*ei
;
383 if (type
== RMAP_OSPF
)
386 ifp
= if_lookup_by_name ((char *)rule
);
388 if (ifp
== NULL
|| ifp
->ifindex
!= ei
->ifindex
)
396 /* Route map `interface' match statement. `arg' should be
399 route_match_interface_compile (const char *arg
)
401 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED
, arg
);
404 /* Free route map's compiled `interface' value. */
406 route_match_interface_free (void *rule
)
408 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
411 /* Route map commands for ip address matching. */
412 struct route_map_rule_cmd route_match_interface_cmd
=
415 route_match_interface
,
416 route_match_interface_compile
,
417 route_match_interface_free
420 /* `set metric METRIC' */
421 /* Set metric to attribute. */
422 static route_map_result_t
423 route_set_metric (void *rule
, struct prefix
*prefix
,
424 route_map_object_t type
, void *object
)
427 struct external_info
*ei
;
429 if (type
== RMAP_OSPF
)
431 /* Fetch routemap's rule information. */
435 /* Set metric out value. */
436 ei
->route_map_set
.metric
= *metric
;
441 /* set metric compilation. */
443 route_set_metric_compile (const char *arg
)
447 metric
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
448 *metric
= atoi (arg
);
453 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric
);
457 /* Free route map's compiled `set metric' value. */
459 route_set_metric_free (void *rule
)
461 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
464 /* Set metric rule structure. */
465 struct route_map_rule_cmd route_set_metric_cmd
=
469 route_set_metric_compile
,
470 route_set_metric_free
,
473 /* `set metric-type TYPE' */
474 /* Set metric-type to attribute. */
475 static route_map_result_t
476 route_set_metric_type (void *rule
, struct prefix
*prefix
,
477 route_map_object_t type
, void *object
)
479 u_int32_t
*metric_type
;
480 struct external_info
*ei
;
482 if (type
== RMAP_OSPF
)
484 /* Fetch routemap's rule information. */
488 /* Set metric out value. */
489 ei
->route_map_set
.metric_type
= *metric_type
;
494 /* set metric-type compilation. */
496 route_set_metric_type_compile (const char *arg
)
498 u_int32_t
*metric_type
;
500 metric_type
= XCALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_int32_t
));
501 if (strcmp (arg
, "type-1") == 0)
502 *metric_type
= EXTERNAL_METRIC_TYPE_1
;
503 else if (strcmp (arg
, "type-2") == 0)
504 *metric_type
= EXTERNAL_METRIC_TYPE_2
;
506 if (*metric_type
== EXTERNAL_METRIC_TYPE_1
||
507 *metric_type
== EXTERNAL_METRIC_TYPE_2
)
510 XFREE (MTYPE_ROUTE_MAP_COMPILED
, metric_type
);
514 /* Free route map's compiled `set metric-type' value. */
516 route_set_metric_type_free (void *rule
)
518 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
521 /* Set metric rule structure. */
522 struct route_map_rule_cmd route_set_metric_type_cmd
=
525 route_set_metric_type
,
526 route_set_metric_type_compile
,
527 route_set_metric_type_free
,
530 DEFUN (match_ip_nexthop
,
531 match_ip_nexthop_cmd
,
532 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
535 "Match next-hop address of route\n"
536 "IP access-list number\n"
537 "IP access-list number (expanded range)\n"
538 "IP access-list name\n")
540 return ospf_route_match_add (vty
, vty
->index
, "ip next-hop", argv
[0]);
543 DEFUN (no_match_ip_nexthop
,
544 no_match_ip_nexthop_cmd
,
545 "no match ip next-hop",
549 "Match next-hop address of route\n")
552 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop", NULL
);
554 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop", argv
[0]);
557 ALIAS (no_match_ip_nexthop
,
558 no_match_ip_nexthop_val_cmd
,
559 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
563 "Match next-hop address of route\n"
564 "IP access-list number\n"
565 "IP access-list number (expanded range)\n"
566 "IP access-list name\n")
568 DEFUN (match_ip_next_hop_prefix_list
,
569 match_ip_next_hop_prefix_list_cmd
,
570 "match ip next-hop prefix-list WORD",
573 "Match next-hop address of route\n"
574 "Match entries of prefix-lists\n"
575 "IP prefix-list name\n")
577 return ospf_route_match_add (vty
, vty
->index
, "ip next-hop prefix-list",
581 DEFUN (no_match_ip_next_hop_prefix_list
,
582 no_match_ip_next_hop_prefix_list_cmd
,
583 "no match ip next-hop prefix-list",
587 "Match next-hop address of route\n"
588 "Match entries of prefix-lists\n")
591 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list",
593 return ospf_route_match_delete (vty
, vty
->index
, "ip next-hop prefix-list",
597 ALIAS (no_match_ip_next_hop_prefix_list
,
598 no_match_ip_next_hop_prefix_list_val_cmd
,
599 "no match ip next-hop prefix-list WORD",
603 "Match next-hop address of route\n"
604 "Match entries of prefix-lists\n"
605 "IP prefix-list name\n")
607 DEFUN (match_ip_address
,
608 match_ip_address_cmd
,
609 "match ip address (<1-199>|<1300-2699>|WORD)",
612 "Match address of route\n"
613 "IP access-list number\n"
614 "IP access-list number (expanded range)\n"
615 "IP access-list name\n")
617 return ospf_route_match_add (vty
, vty
->index
, "ip address", argv
[0]);
620 DEFUN (no_match_ip_address
,
621 no_match_ip_address_cmd
,
622 "no match ip address",
626 "Match address of route\n")
629 return ospf_route_match_delete (vty
, vty
->index
, "ip address", NULL
);
631 return ospf_route_match_delete (vty
, vty
->index
, "ip address", argv
[0]);
634 ALIAS (no_match_ip_address
,
635 no_match_ip_address_val_cmd
,
636 "no match ip address (<1-199>|<1300-2699>|WORD)",
640 "Match address of route\n"
641 "IP access-list number\n"
642 "IP access-list number (expanded range)\n"
643 "IP access-list name\n")
645 DEFUN (match_ip_address_prefix_list
,
646 match_ip_address_prefix_list_cmd
,
647 "match ip address prefix-list WORD",
650 "Match address of route\n"
651 "Match entries of prefix-lists\n"
652 "IP prefix-list name\n")
654 return ospf_route_match_add (vty
, vty
->index
, "ip address prefix-list",
658 DEFUN (no_match_ip_address_prefix_list
,
659 no_match_ip_address_prefix_list_cmd
,
660 "no match ip address prefix-list",
664 "Match address of route\n"
665 "Match entries of prefix-lists\n")
668 return ospf_route_match_delete (vty
, vty
->index
, "ip address prefix-list",
670 return ospf_route_match_delete (vty
, vty
->index
, "ip address prefix-list",
674 ALIAS (no_match_ip_address_prefix_list
,
675 no_match_ip_address_prefix_list_val_cmd
,
676 "no match ip address prefix-list WORD",
680 "Match address of route\n"
681 "Match entries of prefix-lists\n"
682 "IP prefix-list name\n")
684 DEFUN (match_interface
,
686 "match interface WORD",
688 "Match first hop interface of route\n"
691 return ospf_route_match_add (vty
, vty
->index
, "interface", argv
[0]);
694 DEFUN (no_match_interface
,
695 no_match_interface_cmd
,
696 "no match interface",
699 "Match first hop interface of route\n")
702 return ospf_route_match_delete (vty
, vty
->index
, "interface", NULL
);
704 return ospf_route_match_delete (vty
, vty
->index
, "interface", argv
[0]);
707 ALIAS (no_match_interface
,
708 no_match_interface_val_cmd
,
709 "no match interface WORD",
712 "Match first hop interface of route\n"
717 "set metric <0-4294967295>",
719 "Metric value for destination routing protocol\n"
722 return ospf_route_set_add (vty
, vty
->index
, "metric", argv
[0]);
725 DEFUN (no_set_metric
,
730 "Metric value for destination routing protocol\n")
733 return ospf_route_set_delete (vty
, vty
->index
, "metric", NULL
);
735 return ospf_route_set_delete (vty
, vty
->index
, "metric", argv
[0]);
738 ALIAS (no_set_metric
,
739 no_set_metric_val_cmd
,
740 "no set metric <0-4294967295>",
743 "Metric value for destination routing protocol\n"
746 DEFUN (set_metric_type
,
748 "set metric-type (type-1|type-2)",
750 "Type of metric for destination routing protocol\n"
751 "OSPF[6] external type 1 metric\n"
752 "OSPF[6] external type 2 metric\n")
754 if (strcmp (argv
[0], "1") == 0)
755 return ospf_route_set_add (vty
, vty
->index
, "metric-type", "type-1");
756 if (strcmp (argv
[0], "2") == 0)
757 return ospf_route_set_add (vty
, vty
->index
, "metric-type", "type-2");
759 return ospf_route_set_add (vty
, vty
->index
, "metric-type", argv
[0]);
762 DEFUN (no_set_metric_type
,
763 no_set_metric_type_cmd
,
764 "no set metric-type",
767 "Type of metric for destination routing protocol\n")
770 return ospf_route_set_delete (vty
, vty
->index
, "metric-type", NULL
);
772 return ospf_route_set_delete (vty
, vty
->index
, "metric-type", argv
[0]);
775 ALIAS (no_set_metric_type
,
776 no_set_metric_type_val_cmd
,
777 "no set metric-type (type-1|type-2)",
780 "Type of metric for destination routing protocol\n"
781 "OSPF[6] external type 1 metric\n"
782 "OSPF[6] external type 2 metric\n")
786 ospf_route_map_init (void)
789 route_map_init_vty ();
791 route_map_add_hook (ospf_route_map_update
);
792 route_map_delete_hook (ospf_route_map_update
);
793 route_map_event_hook (ospf_route_map_event
);
795 route_map_install_match (&route_match_ip_nexthop_cmd
);
796 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd
);
797 route_map_install_match (&route_match_ip_address_cmd
);
798 route_map_install_match (&route_match_ip_address_prefix_list_cmd
);
799 route_map_install_match (&route_match_interface_cmd
);
801 route_map_install_set (&route_set_metric_cmd
);
802 route_map_install_set (&route_set_metric_type_cmd
);
804 install_element (RMAP_NODE
, &match_ip_nexthop_cmd
);
805 install_element (RMAP_NODE
, &no_match_ip_nexthop_cmd
);
806 install_element (RMAP_NODE
, &no_match_ip_nexthop_val_cmd
);
807 install_element (RMAP_NODE
, &match_ip_next_hop_prefix_list_cmd
);
808 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_cmd
);
809 install_element (RMAP_NODE
, &no_match_ip_next_hop_prefix_list_val_cmd
);
810 install_element (RMAP_NODE
, &match_ip_address_cmd
);
811 install_element (RMAP_NODE
, &no_match_ip_address_cmd
);
812 install_element (RMAP_NODE
, &no_match_ip_address_val_cmd
);
813 install_element (RMAP_NODE
, &match_ip_address_prefix_list_cmd
);
814 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_cmd
);
815 install_element (RMAP_NODE
, &no_match_ip_address_prefix_list_val_cmd
);
816 install_element (RMAP_NODE
, &match_interface_cmd
);
817 install_element (RMAP_NODE
, &no_match_interface_cmd
);
818 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
820 install_element (RMAP_NODE
, &set_metric_cmd
);
821 install_element (RMAP_NODE
, &no_set_metric_cmd
);
822 install_element (RMAP_NODE
, &no_set_metric_val_cmd
);
823 install_element (RMAP_NODE
, &set_metric_type_cmd
);
824 install_element (RMAP_NODE
, &no_set_metric_type_cmd
);
825 install_element (RMAP_NODE
, &no_set_metric_type_val_cmd
);