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
, "Can't find rule.%s", VTY_NEWLINE
);
60 case RMAP_COMPILE_ERROR
:
61 vty_out (vty
, "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
, "Can't find rule.%s", VTY_NEWLINE
);
82 case RMAP_COMPILE_ERROR
:
83 vty_out (vty
, "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
, "Can't find rule.%s", VTY_NEWLINE
);
104 case RMAP_COMPILE_ERROR
:
105 vty_out (vty
, "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
, "Can't find rule.%s", VTY_NEWLINE
);
126 case RMAP_COMPILE_ERROR
:
127 vty_out (vty
, "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 /* Route map `match tag' match statement. `arg' is TAG value */
262 route_match_tag_compile (const char *arg
)
266 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
272 /* Free route map's compiled `match tag' value. */
274 route_match_tag_free (void *rule
)
276 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
279 /* Route map commands for tag matching. */
280 static struct route_map_rule_cmd route_match_tag_cmd
=
284 route_match_tag_compile
,
288 /* `set metric METRIC' */
290 /* Set metric to attribute. */
291 static route_map_result_t
292 route_set_metric (void *rule
, struct prefix
*prefix
,
293 route_map_object_t type
, void *object
)
295 if (type
== RMAP_RIPNG
)
297 struct rip_metric_modifier
*mod
;
298 struct ripng_info
*rinfo
;
303 if (mod
->type
== metric_increment
)
304 rinfo
->metric_out
+= mod
->metric
;
305 else if (mod
->type
== metric_decrement
)
306 rinfo
->metric_out
-= mod
->metric
;
307 else if (mod
->type
== metric_absolute
)
308 rinfo
->metric_out
= mod
->metric
;
310 if (rinfo
->metric_out
< 1)
311 rinfo
->metric_out
= 1;
312 if (rinfo
->metric_out
> RIPNG_METRIC_INFINITY
)
313 rinfo
->metric_out
= RIPNG_METRIC_INFINITY
;
315 rinfo
->metric_set
= 1;
320 /* set metric compilation. */
322 route_set_metric_compile (const char *arg
)
329 struct rip_metric_modifier
*mod
;
337 /* Examine first character. */
340 type
= metric_increment
;
343 else if (arg
[0] == '-')
345 type
= metric_decrement
;
349 type
= metric_absolute
;
351 /* Check beginning with digit string. */
352 if (*pnt
< '0' || *pnt
> '9')
355 /* Convert string to integer. */
356 metric
= strtol (pnt
, &endptr
, 10);
358 if (metric
== LONG_MAX
|| *endptr
!= '\0')
360 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
361 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
365 mod
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
366 sizeof (struct rip_metric_modifier
));
368 mod
->metric
= metric
;
373 /* Free route map's compiled `set metric' value. */
375 route_set_metric_free (void *rule
)
377 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
380 static struct route_map_rule_cmd route_set_metric_cmd
=
384 route_set_metric_compile
,
385 route_set_metric_free
,
388 /* `set ipv6 next-hop local IP_ADDRESS' */
390 /* Set nexthop to object. ojbect must be pointer to struct attr. */
391 static route_map_result_t
392 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
393 route_map_object_t type
, void *object
)
395 struct in6_addr
*address
;
396 struct ripng_info
*rinfo
;
398 if(type
== RMAP_RIPNG
)
400 /* Fetch routemap's rule information. */
404 /* Set next hop value. */
405 rinfo
->nexthop_out
= *address
;
411 /* Route map `ipv6 nexthop local' compile function. Given string is converted
412 to struct in6_addr structure. */
414 route_set_ipv6_nexthop_local_compile (const char *arg
)
417 struct in6_addr
*address
;
419 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
421 ret
= inet_pton (AF_INET6
, arg
, address
);
425 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
432 /* Free route map's compiled `ipv6 nexthop local' value. */
434 route_set_ipv6_nexthop_local_free (void *rule
)
436 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
439 /* Route map commands for ipv6 nexthop local set. */
440 static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
442 "ipv6 next-hop local",
443 route_set_ipv6_nexthop_local
,
444 route_set_ipv6_nexthop_local_compile
,
445 route_set_ipv6_nexthop_local_free
450 /* Set tag to object. ojbect must be pointer to struct attr. */
451 static route_map_result_t
452 route_set_tag (void *rule
, struct prefix
*prefix
,
453 route_map_object_t type
, void *object
)
456 struct ripng_info
*rinfo
;
458 if(type
== RMAP_RIPNG
)
460 /* Fetch routemap's rule information. */
464 /* Set next hop value. */
465 rinfo
->tag_out
= *tag
;
471 /* Route map `tag' compile function. Given string is converted
474 route_set_tag_compile (const char *arg
)
478 tag
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (u_short
));
484 /* Free route map's compiled `ip nexthop' value. */
486 route_set_tag_free (void *rule
)
488 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
491 /* Route map commands for tag set. */
492 static struct route_map_rule_cmd route_set_tag_cmd
=
496 route_set_tag_compile
,
500 #define MATCH_STR "Match values from routing table\n"
501 #define SET_STR "Set values in destination routing protocol\n"
505 "match metric <0-4294967295>",
507 "Match metric of route\n"
510 return ripng_route_match_add (vty
, vty
->index
, "metric", argv
[0]);
513 DEFUN (no_match_metric
,
518 "Match metric of route\n")
521 return ripng_route_match_delete (vty
, vty
->index
, "metric", NULL
);
523 return ripng_route_match_delete (vty
, vty
->index
, "metric", argv
[0]);
526 ALIAS (no_match_metric
,
527 no_match_metric_val_cmd
,
528 "no match metric <0-4294967295>",
531 "Match metric of route\n"
534 DEFUN (match_interface
,
536 "match interface WORD",
538 "Match first hop interface of route\n"
541 return ripng_route_match_add (vty
, vty
->index
, "interface", argv
[0]);
544 DEFUN (no_match_interface
,
545 no_match_interface_cmd
,
546 "no match interface",
549 "Match first hop interface of route\n")
552 return ripng_route_match_delete (vty
, vty
->index
, "interface", NULL
);
554 return ripng_route_match_delete (vty
, vty
->index
, "interface", argv
[0]);
557 ALIAS (no_match_interface
,
558 no_match_interface_val_cmd
,
559 "no match interface WORD",
562 "Match first hop interface of route\n"
567 "match tag <0-65535>",
569 "Match tag of route\n"
572 return ripng_route_match_add (vty
, vty
->index
, "tag", argv
[0]);
580 "Match tag of route\n")
583 return ripng_route_match_delete (vty
, vty
->index
, "tag", NULL
);
585 return ripng_route_match_delete (vty
, vty
->index
, "tag", argv
[0]);
589 no_match_tag_val_cmd
,
590 "no match tag <0-65535>",
593 "Match tag of route\n"
600 "set metric <0-4294967295>",
602 "Metric value for destination routing protocol\n"
605 return ripng_route_set_add (vty
, vty
->index
, "metric", argv
[0]);
608 DEFUN (no_set_metric
,
613 "Metric value for destination routing protocol\n")
616 return ripng_route_set_delete (vty
, vty
->index
, "metric", NULL
);
618 return ripng_route_set_delete (vty
, vty
->index
, "metric", argv
[0]);
621 ALIAS (no_set_metric
,
622 no_set_metric_val_cmd
,
623 "no set metric <0-4294967295>",
626 "Metric value for destination routing protocol\n"
629 DEFUN (set_ipv6_nexthop_local
,
630 set_ipv6_nexthop_local_cmd
,
631 "set ipv6 next-hop local X:X::X:X",
634 "IPv6 next-hop address\n"
635 "IPv6 local address\n"
636 "IPv6 address of next hop\n")
641 ret
= str2sockunion (argv
[0], &su
);
644 vty_out (vty
, "%% Malformed next-hop local address%s", VTY_NEWLINE
);
648 return ripng_route_set_add (vty
, vty
->index
, "ipv6 next-hop local", argv
[0]);
651 DEFUN (no_set_ipv6_nexthop_local
,
652 no_set_ipv6_nexthop_local_cmd
,
653 "no set ipv6 next-hop local",
657 "IPv6 next-hop address\n"
658 "IPv6 local address\n")
661 return ripng_route_set_delete (vty
, vty
->index
, "ipv6 next-hop local", NULL
);
663 return ripng_route_set_delete (vty
, vty
->index
, "ipv6 next-hop local", argv
[0]);
666 ALIAS (no_set_ipv6_nexthop_local
,
667 no_set_ipv6_nexthop_local_val_cmd
,
668 "no set ipv6 next-hop local X:X::X:X",
672 "IPv6 next-hop address\n"
673 "IPv6 local address\n"
674 "IPv6 address of next hop\n")
680 "Tag value for routing protocol\n"
683 return ripng_route_set_add (vty
, vty
->index
, "tag", argv
[0]);
691 "Tag value for routing protocol\n")
694 return ripng_route_set_delete (vty
, vty
->index
, "tag", NULL
);
696 return ripng_route_set_delete (vty
, vty
->index
, "tag", argv
[0]);
701 "no set tag <0-65535>",
704 "Tag value for routing protocol\n"
708 ripng_route_map_reset ()
715 ripng_route_map_init ()
718 route_map_init_vty ();
720 route_map_install_match (&route_match_metric_cmd
);
721 route_map_install_match (&route_match_interface_cmd
);
722 route_map_install_match (&route_match_tag_cmd
);
724 route_map_install_set (&route_set_metric_cmd
);
725 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
726 route_map_install_set (&route_set_tag_cmd
);
728 install_element (RMAP_NODE
, &match_metric_cmd
);
729 install_element (RMAP_NODE
, &no_match_metric_cmd
);
730 install_element (RMAP_NODE
, &no_match_metric_val_cmd
);
731 install_element (RMAP_NODE
, &match_interface_cmd
);
732 install_element (RMAP_NODE
, &no_match_interface_cmd
);
733 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
734 install_element (RMAP_NODE
, &match_tag_cmd
);
735 install_element (RMAP_NODE
, &no_match_tag_cmd
);
736 install_element (RMAP_NODE
, &no_match_tag_val_cmd
);
738 install_element (RMAP_NODE
, &set_metric_cmd
);
739 install_element (RMAP_NODE
, &no_set_metric_cmd
);
740 install_element (RMAP_NODE
, &no_set_metric_val_cmd
);
741 install_element (RMAP_NODE
, &set_ipv6_nexthop_local_cmd
);
742 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_local_cmd
);
743 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_local_val_cmd
);
744 install_element (RMAP_NODE
, &set_tag_cmd
);
745 install_element (RMAP_NODE
, &no_set_tag_cmd
);
746 install_element (RMAP_NODE
, &no_set_tag_val_cmd
);