diff options
Diffstat (limited to 'lib/routemap.c')
| -rw-r--r-- | lib/routemap.c | 89 |
1 files changed, 55 insertions, 34 deletions
diff --git a/lib/routemap.c b/lib/routemap.c index 4898a8d0fa..3542994e65 100644 --- a/lib/routemap.c +++ b/lib/routemap.c @@ -616,14 +616,14 @@ struct route_map_list { void (*add_hook)(const char *); void (*delete_hook)(const char *); - void (*event_hook)(route_map_event_t, const char *); + void (*event_hook)(const char *); }; /* Master list of route map. */ static struct route_map_list route_map_master = {NULL, NULL, NULL, NULL, NULL}; struct hash *route_map_master_hash = NULL; -static unsigned int route_map_hash_key_make(void *p) +static unsigned int route_map_hash_key_make(const void *p) { const struct route_map *map = p; return string_hash_make(map->name); @@ -673,7 +673,7 @@ struct route_map_dep { /* Hashes maintaining dependency between various sublists used by route maps */ struct hash *route_map_dep_hash[ROUTE_MAP_DEP_MAX]; -static unsigned int route_map_dep_hash_make_key(void *p); +static unsigned int route_map_dep_hash_make_key(const void *p); static void route_map_clear_all_references(char *rmap_name); static void route_map_rule_delete(struct route_map_rule_list *, struct route_map_rule *); @@ -902,10 +902,12 @@ static const char *route_map_type_str(enum route_map_type type) case RMAP_DENY: return "deny"; break; - default: + case RMAP_ANY: return ""; break; } + + return ""; } static int route_map_empty(struct route_map *map) @@ -1077,8 +1079,7 @@ static void route_map_index_delete(struct route_map_index *index, int notify) /* Execute event hook. */ if (route_map_master.event_hook && notify) { - (*route_map_master.event_hook)(RMAP_EVENT_INDEX_DELETED, - index->map->name); + (*route_map_master.event_hook)(index->map->name); route_map_notify_dependencies(index->map->name, RMAP_EVENT_CALL_ADDED); } @@ -1137,8 +1138,7 @@ route_map_index_add(struct route_map *map, enum route_map_type type, int pref) /* Execute event hook. */ if (route_map_master.event_hook) { - (*route_map_master.event_hook)(RMAP_EVENT_INDEX_ADDED, - map->name); + (*route_map_master.event_hook)(map->name); route_map_notify_dependencies(map->name, RMAP_EVENT_CALL_ADDED); } return index; @@ -1289,7 +1289,6 @@ int route_map_add_match(struct route_map_index *index, const char *match_name, struct route_map_rule *next; struct route_map_rule_cmd *cmd; void *compile; - int replaced = 0; /* First lookup rule for add match statement. */ cmd = route_map_lookup_match(match_name); @@ -1308,8 +1307,17 @@ int route_map_add_match(struct route_map_index *index, const char *match_name, for (rule = index->match_list.head; rule; rule = next) { next = rule->next; if (rule->cmd == cmd) { + /* If the configured route-map match rule is exactly + * the same as the existing configuration then, + * ignore the duplicate configuration. + */ + if (strcmp(match_arg, rule->rule_str) == 0) { + if (cmd->func_free) + (*cmd->func_free)(compile); + return RMAP_COMPILE_SUCCESS; + } + route_map_rule_delete(&index->match_list, rule); - replaced = 1; } } @@ -1327,10 +1335,7 @@ int route_map_add_match(struct route_map_index *index, const char *match_name, /* Execute event hook. */ if (route_map_master.event_hook) { - (*route_map_master.event_hook)( - replaced ? RMAP_EVENT_MATCH_REPLACED - : RMAP_EVENT_MATCH_ADDED, - index->map->name); + (*route_map_master.event_hook)(index->map->name); route_map_notify_dependencies(index->map->name, RMAP_EVENT_CALL_ADDED); } @@ -1355,9 +1360,7 @@ int route_map_delete_match(struct route_map_index *index, route_map_rule_delete(&index->match_list, rule); /* Execute event hook. */ if (route_map_master.event_hook) { - (*route_map_master.event_hook)( - RMAP_EVENT_MATCH_DELETED, - index->map->name); + (*route_map_master.event_hook)(index->map->name); route_map_notify_dependencies( index->map->name, RMAP_EVENT_CALL_ADDED); @@ -1376,7 +1379,6 @@ int route_map_add_set(struct route_map_index *index, const char *set_name, struct route_map_rule *next; struct route_map_rule_cmd *cmd; void *compile; - int replaced = 0; cmd = route_map_lookup_set(set_name); if (cmd == NULL) @@ -1395,10 +1397,8 @@ int route_map_add_set(struct route_map_index *index, const char *set_name, route_map_index. */ for (rule = index->set_list.head; rule; rule = next) { next = rule->next; - if (rule->cmd == cmd) { + if (rule->cmd == cmd) route_map_rule_delete(&index->set_list, rule); - replaced = 1; - } } /* Add new route map match rule. */ @@ -1415,10 +1415,7 @@ int route_map_add_set(struct route_map_index *index, const char *set_name, /* Execute event hook. */ if (route_map_master.event_hook) { - (*route_map_master.event_hook)(replaced - ? RMAP_EVENT_SET_REPLACED - : RMAP_EVENT_SET_ADDED, - index->map->name); + (*route_map_master.event_hook)(index->map->name); route_map_notify_dependencies(index->map->name, RMAP_EVENT_CALL_ADDED); } @@ -1442,9 +1439,7 @@ int route_map_delete_set(struct route_map_index *index, const char *set_name, route_map_rule_delete(&index->set_list, rule); /* Execute event hook. */ if (route_map_master.event_hook) { - (*route_map_master.event_hook)( - RMAP_EVENT_SET_DELETED, - index->map->name); + (*route_map_master.event_hook)(index->map->name); route_map_notify_dependencies( index->map->name, RMAP_EVENT_CALL_ADDED); @@ -1641,7 +1636,7 @@ void route_map_delete_hook(void (*func)(const char *)) route_map_master.delete_hook = func; } -void route_map_event_hook(void (*func)(route_map_event_t, const char *)) +void route_map_event_hook(void (*func)(const char *name)) { route_map_master.event_hook = func; } @@ -1711,7 +1706,7 @@ static void *route_map_name_hash_alloc(void *p) return ((void *)XSTRDUP(MTYPE_ROUTE_MAP_NAME, (const char *)p)); } -static unsigned int route_map_dep_hash_make_key(void *p) +static unsigned int route_map_dep_hash_make_key(const void *p) { return (string_hash_make((char *)p)); } @@ -1785,7 +1780,14 @@ static int route_map_dep_update(struct hash *dephash, const char *dep_name, dep = NULL; } break; - default: + case RMAP_EVENT_SET_ADDED: + case RMAP_EVENT_SET_DELETED: + case RMAP_EVENT_SET_REPLACED: + case RMAP_EVENT_MATCH_ADDED: + case RMAP_EVENT_MATCH_DELETED: + case RMAP_EVENT_MATCH_REPLACED: + case RMAP_EVENT_INDEX_ADDED: + case RMAP_EVENT_INDEX_DELETED: break; } @@ -1828,13 +1830,26 @@ static struct hash *route_map_get_dep_hash(route_map_event_t event) break; case RMAP_EVENT_CALL_ADDED: case RMAP_EVENT_CALL_DELETED: + case RMAP_EVENT_MATCH_ADDED: + case RMAP_EVENT_MATCH_DELETED: upd8_hash = route_map_dep_hash[ROUTE_MAP_DEP_RMAP]; break; case RMAP_EVENT_FILTER_ADDED: case RMAP_EVENT_FILTER_DELETED: upd8_hash = route_map_dep_hash[ROUTE_MAP_DEP_FILTER]; break; - default: + /* + * Should we actually be ignoring these? + * I am not sure but at this point in time, let + * us get them into this switch and we can peel + * them into the appropriate place in the future + */ + case RMAP_EVENT_SET_ADDED: + case RMAP_EVENT_SET_DELETED: + case RMAP_EVENT_SET_REPLACED: + case RMAP_EVENT_MATCH_REPLACED: + case RMAP_EVENT_INDEX_ADDED: + case RMAP_EVENT_INDEX_DELETED: upd8_hash = NULL; break; } @@ -1844,13 +1859,12 @@ static struct hash *route_map_get_dep_hash(route_map_event_t event) static void route_map_process_dependency(struct hash_bucket *bucket, void *data) { char *rmap_name = (char *)bucket->data; - route_map_event_t type = (route_map_event_t)(ptrdiff_t)data; if (rmap_debug) zlog_debug("%s: Notifying %s of dependency", __FUNCTION__, rmap_name); if (route_map_master.event_hook) - (*route_map_master.event_hook)(type, rmap_name); + (*route_map_master.event_hook)(rmap_name); } void route_map_upd8_dependency(route_map_event_t type, const char *arg, @@ -2803,6 +2817,13 @@ DEFUN (rmap_call, assert(index); + /* If "call" is invoked with the same route-map name as + * the one previously configured then, ignore the duplicate + * configuration. + */ + if (index->nextrm && (strcmp(index->nextrm, rmap) == 0)) + return CMD_SUCCESS; + if (index->nextrm) { route_map_upd8_dependency(RMAP_EVENT_CALL_DELETED, index->nextrm, index->map->name); |
