summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPablo Neira Ayuso <pablo@netfilter.org>2016-04-18 13:03:41 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2016-04-25 15:48:23 +0200
commit13aa334805c461a57ce70f6bf15ca8b2ea4c8473 (patch)
tree663d5c5c137f4cea95a9f62bd96a3edd99038c32
parenta099258ab5796be02602f39d88c41f89ff34209f (diff)
rule: support for incremental set interval element updates
Introduce __do_add_setelems() and do_delete_setelems() to support incremental set interval element updates. From do_add_set(), use netlink_add_setelems() not to try to re-add the same elements again Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r--src/rule.c52
1 files changed, 42 insertions, 10 deletions
diff --git a/src/rule.c b/src/rule.c
index 08bd4ea5..4b112d21 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -874,26 +874,39 @@ static int do_add_chain(struct netlink_ctx *ctx, const struct handle *h,
return 0;
}
-static int do_add_setelems(struct netlink_ctx *ctx, const struct handle *h,
- const struct expr *expr)
+static int __do_add_setelems(struct netlink_ctx *ctx, const struct handle *h,
+ struct set *set, struct expr *expr)
{
+ if (set->flags & SET_F_INTERVAL &&
+ set_to_intervals(ctx->msgs, set, expr) < 0)
+ return -1;
+
if (netlink_add_setelems(ctx, h, expr) < 0)
return -1;
+
return 0;
}
+static int do_add_setelems(struct netlink_ctx *ctx, const struct handle *h,
+ struct expr *init)
+{
+ struct table *table;
+ struct set *set;
+
+ table = table_lookup(h);
+ set = set_lookup(table, h->set);
+
+ return __do_add_setelems(ctx, h, set, init);
+}
+
static int do_add_set(struct netlink_ctx *ctx, const struct handle *h,
struct set *set)
{
if (netlink_add_set(ctx, h, set) < 0)
return -1;
- if (set->init != NULL) {
- if (set->flags & SET_F_INTERVAL &&
- set_to_intervals(ctx->msgs, set, set->init) < 0)
- return -1;
- if (do_add_setelems(ctx, &set->handle, set->init) < 0)
- return -1;
- }
+ if (set->init != NULL)
+ return __do_add_setelems(ctx, &set->handle, set, set->init);
+
return 0;
}
@@ -972,6 +985,25 @@ static int do_command_insert(struct netlink_ctx *ctx, struct cmd *cmd)
return 0;
}
+static int do_delete_setelems(struct netlink_ctx *ctx, const struct handle *h,
+ struct expr *expr)
+{
+ struct table *table;
+ struct set *set;
+
+ table = table_lookup(h);
+ set = set_lookup(table, h->set);
+
+ if (set->flags & SET_F_INTERVAL &&
+ set_to_intervals(ctx->msgs, set, expr) < 0)
+ return -1;
+
+ if (netlink_delete_setelems(ctx, h, expr) < 0)
+ return -1;
+
+ return 0;
+}
+
static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd)
{
switch (cmd->obj) {
@@ -985,7 +1017,7 @@ static int do_command_delete(struct netlink_ctx *ctx, struct cmd *cmd)
case CMD_OBJ_SET:
return netlink_delete_set(ctx, &cmd->handle, &cmd->location);
case CMD_OBJ_SETELEM:
- return netlink_delete_setelems(ctx, &cmd->handle, cmd->expr);
+ return do_delete_setelems(ctx, &cmd->handle, cmd->expr);
default:
BUG("invalid command object type %u\n", cmd->obj);
}