summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/session.c36
-rw-r--r--lib/types.c15
2 files changed, 30 insertions, 21 deletions
diff --git a/lib/session.c b/lib/session.c
index 5d341ab..4a08b94 100644
--- a/lib/session.c
+++ b/lib/session.c
@@ -1510,12 +1510,12 @@ build_send_private_msg(struct ipset_session *session, enum ipset_cmd cmd)
}
static inline bool
-may_aggregate_ad(struct ipset_session *session, struct ipset_data *data,
- enum ipset_cmd cmd)
+may_aggregate_ad(struct ipset_session *session, enum ipset_cmd cmd)
{
- return (cmd == IPSET_CMD_ADD || cmd == IPSET_CMD_DEL)
+ return session->lineno != 0
+ && (cmd == IPSET_CMD_ADD || cmd == IPSET_CMD_DEL)
&& cmd == session->cmd
- && STREQ(ipset_data_setname(data), session->saved_setname);
+ && STREQ(ipset_data_setname(session->data), session->saved_setname);
}
static int
@@ -1693,7 +1693,8 @@ ipset_commit(struct ipset_session *session)
session->buffer,
session->bufsize);
- /* Reset data block and nested state */
+ /* Reset saved data and nested state */
+ session->saved_setname[0] = '\0';
for (i = session->nestid - 1; i >= 0; i--)
session->nested[i] = NULL;
session->nestid = 0;
@@ -1771,8 +1772,13 @@ ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno)
return build_send_private_msg(session, cmd);
/* Check aggregatable commands */
- if (session->lineno != 0)
- aggregate = may_aggregate_ad(session, data, cmd);
+ aggregate = may_aggregate_ad(session, cmd);
+ if (!aggregate) {
+ /* Flush possible aggregated commands */
+ ret = ipset_commit(session);
+ if (ret < 0)
+ return ret;
+ }
/* Real command: update lineno too */
session->cmd = cmd;
@@ -1793,7 +1799,8 @@ ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno)
D("build_msg returned %u", ret);
if (ret > 0) {
/* Buffer is full, send buffered commands */
- if (ipset_commit(session) < 0)
+ ret = ipset_commit(session);
+ if (ret < 0)
goto cleanup;
ret = build_msg(session, false);
D("build_msg 2 returned %u", ret);
@@ -1804,16 +1811,19 @@ ipset_cmd(struct ipset_session *session, enum ipset_cmd cmd, uint32_t lineno)
/* We have to save the type for error handling */
session->saved_type = ipset_data_get(data, IPSET_OPT_TYPE);
- /* Save setname for the next possible aggregated restore line */
if (session->lineno != 0
&& (cmd == IPSET_CMD_ADD || cmd == IPSET_CMD_DEL)) {
+ /* Save setname for the next possible aggregated restore line */
strcpy(session->saved_setname, ipset_data_setname(data));
- ret = 0;
+ ipset_data_reset(data);
/* Don't commit: we may aggregate next command */
- } else {
- D("call commit");
- ret = ipset_commit(session);
+ ret = 0;
+ goto cleanup;
}
+
+ D("call commit");
+ ret = ipset_commit(session);
+
cleanup:
D("reset data");
ipset_data_reset(data);
diff --git a/lib/types.c b/lib/types.c
index 1bd4274..69dac6a 100644
--- a/lib/types.c
+++ b/lib/types.c
@@ -276,10 +276,9 @@ found:
}
#define set_family_and_type(data, match, family) do { \
- if (family == AF_UNSPEC && match->family != AF_UNSPEC) { \
+ if (family == AF_UNSPEC && match->family != AF_UNSPEC) \
family = match->family == AF_INET46 ? AF_INET : match->family;\
- ipset_data_set(data, IPSET_OPT_FAMILY, &family);\
- } \
+ ipset_data_set(data, IPSET_OPT_FAMILY, &family); \
ipset_data_set(data, IPSET_OPT_TYPE, match); \
} while (0)
@@ -293,7 +292,7 @@ adt_type_get(struct ipset_session *session)
const struct ipset_type *match;
const char *setname, *typename;
const uint8_t *revision;
- uint8_t family;
+ uint8_t family = AF_UNSPEC;
int ret;
data = ipset_session_data(session);
@@ -304,8 +303,9 @@ adt_type_get(struct ipset_session *session)
/* Check existing sets in cache */
for (s = setlist; s != NULL; s = s->next) {
if (STREQ(setname, s->name)) {
- match = s->type;
- goto found;
+ ipset_data_set(data, IPSET_OPT_FAMILY, &s->family);
+ ipset_data_set(data, IPSET_OPT_TYPE, s->type);
+ return s->type;
}
}
@@ -342,7 +342,6 @@ adt_type_get(struct ipset_session *session)
family == AF_INET6 ? "inet6" : "unspec",
*revision);
-found:
set_family_and_type(data, match, family);
return match;
@@ -396,7 +395,7 @@ ipset_type_check(struct ipset_session *session)
const struct ipset_type *t, *match = NULL;
struct ipset_data *data;
const char *typename;
- uint8_t family, revision;
+ uint8_t family = AF_UNSPEC, revision;
assert(session);
data = ipset_session_data(session);