summaryrefslogtreecommitdiffstats
path: root/src/mnl.c
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2017-08-09 13:16:42 +0200
committerPablo Neira Ayuso <pablo@netfilter.org>2017-08-14 11:32:20 +0200
commitb99c4d072d9969f7a0dfc539b2b68b517f90af68 (patch)
treedadf8b641cc9082d64f4dec210772e2eaf1451e7 /src/mnl.c
parentc5c6bf14aa53bd16e66fcd281374faa66b3293f8 (diff)
Implement --echo option
When used with add, insert or replace commands, nft tool will print event notifications just like 'nft monitor' does for the same commands. Apart from seeing what a given command will turn out in the rule set, this allows to reliably retrieve a new rule's assigned handle (if used together with --handle option). Here are some examples of how it works: | # nft --echo --handle add table ip t | add table ip t | | # nft --echo --handle add chain ip t c \ | '{ type filter hook forward priority 0; }' | add chain ip t c { type filter hook forward priority 0; policy accept; } | | # nft --echo --handle add rule ip t c tcp dport '{22, 80}' accept | add rule ip t c tcp dport { ssh, http } accept # handle 2 | | # nft --echo --handle add set ip t ipset '{ type ipv4_addr; \ | elements = { 192.168.0.1, 192.168.0.2 }; }' | add set ip t ipset { type ipv4_addr; } | add element ip t ipset { 192.168.0.1 } | add element ip t ipset { 192.168.0.2 } Signed-off-by: Phil Sutter <phil@nwl.cc> Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'src/mnl.c')
-rw-r--r--src/mnl.c25
1 files changed, 23 insertions, 2 deletions
diff --git a/src/mnl.c b/src/mnl.c
index 862311a7..031b7f39 100644
--- a/src/mnl.c
+++ b/src/mnl.c
@@ -67,11 +67,32 @@ out:
return ret;
}
+struct nft_mnl_talk_cb_data {
+ int (*cb)(const struct nlmsghdr *nlh, void *data);
+ void *data;
+};
+
+static int nft_mnl_talk_cb(const struct nlmsghdr *nlh, void *data)
+{
+ struct nft_mnl_talk_cb_data *cbdata = data;
+ int rc;
+
+ if (cbdata->cb)
+ rc = cbdata->cb(nlh, cbdata->data);
+ if (rc)
+ return rc;
+ return netlink_echo_callback(nlh, cbdata->data);
+}
+
static int
nft_mnl_talk(struct mnl_socket *nf_sock, const void *data, unsigned int len,
int (*cb)(const struct nlmsghdr *nlh, void *data), void *cb_data)
{
uint32_t portid = mnl_socket_get_portid(nf_sock);
+ struct nft_mnl_talk_cb_data tcb_data = {
+ .cb = cb,
+ .data = cb_data,
+ };
#ifdef DEBUG
if (debug_level & DEBUG_MNL)
@@ -81,7 +102,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, seq, portid, &nft_mnl_talk_cb, &tcb_data);
}
/*
@@ -276,7 +297,7 @@ int mnl_batch_talk(struct netlink_ctx *ctx, struct list_head *err_list)
if (ret == -1)
return -1;
- ret = mnl_cb_run(rcv_buf, ret, 0, portid, NULL, NULL);
+ ret = mnl_cb_run(rcv_buf, ret, 0, portid, &netlink_echo_callback, ctx);
/* Continue on error, make sure we get all acknowledgments */
if (ret == -1)
mnl_err_list_node_add(err_list, errno, nlh->nlmsg_seq);