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
;
245 route_tag_t rinfo_tag
;
247 if (type
== RMAP_RIPNG
)
252 /* The information stored by rinfo is host ordered. */
253 rinfo_tag
= rinfo
->tag
;
254 if (rinfo_tag
== *tag
)
262 static struct route_map_rule_cmd route_match_tag_cmd
=
266 route_map_rule_tag_compile
,
267 route_map_rule_tag_free
,
270 /* `set metric METRIC' */
272 /* Set metric to attribute. */
273 static route_map_result_t
274 route_set_metric (void *rule
, struct prefix
*prefix
,
275 route_map_object_t type
, void *object
)
277 if (type
== RMAP_RIPNG
)
279 struct rip_metric_modifier
*mod
;
280 struct ripng_info
*rinfo
;
285 if (mod
->type
== metric_increment
)
286 rinfo
->metric_out
+= mod
->metric
;
287 else if (mod
->type
== metric_decrement
)
288 rinfo
->metric_out
-= mod
->metric
;
289 else if (mod
->type
== metric_absolute
)
290 rinfo
->metric_out
= mod
->metric
;
292 if (rinfo
->metric_out
< 1)
293 rinfo
->metric_out
= 1;
294 if (rinfo
->metric_out
> RIPNG_METRIC_INFINITY
)
295 rinfo
->metric_out
= RIPNG_METRIC_INFINITY
;
297 rinfo
->metric_set
= 1;
302 /* set metric compilation. */
304 route_set_metric_compile (const char *arg
)
311 struct rip_metric_modifier
*mod
;
319 /* Examine first character. */
322 type
= metric_increment
;
325 else if (arg
[0] == '-')
327 type
= metric_decrement
;
331 type
= metric_absolute
;
333 /* Check beginning with digit string. */
334 if (*pnt
< '0' || *pnt
> '9')
337 /* Convert string to integer. */
338 metric
= strtol (pnt
, &endptr
, 10);
340 if (metric
== LONG_MAX
|| *endptr
!= '\0')
342 /* Commented out by Hasso Tepper, to avoid problems in vtysh. */
343 /* if (metric < 0 || metric > RIPNG_METRIC_INFINITY) */
347 mod
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
,
348 sizeof (struct rip_metric_modifier
));
350 mod
->metric
= metric
;
355 /* Free route map's compiled `set metric' value. */
357 route_set_metric_free (void *rule
)
359 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
362 static struct route_map_rule_cmd route_set_metric_cmd
=
366 route_set_metric_compile
,
367 route_set_metric_free
,
370 /* `set ipv6 next-hop local IP_ADDRESS' */
372 /* Set nexthop to object. ojbect must be pointer to struct attr. */
373 static route_map_result_t
374 route_set_ipv6_nexthop_local (void *rule
, struct prefix
*prefix
,
375 route_map_object_t type
, void *object
)
377 struct in6_addr
*address
;
378 struct ripng_info
*rinfo
;
380 if(type
== RMAP_RIPNG
)
382 /* Fetch routemap's rule information. */
386 /* Set next hop value. */
387 rinfo
->nexthop_out
= *address
;
393 /* Route map `ipv6 nexthop local' compile function. Given string is converted
394 to struct in6_addr structure. */
396 route_set_ipv6_nexthop_local_compile (const char *arg
)
399 struct in6_addr
*address
;
401 address
= XMALLOC (MTYPE_ROUTE_MAP_COMPILED
, sizeof (struct in6_addr
));
403 ret
= inet_pton (AF_INET6
, arg
, address
);
407 XFREE (MTYPE_ROUTE_MAP_COMPILED
, address
);
414 /* Free route map's compiled `ipv6 nexthop local' value. */
416 route_set_ipv6_nexthop_local_free (void *rule
)
418 XFREE (MTYPE_ROUTE_MAP_COMPILED
, rule
);
421 /* Route map commands for ipv6 nexthop local set. */
422 static struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd
=
424 "ipv6 next-hop local",
425 route_set_ipv6_nexthop_local
,
426 route_set_ipv6_nexthop_local_compile
,
427 route_set_ipv6_nexthop_local_free
432 /* Set tag to object. ojbect must be pointer to struct attr. */
433 static route_map_result_t
434 route_set_tag (void *rule
, struct prefix
*prefix
,
435 route_map_object_t type
, void *object
)
438 struct ripng_info
*rinfo
;
440 if(type
== RMAP_RIPNG
)
442 /* Fetch routemap's rule information. */
446 /* Set next hop value. */
447 rinfo
->tag_out
= *tag
;
453 /* Route map commands for tag set. */
454 static struct route_map_rule_cmd route_set_tag_cmd
=
458 route_map_rule_tag_compile
,
459 route_map_rule_tag_free
462 #define MATCH_STR "Match values from routing table\n"
463 #define SET_STR "Set values in destination routing protocol\n"
467 "match metric <0-4294967295>",
469 "Match metric of route\n"
472 return ripng_route_match_add (vty
, vty
->index
, "metric", argv
[0]);
475 DEFUN (no_match_metric
,
480 "Match metric of route\n")
483 return ripng_route_match_delete (vty
, vty
->index
, "metric", NULL
);
485 return ripng_route_match_delete (vty
, vty
->index
, "metric", argv
[0]);
488 ALIAS (no_match_metric
,
489 no_match_metric_val_cmd
,
490 "no match metric <0-4294967295>",
493 "Match metric of route\n"
496 DEFUN (match_interface
,
498 "match interface WORD",
500 "Match first hop interface of route\n"
503 return ripng_route_match_add (vty
, vty
->index
, "interface", argv
[0]);
506 DEFUN (no_match_interface
,
507 no_match_interface_cmd
,
508 "no match interface",
511 "Match first hop interface of route\n")
514 return ripng_route_match_delete (vty
, vty
->index
, "interface", NULL
);
516 return ripng_route_match_delete (vty
, vty
->index
, "interface", argv
[0]);
519 ALIAS (no_match_interface
,
520 no_match_interface_val_cmd
,
521 "no match interface WORD",
524 "Match first hop interface of route\n"
529 "match tag <1-4294967295>",
531 "Match tag of route\n"
534 return ripng_route_match_add (vty
, vty
->index
, "tag", argv
[0]);
542 "Match tag of route\n")
545 return ripng_route_match_delete (vty
, vty
->index
, "tag", NULL
);
547 return ripng_route_match_delete (vty
, vty
->index
, "tag", argv
[0]);
551 no_match_tag_val_cmd
,
552 "no match tag <1-4294967295>",
555 "Match tag of route\n"
562 "set metric <0-4294967295>",
564 "Metric value for destination routing protocol\n"
567 return ripng_route_set_add (vty
, vty
->index
, "metric", argv
[0]);
570 DEFUN (no_set_metric
,
575 "Metric value for destination routing protocol\n")
578 return ripng_route_set_delete (vty
, vty
->index
, "metric", NULL
);
580 return ripng_route_set_delete (vty
, vty
->index
, "metric", argv
[0]);
583 ALIAS (no_set_metric
,
584 no_set_metric_val_cmd
,
585 "no set metric <0-4294967295>",
588 "Metric value for destination routing protocol\n"
591 DEFUN (set_ipv6_nexthop_local
,
592 set_ipv6_nexthop_local_cmd
,
593 "set ipv6 next-hop local X:X::X:X",
596 "IPv6 next-hop address\n"
597 "IPv6 local address\n"
598 "IPv6 address of next hop\n")
603 ret
= str2sockunion (argv
[0], &su
);
606 vty_out (vty
, "%% Malformed next-hop local address%s", VTY_NEWLINE
);
610 if (!IN6_IS_ADDR_LINKLOCAL(&su
.sin6
.sin6_addr
))
612 vty_out (vty
, "%% Invalid link-local nexthop address%s", VTY_NEWLINE
);
616 return ripng_route_set_add (vty
, vty
->index
, "ipv6 next-hop local", argv
[0]);
619 DEFUN (no_set_ipv6_nexthop_local
,
620 no_set_ipv6_nexthop_local_cmd
,
621 "no set ipv6 next-hop local",
625 "IPv6 next-hop address\n"
626 "IPv6 local address\n")
629 return ripng_route_set_delete (vty
, vty
->index
, "ipv6 next-hop local", NULL
);
631 return ripng_route_set_delete (vty
, vty
->index
, "ipv6 next-hop local", argv
[0]);
634 ALIAS (no_set_ipv6_nexthop_local
,
635 no_set_ipv6_nexthop_local_val_cmd
,
636 "no set ipv6 next-hop local X:X::X:X",
640 "IPv6 next-hop address\n"
641 "IPv6 local address\n"
642 "IPv6 address of next hop\n")
646 "set tag <1-4294967295>",
648 "Tag value for routing protocol\n"
651 return ripng_route_set_add (vty
, vty
->index
, "tag", argv
[0]);
659 "Tag value for routing protocol\n")
662 return ripng_route_set_delete (vty
, vty
->index
, "tag", NULL
);
664 return ripng_route_set_delete (vty
, vty
->index
, "tag", argv
[0]);
669 "no set tag <1-4294967295>",
672 "Tag value for routing protocol\n"
676 ripng_route_map_reset ()
683 ripng_route_map_init ()
687 route_map_install_match (&route_match_metric_cmd
);
688 route_map_install_match (&route_match_interface_cmd
);
689 route_map_install_match (&route_match_tag_cmd
);
691 route_map_install_set (&route_set_metric_cmd
);
692 route_map_install_set (&route_set_ipv6_nexthop_local_cmd
);
693 route_map_install_set (&route_set_tag_cmd
);
695 install_element (RMAP_NODE
, &match_metric_cmd
);
696 install_element (RMAP_NODE
, &no_match_metric_cmd
);
697 install_element (RMAP_NODE
, &no_match_metric_val_cmd
);
698 install_element (RMAP_NODE
, &match_interface_cmd
);
699 install_element (RMAP_NODE
, &no_match_interface_cmd
);
700 install_element (RMAP_NODE
, &no_match_interface_val_cmd
);
701 install_element (RMAP_NODE
, &match_tag_cmd
);
702 install_element (RMAP_NODE
, &no_match_tag_cmd
);
703 install_element (RMAP_NODE
, &no_match_tag_val_cmd
);
705 install_element (RMAP_NODE
, &set_metric_cmd
);
706 install_element (RMAP_NODE
, &no_set_metric_cmd
);
707 install_element (RMAP_NODE
, &no_set_metric_val_cmd
);
708 install_element (RMAP_NODE
, &set_ipv6_nexthop_local_cmd
);
709 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_local_cmd
);
710 install_element (RMAP_NODE
, &no_set_ipv6_nexthop_local_val_cmd
);
711 install_element (RMAP_NODE
, &set_tag_cmd
);
712 install_element (RMAP_NODE
, &no_set_tag_cmd
);
713 install_element (RMAP_NODE
, &no_set_tag_val_cmd
);