Update mnl_genid_get() to return 32-bit long generation ID. Add nft_genid_u16() which allows us to catch ruleset updates from the netlink dump path via 16-bit long nfnetlink resource ID field. Signed-off-by: Pablo Neira Ayuso <pablo@xxxxxxxxxxxxx> --- include/mnl.h | 2 +- include/nftables.h | 2 +- src/mnl.c | 11 ++++++++--- src/rule.c | 5 ++--- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/include/mnl.h b/include/mnl.h index 9f50c3da0f3a..eeba7379706f 100644 --- a/include/mnl.h +++ b/include/mnl.h @@ -10,7 +10,7 @@ struct mnl_socket *nft_mnl_socket_open(void); struct mnl_socket *nft_mnl_socket_reopen(struct mnl_socket *nf_sock); uint32_t mnl_seqnum_alloc(uint32_t *seqnum); -uint16_t mnl_genid_get(struct netlink_ctx *ctx); +uint32_t mnl_genid_get(struct netlink_ctx *ctx); struct mnl_err { struct list_head head; diff --git a/include/nftables.h b/include/nftables.h index af2c1ea16cfb..b7c78572da77 100644 --- a/include/nftables.h +++ b/include/nftables.h @@ -78,7 +78,7 @@ static inline bool nft_output_numeric_symbol(const struct output_ctx *octx) } struct nft_cache { - uint16_t genid; + uint32_t genid; struct list_head list; uint32_t seqnum; uint32_t cmd; diff --git a/src/mnl.c b/src/mnl.c index c0df2c941d88..e0856493909d 100644 --- a/src/mnl.c +++ b/src/mnl.c @@ -108,7 +108,7 @@ nft_mnl_talk(struct netlink_ctx *ctx, const void *data, unsigned int len, /* * Rule-set consistency check across several netlink dumps */ -static uint16_t nft_genid; +static uint32_t nft_genid; static int genid_cb(const struct nlmsghdr *nlh, void *data) { @@ -119,7 +119,7 @@ static int genid_cb(const struct nlmsghdr *nlh, void *data) return MNL_CB_OK; } -uint16_t mnl_genid_get(struct netlink_ctx *ctx) +uint32_t mnl_genid_get(struct netlink_ctx *ctx) { char buf[MNL_SOCKET_BUFFER_SIZE]; struct nlmsghdr *nlh; @@ -131,11 +131,16 @@ uint16_t mnl_genid_get(struct netlink_ctx *ctx) return nft_genid; } +static uint16_t nft_genid_u16(uint32_t nft_genid) +{ + return nft_genid & 0xffff; +} + static int check_genid(const struct nlmsghdr *nlh) { struct nfgenmsg *nfh = mnl_nlmsg_get_payload(nlh); - if (nft_genid != ntohs(nfh->res_id)) { + if (nft_genid_u16(nft_genid) != ntohs(nfh->res_id)) { errno = EINTR; return -1; } diff --git a/src/rule.c b/src/rule.c index 1e081c8fe862..651454733bed 100644 --- a/src/rule.c +++ b/src/rule.c @@ -244,8 +244,6 @@ static bool cache_is_updated(struct nft_cache *cache, uint16_t genid) int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) { - uint16_t genid; - int ret; struct netlink_ctx ctx = { .list = LIST_HEAD_INIT(ctx.list), .nft = nft, @@ -253,7 +251,8 @@ int cache_update(struct nft_ctx *nft, enum cmd_ops cmd, struct list_head *msgs) .nft = nft, }; struct nft_cache *cache = &nft->cache; - + uint32_t genid; + int ret; replay: ctx.seqnum = cache->seqnum++; genid = mnl_genid_get(&ctx); -- 2.11.0