From 0d9551dc3c53f2d46e3c0e3ecb4e4b0eb327179e Mon Sep 17 00:00:00 2001 From: Donald Sharp Date: Tue, 19 May 2015 17:46:33 -0700 Subject: Add support for route tags Credit ------ A huge amount of credit for this patch goes to Piotr Chytla for their 'route tags support' patch that was submitted to quagga-dev in June 2007. Documentation ------------- All ipv4 and ipv6 static route commands now have a "tag" option which allows the user to set a tag between 1 and 65535. quagga(config)# ip route 1.1.1.1/32 10.1.1.1 tag ? <1-65535> Tag value quagga(config)# ip route 1.1.1.1/32 10.1.1.1 tag 40 quagga(config)# quagga# show ip route 1.1.1.1/32 Routing entry for 1.1.1.1/32 Known via "static", distance 1, metric 0, tag 40, best * 10.1.1.1, via swp1 quagga# The route-map parser supports matching on tags and setting tags ! route-map MATCH_TAG_18 permit 10 match tag 18 ! ! route-map SET_TAG_22 permit 10 set tag 22 ! BGP and OSPF support: - matching on tags when redistribing routes from the RIB into BGP/OSPF. - setting tags when redistribing routes from the RIB into BGP/OSPF. BGP also supports setting a tag via a table-map, when installing BGP routes into the RIB. Signed-off-by: Daniel Walton --- ospfd/ospf_routemap.c | 192 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 192 insertions(+) (limited to 'ospfd/ospf_routemap.c') diff --git a/ospfd/ospf_routemap.c b/ospfd/ospf_routemap.c index d0ebce66e..7bd6c3d96 100644 --- a/ospfd/ospf_routemap.c +++ b/ospfd/ospf_routemap.c @@ -417,6 +417,67 @@ struct route_map_rule_cmd route_match_interface_cmd = route_match_interface_free }; +/* Match function return 1 if match is success else return zero. */ +static route_map_result_t +route_match_tag (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + u_short *tag; + struct external_info *ei; + + if (type == RMAP_OSPF) + { + tag = rule; + ei = object; + + return ((ei->tag == *tag)? RMAP_MATCH : RMAP_NOMATCH); + } + + return RMAP_NOMATCH; +} + +/* Route map `match tag' match statement. `arg' is TAG value */ +static void * +route_match_tag_compile (const char *arg) +{ + u_short *tag; + u_short tmp; + + /* tag value shoud be integer. */ + if (! all_digit (arg)) + return NULL; + + tmp = atoi(arg); + if (tmp < 1) + return NULL; + + tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); + + if (!tag) + return tag; + + *tag = tmp; + + return tag; +} + +/* Free route map's compiled 'match tag' value. */ +static 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. */ static route_map_result_t @@ -531,6 +592,67 @@ struct route_map_rule_cmd route_set_metric_type_cmd = route_set_metric_type_free, }; +static route_map_result_t +route_set_tag (void *rule, struct prefix *prefix, + route_map_object_t type, void *object) +{ + u_short *tag; + struct external_info *ei; + + if (type == RMAP_OSPF) + { + tag = rule; + ei = object; + + /* Set tag value */ + ei->tag=*tag; + } + + return RMAP_OKAY; +} + +/* Route map `tag' compile function. Given string is converted to u_short. */ +static void * +route_set_tag_compile (const char *arg) +{ + u_short *tag; + u_short tmp; + + /* tag value shoud be integer. */ + if (! all_digit (arg)) + return NULL; + + tmp = atoi(arg); + + if (tmp < 1) + return NULL; + + tag = XMALLOC (MTYPE_ROUTE_MAP_COMPILED, sizeof (u_short)); + + if (!tag) + return tag; + + *tag = tmp; + + return tag; +} + +/* Free route map's tag value. */ +static 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, +}; + DEFUN (match_ip_nexthop, match_ip_nexthop_cmd, "match ip next-hop (<1-199>|<1300-2699>|WORD)", @@ -716,6 +838,37 @@ ALIAS (no_match_interface, "Match first hop interface of route\n" "Interface name\n") +DEFUN (match_tag, + match_tag_cmd, + "match tag <1-65535>", + MATCH_STR + "Match tag of route\n" + "Tag value\n") +{ + return ospf_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 ospf_route_match_delete (vty, vty->index, "tag", NULL); + + return ospf_route_match_delete (vty, vty->index, "tag", argv[0]); +} + +ALIAS (no_match_tag, + no_match_tag_val_cmd, + "no match tag <1-65535>", + NO_STR + MATCH_STR + "Match tag of route\n" + "Tag value\n") + DEFUN (set_metric, set_metric_cmd, "set metric <0-4294967295>", @@ -785,6 +938,37 @@ ALIAS (no_set_metric_type, "OSPF[6] external type 1 metric\n" "OSPF[6] external type 2 metric\n") +DEFUN (set_tag, + set_tag_cmd, + "set tag <1-65535>", + SET_STR + "Tag value for routing protocol\n" + "Tag value\n") +{ + return ospf_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) + ospf_route_set_delete(vty, vty->index, "tag", NULL); + + return ospf_route_set_delete (vty, vty->index, "tag", argv[0]); +} + +ALIAS (no_set_tag, + no_set_tag_val_cmd, + "no set tag <1-65535>", + NO_STR + SET_STR + "Tag value for routing protocol\n" + "Tag value\n") + /* Route-map init */ void ospf_route_map_init (void) @@ -801,9 +985,11 @@ ospf_route_map_init (void) route_map_install_match (&route_match_ip_address_cmd); route_map_install_match (&route_match_ip_address_prefix_list_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_metric_type_cmd); + route_map_install_set (&route_set_tag_cmd); install_element (RMAP_NODE, &match_ip_nexthop_cmd); install_element (RMAP_NODE, &no_match_ip_nexthop_cmd); @@ -820,6 +1006,9 @@ ospf_route_map_init (void) 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); @@ -827,4 +1016,7 @@ ospf_route_map_init (void) install_element (RMAP_NODE, &set_metric_type_cmd); install_element (RMAP_NODE, &no_set_metric_type_cmd); install_element (RMAP_NODE, &no_set_metric_type_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); } -- cgit v1.2.3