void netlink_close_sock(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);
+uint16_t mnl_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum);
struct mnl_err {
struct list_head head;
extern int netlink_batch_send(struct netlink_ctx *ctx, struct list_head *err_list);
-extern void netlink_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum);
+extern uint16_t 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));
};
struct nft_cache {
- bool initialized;
+ uint16_t genid;
struct list_head list;
uint32_t seqnum;
};
int nft_ctx_add_include_path(struct nft_ctx *ctx, const char *path);
void nft_ctx_clear_include_paths(struct nft_ctx *ctx);
-void nft_ctx_flush_cache(struct nft_ctx *ctx);
-
int nft_run_cmd_from_buffer(struct nft_ctx *nft, char *buf, size_t buflen);
int nft_run_cmd_from_filename(struct nft_ctx *nft, const char *filename);
nft_run_cmd_from_buffer(cli_nft, line, len + 2);
xfree(line);
- nft_ctx_flush_cache(cli_nft);
}
static char **cli_completion(const char *text, int start, int end)
return ctx;
}
-void nft_ctx_flush_cache(struct nft_ctx *ctx)
-{
- iface_cache_release();
- cache_release(&ctx->cache);
-}
-
void nft_ctx_free(struct nft_ctx *ctx)
{
if (ctx->nf_sock)
netlink_close_sock(ctx->nf_sock);
- nft_ctx_flush_cache(ctx);
+ iface_cache_release();
+ cache_release(&ctx->cache);
nft_ctx_clear_include_paths(ctx);
xfree(ctx);
nft_exit();
return MNL_CB_OK;
}
-void mnl_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum)
+uint16_t mnl_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum)
{
char buf[MNL_SOCKET_BUFFER_SIZE];
struct mnl_ctx ctx = {
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(&ctx, nlh, nlh->nlmsg_len, genid_cb, NULL);
+
+ return nft_genid;
}
static int check_genid(const struct nlmsghdr *nlh)
nf_sock = netlink_open_sock();
}
-void netlink_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum)
+uint16_t netlink_genid_get(struct mnl_socket *nf_sock, uint32_t seqnum)
{
- mnl_genid_get(nf_sock, seqnum);
+ return mnl_genid_get(nf_sock, seqnum);
}
void __noreturn __netlink_abi_error(const char *file, int line,
enum cmd_ops cmd, struct list_head *msgs, bool debug,
struct output_ctx *octx)
{
+ uint16_t genid;
int ret;
- if (cache->initialized)
- return 0;
replay:
- netlink_genid_get(nf_sock, cache->seqnum++);
+ genid = netlink_genid_get(nf_sock, cache->seqnum++);
+ if (genid && genid == cache->genid)
+ return 0;
+ cache_release(cache);
ret = cache_init(nf_sock, cache, cmd, msgs, debug, octx);
if (ret < 0) {
cache_release(cache);
}
return -1;
}
- cache->initialized = true;
+ cache->genid = genid;
return 0;
}
void cache_release(struct nft_cache *cache)
{
cache_flush(&cache->list);
- cache->initialized = false;
+ cache->genid = 0;
}
/* internal ID to uniquely identify a set in the batch */