]> git.proxmox.com Git - mirror_frr.git/blob - ospfd/ospf_routemap.c
Merge branch 'cmaster' of ssh://stash.cumulusnetworks.com:7999/quag/quagga into cmaster
[mirror_frr.git] / ospfd / ospf_routemap.c
1 /*
2 * Route map function of ospfd.
3 * Copyright (C) 2000 IP Infusion Inc.
4 *
5 * Written by Toshiaki Takada.
6 *
7 * This file is part of GNU Zebra.
8 *
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
12 * later version.
13 *
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.
18 *
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
22 * 02111-1307, USA.
23 */
24
25 #include <zebra.h>
26
27 #include "memory.h"
28 #include "prefix.h"
29 #include "table.h"
30 #include "routemap.h"
31 #include "command.h"
32 #include "log.h"
33 #include "plist.h"
34
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"
41
42 /* Hook function for updating route_map assignment. */
43 static void
44 ospf_route_map_update (const char *name)
45 {
46 struct ospf *ospf;
47 int type;
48
49 /* If OSPF instatnce does not exist, return right now. */
50 ospf = ospf_lookup ();
51 if (ospf == NULL)
52 return;
53
54 /* Update route-map */
55 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
56 {
57 struct list *red_list;
58 struct listnode *node;
59 struct ospf_redist *red;
60
61 red_list = ospf->redist[type];
62 if (!red_list)
63 continue;
64
65 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
66 {
67 if (ROUTEMAP_NAME (red)
68 && strcmp (ROUTEMAP_NAME (red), name) == 0)
69 {
70 /* Keep old route-map. */
71 struct route_map *old = ROUTEMAP (red);
72
73 /* Update route-map. */
74 ROUTEMAP (red) =
75 route_map_lookup_by_name (ROUTEMAP_NAME (red));
76
77 /* No update for this distribute type. */
78 if (old == NULL && ROUTEMAP (red) == NULL)
79 continue;
80
81 ospf_distribute_list_update (ospf, type, red->instance);
82 }
83 }
84 }
85 }
86
87 static void
88 ospf_route_map_event (route_map_event_t event, const char *name)
89 {
90 struct ospf *ospf;
91 int type;
92
93 /* If OSPF instatnce does not exist, return right now. */
94 ospf = ospf_lookup ();
95 if (ospf == NULL)
96 return;
97
98 for (type = 0; type <= ZEBRA_ROUTE_MAX; type++)
99 {
100 struct list *red_list;
101 struct listnode *node;
102 struct ospf_redist *red;
103
104 red_list = ospf->redist[type];
105 if (!red_list)
106 continue;
107
108 for (ALL_LIST_ELEMENTS_RO(red_list, node, red))
109 {
110 if (ROUTEMAP_NAME (red) && ROUTEMAP (red)
111 && !strcmp (ROUTEMAP_NAME (red), name))
112 {
113 ospf_distribute_list_update (ospf, type, red->instance);
114 }
115 }
116 }
117 }
118
119 /* Delete rip route map rule. */
120 static int
121 ospf_route_match_delete (struct vty *vty, struct route_map_index *index,
122 const char *command, const char *arg)
123 {
124 int ret;
125
126 ret = route_map_delete_match (index, command, arg);
127 if (ret)
128 {
129 switch (ret)
130 {
131 case RMAP_RULE_MISSING:
132 vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE);
133 return CMD_WARNING;
134 case RMAP_COMPILE_ERROR:
135 vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE);
136 return CMD_WARNING;
137 }
138 }
139
140 return CMD_SUCCESS;
141 }
142
143 static int
144 ospf_route_match_add (struct vty *vty, struct route_map_index *index,
145 const char *command, const char *arg)
146 {
147 int ret;
148
149 ret = route_map_add_match (index, command, arg);
150 if (ret)
151 {
152 switch (ret)
153 {
154 case RMAP_RULE_MISSING:
155 vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE);
156 return CMD_WARNING;
157 case RMAP_COMPILE_ERROR:
158 vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE);
159 return CMD_WARNING;
160 }
161 }
162
163 return CMD_SUCCESS;
164 }
165
166 static int
167 ospf_route_set_add (struct vty *vty, struct route_map_index *index,
168 const char *command, const char *arg)
169 {
170 int ret;
171
172 ret = route_map_add_set (index, command, arg);
173 if (ret)
174 {
175 switch (ret)
176 {
177 case RMAP_RULE_MISSING:
178 vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE);
179 return CMD_WARNING;
180 case RMAP_COMPILE_ERROR:
181 vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE);
182 return CMD_WARNING;
183 }
184 }
185
186 return CMD_SUCCESS;
187 }
188
189 /* Delete rip route map rule. */
190 static int
191 ospf_route_set_delete (struct vty *vty, struct route_map_index *index,
192 const char *command, const char *arg)
193 {
194 int ret;
195
196 ret = route_map_delete_set (index, command, arg);
197 if (ret)
198 {
199 switch (ret)
200 {
201 case RMAP_RULE_MISSING:
202 vty_out (vty, "%% OSPF Can't find rule.%s", VTY_NEWLINE);
203 return CMD_WARNING;
204 case RMAP_COMPILE_ERROR:
205 vty_out (vty, "%% OSPF Argument is malformed.%s", VTY_NEWLINE);
206 return CMD_WARNING;
207 }
208 }
209
210 return CMD_SUCCESS;
211 }
212
213 /* `match ip netxthop ' */
214 /* Match function return 1 if match is success else return zero. */
215 static route_map_result_t
216 route_match_ip_nexthop (void *rule, struct prefix *prefix,
217 route_map_object_t type, void *object)
218 {
219 struct access_list *alist;
220 struct external_info *ei = object;
221 struct prefix_ipv4 p;
222
223 if (type == RMAP_OSPF)
224 {
225 p.family = AF_INET;
226 p.prefix = ei->nexthop;
227 p.prefixlen = IPV4_MAX_BITLEN;
228
229 alist = access_list_lookup (AFI_IP, (char *) rule);
230 if (alist == NULL)
231 return RMAP_NOMATCH;
232
233 return (access_list_apply (alist, &p) == FILTER_DENY ?
234 RMAP_NOMATCH : RMAP_MATCH);
235 }
236 return RMAP_NOMATCH;
237 }
238
239 /* Route map `ip next-hop' match statement. `arg' should be
240 access-list name. */
241 static void *
242 route_match_ip_nexthop_compile (const char *arg)
243 {
244 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
245 }
246
247 /* Free route map's compiled `ip address' value. */
248 static void
249 route_match_ip_nexthop_free (void *rule)
250 {
251 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
252 }
253
254 /* Route map commands for metric matching. */
255 struct route_map_rule_cmd route_match_ip_nexthop_cmd =
256 {
257 "ip next-hop",
258 route_match_ip_nexthop,
259 route_match_ip_nexthop_compile,
260 route_match_ip_nexthop_free
261 };
262
263 /* `match ip next-hop prefix-list PREFIX_LIST' */
264
265 static route_map_result_t
266 route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
267 route_map_object_t type, void *object)
268 {
269 struct prefix_list *plist;
270 struct external_info *ei = object;
271 struct prefix_ipv4 p;
272
273 if (type == RMAP_OSPF)
274 {
275 p.family = AF_INET;
276 p.prefix = ei->nexthop;
277 p.prefixlen = IPV4_MAX_BITLEN;
278
279 plist = prefix_list_lookup (AFI_IP, (char *) rule);
280 if (plist == NULL)
281 return RMAP_NOMATCH;
282
283 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
284 RMAP_NOMATCH : RMAP_MATCH);
285 }
286 return RMAP_NOMATCH;
287 }
288
289 static void *
290 route_match_ip_next_hop_prefix_list_compile (const char *arg)
291 {
292 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
293 }
294
295 static void
296 route_match_ip_next_hop_prefix_list_free (void *rule)
297 {
298 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
299 }
300
301 struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
302 {
303 "ip next-hop prefix-list",
304 route_match_ip_next_hop_prefix_list,
305 route_match_ip_next_hop_prefix_list_compile,
306 route_match_ip_next_hop_prefix_list_free
307 };
308
309 /* `match ip address IP_ACCESS_LIST' */
310 /* Match function should return 1 if match is success else return
311 zero. */
312 static route_map_result_t
313 route_match_ip_address (void *rule, struct prefix *prefix,
314 route_map_object_t type, void *object)
315 {
316 struct access_list *alist;
317 /* struct prefix_ipv4 match; */
318
319 if (type == RMAP_OSPF)
320 {
321 alist = access_list_lookup (AFI_IP, (char *) rule);
322 if (alist == NULL)
323 return RMAP_NOMATCH;
324
325 return (access_list_apply (alist, prefix) == FILTER_DENY ?
326 RMAP_NOMATCH : RMAP_MATCH);
327 }
328 return RMAP_NOMATCH;
329 }
330
331 /* Route map `ip address' match statement. `arg' should be
332 access-list name. */
333 static void *
334 route_match_ip_address_compile (const char *arg)
335 {
336 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
337 }
338
339 /* Free route map's compiled `ip address' value. */
340 static void
341 route_match_ip_address_free (void *rule)
342 {
343 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
344 }
345
346 /* Route map commands for ip address matching. */
347 struct route_map_rule_cmd route_match_ip_address_cmd =
348 {
349 "ip address",
350 route_match_ip_address,
351 route_match_ip_address_compile,
352 route_match_ip_address_free
353 };
354
355 /* `match ip address prefix-list PREFIX_LIST' */
356 static route_map_result_t
357 route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
358 route_map_object_t type, void *object)
359 {
360 struct prefix_list *plist;
361
362 if (type == RMAP_OSPF)
363 {
364 plist = prefix_list_lookup (AFI_IP, (char *) rule);
365 if (plist == NULL)
366 return RMAP_NOMATCH;
367
368 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
369 RMAP_NOMATCH : RMAP_MATCH);
370 }
371 return RMAP_NOMATCH;
372 }
373
374 static void *
375 route_match_ip_address_prefix_list_compile (const char *arg)
376 {
377 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
378 }
379
380 static void
381 route_match_ip_address_prefix_list_free (void *rule)
382 {
383 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
384 }
385
386 struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
387 {
388 "ip address prefix-list",
389 route_match_ip_address_prefix_list,
390 route_match_ip_address_prefix_list_compile,
391 route_match_ip_address_prefix_list_free
392 };
393
394 /* `match interface IFNAME' */
395 /* Match function should return 1 if match is success else return
396 zero. */
397 static route_map_result_t
398 route_match_interface (void *rule, struct prefix *prefix,
399 route_map_object_t type, void *object)
400 {
401 struct interface *ifp;
402 struct external_info *ei;
403
404 if (type == RMAP_OSPF)
405 {
406 ei = object;
407 ifp = if_lookup_by_name ((char *)rule);
408
409 if (ifp == NULL || ifp->ifindex != ei->ifindex)
410 return RMAP_NOMATCH;
411
412 return RMAP_MATCH;
413 }
414 return RMAP_NOMATCH;
415 }
416
417 /* Route map `interface' match statement. `arg' should be
418 interface name. */
419 static void *
420 route_match_interface_compile (const char *arg)
421 {
422 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
423 }
424
425 /* Free route map's compiled `interface' value. */
426 static void
427 route_match_interface_free (void *rule)
428 {
429 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
430 }
431
432 /* Route map commands for ip address matching. */
433 struct route_map_rule_cmd route_match_interface_cmd =
434 {
435 "interface",
436 route_match_interface,
437 route_match_interface_compile,
438 route_match_interface_free
439 };
440
441 /* Match function return 1 if match is success else return zero. */
442 static route_map_result_t
443 route_match_tag (void *rule, struct prefix *prefix,
444 route_map_object_t type, void *object)
445 {
446 u_short *tag;
447 struct external_info *ei;
448
449 if (type == RMAP_OSPF)
450 {
451 tag = rule;
452 ei = object;
453
454 return ((ei->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH);
455 }
456
457 return RMAP_NOMATCH;
458 }
459
460 /* Route map `match tag' match statement. `arg' is TAG value */
461 static void *
462 route_match_tag_compile (const char *arg)
463 {
464 u_short *tag;
465 u_short tmp;
466
467 /* tag value shoud be integer. */
468 if (! all_digit (arg))
469 return NULL;
470
471 tmp = atoi(arg);
472 if (tmp < 1)
473 return NULL;
474
475 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
476
477 if (!tag)
478 return tag;
479
480 *tag = tmp;
481
482 return tag;
483 }
484
485 /* Free route map's compiled 'match tag' value. */
486 static void
487 route_match_tag_free (void *rule)
488 {
489 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
490 }
491
492 /* Route map commands for tag matching. */
493 struct route_map_rule_cmd route_match_tag_cmd =
494 {
495 "tag",
496 route_match_tag,
497 route_match_tag_compile,
498 route_match_tag_free,
499 };
500
501
502 /* `set metric METRIC' */
503 /* Set metric to attribute. */
504 static route_map_result_t
505 route_set_metric (void *rule, struct prefix *prefix,
506 route_map_object_t type, void *object)
507 {
508 u_int32_t *metric;
509 struct external_info *ei;
510
511 if (type == RMAP_OSPF)
512 {
513 /* Fetch routemap's rule information. */
514 metric = rule;
515 ei = object;
516
517 /* Set metric out value. */
518 ei->route_map_set.metric = *metric;
519 }
520 return RMAP_OKAY;
521 }
522
523 /* set metric compilation. */
524 static void *
525 route_set_metric_compile (const char *arg)
526 {
527 u_int32_t *metric;
528 int32_t ret;
529
530 /* OSPF doesn't support the +/- in
531 set metric <+/-metric> check
532 Ignore the +/- component */
533 if (! all_digit (arg))
534 {
535 if ((strncmp (arg, "+", 1) == 0 || strncmp (arg, "-", 1) == 0) &&
536 all_digit (arg+1))
537 {
538 zlog_warn ("OSPF does not support 'set metric +/-'");
539 arg++;
540 }
541 else
542 {
543 return NULL;
544 }
545 }
546 metric = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
547 ret = atoi (arg);
548
549 if (ret >= 0)
550 {
551 *metric = (u_int32_t)ret;
552 return metric;
553 }
554
555 XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
556 return NULL;
557 }
558
559 /* Free route map's compiled `set metric' value. */
560 static void
561 route_set_metric_free (void *rule)
562 {
563 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
564 }
565
566 /* Set metric rule structure. */
567 struct route_map_rule_cmd route_set_metric_cmd =
568 {
569 "metric",
570 route_set_metric,
571 route_set_metric_compile,
572 route_set_metric_free,
573 };
574
575 /* `set metric-type TYPE' */
576 /* Set metric-type to attribute. */
577 static route_map_result_t
578 route_set_metric_type (void *rule, struct prefix *prefix,
579 route_map_object_t type, void *object)
580 {
581 u_int32_t *metric_type;
582 struct external_info *ei;
583
584 if (type == RMAP_OSPF)
585 {
586 /* Fetch routemap's rule information. */
587 metric_type = rule;
588 ei = object;
589
590 /* Set metric out value. */
591 ei->route_map_set.metric_type = *metric_type;
592 }
593 return RMAP_OKAY;
594 }
595
596 /* set metric-type compilation. */
597 static void *
598 route_set_metric_type_compile (const char *arg)
599 {
600 u_int32_t *metric_type;
601
602 metric_type = XCALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
603 if (strcmp (arg, "type-1") == 0)
604 *metric_type = EXTERNAL_METRIC_TYPE_1;
605 else if (strcmp (arg, "type-2") == 0)
606 *metric_type = EXTERNAL_METRIC_TYPE_2;
607
608 if (*metric_type == EXTERNAL_METRIC_TYPE_1 ||
609 *metric_type == EXTERNAL_METRIC_TYPE_2)
610 return metric_type;
611
612 XFREE (MTYPE_ROUTE_MAP_COMPILED, metric_type);
613 return NULL;
614 }
615
616 /* Free route map's compiled `set metric-type' value. */
617 static void
618 route_set_metric_type_free (void *rule)
619 {
620 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
621 }
622
623 /* Set metric rule structure. */
624 struct route_map_rule_cmd route_set_metric_type_cmd =
625 {
626 "metric-type",
627 route_set_metric_type,
628 route_set_metric_type_compile,
629 route_set_metric_type_free,
630 };
631
632 static route_map_result_t
633 route_set_tag (void *rule, struct prefix *prefix,
634 route_map_object_t type, void *object)
635 {
636 u_short *tag;
637 struct external_info *ei;
638
639 if (type == RMAP_OSPF)
640 {
641 tag = rule;
642 ei = object;
643
644 /* Set tag value */
645 ei->tag=*tag;
646 }
647
648 return RMAP_OKAY;
649 }
650
651 /* Route map `tag' compile function. Given string is converted to u_short. */
652 static void *
653 route_set_tag_compile (const char *arg)
654 {
655 u_short *tag;
656 u_short tmp;
657
658 /* tag value shoud be integer. */
659 if (! all_digit (arg))
660 return NULL;
661
662 tmp = atoi(arg);
663
664 if (tmp < 1)
665 return NULL;
666
667 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
668
669 if (!tag)
670 return tag;
671
672 *tag = tmp;
673
674 return tag;
675 }
676
677 /* Free route map's tag value. */
678 static void
679 route_set_tag_free (void *rule)
680 {
681 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
682 }
683
684 /* Route map commands for tag set. */
685 struct route_map_rule_cmd route_set_tag_cmd =
686 {
687 "tag",
688 route_set_tag,
689 route_set_tag_compile,
690 route_set_tag_free,
691 };
692
693 DEFUN (match_ip_nexthop,
694 match_ip_nexthop_cmd,
695 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
696 MATCH_STR
697 IP_STR
698 "Match next-hop address of route\n"
699 "IP access-list number\n"
700 "IP access-list number (expanded range)\n"
701 "IP access-list name\n")
702 {
703 return ospf_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
704 }
705
706 DEFUN (no_match_ip_nexthop,
707 no_match_ip_nexthop_cmd,
708 "no match ip next-hop",
709 NO_STR
710 MATCH_STR
711 IP_STR
712 "Match next-hop address of route\n")
713 {
714 if (argc == 0)
715 return ospf_route_match_delete (vty, vty->index, "ip next-hop", NULL);
716
717 return ospf_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
718 }
719
720 ALIAS (no_match_ip_nexthop,
721 no_match_ip_nexthop_val_cmd,
722 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
723 NO_STR
724 MATCH_STR
725 IP_STR
726 "Match next-hop address of route\n"
727 "IP access-list number\n"
728 "IP access-list number (expanded range)\n"
729 "IP access-list name\n")
730
731 DEFUN (match_ip_next_hop_prefix_list,
732 match_ip_next_hop_prefix_list_cmd,
733 "match ip next-hop prefix-list WORD",
734 MATCH_STR
735 IP_STR
736 "Match next-hop address of route\n"
737 "Match entries of prefix-lists\n"
738 "IP prefix-list name\n")
739 {
740 return ospf_route_match_add (vty, vty->index, "ip next-hop prefix-list",
741 argv[0]);
742 }
743
744 DEFUN (no_match_ip_next_hop_prefix_list,
745 no_match_ip_next_hop_prefix_list_cmd,
746 "no match ip next-hop prefix-list",
747 NO_STR
748 MATCH_STR
749 IP_STR
750 "Match next-hop address of route\n"
751 "Match entries of prefix-lists\n")
752 {
753 if (argc == 0)
754 return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
755 NULL);
756 return ospf_route_match_delete (vty, vty->index, "ip next-hop prefix-list",
757 argv[0]);
758 }
759
760 ALIAS (no_match_ip_next_hop_prefix_list,
761 no_match_ip_next_hop_prefix_list_val_cmd,
762 "no match ip next-hop prefix-list WORD",
763 NO_STR
764 MATCH_STR
765 IP_STR
766 "Match next-hop address of route\n"
767 "Match entries of prefix-lists\n"
768 "IP prefix-list name\n")
769
770 DEFUN (match_ip_address,
771 match_ip_address_cmd,
772 "match ip address (<1-199>|<1300-2699>|WORD)",
773 MATCH_STR
774 IP_STR
775 "Match address of route\n"
776 "IP access-list number\n"
777 "IP access-list number (expanded range)\n"
778 "IP access-list name\n")
779 {
780 return ospf_route_match_add (vty, vty->index, "ip address", argv[0]);
781 }
782
783 DEFUN (no_match_ip_address,
784 no_match_ip_address_cmd,
785 "no match ip address",
786 NO_STR
787 MATCH_STR
788 IP_STR
789 "Match address of route\n")
790 {
791 if (argc == 0)
792 return ospf_route_match_delete (vty, vty->index, "ip address", NULL);
793
794 return ospf_route_match_delete (vty, vty->index, "ip address", argv[0]);
795 }
796
797 ALIAS (no_match_ip_address,
798 no_match_ip_address_val_cmd,
799 "no match ip address (<1-199>|<1300-2699>|WORD)",
800 NO_STR
801 MATCH_STR
802 IP_STR
803 "Match address of route\n"
804 "IP access-list number\n"
805 "IP access-list number (expanded range)\n"
806 "IP access-list name\n")
807
808 DEFUN (match_ip_address_prefix_list,
809 match_ip_address_prefix_list_cmd,
810 "match ip address prefix-list WORD",
811 MATCH_STR
812 IP_STR
813 "Match address of route\n"
814 "Match entries of prefix-lists\n"
815 "IP prefix-list name\n")
816 {
817 return ospf_route_match_add (vty, vty->index, "ip address prefix-list",
818 argv[0]);
819 }
820
821 DEFUN (no_match_ip_address_prefix_list,
822 no_match_ip_address_prefix_list_cmd,
823 "no match ip address prefix-list",
824 NO_STR
825 MATCH_STR
826 IP_STR
827 "Match address of route\n"
828 "Match entries of prefix-lists\n")
829 {
830 if (argc == 0)
831 return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
832 NULL);
833 return ospf_route_match_delete (vty, vty->index, "ip address prefix-list",
834 argv[0]);
835 }
836
837 ALIAS (no_match_ip_address_prefix_list,
838 no_match_ip_address_prefix_list_val_cmd,
839 "no match ip address prefix-list WORD",
840 NO_STR
841 MATCH_STR
842 IP_STR
843 "Match address of route\n"
844 "Match entries of prefix-lists\n"
845 "IP prefix-list name\n")
846
847 DEFUN (match_interface,
848 match_interface_cmd,
849 "match interface WORD",
850 MATCH_STR
851 "Match first hop interface of route\n"
852 "Interface name\n")
853 {
854 return ospf_route_match_add (vty, vty->index, "interface", argv[0]);
855 }
856
857 DEFUN (no_match_interface,
858 no_match_interface_cmd,
859 "no match interface",
860 NO_STR
861 MATCH_STR
862 "Match first hop interface of route\n")
863 {
864 if (argc == 0)
865 return ospf_route_match_delete (vty, vty->index, "interface", NULL);
866
867 return ospf_route_match_delete (vty, vty->index, "interface", argv[0]);
868 }
869
870 ALIAS (no_match_interface,
871 no_match_interface_val_cmd,
872 "no match interface WORD",
873 NO_STR
874 MATCH_STR
875 "Match first hop interface of route\n"
876 "Interface name\n")
877
878 DEFUN (match_tag,
879 match_tag_cmd,
880 "match tag <1-65535>",
881 MATCH_STR
882 "Match tag of route\n"
883 "Tag value\n")
884 {
885 return ospf_route_match_add (vty, vty->index, "tag", argv[0]);
886 }
887
888 DEFUN (no_match_tag,
889 no_match_tag_cmd,
890 "no match tag",
891 NO_STR
892 MATCH_STR
893 "Match tag of route\n")
894 {
895 if (argc == 0)
896 return ospf_route_match_delete (vty, vty->index, "tag", NULL);
897
898 return ospf_route_match_delete (vty, vty->index, "tag", argv[0]);
899 }
900
901 ALIAS (no_match_tag,
902 no_match_tag_val_cmd,
903 "no match tag <1-65535>",
904 NO_STR
905 MATCH_STR
906 "Match tag of route\n"
907 "Tag value\n")
908
909 DEFUN (set_metric,
910 set_metric_cmd,
911 "set metric <0-4294967295>",
912 SET_STR
913 "Metric value for destination routing protocol\n"
914 "Metric value\n")
915 {
916 return ospf_route_set_add (vty, vty->index, "metric", argv[0]);
917 }
918
919 DEFUN (no_set_metric,
920 no_set_metric_cmd,
921 "no set metric",
922 NO_STR
923 SET_STR
924 "Metric value for destination routing protocol\n")
925 {
926 if (argc == 0)
927 return ospf_route_set_delete (vty, vty->index, "metric", NULL);
928
929 return ospf_route_set_delete (vty, vty->index, "metric", argv[0]);
930 }
931
932 ALIAS (no_set_metric,
933 no_set_metric_val_cmd,
934 "no set metric <0-4294967295>",
935 NO_STR
936 SET_STR
937 "Metric value for destination routing protocol\n"
938 "Metric value\n")
939
940 DEFUN (set_metric_type,
941 set_metric_type_cmd,
942 "set metric-type (type-1|type-2)",
943 SET_STR
944 "Type of metric for destination routing protocol\n"
945 "OSPF[6] external type 1 metric\n"
946 "OSPF[6] external type 2 metric\n")
947 {
948 if (strcmp (argv[0], "1") == 0)
949 return ospf_route_set_add (vty, vty->index, "metric-type", "type-1");
950 if (strcmp (argv[0], "2") == 0)
951 return ospf_route_set_add (vty, vty->index, "metric-type", "type-2");
952
953 return ospf_route_set_add (vty, vty->index, "metric-type", argv[0]);
954 }
955
956 DEFUN (no_set_metric_type,
957 no_set_metric_type_cmd,
958 "no set metric-type",
959 NO_STR
960 SET_STR
961 "Type of metric for destination routing protocol\n")
962 {
963 if (argc == 0)
964 return ospf_route_set_delete (vty, vty->index, "metric-type", NULL);
965
966 return ospf_route_set_delete (vty, vty->index, "metric-type", argv[0]);
967 }
968
969 ALIAS (no_set_metric_type,
970 no_set_metric_type_val_cmd,
971 "no set metric-type (type-1|type-2)",
972 NO_STR
973 SET_STR
974 "Type of metric for destination routing protocol\n"
975 "OSPF[6] external type 1 metric\n"
976 "OSPF[6] external type 2 metric\n")
977
978 DEFUN (set_tag,
979 set_tag_cmd,
980 "set tag <1-65535>",
981 SET_STR
982 "Tag value for routing protocol\n"
983 "Tag value\n")
984 {
985 return ospf_route_set_add (vty, vty->index, "tag", argv[0]);
986 }
987
988 DEFUN (no_set_tag,
989 no_set_tag_cmd,
990 "no set tag",
991 NO_STR
992 SET_STR
993 "Tag value for routing protocol\n")
994 {
995 if (argc == 0)
996 ospf_route_set_delete(vty, vty->index, "tag", NULL);
997
998 return ospf_route_set_delete (vty, vty->index, "tag", argv[0]);
999 }
1000
1001 ALIAS (no_set_tag,
1002 no_set_tag_val_cmd,
1003 "no set tag <1-65535>",
1004 NO_STR
1005 SET_STR
1006 "Tag value for routing protocol\n"
1007 "Tag value\n")
1008
1009 /* Route-map init */
1010 void
1011 ospf_route_map_init (void)
1012 {
1013 route_map_init ();
1014 route_map_init_vty ();
1015
1016 route_map_add_hook (ospf_route_map_update);
1017 route_map_delete_hook (ospf_route_map_update);
1018 route_map_event_hook (ospf_route_map_event);
1019
1020 route_map_install_match (&route_match_ip_nexthop_cmd);
1021 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
1022 route_map_install_match (&route_match_ip_address_cmd);
1023 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
1024 route_map_install_match (&route_match_interface_cmd);
1025 route_map_install_match (&route_match_tag_cmd);
1026
1027 route_map_install_set (&route_set_metric_cmd);
1028 route_map_install_set (&route_set_metric_type_cmd);
1029 route_map_install_set (&route_set_tag_cmd);
1030
1031 install_element (RMAP_NODE, &match_ip_nexthop_cmd);
1032 install_element (RMAP_NODE, &no_match_ip_nexthop_cmd);
1033 install_element (RMAP_NODE, &no_match_ip_nexthop_val_cmd);
1034 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
1035 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
1036 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
1037 install_element (RMAP_NODE, &match_ip_address_cmd);
1038 install_element (RMAP_NODE, &no_match_ip_address_cmd);
1039 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
1040 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
1041 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
1042 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
1043 install_element (RMAP_NODE, &match_interface_cmd);
1044 install_element (RMAP_NODE, &no_match_interface_cmd);
1045 install_element (RMAP_NODE, &no_match_interface_val_cmd);
1046 install_element (RMAP_NODE, &match_tag_cmd);
1047 install_element (RMAP_NODE, &no_match_tag_cmd);
1048 install_element (RMAP_NODE, &no_match_tag_val_cmd);
1049
1050 install_element (RMAP_NODE, &set_metric_cmd);
1051 install_element (RMAP_NODE, &no_set_metric_cmd);
1052 install_element (RMAP_NODE, &no_set_metric_val_cmd);
1053 install_element (RMAP_NODE, &set_metric_type_cmd);
1054 install_element (RMAP_NODE, &no_set_metric_type_cmd);
1055 install_element (RMAP_NODE, &no_set_metric_type_val_cmd);
1056 install_element (RMAP_NODE, &set_tag_cmd);
1057 install_element (RMAP_NODE, &no_set_tag_cmd);
1058 install_element (RMAP_NODE, &no_set_tag_val_cmd);
1059 }