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