diff options
Diffstat (limited to 'lib')
-rw-r--r-- | lib/session.c | 36 | ||||
-rw-r--r-- | lib/types.c | 15 |
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); |