blob: b354a896bd875b381e9e80c5021498f5ec653fcf [file] [log] [blame]
paul718e3742002-12-13 20:15:29 +00001/* RIPv2 routemap.
2 * Copyright (C) 1999 Kunihiro Ishiguro <kunihiro@zebra.org>
3 *
4 * This file is part of GNU Zebra.
5 *
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
9 * later version.
10 *
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.
15 *
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
19 * 02111-1307, USA.
20 */
21
22#include <zebra.h>
23
24#include "memory.h"
25#include "prefix.h"
26#include "routemap.h"
27#include "command.h"
28#include "filter.h"
29#include "log.h"
30#include "sockunion.h" /* for inet_aton () */
31#include "plist.h"
32
33#include "ripd/ripd.h"
hasso16705132003-05-25 14:49:19 +000034
35struct rip_metric_modifier
36{
37 enum
38 {
39 metric_increment,
40 metric_decrement,
41 metric_absolute
42 } type;
43
44 u_char metric;
45};
paul718e3742002-12-13 20:15:29 +000046
47/* Add rip route map rule. */
48int
49rip_route_match_add (struct vty *vty, struct route_map_index *index,
50 char *command, char *arg)
51{
52 int ret;
53
54 ret = route_map_add_match (index, command, arg);
55 if (ret)
56 {
57 switch (ret)
58 {
59 case RMAP_RULE_MISSING:
60 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
61 return CMD_WARNING;
62 break;
63 case RMAP_COMPILE_ERROR:
64 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
65 return CMD_WARNING;
66 break;
67 }
68 }
69 return CMD_SUCCESS;
70}
71
72/* Delete rip route map rule. */
73int
74rip_route_match_delete (struct vty *vty, struct route_map_index *index,
75 char *command, char *arg)
76{
77 int ret;
78
79 ret = route_map_delete_match (index, command, arg);
80 if (ret)
81 {
82 switch (ret)
83 {
84 case RMAP_RULE_MISSING:
85 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
86 return CMD_WARNING;
87 break;
88 case RMAP_COMPILE_ERROR:
89 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
90 return CMD_WARNING;
91 break;
92 }
93 }
94 return CMD_SUCCESS;
95}
96
97/* Add rip route map rule. */
98int
99rip_route_set_add (struct vty *vty, struct route_map_index *index,
100 char *command, char *arg)
101{
102 int ret;
103
104 ret = route_map_add_set (index, command, arg);
105 if (ret)
106 {
107 switch (ret)
108 {
109 case RMAP_RULE_MISSING:
110 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
111 return CMD_WARNING;
112 break;
113 case RMAP_COMPILE_ERROR:
114 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
115 return CMD_WARNING;
116 break;
117 }
118 }
119 return CMD_SUCCESS;
120}
121
122/* Delete rip route map rule. */
123int
124rip_route_set_delete (struct vty *vty, struct route_map_index *index,
125 char *command, char *arg)
126{
127 int ret;
128
129 ret = route_map_delete_set (index, command, arg);
130 if (ret)
131 {
132 switch (ret)
133 {
134 case RMAP_RULE_MISSING:
135 vty_out (vty, "%% Can't find rule.%s", VTY_NEWLINE);
136 return CMD_WARNING;
137 break;
138 case RMAP_COMPILE_ERROR:
139 vty_out (vty, "%% Argument is malformed.%s", VTY_NEWLINE);
140 return CMD_WARNING;
141 break;
142 }
143 }
144 return CMD_SUCCESS;
145}
146
147/* Hook function for updating route_map assignment. */
148void
149rip_route_map_update ()
150{
151 int i;
152
153 if (rip)
154 {
155 for (i = 0; i < ZEBRA_ROUTE_MAX; i++)
156 {
157 if (rip->route_map[i].name)
158 rip->route_map[i].map =
159 route_map_lookup_by_name (rip->route_map[i].name);
160 }
161 }
162}
163
164/* `match metric METRIC' */
165/* Match function return 1 if match is success else return zero. */
166route_map_result_t
167route_match_metric (void *rule, struct prefix *prefix,
168 route_map_object_t type, void *object)
169{
170 u_int32_t *metric;
171 struct rip_info *rinfo;
172
173 if (type == RMAP_RIP)
174 {
175 metric = rule;
176 rinfo = object;
177
178 if (rinfo->metric == *metric)
179 return RMAP_MATCH;
180 else
181 return RMAP_NOMATCH;
182 }
183 return RMAP_NOMATCH;
184}
185
186/* Route map `match metric' match statement. `arg' is METRIC value */
187void *
188route_match_metric_compile (char *arg)
189{
190 u_int32_t *metric;
191
192 metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
193 *metric = atoi (arg);
194
195 if(*metric > 0)
196 return metric;
197
198 XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
199 return NULL;
200}
201
202/* Free route map's compiled `match metric' value. */
203void
204route_match_metric_free (void *rule)
205{
206 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
207}
208
209/* Route map commands for metric matching. */
210struct route_map_rule_cmd route_match_metric_cmd =
211{
212 "metric",
213 route_match_metric,
214 route_match_metric_compile,
215 route_match_metric_free
216};
217
218/* `match interface IFNAME' */
219/* Match function return 1 if match is success else return zero. */
220route_map_result_t
221route_match_interface (void *rule, struct prefix *prefix,
222 route_map_object_t type, void *object)
223{
224 struct rip_info *rinfo;
225 struct interface *ifp;
226 char *ifname;
227
228 if (type == RMAP_RIP)
229 {
230 ifname = rule;
231 ifp = if_lookup_by_name(ifname);
232
233 if (!ifp)
234 return RMAP_NOMATCH;
235
236 rinfo = object;
237
238 if (rinfo->ifindex_out == ifp->ifindex)
239 return RMAP_MATCH;
240 else
241 return RMAP_NOMATCH;
242 }
243 return RMAP_NOMATCH;
244}
245
246/* Route map `match interface' match statement. `arg' is IFNAME value */
247/* XXX I don`t know if I need to check does interface exist? */
248void *
249route_match_interface_compile (char *arg)
250{
251 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
252}
253
254/* Free route map's compiled `match interface' value. */
255void
256route_match_interface_free (void *rule)
257{
258 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
259}
260
261/* Route map commands for interface matching. */
262struct route_map_rule_cmd route_match_interface_cmd =
263{
264 "interface",
265 route_match_interface,
266 route_match_interface_compile,
267 route_match_interface_free
268};
269
270/* `match ip next-hop IP_ACCESS_LIST' */
271
272/* Match function return 1 if match is success else return zero. */
273route_map_result_t
274route_match_ip_next_hop (void *rule, struct prefix *prefix,
275 route_map_object_t type, void *object)
276{
277 struct access_list *alist;
278 struct rip_info *rinfo;
279 struct prefix_ipv4 p;
280
281 if (type == RMAP_RIP)
282 {
283 rinfo = object;
284 p.family = AF_INET;
285 p.prefix = rinfo->nexthop;
286 p.prefixlen = IPV4_MAX_BITLEN;
287
288 alist = access_list_lookup (AFI_IP, (char *) rule);
289 if (alist == NULL)
290 return RMAP_NOMATCH;
291
292 return (access_list_apply (alist, &p) == FILTER_DENY ?
293 RMAP_NOMATCH : RMAP_MATCH);
294 }
295 return RMAP_NOMATCH;
296}
297
298/* Route map `ip next-hop' match statement. `arg' should be
299 access-list name. */
300void *
301route_match_ip_next_hop_compile (char *arg)
302{
303 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
304}
305
306/* Free route map's compiled `. */
307void
308route_match_ip_next_hop_free (void *rule)
309{
310 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
311}
312
313/* Route map commands for ip next-hop matching. */
314struct route_map_rule_cmd route_match_ip_next_hop_cmd =
315{
316 "ip next-hop",
317 route_match_ip_next_hop,
318 route_match_ip_next_hop_compile,
319 route_match_ip_next_hop_free
320};
321
322/* `match ip next-hop prefix-list PREFIX_LIST' */
323
324route_map_result_t
325route_match_ip_next_hop_prefix_list (void *rule, struct prefix *prefix,
326 route_map_object_t type, void *object)
327{
328 struct prefix_list *plist;
329 struct rip_info *rinfo;
330 struct prefix_ipv4 p;
331
332 if (type == RMAP_RIP)
333 {
334 rinfo = object;
335 p.family = AF_INET;
336 p.prefix = rinfo->nexthop;
337 p.prefixlen = IPV4_MAX_BITLEN;
338
339 plist = prefix_list_lookup (AFI_IP, (char *) rule);
340 if (plist == NULL)
341 return RMAP_NOMATCH;
342
343 return (prefix_list_apply (plist, &p) == PREFIX_DENY ?
344 RMAP_NOMATCH : RMAP_MATCH);
345 }
346 return RMAP_NOMATCH;
347}
348
349void *
350route_match_ip_next_hop_prefix_list_compile (char *arg)
351{
352 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
353}
354
355void
356route_match_ip_next_hop_prefix_list_free (void *rule)
357{
358 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
359}
360
361struct route_map_rule_cmd route_match_ip_next_hop_prefix_list_cmd =
362{
363 "ip next-hop prefix-list",
364 route_match_ip_next_hop_prefix_list,
365 route_match_ip_next_hop_prefix_list_compile,
366 route_match_ip_next_hop_prefix_list_free
367};
368
369/* `match ip address IP_ACCESS_LIST' */
370
371/* Match function should return 1 if match is success else return
372 zero. */
373route_map_result_t
374route_match_ip_address (void *rule, struct prefix *prefix,
375 route_map_object_t type, void *object)
376{
377 struct access_list *alist;
378
379 if (type == RMAP_RIP)
380 {
381 alist = access_list_lookup (AFI_IP, (char *) rule);
382 if (alist == NULL)
383 return RMAP_NOMATCH;
384
385 return (access_list_apply (alist, prefix) == FILTER_DENY ?
386 RMAP_NOMATCH : RMAP_MATCH);
387 }
388 return RMAP_NOMATCH;
389}
390
391/* Route map `ip address' match statement. `arg' should be
392 access-list name. */
393void *
394route_match_ip_address_compile (char *arg)
395{
396 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
397}
398
399/* Free route map's compiled `ip address' value. */
400void
401route_match_ip_address_free (void *rule)
402{
403 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
404}
405
406/* Route map commands for ip address matching. */
407struct route_map_rule_cmd route_match_ip_address_cmd =
408{
409 "ip address",
410 route_match_ip_address,
411 route_match_ip_address_compile,
412 route_match_ip_address_free
413};
414
415/* `match ip address prefix-list PREFIX_LIST' */
416
417route_map_result_t
418route_match_ip_address_prefix_list (void *rule, struct prefix *prefix,
419 route_map_object_t type, void *object)
420{
421 struct prefix_list *plist;
422
423 if (type == RMAP_RIP)
424 {
425 plist = prefix_list_lookup (AFI_IP, (char *) rule);
426 if (plist == NULL)
427 return RMAP_NOMATCH;
428
429 return (prefix_list_apply (plist, prefix) == PREFIX_DENY ?
430 RMAP_NOMATCH : RMAP_MATCH);
431 }
432 return RMAP_NOMATCH;
433}
434
435void *
436route_match_ip_address_prefix_list_compile (char *arg)
437{
438 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
439}
440
441void
442route_match_ip_address_prefix_list_free (void *rule)
443{
444 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
445}
446
447struct route_map_rule_cmd route_match_ip_address_prefix_list_cmd =
448{
449 "ip address prefix-list",
450 route_match_ip_address_prefix_list,
451 route_match_ip_address_prefix_list_compile,
452 route_match_ip_address_prefix_list_free
453};
hasso16705132003-05-25 14:49:19 +0000454
455/* `match tag TAG' */
456/* Match function return 1 if match is success else return zero. */
457route_map_result_t
458route_match_tag (void *rule, struct prefix *prefix,
459 route_map_object_t type, void *object)
460{
461 u_short *tag;
462 struct rip_info *rinfo;
463
464 if (type == RMAP_RIP)
465 {
466 tag = rule;
467 rinfo = object;
468
469 /* The information stored by rinfo is host ordered. */
470 if (rinfo->tag == *tag)
471 return RMAP_MATCH;
472 else
473 return RMAP_NOMATCH;
474 }
475 return RMAP_NOMATCH;
476}
477
478/* Route map `match tag' match statement. `arg' is TAG value */
479void *
480route_match_tag_compile (char *arg)
481{
482 u_short *tag;
483
484 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
485 *tag = atoi (arg);
486
487 return tag;
488}
489
490/* Free route map's compiled `match tag' value. */
491void
492route_match_tag_free (void *rule)
493{
494 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
495}
496
497/* Route map commands for tag matching. */
498struct route_map_rule_cmd route_match_tag_cmd =
499{
500 "tag",
501 route_match_tag,
502 route_match_tag_compile,
503 route_match_tag_free
504};
paul718e3742002-12-13 20:15:29 +0000505
506/* `set metric METRIC' */
507
508/* Set metric to attribute. */
509route_map_result_t
510route_set_metric (void *rule, struct prefix *prefix,
511 route_map_object_t type, void *object)
512{
paul718e3742002-12-13 20:15:29 +0000513 if (type == RMAP_RIP)
514 {
hasso16705132003-05-25 14:49:19 +0000515 struct rip_metric_modifier *mod;
516 struct rip_info *rinfo;
517
518 mod = rule;
paul718e3742002-12-13 20:15:29 +0000519 rinfo = object;
hasso16705132003-05-25 14:49:19 +0000520
521 if (mod->type == metric_increment)
522 rinfo->metric_out += mod->metric;
523 else if (mod->type == metric_decrement)
524 rinfo->metric_out -= mod->metric;
525 else if (mod->type == metric_absolute)
526 rinfo->metric_out = mod->metric;
527
528 if (rinfo->metric_out < 1)
529 rinfo->metric_out = 1;
530 if (rinfo->metric_out > RIP_METRIC_INFINITY)
531 rinfo->metric_out = RIP_METRIC_INFINITY;
532
paul718e3742002-12-13 20:15:29 +0000533 rinfo->metric_set = 1;
534 }
535 return RMAP_OKAY;
536}
537
538/* set metric compilation. */
539void *
540route_set_metric_compile (char *arg)
541{
hasso16705132003-05-25 14:49:19 +0000542 int len;
543 char *pnt;
544 int type;
545 long metric;
546 char *endptr = NULL;
547 struct rip_metric_modifier *mod;
paul718e3742002-12-13 20:15:29 +0000548
hasso16705132003-05-25 14:49:19 +0000549 len = strlen (arg);
550 pnt = arg;
paul718e3742002-12-13 20:15:29 +0000551
hasso16705132003-05-25 14:49:19 +0000552 if (len == 0)
553 return NULL;
paul718e3742002-12-13 20:15:29 +0000554
hasso16705132003-05-25 14:49:19 +0000555 /* Examine first character. */
556 if (arg[0] == '+')
557 {
558 type = metric_increment;
559 pnt++;
560 }
561 else if (arg[0] == '-')
562 {
563 type = metric_decrement;
564 pnt++;
565 }
566 else
567 type = metric_absolute;
paul718e3742002-12-13 20:15:29 +0000568
hasso16705132003-05-25 14:49:19 +0000569 /* Check beginning with digit string. */
570 if (*pnt < '0' || *pnt > '9')
571 return NULL;
572
573 /* Convert string to integer. */
574 metric = strtol (pnt, &endptr, 10);
575
576 if (metric == LONG_MAX || *endptr != '\0')
577 return NULL;
578 if (metric < 0 || metric > RIP_METRIC_INFINITY)
579 return NULL;
580
581 mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
582 sizeof (struct rip_metric_modifier));
583 mod->type = type;
584 mod->metric = metric;
585
586 return mod;
paul718e3742002-12-13 20:15:29 +0000587}
588
589/* Free route map's compiled `set metric' value. */
590void
591route_set_metric_free (void *rule)
592{
593 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
594}
595
596/* Set metric rule structure. */
597struct route_map_rule_cmd route_set_metric_cmd =
598{
599 "metric",
600 route_set_metric,
601 route_set_metric_compile,
602 route_set_metric_free,
603};
604
605/* `set ip next-hop IP_ADDRESS' */
606
607/* Set nexthop to object. ojbect must be pointer to struct attr. */
608route_map_result_t
609route_set_ip_nexthop (void *rule, struct prefix *prefix,
610 route_map_object_t type, void *object)
611{
612 struct in_addr *address;
613 struct rip_info *rinfo;
614
615 if(type == RMAP_RIP)
616 {
617 /* Fetch routemap's rule information. */
618 address = rule;
619 rinfo = object;
620
621 /* Set next hop value. */
622 rinfo->nexthop_out = *address;
623 }
624
625 return RMAP_OKAY;
626}
627
628/* Route map `ip nexthop' compile function. Given string is converted
629 to struct in_addr structure. */
630void *
631route_set_ip_nexthop_compile (char *arg)
632{
633 int ret;
634 struct in_addr *address;
635
636 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr));
637
638 ret = inet_aton (arg, address);
639
640 if (ret == 0)
641 {
642 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
643 return NULL;
644 }
645
646 return address;
647}
648
649/* Free route map's compiled `ip nexthop' value. */
650void
651route_set_ip_nexthop_free (void *rule)
652{
653 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
654}
655
656/* Route map commands for ip nexthop set. */
657struct route_map_rule_cmd route_set_ip_nexthop_cmd =
658{
659 "ip next-hop",
660 route_set_ip_nexthop,
661 route_set_ip_nexthop_compile,
662 route_set_ip_nexthop_free
663};
hasso16705132003-05-25 14:49:19 +0000664
665/* `set tag TAG' */
666
667/* Set tag to object. ojbect must be pointer to struct attr. */
668route_map_result_t
669route_set_tag (void *rule, struct prefix *prefix,
670 route_map_object_t type, void *object)
671{
672 u_short *tag;
673 struct rip_info *rinfo;
674
675 if(type == RMAP_RIP)
676 {
677 /* Fetch routemap's rule information. */
678 tag = rule;
679 rinfo = object;
680
681 /* Set next hop value. */
682 rinfo->tag_out = *tag;
683 }
684
685 return RMAP_OKAY;
686}
687
688/* Route map `tag' compile function. Given string is converted
689 to u_short. */
690void *
691route_set_tag_compile (char *arg)
692{
693 u_short *tag;
694
695 tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short));
696 *tag = atoi (arg);
697
698 return tag;
699}
700
701/* Free route map's compiled `ip nexthop' value. */
702void
703route_set_tag_free (void *rule)
704{
705 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
706}
707
708/* Route map commands for tag set. */
709struct route_map_rule_cmd route_set_tag_cmd =
710{
711 "tag",
712 route_set_tag,
713 route_set_tag_compile,
714 route_set_tag_free
715};
paul718e3742002-12-13 20:15:29 +0000716
717#define MATCH_STR "Match values from routing table\n"
718#define SET_STR "Set values in destination routing protocol\n"
719
720DEFUN (match_metric,
721 match_metric_cmd,
722 "match metric <0-4294967295>",
723 MATCH_STR
724 "Match metric of route\n"
725 "Metric value\n")
726{
727 return rip_route_match_add (vty, vty->index, "metric", argv[0]);
728}
729
730DEFUN (no_match_metric,
731 no_match_metric_cmd,
732 "no match metric",
733 NO_STR
734 MATCH_STR
735 "Match metric of route\n")
736{
737 if (argc == 0)
738 return rip_route_match_delete (vty, vty->index, "metric", NULL);
739
740 return rip_route_match_delete (vty, vty->index, "metric", argv[0]);
741}
742
743ALIAS (no_match_metric,
744 no_match_metric_val_cmd,
745 "no match metric <0-4294967295>",
746 NO_STR
747 MATCH_STR
748 "Match metric of route\n"
749 "Metric value\n")
750
751DEFUN (match_interface,
752 match_interface_cmd,
753 "match interface WORD",
754 MATCH_STR
755 "Match first hop interface of route\n"
756 "Interface name\n")
757{
758 return rip_route_match_add (vty, vty->index, "interface", argv[0]);
759}
760
761DEFUN (no_match_interface,
762 no_match_interface_cmd,
763 "no match interface",
764 NO_STR
765 MATCH_STR
766 "Match first hop interface of route\n")
767{
768 if (argc == 0)
769 return rip_route_match_delete (vty, vty->index, "interface", NULL);
770
771 return rip_route_match_delete (vty, vty->index, "interface", argv[0]);
772}
773
774ALIAS (no_match_interface,
775 no_match_interface_val_cmd,
776 "no match interface WORD",
777 NO_STR
778 MATCH_STR
779 "Match first hop interface of route\n"
780 "Interface name\n")
781
782DEFUN (match_ip_next_hop,
783 match_ip_next_hop_cmd,
paul73ffb252003-04-19 15:49:49 +0000784 "match ip next-hop (<1-199>|<1300-2699>|WORD)",
paul718e3742002-12-13 20:15:29 +0000785 MATCH_STR
786 IP_STR
787 "Match next-hop address of route\n"
paul73ffb252003-04-19 15:49:49 +0000788 "IP access-list number\n"
789 "IP access-list number (expanded range)\n"
790 "IP Access-list name\n")
paul718e3742002-12-13 20:15:29 +0000791{
792 return rip_route_match_add (vty, vty->index, "ip next-hop", argv[0]);
793}
794
795DEFUN (no_match_ip_next_hop,
796 no_match_ip_next_hop_cmd,
797 "no match ip next-hop",
798 NO_STR
799 MATCH_STR
800 IP_STR
801 "Match next-hop address of route\n")
802{
803 if (argc == 0)
804 return rip_route_match_delete (vty, vty->index, "ip next-hop", NULL);
805
806 return rip_route_match_delete (vty, vty->index, "ip next-hop", argv[0]);
807}
808
809ALIAS (no_match_ip_next_hop,
810 no_match_ip_next_hop_val_cmd,
paul73ffb252003-04-19 15:49:49 +0000811 "no match ip next-hop (<1-199>|<1300-2699>|WORD)",
paul718e3742002-12-13 20:15:29 +0000812 NO_STR
813 MATCH_STR
814 IP_STR
815 "Match next-hop address of route\n"
paul73ffb252003-04-19 15:49:49 +0000816 "IP access-list number\n"
817 "IP access-list number (expanded range)\n"
818 "IP Access-list name\n")
paul718e3742002-12-13 20:15:29 +0000819
820DEFUN (match_ip_next_hop_prefix_list,
821 match_ip_next_hop_prefix_list_cmd,
822 "match ip next-hop prefix-list WORD",
823 MATCH_STR
824 IP_STR
825 "Match next-hop address of route\n"
826 "Match entries of prefix-lists\n"
827 "IP prefix-list name\n")
828{
829 return rip_route_match_add (vty, vty->index, "ip next-hop prefix-list", argv[0]);
830}
831
832DEFUN (no_match_ip_next_hop_prefix_list,
833 no_match_ip_next_hop_prefix_list_cmd,
834 "no match ip next-hop prefix-list",
835 NO_STR
836 MATCH_STR
837 IP_STR
838 "Match next-hop address of route\n"
839 "Match entries of prefix-lists\n")
840{
841 if (argc == 0)
842 return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", NULL);
843
844 return rip_route_match_delete (vty, vty->index, "ip next-hop prefix-list", argv[0]);
845}
846
847ALIAS (no_match_ip_next_hop_prefix_list,
848 no_match_ip_next_hop_prefix_list_val_cmd,
849 "no match ip next-hop prefix-list WORD",
850 NO_STR
851 MATCH_STR
852 IP_STR
853 "Match next-hop address of route\n"
854 "Match entries of prefix-lists\n"
855 "IP prefix-list name\n")
856
paul73ffb252003-04-19 15:49:49 +0000857DEFUN (match_ip_address,
paul718e3742002-12-13 20:15:29 +0000858 match_ip_address_cmd,
paul73ffb252003-04-19 15:49:49 +0000859 "match ip address (<1-199>|<1300-2699>|WORD)",
paul718e3742002-12-13 20:15:29 +0000860 MATCH_STR
861 IP_STR
862 "Match address of route\n"
paul73ffb252003-04-19 15:49:49 +0000863 "IP access-list number\n"
864 "IP access-list number (expanded range)\n"
865 "IP Access-list name\n")
866
paul718e3742002-12-13 20:15:29 +0000867{
868 return rip_route_match_add (vty, vty->index, "ip address", argv[0]);
869}
870
871DEFUN (no_match_ip_address,
872 no_match_ip_address_cmd,
873 "no match ip address",
874 NO_STR
875 MATCH_STR
876 IP_STR
877 "Match address of route\n")
878{
879 if (argc == 0)
880 return rip_route_match_delete (vty, vty->index, "ip address", NULL);
881
882 return rip_route_match_delete (vty, vty->index, "ip address", argv[0]);
883}
884
paul73ffb252003-04-19 15:49:49 +0000885ALIAS (no_match_ip_address,
paul718e3742002-12-13 20:15:29 +0000886 no_match_ip_address_val_cmd,
paul73ffb252003-04-19 15:49:49 +0000887 "no match ip address (<1-199>|<1300-2699>|WORD)",
paul718e3742002-12-13 20:15:29 +0000888 NO_STR
889 MATCH_STR
890 IP_STR
891 "Match address of route\n"
paul73ffb252003-04-19 15:49:49 +0000892 "IP access-list number\n"
893 "IP access-list number (expanded range)\n"
894 "IP Access-list name\n")
paul718e3742002-12-13 20:15:29 +0000895
896DEFUN (match_ip_address_prefix_list,
897 match_ip_address_prefix_list_cmd,
898 "match ip address prefix-list WORD",
899 MATCH_STR
900 IP_STR
901 "Match address of route\n"
902 "Match entries of prefix-lists\n"
903 "IP prefix-list name\n")
904{
905 return rip_route_match_add (vty, vty->index, "ip address prefix-list", argv[0]);
906}
907
908DEFUN (no_match_ip_address_prefix_list,
909 no_match_ip_address_prefix_list_cmd,
910 "no match ip address prefix-list",
911 NO_STR
912 MATCH_STR
913 IP_STR
914 "Match address of route\n"
915 "Match entries of prefix-lists\n")
916{
917 if (argc == 0)
918 return rip_route_match_delete (vty, vty->index, "ip address prefix-list", NULL);
919
920 return rip_route_match_delete (vty, vty->index, "ip address prefix-list", argv[0]);
921}
922
923ALIAS (no_match_ip_address_prefix_list,
924 no_match_ip_address_prefix_list_val_cmd,
925 "no match ip address prefix-list WORD",
926 NO_STR
927 MATCH_STR
928 IP_STR
929 "Match address of route\n"
930 "Match entries of prefix-lists\n"
931 "IP prefix-list name\n")
932
hasso16705132003-05-25 14:49:19 +0000933DEFUN (match_tag,
934 match_tag_cmd,
935 "match tag <0-65535>",
936 MATCH_STR
937 "Match tag of route\n"
938 "Metric value\n")
939{
940 return rip_route_match_add (vty, vty->index, "tag", argv[0]);
941}
942
943DEFUN (no_match_tag,
944 no_match_tag_cmd,
945 "no match tag",
946 NO_STR
947 MATCH_STR
948 "Match tag of route\n")
949{
950 if (argc == 0)
951 return rip_route_match_delete (vty, vty->index, "tag", NULL);
952
953 return rip_route_match_delete (vty, vty->index, "tag", argv[0]);
954}
955
956ALIAS (no_match_tag,
957 no_match_tag_val_cmd,
958 "no match tag <0-65535>",
959 NO_STR
960 MATCH_STR
961 "Match tag of route\n"
962 "Metric value\n")
963
paul718e3742002-12-13 20:15:29 +0000964/* set functions */
965
966DEFUN (set_metric,
967 set_metric_cmd,
hasso16705132003-05-25 14:49:19 +0000968 "set metric (<0-4294967295>|<+/-metric>)",
paul718e3742002-12-13 20:15:29 +0000969 SET_STR
970 "Metric value for destination routing protocol\n"
hasso16705132003-05-25 14:49:19 +0000971 "Metric value\n"
972 "Add or subtract metric\n")
paul718e3742002-12-13 20:15:29 +0000973{
974 return rip_route_set_add (vty, vty->index, "metric", argv[0]);
975}
976
977DEFUN (no_set_metric,
978 no_set_metric_cmd,
979 "no set metric",
980 NO_STR
981 SET_STR
982 "Metric value for destination routing protocol\n")
983{
984 if (argc == 0)
985 return rip_route_set_delete (vty, vty->index, "metric", NULL);
986
987 return rip_route_set_delete (vty, vty->index, "metric", argv[0]);
988}
989
990ALIAS (no_set_metric,
991 no_set_metric_val_cmd,
hasso16705132003-05-25 14:49:19 +0000992 "no set metric (<0-4294967295>|<+/-metric>)",
paul718e3742002-12-13 20:15:29 +0000993 NO_STR
994 SET_STR
995 "Metric value for destination routing protocol\n"
hasso16705132003-05-25 14:49:19 +0000996 "Metric value\n"
997 "Add or subtract metric\n")
paul718e3742002-12-13 20:15:29 +0000998
999DEFUN (set_ip_nexthop,
1000 set_ip_nexthop_cmd,
1001 "set ip next-hop A.B.C.D",
1002 SET_STR
1003 IP_STR
1004 "Next hop address\n"
1005 "IP address of next hop\n")
1006{
1007 union sockunion su;
1008 int ret;
1009
1010 ret = str2sockunion (argv[0], &su);
1011 if (ret < 0)
1012 {
1013 vty_out (vty, "%% Malformed next-hop address%s", VTY_NEWLINE);
1014 return CMD_WARNING;
1015 }
1016
1017 return rip_route_set_add (vty, vty->index, "ip next-hop", argv[0]);
1018}
1019
1020DEFUN (no_set_ip_nexthop,
1021 no_set_ip_nexthop_cmd,
1022 "no set ip next-hop",
1023 NO_STR
1024 SET_STR
1025 IP_STR
1026 "Next hop address\n")
1027{
1028 if (argc == 0)
1029 return rip_route_set_delete (vty, vty->index, "ip next-hop", NULL);
1030
1031 return rip_route_set_delete (vty, vty->index, "ip next-hop", argv[0]);
1032}
1033
1034ALIAS (no_set_ip_nexthop,
1035 no_set_ip_nexthop_val_cmd,
1036 "no set ip next-hop A.B.C.D",
1037 NO_STR
1038 SET_STR
1039 IP_STR
1040 "Next hop address\n"
1041 "IP address of next hop\n")
1042
hasso16705132003-05-25 14:49:19 +00001043DEFUN (set_tag,
1044 set_tag_cmd,
1045 "set tag <0-65535>",
1046 SET_STR
1047 "Tag value for routing protocol\n"
1048 "Tag value\n")
1049{
1050 return rip_route_set_add (vty, vty->index, "tag", argv[0]);
1051}
1052
1053DEFUN (no_set_tag,
1054 no_set_tag_cmd,
1055 "no set tag",
1056 NO_STR
1057 SET_STR
1058 "Tag value for routing protocol\n")
1059{
1060 if (argc == 0)
1061 return rip_route_set_delete (vty, vty->index, "tag", NULL);
1062
1063 return rip_route_set_delete (vty, vty->index, "tag", argv[0]);
1064}
1065
1066ALIAS (no_set_tag,
1067 no_set_tag_val_cmd,
1068 "no set tag <0-65535>",
1069 NO_STR
1070 SET_STR
1071 "Tag value for routing protocol\n"
1072 "Tag value\n")
1073
paul718e3742002-12-13 20:15:29 +00001074void
1075rip_route_map_reset ()
1076{
1077 ;
1078}
1079
1080/* Route-map init */
1081void
1082rip_route_map_init ()
1083{
1084 route_map_init ();
1085 route_map_init_vty ();
1086 route_map_add_hook (rip_route_map_update);
1087 route_map_delete_hook (rip_route_map_update);
1088
1089 route_map_install_match (&route_match_metric_cmd);
1090 route_map_install_match (&route_match_interface_cmd);
1091 route_map_install_match (&route_match_ip_next_hop_cmd);
1092 route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
1093 route_map_install_match (&route_match_ip_address_cmd);
1094 route_map_install_match (&route_match_ip_address_prefix_list_cmd);
hasso16705132003-05-25 14:49:19 +00001095 route_map_install_match (&route_match_tag_cmd);
paul718e3742002-12-13 20:15:29 +00001096
1097 route_map_install_set (&route_set_metric_cmd);
1098 route_map_install_set (&route_set_ip_nexthop_cmd);
hasso16705132003-05-25 14:49:19 +00001099 route_map_install_set (&route_set_tag_cmd);
paul718e3742002-12-13 20:15:29 +00001100
1101 install_element (RMAP_NODE, &match_metric_cmd);
1102 install_element (RMAP_NODE, &no_match_metric_cmd);
1103 install_element (RMAP_NODE, &no_match_metric_val_cmd);
1104 install_element (RMAP_NODE, &match_interface_cmd);
1105 install_element (RMAP_NODE, &no_match_interface_cmd);
1106 install_element (RMAP_NODE, &no_match_interface_val_cmd);
1107 install_element (RMAP_NODE, &match_ip_next_hop_cmd);
1108 install_element (RMAP_NODE, &no_match_ip_next_hop_cmd);
1109 install_element (RMAP_NODE, &no_match_ip_next_hop_val_cmd);
1110 install_element (RMAP_NODE, &match_ip_next_hop_prefix_list_cmd);
1111 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_cmd);
1112 install_element (RMAP_NODE, &no_match_ip_next_hop_prefix_list_val_cmd);
1113 install_element (RMAP_NODE, &match_ip_address_cmd);
1114 install_element (RMAP_NODE, &no_match_ip_address_cmd);
1115 install_element (RMAP_NODE, &no_match_ip_address_val_cmd);
1116 install_element (RMAP_NODE, &match_ip_address_prefix_list_cmd);
1117 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_cmd);
1118 install_element (RMAP_NODE, &no_match_ip_address_prefix_list_val_cmd);
hasso16705132003-05-25 14:49:19 +00001119 install_element (RMAP_NODE, &match_tag_cmd);
1120 install_element (RMAP_NODE, &no_match_tag_cmd);
1121 install_element (RMAP_NODE, &no_match_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00001122
1123 install_element (RMAP_NODE, &set_metric_cmd);
1124 install_element (RMAP_NODE, &no_set_metric_cmd);
1125 install_element (RMAP_NODE, &no_set_metric_val_cmd);
1126 install_element (RMAP_NODE, &set_ip_nexthop_cmd);
1127 install_element (RMAP_NODE, &no_set_ip_nexthop_cmd);
1128 install_element (RMAP_NODE, &no_set_ip_nexthop_val_cmd);
hasso16705132003-05-25 14:49:19 +00001129 install_element (RMAP_NODE, &set_tag_cmd);
1130 install_element (RMAP_NODE, &no_set_tag_cmd);
1131 install_element (RMAP_NODE, &no_set_tag_val_cmd);
paul718e3742002-12-13 20:15:29 +00001132}