Commit
8bd99f2fca7e ("mnl: don't send empty set elements netlink message
to kernel") broke set flush because we still need to send the netlink
message with no elements to flush sets.
To avoid more whack-a-mole games, add a new explicit function
mnl_nft_setelem_batch_flush() that is used to request a set flush,
instead of reusing the one that allows us to explicitly delete given set
elements.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
unsigned int flags);
int mnl_nft_setelem_batch_del(struct nftnl_set *nls,
unsigned int flags, uint32_t seq);
+int mnl_nft_setelem_batch_flush(struct nftnl_set *nls, unsigned int flags,
+ uint32_t seqnum);
int mnl_nft_setelem_get(struct mnl_socket *nf_sock, struct nftnl_set *nls);
struct nftnl_ruleset *mnl_nft_ruleset_dump(struct mnl_socket *nf_sock,
return mnl_nft_setelem_batch(nls, NFT_MSG_NEWSETELEM, flags, seqnum);
}
+int mnl_nft_setelem_batch_flush(struct nftnl_set *nls, unsigned int flags,
+ uint32_t seqnum)
+{
+ struct nlmsghdr *nlh;
+
+ nlh = nftnl_set_elem_nlmsg_build_hdr(nftnl_batch_buffer(batch),
+ NFT_MSG_DELSETELEM,
+ nftnl_set_get_u32(nls, NFTNL_SET_FAMILY),
+ NLM_F_CREATE | flags, seqnum);
+ nftnl_set_elems_nlmsg_build_payload(nlh, nls);
+ mnl_nft_batch_continue();
+
+ return 0;
+}
+
int mnl_nft_setelem_batch_del(struct nftnl_set *nls, unsigned int flags,
uint32_t seqnum)
{
int netlink_flush_setelems(struct netlink_ctx *ctx, const struct handle *h,
const struct location *loc)
{
- return netlink_del_setelems_batch(ctx, h, NULL);
+ struct nftnl_set *nls;
+ int err;
+
+ nls = alloc_nftnl_set(h);
+ netlink_dump_set(nls);
+
+ err = mnl_nft_setelem_batch_flush(nls, 0, ctx->seqnum);
+ nftnl_set_free(nls);
+ if (err < 0)
+ netlink_io_error(ctx, loc,
+ "Could not flush set elements: %s",
+ strerror(errno));
+ return err;
}
static struct expr *netlink_parse_concat_elem(const struct datatype *dtype,