From b99c4d072d9969f7a0dfc539b2b68b517f90af68 Mon Sep 17 00:00:00 2001 From: Phil Sutter Date: Wed, 9 Aug 2017 13:16:42 +0200 Subject: 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 Signed-off-by: Pablo Neira Ayuso --- src/mnl.c | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) (limited to 'src/mnl.c') 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); -- cgit v1.2.3