Add support for filtering by tag in a route-map when installing routes in the kernel

This commit is contained in:
Donald Sharp 2015-05-19 18:03:44 -07:00
parent 0de5153cfb
commit ca84c8efc3
3 changed files with 107 additions and 4 deletions

View File

@ -1263,9 +1263,9 @@ nexthop_active_check (struct route_node *rn, struct rib *rib,
family = info->afi; family = info->afi;
memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr)); memset(&nexthop->rmap_src.ipv6, 0, sizeof(union g_addr));
/* It'll get set if required inside */
ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop); /* It'll get set if required inside */
ret = zebra_route_map_check(family, rib->type, &rn->p, nexthop, rib->tag);
if (ret == RMAP_DENYMATCH) if (ret == RMAP_DENYMATCH)
{ {
if (IS_ZEBRA_DEBUG_RIB) if (IS_ZEBRA_DEBUG_RIB)

View File

@ -46,6 +46,7 @@ struct nh_rmap_obj
struct nexthop *nexthop; struct nexthop *nexthop;
u_int32_t source_protocol; u_int32_t source_protocol;
int metric; int metric;
u_short tag;
}; };
static void zebra_route_map_set_delay_timer(u_int32_t value); static void zebra_route_map_set_delay_timer(u_int32_t value);
@ -172,6 +173,68 @@ zebra_route_set_delete (struct vty *vty, struct route_map_index *index,
return CMD_SUCCESS; return CMD_SUCCESS;
} }
/* 'match tag TAG'
* Match function return 1 if match is success else return 0
*/
static route_map_result_t
route_match_tag (void *rule, struct prefix *prefix,
route_map_object_t type, void *object)
{
u_short *tag;
struct nh_rmap_obj *nh_data;
if (type == RMAP_ZEBRA)
{
tag = rule;
nh_data = object;
if (nh_data->tag == *tag)
return RMAP_MATCH;
}
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
};
/* `match interface IFNAME' */ /* `match interface IFNAME' */
/* Match function return 1 if match is success else return zero. */ /* Match function return 1 if match is success else return zero. */
@ -254,6 +317,39 @@ ALIAS (no_match_interface,
"Match first hop interface of route\n" "Match first hop interface of route\n"
"Interface name\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 zebra_route_match_add (vty, vty->index, "tag", argv[0],
RMAP_EVENT_MATCH_ADDED);
}
DEFUN (no_match_tag,
no_match_tag_cmd,
"no match tag",
NO_STR
MATCH_STR
"Match tag of route\n")
{
if (argc == 0)
return zebra_route_match_delete (vty, vty->index, "tag", NULL,
RMAP_EVENT_MATCH_DELETED);
return zebra_route_match_delete (vty, vty->index, "tag", argv[0],
RMAP_EVENT_MATCH_DELETED);
}
ALIAS (no_match_tag,
no_match_tag_val_cmd,
"no match tag <1-65535>",
NO_STR
MATCH_STR
"Match tag of route\n")
DEFUN (match_ip_next_hop, DEFUN (match_ip_next_hop,
match_ip_next_hop_cmd, match_ip_next_hop_cmd,
"match ip next-hop (<1-199>|<1300-2699>|WORD)", "match ip next-hop (<1-199>|<1300-2699>|WORD)",
@ -1380,7 +1476,7 @@ zebra_route_map_write_delay_timer (struct vty *vty)
route_map_result_t route_map_result_t
zebra_route_map_check (int family, int rib_type, struct prefix *p, zebra_route_map_check (int family, int rib_type, struct prefix *p,
struct nexthop *nexthop) struct nexthop *nexthop, u_short tag)
{ {
struct route_map *rmap = NULL; struct route_map *rmap = NULL;
route_map_result_t ret = RMAP_MATCH; route_map_result_t ret = RMAP_MATCH;
@ -1389,6 +1485,7 @@ zebra_route_map_check (int family, int rib_type, struct prefix *p,
nh_obj.nexthop = nexthop; nh_obj.nexthop = nexthop;
nh_obj.source_protocol = rib_type; nh_obj.source_protocol = rib_type;
nh_obj.metric = 0; nh_obj.metric = 0;
nh_obj.tag = tag;
if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX) if (rib_type >= 0 && rib_type < ZEBRA_ROUTE_MAX)
rmap = route_map_lookup_by_name (proto_rm[family][rib_type]); rmap = route_map_lookup_by_name (proto_rm[family][rib_type]);
@ -1412,6 +1509,7 @@ zebra_nht_route_map_check (int family, int client_proto, struct prefix *p,
nh_obj.nexthop = nexthop; nh_obj.nexthop = nexthop;
nh_obj.source_protocol = rib->type; nh_obj.source_protocol = rib->type;
nh_obj.metric = rib->metric; nh_obj.metric = rib->metric;
nh_obj.tag = rib->tag;
if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX) if (client_proto >= 0 && client_proto < ZEBRA_ROUTE_MAX)
rmap = route_map_lookup_by_name (nht_rm[family][client_proto]); rmap = route_map_lookup_by_name (nht_rm[family][client_proto]);
@ -1524,6 +1622,7 @@ zebra_route_map_init ()
route_map_delete_hook (zebra_route_map_delete); route_map_delete_hook (zebra_route_map_delete);
route_map_event_hook (zebra_route_map_event); route_map_event_hook (zebra_route_map_event);
route_map_install_match (&route_match_tag_cmd);
route_map_install_match (&route_match_interface_cmd); route_map_install_match (&route_match_interface_cmd);
route_map_install_match (&route_match_ip_next_hop_cmd); route_map_install_match (&route_match_ip_next_hop_cmd);
route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd); route_map_install_match (&route_match_ip_next_hop_prefix_list_cmd);
@ -1535,6 +1634,9 @@ zebra_route_map_init ()
/* */ /* */
route_map_install_set (&route_set_src_cmd); route_map_install_set (&route_set_src_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, &match_interface_cmd); install_element (RMAP_NODE, &match_interface_cmd);
install_element (RMAP_NODE, &no_match_interface_cmd); install_element (RMAP_NODE, &no_match_interface_cmd);
install_element (RMAP_NODE, &no_match_interface_val_cmd); install_element (RMAP_NODE, &no_match_interface_val_cmd);

View File

@ -157,7 +157,8 @@ extern int zebra_server_send_message(struct zserv *client);
extern void zebra_route_map_write_delay_timer(struct vty *); extern void zebra_route_map_write_delay_timer(struct vty *);
extern route_map_result_t zebra_route_map_check (int family, int rib_type, extern route_map_result_t zebra_route_map_check (int family, int rib_type,
struct prefix *p, struct prefix *p,
struct nexthop *nexthop); struct nexthop *nexthop,
u_short tag);
extern route_map_result_t zebra_nht_route_map_check (int family, extern route_map_result_t zebra_nht_route_map_check (int family,
int client_proto, int client_proto,
struct prefix *p, struct prefix *p,