summaryrefslogtreecommitdiff
path: root/lib/routemap.c
diff options
context:
space:
mode:
Diffstat (limited to 'lib/routemap.c')
-rw-r--r--lib/routemap.c89
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);