diff options
author | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-12-13 23:51:33 +0100 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2016-12-14 00:07:34 +0100 |
commit | 8bd99f2fca7e8210771e0b3cb97ce7dbb3cb494d (patch) | |
tree | 2e3b3d70c6027c91015e13dac6d70f21858c131e /src | |
parent | cd326af6d46b725c99fa8017a294c51876e486f7 (diff) |
mnl: don't send empty set elements netlink message to kernel
The following command:
# nft --debug=mnl add rule x y flow table xyz { ip saddr timeout 30s counter }
breaks with EINVAL. The following netlink message is causing the
problem:
...
---------------- ------------------
| 0000000044 | | message length |
| 02572 | R--- | | type | flags |
| 0000000004 | | sequence number|
| 0000000000 | | port ID |
---------------- ------------------
| 02 00 00 00 | | extra header |
|00008|--|00002| |len |flags| type|
| 78 79 7a 00 | | data | x y z
|00008|--|00004| |len |flags| type|
| 00 00 00 01 | | data |
|00006|--|00001| |len |flags| type|
| 78 00 00 00 | | data | x
---------------- ------------------
...
This is incorrect since this describes no elements at all, so it is
useless. Add upfront check before iterating over the list of set
elements so the netlink message is not placed in the batch.
This patch also adds a set so flow tables are minimally covered.
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src')
-rw-r--r-- | src/mnl.c | 14 |
1 files changed, 9 insertions, 5 deletions
@@ -825,19 +825,21 @@ int mnl_nft_setelem_add(struct mnl_socket *nf_sock, struct nftnl_set *nls, char buf[NFT_NLMSG_MAXSIZE]; struct nlmsghdr *nlh; struct nftnl_set_elems_iter *iter; - int ret, err; + int ret, err = 0; iter = nftnl_set_elems_iter_create(nls); if (iter == NULL) memory_allocation_error(); - do { + while (nftnl_set_elems_iter_cur(iter)) { nlh = nftnl_set_elem_nlmsg_build_hdr(buf, NFT_MSG_NEWSETELEM, nftnl_set_get_u32(nls, NFTNL_SET_FAMILY), NLM_F_CREATE | NLM_F_ACK | flags, seq); ret = nftnl_set_elems_nlmsg_build_payload_iter(nlh, iter); err = nft_mnl_talk(nf_sock, nlh, nlh->nlmsg_len, NULL, NULL); - } while (ret > 0 && err >= 0); + if (ret <= 0 || err < 0) + break; + } nftnl_set_elems_iter_destroy(iter); @@ -879,13 +881,15 @@ static int mnl_nft_setelem_batch(struct nftnl_set *nls, if (iter == NULL) memory_allocation_error(); - do { + while (nftnl_set_elems_iter_cur(iter)) { nlh = nftnl_set_elem_nlmsg_build_hdr(nftnl_batch_buffer(batch), cmd, nftnl_set_get_u32(nls, NFTNL_SET_FAMILY), NLM_F_CREATE | flags, seqnum); ret = nftnl_set_elems_nlmsg_build_payload_iter(nlh, iter); mnl_nft_batch_continue(); - } while (ret > 0); + if (ret <= 0) + break; + } nftnl_set_elems_iter_destroy(iter); |