From 909f3d56aef817208942635fc843b148edb5f38e Mon Sep 17 00:00:00 2001 From: vdhingra Date: Tue, 27 Aug 2019 03:45:54 -0700 Subject: [PATCH] lib: rmap dep table is not correct in case of exact-match clause MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit User pass the string match large-community 1 exact-match from CLI. Now route map lib has got the string as "1 exact-match". It passes the string to call back for compilation. BGP will parse this string and came to know that for "1" it has to do exact match. Routemap lib has to save "1" in it’s dependency table. Here routemap is saving this as a “1 exact-match” which is wrong. The solution is used the compiled data. Signed-off-by: vishaldhingra --- bgpd/bgp_routemap.c | 32 +++++++++++++++++++----------- bgpd/bgp_rpki.c | 5 ++--- eigrpd/eigrp_routemap.c | 6 +----- lib/routemap.c | 44 +++++++++++++++++++++++++---------------- lib/routemap.h | 8 +++++--- ospf6d/ospf6_asbr.c | 1 - zebra/zebra_routemap.c | 11 +---------- 7 files changed, 56 insertions(+), 51 deletions(-) diff --git a/bgpd/bgp_routemap.c b/bgpd/bgp_routemap.c index b1f1819b6b..a69cf26b8b 100644 --- a/bgpd/bgp_routemap.c +++ b/bgpd/bgp_routemap.c @@ -1210,10 +1210,26 @@ static void route_match_community_free(void *rule) XFREE(MTYPE_ROUTE_MAP_COMPILED, rcom); } +/* + * In routemap processing there is a need to add the + * name as a rule_key in the dependency table. Routemap + * lib is unaware of rule_key when exact-match clause + * is in use. routemap lib uses the compiled output to + * get the rule_key value. + */ +static void *route_match_get_community_key(void *rule) +{ + struct rmap_community *rcom; + + rcom = rule; + return rcom->name; +} + + /* Route map commands for community matching. */ struct route_map_rule_cmd route_match_community_cmd = { "community", route_match_community, route_match_community_compile, - route_match_community_free}; + route_match_community_free, route_match_get_community_key}; /* Match function for lcommunity match. */ static enum route_map_cmd_result_t @@ -1284,7 +1300,8 @@ static void route_match_lcommunity_free(void *rule) /* Route map commands for community matching. */ struct route_map_rule_cmd route_match_lcommunity_cmd = { "large-community", route_match_lcommunity, - route_match_lcommunity_compile, route_match_lcommunity_free}; + route_match_lcommunity_compile, route_match_lcommunity_free, + route_match_get_community_key}; /* Match function for extcommunity match. */ @@ -3073,11 +3090,6 @@ static int bgp_route_match_add(struct vty *vty, const char *command, retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - if (type != RMAP_EVENT_MATCH_ADDED) { - route_map_upd8_dependency(type, arg, index->map->name); - } - break; - case RMAP_DUPLICATE_RULE: /* * Intentionally doing nothing here. */ @@ -3111,7 +3123,7 @@ static int bgp_route_match_delete(struct vty *vty, const char *command, rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name); } - ret = route_map_delete_match(index, command, dep_name); + ret = route_map_delete_match(index, command, dep_name, type); switch (ret) { case RMAP_RULE_MISSING: vty_out(vty, "%% BGP Can't find rule.\n"); @@ -3122,10 +3134,6 @@ static int bgp_route_match_delete(struct vty *vty, const char *command, retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - if (type != RMAP_EVENT_MATCH_DELETED && dep_name) - route_map_upd8_dependency(type, dep_name, rmap_name); - break; - case RMAP_DUPLICATE_RULE: /* * Nothing to do here */ diff --git a/bgpd/bgp_rpki.c b/bgpd/bgp_rpki.c index 2cfd65896c..352e3b87e8 100644 --- a/bgpd/bgp_rpki.c +++ b/bgpd/bgp_rpki.c @@ -1420,7 +1420,6 @@ DEFUN (match_rpki, vty_out(vty, "%% BGP Argument is malformed.\n"); return CMD_WARNING_CONFIG_FAILED; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: /* * Intentionally doing nothing here */ @@ -1443,7 +1442,8 @@ DEFUN (no_match_rpki, VTY_DECLVAR_CONTEXT(route_map_index, index); enum rmap_compile_rets ret; - ret = route_map_delete_match(index, "rpki", argv[3]->arg); + ret = route_map_delete_match(index, "rpki", argv[3]->arg, + RMAP_EVENT_MATCH_DELETED); if (ret) { switch (ret) { case RMAP_RULE_MISSING: @@ -1453,7 +1453,6 @@ DEFUN (no_match_rpki, vty_out(vty, "%% BGP Argument is malformed.\n"); break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: /* * Nothing to do here */ diff --git a/eigrpd/eigrp_routemap.c b/eigrpd/eigrp_routemap.c index d78588644f..e7a7cc56aa 100644 --- a/eigrpd/eigrp_routemap.c +++ b/eigrpd/eigrp_routemap.c @@ -148,7 +148,6 @@ static int eigrp_route_match_add(struct vty *vty, struct route_map_index *index, return CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: /* * Intentionally not handling these cases */ @@ -165,7 +164,7 @@ static int eigrp_route_match_delete(struct vty *vty, { enum rmap_compile_rets ret; - ret = route_map_delete_match(index, command, arg); + ret = route_map_delete_match(index, command, arg, type); switch (ret) { case RMAP_RULE_MISSING: vty_out(vty, "%% Can't find rule.\n"); @@ -176,7 +175,6 @@ static int eigrp_route_match_delete(struct vty *vty, return CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: /* * These cases intentionally ignored */ @@ -211,7 +209,6 @@ static int eigrp_route_set_add(struct vty *vty, struct route_map_index *index, } break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: /* * These cases intentionally left blank here */ @@ -239,7 +236,6 @@ static int eigrp_route_set_delete(struct vty *vty, return CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: /* * These cases intentionally not handled */ diff --git a/lib/routemap.c b/lib/routemap.c index fc15183bf9..580d898448 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -478,11 +478,6 @@ int generic_match_add(struct vty *vty, struct route_map_index *index, ret = route_map_add_match(index, command, arg, type); switch (ret) { - case RMAP_COMPILE_SUCCESS: - if (type != RMAP_EVENT_MATCH_ADDED) { - route_map_upd8_dependency(type, arg, index->map->name); - } - break; case RMAP_RULE_MISSING: vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; @@ -493,7 +488,7 @@ int generic_match_add(struct vty *vty, struct route_map_index *index, frr_protonameinst); return CMD_WARNING_CONFIG_FAILED; break; - case RMAP_DUPLICATE_RULE: + case RMAP_COMPILE_SUCCESS: /* * Nothing to do here move along */ @@ -526,7 +521,7 @@ int generic_match_delete(struct vty *vty, struct route_map_index *index, rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name); } - ret = route_map_delete_match(index, command, dep_name); + ret = route_map_delete_match(index, command, dep_name, type); switch (ret) { case RMAP_RULE_MISSING: vty_out(vty, "%% [%s] Can't find rule.\n", frr_protonameinst); @@ -539,10 +534,6 @@ int generic_match_delete(struct vty *vty, struct route_map_index *index, retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - if (type != RMAP_EVENT_MATCH_DELETED && dep_name) - route_map_upd8_dependency(type, dep_name, rmap_name); - break; - case RMAP_DUPLICATE_RULE: /* * Nothing to do here */ @@ -573,7 +564,6 @@ int generic_set_add(struct vty *vty, struct route_map_index *index, return CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: break; } @@ -598,7 +588,6 @@ int generic_set_delete(struct vty *vty, struct route_map_index *index, return CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: break; } @@ -1410,6 +1399,7 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, struct route_map_rule_cmd *cmd; void *compile; int8_t delete_rmap_event_type = 0; + const char *rule_key; /* First lookup rule for add match statement. */ cmd = route_map_lookup_match(match_name); @@ -1423,6 +1413,12 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, return RMAP_COMPILE_ERROR; } else compile = NULL; + /* use the compiled results if applicable */ + if (compile && cmd->func_get_rmap_rule_key) + rule_key = (*cmd->func_get_rmap_rule_key) + (compile); + else + rule_key = match_arg; /* If argument is completely same ignore it. */ for (rule = index->match_list.head; rule; rule = next) { @@ -1436,7 +1432,7 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, if (cmd->func_free) (*cmd->func_free)(compile); - return RMAP_DUPLICATE_RULE; + return RMAP_COMPILE_SUCCESS; } /* Remove the dependency of the route-map on the rule @@ -1447,7 +1443,7 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, get_route_map_delete_event(type); route_map_upd8_dependency( delete_rmap_event_type, - rule->rule_str, + rule_key, index->map->name); } @@ -1473,6 +1469,8 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, route_map_notify_dependencies(index->map->name, RMAP_EVENT_CALL_ADDED); } + if (type != RMAP_EVENT_MATCH_ADDED) + route_map_upd8_dependency(type, rule_key, index->map->name); return RMAP_COMPILE_SUCCESS; } @@ -1480,10 +1478,12 @@ enum rmap_compile_rets route_map_add_match(struct route_map_index *index, /* Delete specified route match rule. */ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index, const char *match_name, - const char *match_arg) + const char *match_arg, + route_map_event_t type) { struct route_map_rule *rule; struct route_map_rule_cmd *cmd; + const char *rule_key; cmd = route_map_lookup_match(match_name); if (cmd == NULL) @@ -1492,7 +1492,6 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index, for (rule = index->match_list.head; rule; rule = rule->next) if (rule->cmd == cmd && (rulecmp(rule->rule_str, match_arg) == 0 || match_arg == NULL)) { - route_map_rule_delete(&index->match_list, rule); /* Execute event hook. */ if (route_map_master.event_hook) { (*route_map_master.event_hook)(index->map->name); @@ -1500,6 +1499,17 @@ enum rmap_compile_rets route_map_delete_match(struct route_map_index *index, index->map->name, RMAP_EVENT_CALL_ADDED); } + if (cmd->func_get_rmap_rule_key) + rule_key = (*cmd->func_get_rmap_rule_key) + (rule->value); + else + rule_key = match_arg; + + if (type != RMAP_EVENT_MATCH_DELETED && rule_key) + route_map_upd8_dependency(type, rule_key, + index->map->name); + + route_map_rule_delete(&index->match_list, rule); return RMAP_COMPILE_SUCCESS; } /* Can't find matched rule. */ diff --git a/lib/routemap.h b/lib/routemap.h index 40525987e9..e6eccd4b29 100644 --- a/lib/routemap.h +++ b/lib/routemap.h @@ -123,6 +123,9 @@ struct route_map_rule_cmd { /* Free allocated value by func_compile (). */ void (*func_free)(void *); + + /** To get the rule key after Compilation **/ + void *(*func_get_rmap_rule_key)(void *val); }; /* Route map apply error. */ @@ -135,8 +138,6 @@ enum rmap_compile_rets { /* Route map rule can't compile */ RMAP_COMPILE_ERROR, - /* Route map rule is duplicate */ - RMAP_DUPLICATE_RULE }; /* Route map rule list. */ @@ -228,7 +229,8 @@ extern enum rmap_compile_rets route_map_add_match(struct route_map_index *index, /* Delete specified route match rule. */ extern enum rmap_compile_rets route_map_delete_match(struct route_map_index *index, - const char *match_name, const char *match_arg); + const char *match_name, const char *match_arg, + route_map_event_t type); extern const char *route_map_get_match_arg(struct route_map_index *index, const char *match_name); diff --git a/ospf6d/ospf6_asbr.c b/ospf6d/ospf6_asbr.c index 4d1c085081..7914412e87 100644 --- a/ospf6d/ospf6_asbr.c +++ b/ospf6d/ospf6_asbr.c @@ -1593,7 +1593,6 @@ static int route_map_command_status(struct vty *vty, enum rmap_compile_rets ret) return CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - case RMAP_DUPLICATE_RULE: break; } diff --git a/zebra/zebra_routemap.c b/zebra/zebra_routemap.c index 88d2091394..364f5755d8 100644 --- a/zebra/zebra_routemap.c +++ b/zebra/zebra_routemap.c @@ -78,11 +78,6 @@ static int zebra_route_match_add(struct vty *vty, const char *command, retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - if (type != RMAP_EVENT_MATCH_ADDED) { - route_map_upd8_dependency(type, arg, index->map->name); - } - break; - case RMAP_DUPLICATE_RULE: /* * Nothing to do here */ @@ -116,7 +111,7 @@ static int zebra_route_match_delete(struct vty *vty, const char *command, rmap_name = XSTRDUP(MTYPE_ROUTE_MAP_NAME, index->map->name); } - ret = route_map_delete_match(index, command, arg); + ret = route_map_delete_match(index, command, arg, type); switch (ret) { case RMAP_RULE_MISSING: vty_out(vty, "%% Zebra Can't find rule.\n"); @@ -127,10 +122,6 @@ static int zebra_route_match_delete(struct vty *vty, const char *command, retval = CMD_WARNING_CONFIG_FAILED; break; case RMAP_COMPILE_SUCCESS: - if (type != RMAP_EVENT_MATCH_DELETED && dep_name) - route_map_upd8_dependency(type, dep_name, rmap_name); - break; - case RMAP_DUPLICATE_RULE: /* * Nothing to do here */ -- 2.39.5