]> git.puffer.fish Git - mirror/frr.git/commitdiff
lib: rmap dep table is not correct in case of exact-match clause 4887/head
authorvdhingra <vdhingra@vmware.com>
Tue, 27 Aug 2019 10:45:54 +0000 (03:45 -0700)
committervdhingra <vdhingra@vmware.com>
Sun, 15 Sep 2019 12:45:27 +0000 (05:45 -0700)
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 <vdhingra@vmware.com>
bgpd/bgp_routemap.c
bgpd/bgp_rpki.c
eigrpd/eigrp_routemap.c
lib/routemap.c
lib/routemap.h
ospf6d/ospf6_asbr.c
zebra/zebra_routemap.c

index b1f1819b6baac61d4230dced6e137f13e1625181..a69cf26b8b701b706e5e00a66cfa07964a1292d5 100644 (file)
@@ -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
                 */
index 2cfd65896c9ac1160ca86a00ef0ef67b5276cd49..352e3b87e81fdb0adaa4f610b61b36851b63ac47 100644 (file)
@@ -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
                         */
index d78588644f5cceba071b854bde3266d3fcc6b6c1..e7a7cc56aacfd66a5e1113855361630833f70fd9 100644 (file)
@@ -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
                 */
index fc15183bf95c8d029b5438f42c0d06751f4c6304..580d898448d4d4e0dfa559d1400326493a1c874e 100644 (file)
@@ -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. */
index 40525987e94662d8ef0b544d1f9fbd96ea111c12..e6eccd4b291d69d438db27c985f55a2e6bee353a 100644 (file)
@@ -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);
index 4d1c085081760c061829e5588c3b53d95d7d2d5c..7914412e875bb43632fa0bbc3763f6cb3587963b 100644 (file)
@@ -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;
        }
 
index 88d2091394c99dcf74ee0e5a8e7b6c33cdc0b7e9..364f5755d8235237d89c734839ab92d8e72895d4 100644 (file)
@@ -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
                 */