2 * Copyright (C) 1999 Kunihiro Ishiguro
4 * This file is part of GNU Zebra.
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
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.
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
29 #include "sockunion.h"
31 #include "ripngd/ripngd.h"
33 struct rip_metric_modifier
47 ripng_route_match_add (struct vty *vty, struct route_map_index *index,
48 const char *command, const char *arg)
52 ret = route_map_add_match (index, command, arg);
57 case RMAP_RULE_MISSING:
58 vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
60 case RMAP_COMPILE_ERROR:
61 vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
69 ripng_route_match_delete (struct vty *vty, struct route_map_index *index,
70 const char *command, const char *arg)
74 ret = route_map_delete_match (index, command, arg);
79 case RMAP_RULE_MISSING:
80 vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
82 case RMAP_COMPILE_ERROR:
83 vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
91 ripng_route_set_add (struct vty *vty, struct route_map_index *index,
92 const char *command, const char *arg)
96 ret = route_map_add_set (index, command, arg);
101 case RMAP_RULE_MISSING:
102 vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
104 case RMAP_COMPILE_ERROR:
105 vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
113 ripng_route_set_delete (struct vty *vty, struct route_map_index *index,
114 const char *command, const char *arg)
118 ret = route_map_delete_set (index, command, arg);
123 case RMAP_RULE_MISSING:
124 vty_out (vty, "RIPng Can't find rule.%s", VTY_NEWLINE);
126 case RMAP_COMPILE_ERROR:
127 vty_out (vty, "RIPng Argument is malformed.%s", VTY_NEWLINE);
134 /* `match metric METRIC' */
135 /* Match function return 1 if match is success else return zero. */
136 static route_map_result_t
137 route_match_metric (void *rule, struct prefix *prefix,
138 route_map_object_t type, void *object)
141 struct ripng_info *rinfo;
143 if (type == RMAP_RIPNG)
148 if (rinfo->metric == *metric)
156 /* Route map `match metric' match statement. `arg' is METRIC value */
158 route_match_metric_compile (const char *arg)
162 metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t));
163 *metric = atoi (arg);
168 XFREE (MTYPE_ROUTE_MAP_COMPILED, metric);
172 /* Free route map's compiled `match metric' value. */
174 route_match_metric_free (void *rule)
176 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
179 /* Route map commands for metric matching. */
180 static struct route_map_rule_cmd route_match_metric_cmd =
184 route_match_metric_compile,
185 route_match_metric_free
188 /* `match interface IFNAME' */
189 /* Match function return 1 if match is success else return zero. */
190 static route_map_result_t
191 route_match_interface (void *rule, struct prefix *prefix,
192 route_map_object_t type, void *object)
194 struct ripng_info *rinfo;
195 struct interface *ifp;
198 if (type == RMAP_RIPNG)
201 ifp = if_lookup_by_name(ifname);
208 if (rinfo->ifindex == ifp->ifindex)
216 /* Route map `match interface' match statement. `arg' is IFNAME value */
218 route_match_interface_compile (const char *arg)
220 return XSTRDUP (MTYPE_ROUTE_MAP_COMPILED, arg);
224 route_match_interface_free (void *rule)
226 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
229 static struct route_map_rule_cmd route_match_interface_cmd =
232 route_match_interface,
233 route_match_interface_compile,
234 route_match_interface_free
237 /* `match tag TAG' */
238 /* Match function return 1 if match is success else return zero. */
239 static route_map_result_t
240 route_match_tag (void *rule, struct prefix *prefix,
241 route_map_object_t type, void *object)
244 struct ripng_info *rinfo;
246 if (type == RMAP_RIPNG)
251 /* The information stored by rinfo is host ordered. */
252 if (rinfo->tag == *tag)
260 static struct route_map_rule_cmd route_match_tag_cmd =
264 route_map_rule_tag_compile,
265 route_map_rule_tag_free,
268 /* `set metric METRIC' */
270 /* Set metric to attribute. */
271 static route_map_result_t
272 route_set_metric (void *rule, struct prefix *prefix,
273 route_map_object_t type, void *object)
275 if (type == RMAP_RIPNG)
277 struct rip_metric_modifier *mod;
278 struct ripng_info *rinfo;
283 if (mod->type == metric_increment)
284 rinfo->metric_out += mod->metric;
285 else if (mod->type == metric_decrement)
286 rinfo->metric_out-= mod->metric;
287 else if (mod->type == metric_absolute)
288 rinfo->metric_out = mod->metric;
290 if (rinfo->metric_out < 1)
291 rinfo->metric_out = 1;
292 if (rinfo->metric_out > RIPNG_METRIC_INFINITY)
293 rinfo->metric_out = RIPNG_METRIC_INFINITY;
295 rinfo->metric_set = 1;
300 /* set metric compilation. */
302 route_set_metric_compile (const char *arg)
309 struct rip_metric_modifier *mod;
317 /* Examine first character. */
320 type = metric_increment;
323 else if (arg[0] == '-')
325 type = metric_decrement;
329 type = metric_absolute;
331 /* Check beginning with digit string. */
332 if (*pnt < '0' || *pnt > '9')
335 /* Convert string to integer. */
336 metric = strtol (pnt, &endptr, 10);
338 if (metric == LONG_MAX || *endptr != '\0')
340 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
341 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
345 mod = XMALLOC (MTYPE_ROUTE_MAP_COMPILED,
346 sizeof (struct rip_metric_modifier));
348 mod->metric = metric;
353 /* Free route map's compiled `set metric' value. */
355 route_set_metric_free (void *rule)
357 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
360 static struct route_map_rule_cmd route_set_metric_cmd =
364 route_set_metric_compile,
365 route_set_metric_free,
368 /* `set ipv6 next-hop local IP_ADDRESS' */
370 /* Set nexthop to object. ojbect must be pointer to struct attr. */
371 static route_map_result_t
372 route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix,
373 route_map_object_t type, void *object)
375 struct in6_addr *address;
376 struct ripng_info *rinfo;
378 if(type == RMAP_RIPNG)
380 /* Fetch routemap's rule information. */
384 /* Set next hop value. */
385 rinfo->nexthop_out = *address;
391 /* Route map `ipv6 nexthop local' compile function. Given string is converted
392 to struct in6_addr structure. */
394 route_set_ipv6_nexthop_local_compile (const char *arg)
397 struct in6_addr *address;
399 address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in6_addr));
401 ret = inet_pton (AF_INET6, arg, address);
405 XFREE (MTYPE_ROUTE_MAP_COMPILED, address);
412 /* Free route map's compiled `ipv6 nexthop local' value. */
414 route_set_ipv6_nexthop_local_free (void *rule)
416 XFREE (MTYPE_ROUTE_MAP_COMPILED, rule);
419 /* Route map commands for ipv6 nexthop local set. */
420 static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd =
422 "ipv6 next-hop local",
423 route_set_ipv6_nexthop_local,
424 route_set_ipv6_nexthop_local_compile,
425 route_set_ipv6_nexthop_local_free
430 /* Set tag to object. ojbect must be pointer to struct attr. */
431 static route_map_result_t
432 route_set_tag (void *rule, struct prefix *prefix,
433 route_map_object_t type, void *object)
436 struct ripng_info *rinfo;
438 if(type == RMAP_RIPNG)
440 /* Fetch routemap's rule information. */
444 /* Set next hop value. */
445 rinfo->tag_out = *tag;
451 /* Route map commands for tag set. */
452 static struct route_map_rule_cmd route_set_tag_cmd =
456 route_map_rule_tag_compile,
457 route_map_rule_tag_free
460 #define MATCH_STR "Match values from routing table\n"
461 #define SET_STR "Set values in destination routing protocol\n"
465 "match metric <0-4294967295>",
467 "Match metric of route\n"
470 return ripng_route_match_add (vty, vty->index, "metric", argv[0]);
473 DEFUN (no_match_metric,
478 "Match metric of route\n")
481 return ripng_route_match_delete (vty, vty->index, "metric", NULL);
483 return ripng_route_match_delete (vty, vty->index, "metric", argv[0]);
486 ALIAS (no_match_metric,
487 no_match_metric_val_cmd,
488 "no match metric <0-4294967295>",
491 "Match metric of route\n"
494 DEFUN (match_interface,
496 "match interface WORD",
498 "Match first hop interface of route\n"
501 return ripng_route_match_add (vty, vty->index, "interface", argv[0]);
504 DEFUN (no_match_interface,
505 no_match_interface_cmd,
506 "no match interface",
509 "Match first hop interface of route\n")
512 return ripng_route_match_delete (vty, vty->index, "interface", NULL);
514 return ripng_route_match_delete (vty, vty->index, "interface", argv[0]);
517 ALIAS (no_match_interface,
518 no_match_interface_val_cmd,
519 "no match interface WORD",
522 "Match first hop interface of route\n"
527 "match tag <1-4294967295>",
529 "Match tag of route\n"
532 return ripng_route_match_add (vty, vty->index, "tag", argv[0]);
540 "Match tag of route\n")
543 return ripng_route_match_delete (vty, vty->index, "tag", NULL);
545 return ripng_route_match_delete (vty, vty->index, "tag", argv[0]);
549 no_match_tag_val_cmd,
550 "no match tag <1-4294967295>",
553 "Match tag of route\n"
560 "set metric <0-4294967295>",
562 "Metric value for destination routing protocol\n"
565 return ripng_route_set_add (vty, vty->index, "metric", argv[0]);
568 DEFUN (no_set_metric,
573 "Metric value for destination routing protocol\n")
576 return ripng_route_set_delete (vty, vty->index, "metric", NULL);
578 return ripng_route_set_delete (vty, vty->index, "metric", argv[0]);
581 ALIAS (no_set_metric,
582 no_set_metric_val_cmd,
583 "no set metric <0-4294967295>",
586 "Metric value for destination routing protocol\n"
589 DEFUN (set_ipv6_nexthop_local,
590 set_ipv6_nexthop_local_cmd,
591 "set ipv6 next-hop local X:X::X:X",
594 "IPv6 next-hop address\n"
595 "IPv6 local address\n"
596 "IPv6 address of next hop\n")
601 ret = str2sockunion (argv[0], &su);
604 vty_out (vty, "%% Malformed next-hop local address%s", VTY_NEWLINE);
608 return ripng_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]);
611 DEFUN (no_set_ipv6_nexthop_local,
612 no_set_ipv6_nexthop_local_cmd,
613 "no set ipv6 next-hop local",
617 "IPv6 next-hop address\n"
618 "IPv6 local address\n")
621 return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL);
623 return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]);
626 ALIAS (no_set_ipv6_nexthop_local,
627 no_set_ipv6_nexthop_local_val_cmd,
628 "no set ipv6 next-hop local X:X::X:X",
632 "IPv6 next-hop address\n"
633 "IPv6 local address\n"
634 "IPv6 address of next hop\n")
638 "set tag <1-4294967295>",
640 "Tag value for routing protocol\n"
643 return ripng_route_set_add (vty, vty->index, "tag", argv[0]);
651 "Tag value for routing protocol\n")
654 return ripng_route_set_delete (vty, vty->index, "tag", NULL);
656 return ripng_route_set_delete (vty, vty->index, "tag", argv[0]);
661 "no set tag <1-4294967295>",
664 "Tag value for routing protocol\n"
668 ripng_route_map_reset ()
675 ripng_route_map_init ()
678 route_map_init_vty ();
680 route_map_install_match (&route_match_metric_cmd);
681 route_map_install_match (&route_match_interface_cmd);
682 route_map_install_match (&route_match_tag_cmd);
684 route_map_install_set (&route_set_metric_cmd);
685 route_map_install_set (&route_set_ipv6_nexthop_local_cmd);
686 route_map_install_set (&route_set_tag_cmd);
688 install_element (RMAP_NODE, &match_metric_cmd);
689 install_element (RMAP_NODE, &no_match_metric_cmd);
690 install_element (RMAP_NODE, &no_match_metric_val_cmd);
691 install_element (RMAP_NODE, &match_interface_cmd);
692 install_element (RMAP_NODE, &no_match_interface_cmd);
693 install_element (RMAP_NODE, &no_match_interface_val_cmd);
694 install_element (RMAP_NODE, &match_tag_cmd);
695 install_element (RMAP_NODE, &no_match_tag_cmd);
696 install_element (RMAP_NODE, &no_match_tag_val_cmd);
698 install_element (RMAP_NODE, &set_metric_cmd);
699 install_element (RMAP_NODE, &no_set_metric_cmd);
700 install_element (RMAP_NODE, &no_set_metric_val_cmd);
701 install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd);
702 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd);
703 install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd);
704 install_element (RMAP_NODE, &set_tag_cmd);
705 install_element (RMAP_NODE, &no_set_tag_cmd);
706 install_element (RMAP_NODE, &no_set_tag_val_cmd);