diff options
Diffstat (limited to 'ripngd/ripng_routemap.c')
-rw-r--r-- | ripngd/ripng_routemap.c | 619 |
1 files changed, 510 insertions, 109 deletions
diff --git a/ripngd/ripng_routemap.c b/ripngd/ripng_routemap.c index 832f17c9..0bd7e448 100644 --- a/ripngd/ripng_routemap.c +++ b/ripngd/ripng_routemap.c @@ -26,11 +26,175 @@ #include "prefix.h" #include "routemap.h" #include "command.h" +#include "sockunion.h" #include "ripngd/ripngd.h" -#if 0 +struct rip_metric_modifier +{ + enum + { + metric_increment, + metric_decrement, + metric_absolute + } type; + + u_char metric; +}; + + +int +ripng_route_match_add (struct vty *vty, struct route_map_index *index, + char *command, char *arg) +{ + int ret; + + ret = route_map_add_match (index, command, arg); + if (ret) + { + switch (ret) + { + case RMAP_RULE_MISSING: + vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + case RMAP_COMPILE_ERROR: + vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + } + } + return CMD_SUCCESS; +} + +int +ripng_route_match_delete (struct vty *vty, struct route_map_index *index, + char *command, char *arg) +{ + int ret; + + ret = route_map_delete_match (index, command, arg); + if (ret) + { + switch (ret) + { + case RMAP_RULE_MISSING: + vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + case RMAP_COMPILE_ERROR: + vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + } + } + return CMD_SUCCESS; +} + +int +ripng_route_set_add (struct vty *vty, struct route_map_index *index, + char *command, char *arg) +{ + int ret; + + ret = route_map_add_set (index, command, arg); + if (ret) + { + switch (ret) + { + case RMAP_RULE_MISSING: + vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + case RMAP_COMPILE_ERROR: + vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + } + } + return CMD_SUCCESS; +} + +int +ripng_route_set_delete (struct vty *vty, struct route_map_index *index, + char *command, char *arg) +{ + int ret; + + ret = route_map_delete_set (index, command, arg); + if (ret) + { + switch (ret) + { + case RMAP_RULE_MISSING: + vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + case RMAP_COMPILE_ERROR: + vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); + return CMD_WARNING; + break; + } + } + return CMD_SUCCESS; +} + +/* `match metric METRIC' */ +/* Match function return 1 if match is success else return zero. */ +route_map_result_t +route_match_metric (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + u_int32_t *metric; + struct ripng_info *rinfo; + + if (type == RMAP_RIPNG) + { + metric = rule; + rinfo = object; + + if (rinfo->metric == *metric) + return RMAP_MATCH; + else + return RMAP_NOMATCH; + } + return RMAP_NOMATCH; +} + +/* Route map `match metric' match statement. `arg' is METRIC value */ +void * +route_match_metric_compile (char *arg) +{ + u_int32_t *metric; + + metric = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_int32_t)); + *metric = atoi (arg); + + if(*metric > 0) + return metric; + + XFREE (MTYPE_ROUTE_MAP_COMPILED, metric); + return NULL; +} + +/* Free route map's compiled `match metric' value. */ +void +route_match_metric_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for metric matching. */ +struct route_map_rule_cmd route_match_metric_cmd = +{ + "metric", + route_match_metric, + route_match_metric_compile, + route_match_metric_free +}; + /* `match interface IFNAME' */ +/* Match function return 1 if match is success else return zero. */ route_map_result_t route_match_interface (void *rule, struct prefix *prefix, route_map_object_t type, void *object) @@ -39,24 +203,25 @@ route_match_interface (void *rule, struct prefix *prefix, struct interface *ifp; char *ifname; - if (type == ROUTE_MAP_RIPNG) + if (type == RMAP_RIPNG) { ifname = rule; ifp = if_lookup_by_name(ifname); if (!ifp) - return RM_NOMATCH; + return RMAP_NOMATCH; rinfo = object; if (rinfo->ifindex == ifp->ifindex) - return RM_MATCH; + return RMAP_MATCH; else - return RM_NOMATCH; + return RMAP_NOMATCH; } - return RM_NOMATCH; + return RMAP_NOMATCH; } +/* Route map `match interface' match statement. `arg' is IFNAME value */ void * route_match_interface_compile (char *arg) { @@ -76,20 +241,61 @@ struct route_map_rule_cmd route_match_interface_cmd = route_match_interface_compile, route_match_interface_free }; -#endif /* 0 */ - -struct rip_metric_modifier + +/* `match tag TAG' */ +/* Match function return 1 if match is success else return zero. */ +route_map_result_t +route_match_tag (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - enum - { - metric_increment, - metric_decrement, - metric_absolute - } type; + u_short *tag; + struct ripng_info *rinfo; - u_char metric; + if (type == RMAP_RIPNG) + { + tag = rule; + rinfo = object; + + /* The information stored by rinfo is host ordered. */ + if (rinfo->tag == *tag) + return RMAP_MATCH; + else + return RMAP_NOMATCH; + } + return RMAP_NOMATCH; +} + +/* Route map `match tag' match statement. `arg' is TAG value */ +void * +route_match_tag_compile (char *arg) +{ + u_short *tag; + + tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); + *tag = atoi (arg); + + return tag; +} + +/* Free route map's compiled `match tag' value. */ +void +route_match_tag_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} + +/* Route map commands for tag matching. */ +struct route_map_rule_cmd route_match_tag_cmd = +{ + "tag", + route_match_tag, + route_match_tag_compile, + route_match_tag_free }; + +/* `set metric METRIC' */ +/* Set metric to attribute. */ route_map_result_t route_set_metric (void *rule, struct prefix *prefix, route_map_object_t type, void *object) @@ -103,22 +309,23 @@ route_set_metric (void *rule, struct prefix *prefix, rinfo = object; if (mod->type == metric_increment) - rinfo->metric += mod->metric; + rinfo->metric_out += mod->metric; else if (mod->type == metric_decrement) - rinfo->metric -= mod->metric; + rinfo->metric_out-= mod->metric; else if (mod->type == metric_absolute) - rinfo->metric = mod->metric; + rinfo->metric_out = mod->metric; - if (rinfo->metric < 1) - rinfo->metric = 1; - if (rinfo->metric > RIPNG_METRIC_INFINITY) - rinfo->metric = RIPNG_METRIC_INFINITY; + if (rinfo->metric_out < 1) + rinfo->metric_out = 1; + if (rinfo->metric_out > RIPNG_METRIC_INFINITY) + rinfo->metric_out = RIPNG_METRIC_INFINITY; rinfo->metric_set = 1; } return RMAP_OKAY; } +/* set metric compilation. */ void * route_set_metric_compile (char *arg) { @@ -171,6 +378,7 @@ route_set_metric_compile (char *arg) return mod; } +/* Free route map's compiled `set metric' value. */ void route_set_metric_free (void *rule) { @@ -184,109 +392,158 @@ struct route_map_rule_cmd route_set_metric_cmd = route_set_metric_compile, route_set_metric_free, }; - -int -ripng_route_match_add (struct vty *vty, struct route_map_index *index, - char *command, char *arg) + +/* `set ipv6 next-hop local IP_ADDRESS' */ + +/* Set nexthop to object. ojbect must be pointer to struct attr. */ +route_map_result_t +route_set_ipv6_nexthop_local (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) { - int ret; + struct in6_addr *address; + struct ripng_info *rinfo; - ret = route_map_add_match (index, command, arg); - if (ret) + if(type == RMAP_RIPNG) { - switch (ret) - { - case RMAP_RULE_MISSING: - vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - case RMAP_COMPILE_ERROR: - vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - } + /* Fetch routemap's rule information. */ + address = rule; + rinfo = object; + + /* Set next hop value. */ + rinfo->nexthop_out = *address; } - return CMD_SUCCESS; + + return RMAP_OKAY; } -int -ripng_route_match_delete (struct vty *vty, struct route_map_index *index, - char *command, char *arg) +/* Route map `ipv6 nexthop local' compile function. Given string is converted + to struct in6_addr structure. */ +void * +route_set_ipv6_nexthop_local_compile (char *arg) { int ret; + struct in6_addr *address; - ret = route_map_delete_match (index, command, arg); - if (ret) + address = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (struct in_addr)); + + ret = inet_pton (AF_INET6, arg, address); + + if (ret == 0) { - switch (ret) - { - case RMAP_RULE_MISSING: - vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - case RMAP_COMPILE_ERROR: - vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - } + XFREE (MTYPE_ROUTE_MAP_COMPILED, address); + return NULL; } - return CMD_SUCCESS; + + return address; } -int -ripng_route_set_add (struct vty *vty, struct route_map_index *index, - char *command, char *arg) +/* Free route map's compiled `ipv6 nexthop local' value. */ +void +route_set_ipv6_nexthop_local_free (void *rule) { - int ret; + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); +} - ret = route_map_add_set (index, command, arg); - if (ret) +/* Route map commands for ipv6 nexthop local set. */ +struct route_map_rule_cmd route_set_ipv6_nexthop_local_cmd = +{ + "ipv6 next-hop local", + route_set_ipv6_nexthop_local, + route_set_ipv6_nexthop_local_compile, + route_set_ipv6_nexthop_local_free +}; + +/* `set tag TAG' */ + +/* Set tag to object. ojbect must be pointer to struct attr. */ +route_map_result_t +route_set_tag (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + u_short *tag; + struct ripng_info *rinfo; + + if(type == RMAP_RIPNG) { - switch (ret) - { - case RMAP_RULE_MISSING: - vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - case RMAP_COMPILE_ERROR: - vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - } + /* Fetch routemap's rule information. */ + tag = rule; + rinfo = object; + + /* Set next hop value. */ + rinfo->tag_out = *tag; } - return CMD_SUCCESS; + + return RMAP_OKAY; } -int -ripng_route_set_delete (struct vty *vty, struct route_map_index *index, - char *command, char *arg) +/* Route map `tag' compile function. Given string is converted + to u_short. */ +void * +route_set_tag_compile (char *arg) { - int ret; + u_short *tag; - ret = route_map_delete_set (index, command, arg); - if (ret) - { - switch (ret) - { - case RMAP_RULE_MISSING: - vty_out (vty, "Can't find rule.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - case RMAP_COMPILE_ERROR: - vty_out (vty, "Argument is malformed.%s", VTY_NEWLINE); - return CMD_WARNING; - break; - } - } - return CMD_SUCCESS; + tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); + *tag = atoi (arg); + + return tag; +} + +/* Free route map's compiled `ip nexthop' value. */ +void +route_set_tag_free (void *rule) +{ + XFREE (MTYPE_ROUTE_MAP_COMPILED, rule); } + +/* Route map commands for tag set. */ +struct route_map_rule_cmd route_set_tag_cmd = +{ + "tag", + route_set_tag, + route_set_tag_compile, + route_set_tag_free +}; -#if 0 +#define MATCH_STR "Match values from routing table\n" +#define SET_STR "Set values in destination routing protocol\n" + +DEFUN (match_metric, + match_metric_cmd, + "match metric <0-4294967295>", + MATCH_STR + "Match metric of route\n" + "Metric value\n") +{ + return ripng_route_match_add (vty, vty->index, "metric", argv[0]); +} + +DEFUN (no_match_metric, + no_match_metric_cmd, + "no match metric", + NO_STR + MATCH_STR + "Match metric of route\n") +{ + if (argc == 0) + return ripng_route_match_delete (vty, vty->index, "metric", NULL); + + return ripng_route_match_delete (vty, vty->index, "metric", argv[0]); +} + +ALIAS (no_match_metric, + no_match_metric_val_cmd, + "no match metric <0-4294967295>", + NO_STR + MATCH_STR + "Match metric of route\n" + "Metric value\n") + DEFUN (match_interface, match_interface_cmd, "match interface WORD", - "Match value\n" - "Interface\n" + MATCH_STR + "Match first hop interface of route\n" "Interface name\n") { return ripng_route_match_add (vty, vty->index, "interface", argv[0]); @@ -294,22 +551,64 @@ DEFUN (match_interface, DEFUN (no_match_interface, no_match_interface_cmd, + "no match interface", + NO_STR + MATCH_STR + "Match first hop interface of route\n") +{ + if (argc == 0) + return ripng_route_match_delete (vty, vty->index, "interface", NULL); + + return ripng_route_match_delete (vty, vty->index, "interface", argv[0]); +} + +ALIAS (no_match_interface, + no_match_interface_val_cmd, "no match interface WORD", NO_STR - "Match value\n" - "Interface\n" + MATCH_STR + "Match first hop interface of route\n" "Interface name\n") + +DEFUN (match_tag, + match_tag_cmd, + "match tag <0-65535>", + MATCH_STR + "Match tag of route\n" + "Metric value\n") { - return ripng_route_match_delete (vty, vty->index, "interface", argv[0]); + return ripng_route_match_add (vty, vty->index, "tag", argv[0]); +} + +DEFUN (no_match_tag, + no_match_tag_cmd, + "no match tag", + NO_STR + MATCH_STR + "Match tag of route\n") +{ + if (argc == 0) + return ripng_route_match_delete (vty, vty->index, "tag", NULL); + + return ripng_route_match_delete (vty, vty->index, "tag", argv[0]); } -#endif /* 0 */ + +ALIAS (no_match_tag, + no_match_tag_val_cmd, + "no match tag <0-65535>", + NO_STR + MATCH_STR + "Match tag of route\n" + "Metric value\n") + +/* set functions */ DEFUN (set_metric, set_metric_cmd, "set metric <0-4294967295>", "Set value\n" - "Metric\n" - "METRIC value\n") + "Metric value for destination routing protocol\n" + "Metric value\n") { return ripng_route_set_add (vty, vty->index, "metric", argv[0]); } @@ -335,20 +634,122 @@ ALIAS (no_set_metric, "Metric value for destination routing protocol\n" "Metric value\n") +DEFUN (set_ipv6_nexthop_local, + set_ipv6_nexthop_local_cmd, + "set ipv6 next-hop local X:X::X:X", + SET_STR + IPV6_STR + "IPv6 next-hop address\n" + "IPv6 local address\n" + "IPv6 address of next hop\n") +{ + union sockunion su; + int ret; + + ret = str2sockunion (argv[0], &su); + if (ret < 0) + { + vty_out (vty, "%% Malformed next-hop local address%s", VTY_NEWLINE); + return CMD_WARNING; + } + + return ripng_route_set_add (vty, vty->index, "ipv6 next-hop local", argv[0]); +} + +DEFUN (no_set_ipv6_nexthop_local, + no_set_ipv6_nexthop_local_cmd, + "no set ipv6 next-hop local", + NO_STR + SET_STR + IPV6_STR + "IPv6 next-hop address\n" + "IPv6 local address\n") +{ + if (argc == 0) + return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", NULL); + + return ripng_route_set_delete (vty, vty->index, "ipv6 next-hop local", argv[0]); +} + +ALIAS (no_set_ipv6_nexthop_local, + no_set_ipv6_nexthop_local_val_cmd, + "no set ipv6 next-hop local X:X::X:X", + NO_STR + SET_STR + IPV6_STR + "IPv6 next-hop address\n" + "IPv6 local address\n" + "IPv6 address of next hop\n") + +DEFUN (set_tag, + set_tag_cmd, + "set tag <0-65535>", + SET_STR + "Tag value for routing protocol\n" + "Tag value\n") +{ + return ripng_route_set_add (vty, vty->index, "tag", argv[0]); +} + +DEFUN (no_set_tag, + no_set_tag_cmd, + "no set tag", + NO_STR + SET_STR + "Tag value for routing protocol\n") +{ + if (argc == 0) + return ripng_route_set_delete (vty, vty->index, "tag", NULL); + + return ripng_route_set_delete (vty, vty->index, "tag", argv[0]); +} + +ALIAS (no_set_tag, + no_set_tag_val_cmd, + "no set tag <0-65535>", + NO_STR + SET_STR + "Tag value for routing protocol\n" + "Tag value\n") + +void +ripng_route_map_reset () +{ + /* XXX ??? */ + ; +} + void ripng_route_map_init () { route_map_init (); route_map_init_vty (); - /* route_map_install_match (&route_match_interface_cmd); */ + route_map_install_match (&route_match_metric_cmd); + route_map_install_match (&route_match_interface_cmd); + route_map_install_match (&route_match_tag_cmd); + route_map_install_set (&route_set_metric_cmd); + route_map_install_set (&route_set_ipv6_nexthop_local_cmd); + route_map_install_set (&route_set_tag_cmd); - /* + install_element (RMAP_NODE, &match_metric_cmd); + install_element (RMAP_NODE, &no_match_metric_cmd); + install_element (RMAP_NODE, &no_match_metric_val_cmd); install_element (RMAP_NODE, &match_interface_cmd); install_element (RMAP_NODE, &no_match_interface_cmd); - */ + install_element (RMAP_NODE, &no_match_interface_val_cmd); + install_element (RMAP_NODE, &match_tag_cmd); + install_element (RMAP_NODE, &no_match_tag_cmd); + install_element (RMAP_NODE, &no_match_tag_val_cmd); install_element (RMAP_NODE, &set_metric_cmd); install_element (RMAP_NODE, &no_set_metric_cmd); + install_element (RMAP_NODE, &no_set_metric_val_cmd); + install_element (RMAP_NODE, &set_ipv6_nexthop_local_cmd); + install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_cmd); + install_element (RMAP_NODE, &no_set_ipv6_nexthop_local_val_cmd); + install_element (RMAP_NODE, &set_tag_cmd); + install_element (RMAP_NODE, &no_set_tag_cmd); + install_element (RMAP_NODE, &no_set_tag_val_cmd); } |