summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/mnl.h69
-rw-r--r--include/netlink.h4
-rw-r--r--include/nftables.h1
-rw-r--r--include/rule.h2
-rw-r--r--src/main.c10
-rw-r--r--src/mnl.c187
-rw-r--r--src/netlink.c54
-rw-r--r--src/rule.c3
8 files changed, 177 insertions, 153 deletions
diff --git a/include/mnl.h b/include/mnl.h
index 31dff2c2..7df08236 100644
--- a/include/mnl.h
+++ b/include/mnl.h
@@ -9,8 +9,8 @@ struct mnl_socket;
struct mnl_socket *netlink_open_sock(void);
void netlink_close_sock(struct mnl_socket *nf_sock);
-uint32_t mnl_seqnum_alloc(void);
-void mnl_genid_get(struct mnl_socket *nf_sock);
+uint32_t mnl_seqnum_alloc(uint32_t *seqnum);
+void mnl_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum);
struct mnl_err {
struct list_head head;
@@ -23,8 +23,8 @@ void mnl_err_list_free(struct mnl_err *err);
struct nftnl_batch *mnl_batch_init(void);
bool mnl_batch_ready(struct nftnl_batch *batch);
void mnl_batch_reset(struct nftnl_batch *batch);
-uint32_t mnl_batch_begin(struct nftnl_batch *batch);
-void mnl_batch_end(struct nftnl_batch *batch);
+uint32_t mnl_batch_begin(struct nftnl_batch *batch, uint32_t seqnum);
+void mnl_batch_end(struct nftnl_batch *batch, uint32_t seqnum);
int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list);
int mnl_nft_rule_batch_add(struct nftnl_rule *nlr, struct nftnl_batch *batch,
unsigned int flags, uint32_t seqnum);
@@ -34,76 +34,79 @@ int mnl_nft_rule_batch_replace(struct nftnl_rule *nlr, struct nftnl_batch *batch
unsigned int flags, uint32_t seqnum);
int mnl_nft_rule_add(struct mnl_socket *nf_sock, struct nftnl_rule *r,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_rule_delete(struct mnl_socket *nf_sock, struct nftnl_rule *r,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
struct nftnl_rule_list *mnl_nft_rule_dump(struct mnl_socket *nf_sock,
- int family);
+ int family, uint32_t seqnum);
int mnl_nft_chain_add(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_chain_batch_add(struct nftnl_chain *nlc, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_chain_delete(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_chain_batch_del(struct nftnl_chain *nlc, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
struct nftnl_chain_list *mnl_nft_chain_dump(struct mnl_socket *nf_sock,
- int family);
+ int family, uint32_t seqnum);
int mnl_nft_chain_get(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_table_add(struct mnl_socket *nf_sock, struct nftnl_table *nlt,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_table_batch_add(struct nftnl_table *nlt, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_table_delete(struct mnl_socket *nf_sock, struct nftnl_table *nlt,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_table_batch_del(struct nftnl_table *nlt, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
struct nftnl_table_list *mnl_nft_table_dump(struct mnl_socket *nf_sock,
- int family);
+ int family, uint32_t seqnum);
int mnl_nft_table_get(struct mnl_socket *nf_sock, struct nftnl_table *nlt,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_set_add(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_set_batch_add(struct nftnl_set *nls, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_set_delete(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_set_batch_del(struct nftnl_set *nls, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
struct nftnl_set_list *mnl_nft_set_dump(struct mnl_socket *nf_sock, int family,
- const char *table);
-int mnl_nft_set_get(struct mnl_socket *nf_sock, struct nftnl_set *nls);
+ const char *table, uint32_t seqnum);
+int mnl_nft_set_get(struct mnl_socket *nf_sock, struct nftnl_set *nls,
+ uint32_t seqnum);
int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_setelem_batch_add(struct nftnl_set *nls, struct nftnl_batch *batch,
- unsigned int flags, uint32_t seq);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_setelem_delete(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags);
+ unsigned int flags, uint32_t seqnum);
int mnl_nft_setelem_batch_del(struct nftnl_set *nls, struct nftnl_batch *batch,
unsigned int flags, uint32_t seq);
int mnl_nft_setelem_batch_flush(struct nftnl_set *nls, struct nftnl_batch *batch,
unsigned int flags, uint32_t seqnum);
-int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nftnl_set *nls);
+int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nftnl_set *nls,
+ uint32_t seqnum);
struct nftnl_obj_list *mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family,
- const char *table, const char *name,
- uint32_t type, bool dump, bool reset);
+ uint32_t seqnum, const char *table,
+ const char *name, uint32_t type,
+ bool dump, bool reset);
int mnl_nft_obj_batch_add(struct nftnl_obj *nln, struct nftnl_batch *batch,
unsigned int flags, uint32_t seqnum);
int mnl_nft_obj_batch_del(struct nftnl_obj *nln, struct nftnl_batch *batch,
unsigned int flags, uint32_t seqnum);
struct nftnl_ruleset *mnl_nft_ruleset_dump(struct mnl_socket *nf_sock,
- uint32_t family);
+ uint32_t family, uint32_t seqnum);
int mnl_nft_event_listener(struct mnl_socket *nf_sock,
int (*cb)(const struct nlmsghdr *nlh, void *data),
void *cb_data);
-bool mnl_batch_supported(struct mnl_socket *nf_sock);
+bool mnl_batch_supported(struct mnl_socket *nf_sock, uint32_t *seqnum);
#endif /* _NFTABLES_MNL_H_ */
diff --git a/include/netlink.h b/include/netlink.h
index 37261714..0e1d26b6 100644
--- a/include/netlink.h
+++ b/include/netlink.h
@@ -195,7 +195,7 @@ extern void netlink_dump_obj(struct nftnl_obj *nlo);
extern int netlink_batch_send(struct netlink_ctx *ctx, struct list_head *err_list);
-extern void netlink_genid_get(struct mnl_socket *nf_sock);
+extern void netlink_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum);
extern void netlink_restart(struct mnl_socket *nf_sock);
#define netlink_abi_error() \
__netlink_abi_error(__FILE__, __LINE__, strerror(errno));
@@ -224,7 +224,7 @@ struct netlink_mon_handler {
extern int netlink_monitor(struct netlink_mon_handler *monhandler,
struct mnl_socket *nf_sock);
-bool netlink_batch_supported(struct mnl_socket *nf_sock);
+bool netlink_batch_supported(struct mnl_socket *nf_sock, uint32_t *seqnum);
int netlink_echo_callback(const struct nlmsghdr *nlh, void *data);
diff --git a/include/nftables.h b/include/nftables.h
index a88c86d1..a457aba6 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -40,6 +40,7 @@ struct nft_ctx {
struct nft_cache {
bool initialized;
struct list_head list;
+ uint32_t seqnum;
};
extern unsigned int max_errors;
diff --git a/include/rule.h b/include/rule.h
index 10ac0e26..f9de8367 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -470,6 +470,7 @@ extern void cmd_free(struct cmd *cmd);
* @set: current set
* @stmt: current statement
* @cache: cache context
+ * @seqnum: netlink sequence number
* @ectx: expression context
* @pctx: payload context
*/
@@ -482,6 +483,7 @@ struct eval_ctx {
struct set *set;
struct stmt *stmt;
struct nft_cache *cache;
+ uint32_t seqnum;
struct expr_ctx ectx;
struct proto_ctx pctx;
};
diff --git a/src/main.c b/src/main.c
index 2e77ee0a..88839598 100644
--- a/src/main.c
+++ b/src/main.c
@@ -191,22 +191,22 @@ static int nft_netlink(struct nft_ctx *nft, struct nft_cache *cache,
struct parser_state *state, struct list_head *msgs,
struct mnl_socket *nf_sock)
{
+ uint32_t batch_seqnum, seqnum = 0;
struct nftnl_batch *batch;
struct netlink_ctx ctx;
struct cmd *cmd;
struct mnl_err *err, *tmp;
LIST_HEAD(err_list);
- uint32_t batch_seqnum;
- bool batch_supported = netlink_batch_supported(nf_sock);
+ bool batch_supported = netlink_batch_supported(nf_sock, &seqnum);
int ret = 0;
batch = mnl_batch_init();
- batch_seqnum = mnl_batch_begin(batch);
+ batch_seqnum = mnl_batch_begin(batch, mnl_seqnum_alloc(&seqnum));
list_for_each_entry(cmd, &state->cmds, list) {
memset(&ctx, 0, sizeof(ctx));
ctx.msgs = msgs;
- ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc();
+ ctx.seqnum = cmd->seqnum = mnl_seqnum_alloc(&seqnum);
ctx.batch = batch;
ctx.batch_supported = batch_supported;
ctx.octx = &nft->output;
@@ -218,7 +218,7 @@ static int nft_netlink(struct nft_ctx *nft, struct nft_cache *cache,
goto out;
}
if (!nft->check)
- mnl_batch_end(batch);
+ mnl_batch_end(batch, mnl_seqnum_alloc(&seqnum));
if (!mnl_batch_ready(batch))
goto out;
diff --git a/src/mnl.c b/src/mnl.c
index 5017b81c..b0f51913 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -30,11 +30,9 @@
#include <utils.h>
#include <nftables.h>
-static int seq;
-
-uint32_t mnl_seqnum_alloc(void)
+uint32_t mnl_seqnum_alloc(unsigned int *seqnum)
{
- return seq++;
+ return *seqnum++;
}
/* The largest nf_tables netlink message is the set element message, which
@@ -68,7 +66,8 @@ out:
}
static int
-nft_mnl_talk(struct mnl_socket *nf_sock, const void *data, unsigned int len,
+nft_mnl_talk(struct mnl_socket *nf_sock, const void *data,
+ unsigned int len, uint32_t seqnum,
int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
{
uint32_t portid = mnl_socket_get_portid(nf_sock);
@@ -81,7 +80,7 @@ nft_mnl_talk(struct mnl_socket *nf_sock, const void *data, unsigned int len,
if (mnl_socket_sendto(nf_sock, data, len) < 0)
return -1;
- return nft_mnl_recv(nf_sock, seq, portid, cb, cb_data);
+ return nft_mnl_recv(nf_sock, seqnum, portid, cb, cb_data);
}
/*
@@ -98,14 +97,14 @@ static int genid_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK;
}
-void mnl_genid_get(struct mnl_socket *nf_sock)
+void mnl_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
- nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETGEN, AF_UNSPEC, 0, seq);
+ nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETGEN, AF_UNSPEC, 0, seqnum);
/* Skip error checking, old kernels sets res_id field to zero. */
- nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, genid_cb, NULL);
+ nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, genid_cb, NULL);
}
static int check_genid(const struct nlmsghdr *nlh)
@@ -146,19 +145,17 @@ static void mnl_nft_batch_continue(struct nftnl_batch *batch)
memory_allocation_error();
}
-uint32_t mnl_batch_begin(struct nftnl_batch *batch)
+uint32_t mnl_batch_begin(struct nftnl_batch *batch, uint32_t seqnum)
{
- uint32_t seq = mnl_seqnum_alloc();
-
- nftnl_batch_begin(nftnl_batch_buffer(batch), seq);
+ nftnl_batch_begin(nftnl_batch_buffer(batch), seqnum);
mnl_nft_batch_continue(batch);
- return seq;
+ return seqnum;
}
-void mnl_batch_end(struct nftnl_batch *batch)
+void mnl_batch_end(struct nftnl_batch *batch, uint32_t seqnum)
{
- nftnl_batch_end(nftnl_batch_buffer(batch), mnl_seqnum_alloc());
+ nftnl_batch_end(nftnl_batch_buffer(batch), seqnum);
mnl_nft_batch_continue(batch);
}
@@ -340,31 +337,31 @@ int mnl_nft_rule_batch_del(struct nftnl_rule *nlr, struct nftnl_batch *batch,
* Rule
*/
int mnl_nft_rule_add(struct mnl_socket *nf_sock, struct nftnl_rule *nlr,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWRULE,
nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY),
- NLM_F_ACK | NLM_F_CREATE | flags, seq);
+ NLM_F_ACK | NLM_F_CREATE | flags, seqnum);
nftnl_rule_nlmsg_build_payload(nlh, nlr);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
int mnl_nft_rule_delete(struct mnl_socket *nf_sock, struct nftnl_rule *nlr,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_DELRULE,
nftnl_rule_get_u32(nlr, NFTNL_RULE_FAMILY),
- NLM_F_ACK, seq);
+ NLM_F_ACK, seqnum);
nftnl_rule_nlmsg_build_payload(nlh, nlr);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
static int rule_cb(const struct nlmsghdr *nlh, void *data)
@@ -390,7 +387,8 @@ err_free:
return MNL_CB_OK;
}
-struct nftnl_rule_list *mnl_nft_rule_dump(struct mnl_socket *nf_sock, int family)
+struct nftnl_rule_list *mnl_nft_rule_dump(struct mnl_socket *nf_sock,
+ int family, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
@@ -402,9 +400,10 @@ struct nftnl_rule_list *mnl_nft_rule_dump(struct mnl_socket *nf_sock, int family
memory_allocation_error();
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETRULE, family,
- NLM_F_DUMP, seq);
+ NLM_F_DUMP, seqnum);
- ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, rule_cb, nlr_list);
+ ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, rule_cb,
+ nlr_list);
if (ret < 0)
goto err;
@@ -418,7 +417,7 @@ err:
* Chain
*/
int mnl_nft_chain_add(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -426,10 +425,10 @@ int mnl_nft_chain_add(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWCHAIN,
nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY),
- NLM_F_CREATE | NLM_F_ACK | flags, seq);
+ NLM_F_CREATE | NLM_F_ACK | flags, seqnum);
nftnl_chain_nlmsg_build_payload(nlh, nlc);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
int mnl_nft_chain_batch_add(struct nftnl_chain *nlc, struct nftnl_batch *batch,
@@ -448,17 +447,17 @@ int mnl_nft_chain_batch_add(struct nftnl_chain *nlc, struct nftnl_batch *batch,
}
int mnl_nft_chain_delete(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_DELCHAIN,
nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY),
- NLM_F_ACK, seq);
+ NLM_F_ACK, seqnum);
nftnl_chain_nlmsg_build_payload(nlh, nlc);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
int mnl_nft_chain_batch_del(struct nftnl_chain *nlc, struct nftnl_batch *batch,
@@ -499,7 +498,8 @@ err_free:
return MNL_CB_OK;
}
-struct nftnl_chain_list *mnl_nft_chain_dump(struct mnl_socket *nf_sock, int family)
+struct nftnl_chain_list *mnl_nft_chain_dump(struct mnl_socket *nf_sock,
+ int family, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
@@ -511,9 +511,10 @@ struct nftnl_chain_list *mnl_nft_chain_dump(struct mnl_socket *nf_sock, int fami
memory_allocation_error();
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN, family,
- NLM_F_DUMP, seq);
+ NLM_F_DUMP, seqnum);
- ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, chain_cb, nlc_list);
+ ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, chain_cb,
+ nlc_list);
if (ret < 0)
goto err;
@@ -530,34 +531,35 @@ static int chain_get_cb(const struct nlmsghdr *nlh, void *data)
}
int mnl_nft_chain_get(struct mnl_socket *nf_sock, struct nftnl_chain *nlc,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETCHAIN,
nftnl_chain_get_u32(nlc, NFTNL_CHAIN_FAMILY),
- NLM_F_ACK | flags, seq);
+ seqnum, NLM_F_ACK | flags);
nftnl_chain_nlmsg_build_payload(nlh, nlc);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, chain_get_cb, nlc);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, chain_get_cb,
+ nlc);
}
/*
* Table
*/
int mnl_nft_table_add(struct mnl_socket *nf_sock, struct nftnl_table *nlt,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWTABLE,
nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY),
- NLM_F_ACK | flags, seq);
+ NLM_F_ACK | flags, seqnum);
nftnl_table_nlmsg_build_payload(nlh, nlt);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
int mnl_nft_table_batch_add(struct nftnl_table *nlt, struct nftnl_batch *batch,
@@ -576,17 +578,17 @@ int mnl_nft_table_batch_add(struct nftnl_table *nlt, struct nftnl_batch *batch,
}
int mnl_nft_table_delete(struct mnl_socket *nf_sock, struct nftnl_table *nlt,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_DELTABLE,
nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY),
- NLM_F_ACK, seq);
+ NLM_F_ACK, seqnum);
nftnl_table_nlmsg_build_payload(nlh, nlt);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
int mnl_nft_table_batch_del(struct nftnl_table *nlt, struct nftnl_batch *batch,
@@ -627,7 +629,8 @@ err_free:
return MNL_CB_OK;
}
-struct nftnl_table_list *mnl_nft_table_dump(struct mnl_socket *nf_sock, int family)
+struct nftnl_table_list *mnl_nft_table_dump(struct mnl_socket *nf_sock,
+ int family, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
@@ -639,9 +642,10 @@ struct nftnl_table_list *mnl_nft_table_dump(struct mnl_socket *nf_sock, int fami
memory_allocation_error();
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE, family,
- NLM_F_DUMP, seq);
+ NLM_F_DUMP, seqnum);
- ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, table_cb, nlt_list);
+ ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, table_cb,
+ nlt_list);
if (ret < 0)
goto err;
@@ -660,17 +664,18 @@ static int table_get_cb(const struct nlmsghdr *nlh, void *data)
}
int mnl_nft_table_get(struct mnl_socket *nf_sock, struct nftnl_table *nlt,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETTABLE,
nftnl_table_get_u32(nlt, NFTNL_TABLE_FAMILY),
- NLM_F_ACK, seq);
+ NLM_F_ACK, seqnum);
nftnl_table_nlmsg_build_payload(nlh, nlt);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, table_get_cb, nlt);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, table_get_cb,
+ nlt);
}
/*
@@ -683,31 +688,32 @@ static int set_add_cb(const struct nlmsghdr *nlh, void *data)
}
int mnl_nft_set_add(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWSET,
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
- NLM_F_CREATE | NLM_F_ACK | flags, seq);
+ NLM_F_CREATE | NLM_F_ACK | flags, seqnum);
nftnl_set_nlmsg_build_payload(nlh, nls);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_add_cb, nls);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum,
+ set_add_cb, nls);
}
int mnl_nft_set_delete(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_DELSET,
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
- flags | NLM_F_ACK, seq);
+ flags | NLM_F_ACK, seqnum);
nftnl_set_nlmsg_build_payload(nlh, nls);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
int mnl_nft_set_batch_add(struct nftnl_set *nls, struct nftnl_batch *batch,
@@ -764,7 +770,8 @@ err_free:
}
struct nftnl_set_list *
-mnl_nft_set_dump(struct mnl_socket *nf_sock, int family, const char *table)
+mnl_nft_set_dump(struct mnl_socket *nf_sock, int family, const char *table,
+ uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
@@ -777,7 +784,7 @@ mnl_nft_set_dump(struct mnl_socket *nf_sock, int family, const char *table)
memory_allocation_error();
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSET, family,
- NLM_F_DUMP | NLM_F_ACK, seq);
+ NLM_F_DUMP | NLM_F_ACK, seqnum);
if (table != NULL)
nftnl_set_set(s, NFTNL_SET_TABLE, table);
nftnl_set_nlmsg_build_payload(nlh, s);
@@ -787,7 +794,8 @@ mnl_nft_set_dump(struct mnl_socket *nf_sock, int family, const char *table)
if (nls_list == NULL)
memory_allocation_error();
- ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_cb, nls_list);
+ ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, set_cb,
+ nls_list);
if (ret < 0)
goto err;
@@ -852,8 +860,9 @@ err_free:
struct nftnl_obj_list *
-mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family, const char *table,
- const char *name, uint32_t type, bool dump, bool reset)
+mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family, uint32_t seqnum,
+ const char *table, const char *name, uint32_t type, bool dump,
+ bool reset)
{
uint16_t nl_flags = dump ? NLM_F_DUMP : 0;
struct nftnl_obj_list *nln_list;
@@ -872,7 +881,7 @@ mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family, const char *table,
memory_allocation_error();
nlh = nftnl_nlmsg_build_hdr(buf, msg_type, family,
- nl_flags | NLM_F_ACK, seq);
+ nl_flags | NLM_F_ACK, seqnum);
if (table != NULL)
nftnl_obj_set_str(n, NFTNL_OBJ_TABLE, table);
if (name != NULL)
@@ -886,7 +895,8 @@ mnl_nft_obj_dump(struct mnl_socket *nf_sock, int family, const char *table,
if (nln_list == NULL)
memory_allocation_error();
- ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, obj_cb, nln_list);
+ ret = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, obj_cb,
+ nln_list);
if (ret < 0)
goto err;
@@ -904,24 +914,26 @@ static int set_get_cb(const struct nlmsghdr *nlh, void *data)
return MNL_CB_OK;
}
-int mnl_nft_set_get(struct mnl_socket *nf_sock, struct nftnl_set *nls)
+int mnl_nft_set_get(struct mnl_socket *nf_sock, struct nftnl_set *nls,
+ uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSET,
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
- NLM_F_ACK, seq);
+ NLM_F_ACK, seqnum);
nftnl_set_nlmsg_build_payload(nlh, nls);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_get_cb, nls);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, set_get_cb,
+ nls);
}
/*
* Set elements
*/
int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[NFT_NLMSG_MAXSIZE];
struct nlmsghdr *nlh;
@@ -936,9 +948,10 @@ int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nftnl_set *nls,
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_NEWSETELEM,
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
NLM_F_CREATE | NLM_F_ACK | flags,
- seq);
+ seqnum);
ret = nftnl_set_elems_nlmsg_build_payload_iter(nlh, iter);
- err = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ err = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum,
+ NULL, NULL);
if (ret <= 0 || err < 0)
break;
}
@@ -949,17 +962,17 @@ int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nftnl_set *nls,
}
int mnl_nft_setelem_delete(struct mnl_socket *nf_sock, struct nftnl_set *nls,
- unsigned int flags)
+ unsigned int flags, uint32_t seqnum)
{
char buf[NFT_NLMSG_MAXSIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_DELSETELEM,
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
- NLM_F_ACK, seq);
+ NLM_F_ACK, seqnum);
nftnl_set_elems_nlmsg_build_payload(nlh, nls);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, NULL, NULL);
}
static int set_elem_cb(const struct nlmsghdr *nlh, void *data)
@@ -1028,24 +1041,26 @@ int mnl_nft_setelem_batch_del(struct nftnl_set *nls, struct nftnl_batch *batch,
seqnum);
}
-int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nftnl_set *nls)
+int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nftnl_set *nls,
+ uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct nlmsghdr *nlh;
nlh = nftnl_nlmsg_build_hdr(buf, NFT_MSG_GETSETELEM,
nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
- NLM_F_DUMP|NLM_F_ACK, seq);
+ NLM_F_DUMP|NLM_F_ACK, seqnum);
nftnl_set_nlmsg_build_payload(nlh, nls);
- return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, set_elem_cb, nls);
+ return nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, seqnum, set_elem_cb,
+ nls);
}
/*
* ruleset
*/
struct nftnl_ruleset *mnl_nft_ruleset_dump(struct mnl_socket *nf_sock,
- uint32_t family)
+ uint32_t family, uint32_t seqnum)
{
struct nftnl_ruleset *rs;
struct nftnl_table_list *t;
@@ -1060,26 +1075,26 @@ struct nftnl_ruleset *mnl_nft_ruleset_dump(struct mnl_socket *nf_sock,
if (rs == NULL)
memory_allocation_error();
- t = mnl_nft_table_dump(nf_sock, family);
+ t = mnl_nft_table_dump(nf_sock, family, seqnum);
if (t == NULL)
goto err;
nftnl_ruleset_set(rs, NFTNL_RULESET_TABLELIST, t);
- c = mnl_nft_chain_dump(nf_sock, family);
+ c = mnl_nft_chain_dump(nf_sock, family, seqnum);
if (c == NULL)
goto err;
nftnl_ruleset_set(rs, NFTNL_RULESET_CHAINLIST, c);
- sl = mnl_nft_set_dump(nf_sock, family, NULL);
+ sl = mnl_nft_set_dump(nf_sock, family, NULL, seqnum);
if (sl == NULL)
goto err;
i = nftnl_set_list_iter_create(sl);
s = nftnl_set_list_iter_next(i);
while (s != NULL) {
- ret = mnl_nft_setelem_get(nf_sock, s);
+ ret = mnl_nft_setelem_get(nf_sock, s, seqnum);
if (ret < 0)
goto err;
@@ -1089,7 +1104,7 @@ struct nftnl_ruleset *mnl_nft_ruleset_dump(struct mnl_socket *nf_sock,
nftnl_ruleset_set(rs, NFTNL_RULESET_SETLIST, sl);
- r = mnl_nft_rule_dump(nf_sock, family);
+ r = mnl_nft_rule_dump(nf_sock, family, seqnum);
if (r == NULL)
goto err;
@@ -1164,7 +1179,7 @@ int mnl_nft_event_listener(struct mnl_socket *nf_sock,
return ret;
}
-static void nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seq)
+static void nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seqnum)
{
struct nlmsghdr *nlh;
struct nfgenmsg *nfg;
@@ -1172,7 +1187,7 @@ static void nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seq)
nlh = mnl_nlmsg_put_header(buf);
nlh->nlmsg_type = type;
nlh->nlmsg_flags = NLM_F_REQUEST;
- nlh->nlmsg_seq = seq;
+ nlh->nlmsg_seq = seqnum;
nfg = mnl_nlmsg_put_extra_header(nlh, sizeof(*nfg));
nfg->nfgen_family = AF_INET;
@@ -1180,7 +1195,7 @@ static void nft_mnl_batch_put(char *buf, uint16_t type, uint32_t seq)
nfg->res_id = NFNL_SUBSYS_NFTABLES;
}
-bool mnl_batch_supported(struct mnl_socket *nf_sock)
+bool mnl_batch_supported(struct mnl_socket *nf_sock, uint32_t *seqnum)
{
struct mnl_nlmsg_batch *b;
char buf[MNL_SOCKET_BUFFER_SIZE];
@@ -1189,15 +1204,15 @@ bool mnl_batch_supported(struct mnl_socket *nf_sock)
b = mnl_nlmsg_batch_start(buf, sizeof(buf));
nft_mnl_batch_put(mnl_nlmsg_batch_current(b), NFNL_MSG_BATCH_BEGIN,
- seq++);
+ mnl_seqnum_alloc(seqnum));
mnl_nlmsg_batch_next(b);
nftnl_nlmsg_build_hdr(mnl_nlmsg_batch_current(b), NFT_MSG_NEWSET,
- AF_INET, NLM_F_ACK, seq++);
+ AF_INET, NLM_F_ACK, mnl_seqnum_alloc(seqnum));
mnl_nlmsg_batch_next(b);
nft_mnl_batch_put(mnl_nlmsg_batch_current(b), NFNL_MSG_BATCH_END,
- seq++);
+ mnl_seqnum_alloc(seqnum));
mnl_nlmsg_batch_next(b);
ret = mnl_socket_sendto(nf_sock, mnl_nlmsg_batch_head(b),
diff --git a/src/netlink.c b/src/netlink.c
index 68f33625..7311149f 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -79,9 +79,9 @@ void netlink_restart(struct mnl_socket *nf_sock)
nf_sock = netlink_open_sock();
}
-void netlink_genid_get(struct mnl_socket *nf_sock)
+void netlink_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum)
{
- mnl_genid_get(nf_sock);
+ mnl_genid_get(nf_sock, seqnum);
}
void __noreturn __netlink_abi_error(const char *file, int line,
@@ -570,7 +570,7 @@ static int netlink_list_rules(struct netlink_ctx *ctx, const struct handle *h,
{
struct nftnl_rule_list *rule_cache;
- rule_cache = mnl_nft_rule_dump(ctx->nf_sock, h->family);
+ rule_cache = mnl_nft_rule_dump(ctx->nf_sock, h->family, ctx->seqnum);
if (rule_cache == NULL) {
if (errno == EINTR)
return -1;
@@ -627,7 +627,7 @@ static int netlink_add_chain_compat(struct netlink_ctx *ctx,
}
netlink_dump_chain(nlc);
- err = mnl_nft_chain_add(ctx->nf_sock, nlc, flags);
+ err = mnl_nft_chain_add(ctx->nf_sock, nlc, flags, ctx->seqnum);
nftnl_chain_free(nlc);
if (err < 0)
@@ -693,7 +693,7 @@ static int netlink_rename_chain_compat(struct netlink_ctx *ctx,
nlc = alloc_nftnl_chain(h);
nftnl_chain_set_str(nlc, NFTNL_CHAIN_NAME, name);
netlink_dump_chain(nlc);
- err = mnl_nft_chain_add(ctx->nf_sock, nlc, 0);
+ err = mnl_nft_chain_add(ctx->nf_sock, nlc, 0, ctx->seqnum);
nftnl_chain_free(nlc);
if (err < 0)
@@ -740,7 +740,7 @@ static int netlink_del_chain_compat(struct netlink_ctx *ctx,
nlc = alloc_nftnl_chain(h);
netlink_dump_chain(nlc);
- err = mnl_nft_chain_delete(ctx->nf_sock, nlc, 0);
+ err = mnl_nft_chain_delete(ctx->nf_sock, nlc, 0, ctx->seqnum);
nftnl_chain_free(nlc);
if (err < 0)
@@ -843,7 +843,7 @@ int netlink_list_chains(struct netlink_ctx *ctx, const struct handle *h,
struct nftnl_chain_list *chain_cache;
struct chain *chain;
- chain_cache = mnl_nft_chain_dump(ctx->nf_sock, h->family);
+ chain_cache = mnl_nft_chain_dump(ctx->nf_sock, h->family, ctx->seqnum);
if (chain_cache == NULL) {
if (errno == EINTR)
return -1;
@@ -879,7 +879,7 @@ int netlink_get_chain(struct netlink_ctx *ctx, const struct handle *h,
int err;
nlc = alloc_nftnl_chain(h);
- err = mnl_nft_chain_get(ctx->nf_sock, nlc, 0);
+ err = mnl_nft_chain_get(ctx->nf_sock, nlc, 0, ctx->seqnum);
if (err < 0) {
netlink_io_error(ctx, loc,
"Could not receive chain from kernel: %s",
@@ -915,7 +915,7 @@ static int netlink_add_table_compat(struct netlink_ctx *ctx,
int err;
nlt = alloc_nftnl_table(h);
- err = mnl_nft_table_add(ctx->nf_sock, nlt, flags);
+ err = mnl_nft_table_add(ctx->nf_sock, nlt, flags, ctx->seqnum);
nftnl_table_free(nlt);
if (err < 0)
@@ -965,7 +965,7 @@ static int netlink_del_table_compat(struct netlink_ctx *ctx,
int err;
nlt = alloc_nftnl_table(h);
- err = mnl_nft_table_delete(ctx->nf_sock, nlt, 0);
+ err = mnl_nft_table_delete(ctx->nf_sock, nlt, 0, ctx->seqnum);
nftnl_table_free(nlt);
if (err < 0)
@@ -1042,7 +1042,7 @@ int netlink_list_tables(struct netlink_ctx *ctx, const struct handle *h,
{
struct nftnl_table_list *table_cache;
- table_cache = mnl_nft_table_dump(ctx->nf_sock, h->family);
+ table_cache = mnl_nft_table_dump(ctx->nf_sock, h->family, ctx->seqnum);
if (table_cache == NULL) {
if (errno == EINTR)
return -1;
@@ -1063,7 +1063,7 @@ int netlink_get_table(struct netlink_ctx *ctx, const struct handle *h,
int err;
nlt = alloc_nftnl_table(h);
- err = mnl_nft_table_get(ctx->nf_sock, nlt, 0);
+ err = mnl_nft_table_get(ctx->nf_sock, nlt, 0, ctx->seqnum);
if (err < 0) {
netlink_io_error(ctx, loc,
"Could not receive table from kernel: %s",
@@ -1254,7 +1254,8 @@ static int netlink_add_set_compat(struct netlink_ctx *ctx,
}
netlink_dump_set(nls);
- err = mnl_nft_set_add(ctx->nf_sock, nls, NLM_F_ECHO | flags);
+ err = mnl_nft_set_add(ctx->nf_sock, nls, NLM_F_ECHO | flags,
+ ctx->seqnum);
if (err < 0)
netlink_io_error(ctx, &set->location, "Could not add set: %s",
strerror(errno));
@@ -1350,7 +1351,7 @@ static int netlink_del_set_compat(struct netlink_ctx *ctx,
int err;
nls = alloc_nftnl_set(h);
- err = mnl_nft_set_delete(ctx->nf_sock, nls, 0);
+ err = mnl_nft_set_delete(ctx->nf_sock, nls, 0, ctx->seqnum);
nftnl_set_free(nls);
if (err < 0)
@@ -1403,7 +1404,8 @@ int netlink_list_sets(struct netlink_ctx *ctx, const struct handle *h,
struct nftnl_set_list *set_cache;
int err;
- set_cache = mnl_nft_set_dump(ctx->nf_sock, h->family, h->table);
+ set_cache = mnl_nft_set_dump(ctx->nf_sock, h->family, h->table,
+ ctx->seqnum);
if (set_cache == NULL) {
if (errno == EINTR)
return -1;
@@ -1424,7 +1426,7 @@ int netlink_get_set(struct netlink_ctx *ctx, const struct handle *h,
int err;
nls = alloc_nftnl_set(h);
- err = mnl_nft_set_get(ctx->nf_sock, nls);
+ err = mnl_nft_set_get(ctx->nf_sock, nls, ctx->seqnum);
if (err < 0) {
nftnl_set_free(nls);
return netlink_io_error(ctx, loc,
@@ -1483,7 +1485,7 @@ static int netlink_add_setelems_compat(struct netlink_ctx *ctx,
alloc_setelem_cache(expr, nls);
netlink_dump_set(nls);
- err = mnl_nft_setelem_add(ctx->nf_sock, nls, flags);
+ err = mnl_nft_setelem_add(ctx->nf_sock, nls, flags, ctx->seqnum);
nftnl_set_free(nls);
if (err < 0)
netlink_io_error(ctx, &expr->location,
@@ -1533,7 +1535,7 @@ static int netlink_del_setelems_compat(struct netlink_ctx *ctx,
alloc_setelem_cache(expr, nls);
netlink_dump_set(nls);
- err = mnl_nft_setelem_delete(ctx->nf_sock, nls, 0);
+ err = mnl_nft_setelem_delete(ctx->nf_sock, nls, 0, ctx->seqnum);
nftnl_set_free(nls);
if (err < 0)
netlink_io_error(ctx, &expr->location,
@@ -1733,7 +1735,7 @@ int netlink_get_setelems(struct netlink_ctx *ctx, const struct handle *h,
nls = alloc_nftnl_set(h);
- err = mnl_nft_setelem_get(ctx->nf_sock, nls);
+ err = mnl_nft_setelem_get(ctx->nf_sock, nls, ctx->seqnum);
if (err < 0) {
nftnl_set_free(nls);
if (errno == EINTR)
@@ -1869,8 +1871,8 @@ int netlink_list_objs(struct netlink_ctx *ctx, const struct handle *h,
struct nftnl_obj_list *obj_cache;
int err;
- obj_cache = mnl_nft_obj_dump(ctx->nf_sock, h->family, h->table, NULL,
- 0, true, false);
+ obj_cache = mnl_nft_obj_dump(ctx->nf_sock, h->family, ctx->seqnum,
+ h->table, NULL, 0, true, false);
if (obj_cache == NULL) {
if (errno == EINTR)
return -1;
@@ -1889,8 +1891,8 @@ int netlink_reset_objs(struct netlink_ctx *ctx, const struct handle *h,
struct nftnl_obj_list *obj_cache;
int err;
- obj_cache = mnl_nft_obj_dump(ctx->nf_sock, h->family, h->table, h->obj,
- type, dump, true);
+ obj_cache = mnl_nft_obj_dump(ctx->nf_sock, h->family, ctx->seqnum,
+ h->table, h->obj, type, dump, true);
if (obj_cache == NULL) {
if (errno == EINTR)
return -1;
@@ -1935,7 +1937,7 @@ struct nftnl_ruleset *netlink_dump_ruleset(struct netlink_ctx *ctx,
{
struct nftnl_ruleset *rs;
- rs = mnl_nft_ruleset_dump(ctx->nf_sock, h->family);
+ rs = mnl_nft_ruleset_dump(ctx->nf_sock, h->family, ctx->seqnum);
if (rs == NULL) {
if (errno == EINTR)
return NULL;
@@ -3127,7 +3129,7 @@ int netlink_monitor(struct netlink_mon_handler *monhandler,
return mnl_nft_event_listener(nf_sock, netlink_events_cb, monhandler);
}
-bool netlink_batch_supported(struct mnl_socket *nf_sock)
+bool netlink_batch_supported(struct mnl_socket *nf_sock, uint32_t *seqnum)
{
- return mnl_batch_supported(nf_sock);
+ return mnl_batch_supported(nf_sock, seqnum);
}
diff --git a/src/rule.c b/src/rule.c
index 38cd648e..ef12becd 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -135,6 +135,7 @@ static int cache_init(struct mnl_socket *nf_sock, struct nft_cache *cache,
ctx.nf_sock = nf_sock;
ctx.cache = cache;
ctx.msgs = msgs;
+ ctx.seqnum = cache->seqnum++;
ret = cache_init_tables(&ctx, &handle, cache);
if (ret < 0)
@@ -154,7 +155,7 @@ int cache_update(struct mnl_socket *nf_sock, struct nft_cache *cache,
if (cache->initialized)
return 0;
replay:
- netlink_genid_get(nf_sock);
+ netlink_genid_get(nf_sock, cache->seqnum++);
ret = cache_init(nf_sock, cache, cmd, msgs);
if (ret < 0) {
cache_release(cache);