From: Florian Westphal <fw@strlen.de>
To: <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [PATCH nftables 6/6] src: add trace support to nft monitor mode
Date: Tue, 24 Nov 2015 11:02:11 +0100 [thread overview]
Message-ID: <1448359331-12692-7-git-send-email-fw@strlen.de> (raw)
In-Reply-To: <1448359331-12692-1-git-send-email-fw@strlen.de>
nft monitor [ trace ]
... can now display nftables nftrace debug information.
$ nft rule bridge raw prerouting add tcp dport 22 limit rate 1/second meta nftrace set 1
$ nft monitor trace
trace id 834dd100 bridge packet src 5e:95:99:72:ea:c5 dst 52:54:40:a2:3f:a6 src 192.168.7.1 dst 192.168.7.11 len 88 ttl 64 id 2719 protocol 6 sport 3628 dport 22 iif eth0
trace id 834dd100 bridge raw prerouting rule verdict continue iif eth0
trace id 834dd100 rule tcp dport ssh limit rate 1/second nftrace set 1
trace id 834dd100 bridge raw prerouting policy verdict accept iif eth0
trace id 834dd100 ip filter input rule verdict jump iif br0
trace id 834dd100 rule ip saddr . tcp dport vmap { }
trace id 834dd100 ip filter test rule verdict accept iif br0
trace id 834dd100 rule accept
based on an initial patch from Markus Kötter.
Signed-off-by: Florian Westphal <fw@strlen.de>
---
include/linux/netfilter/nf_tables.h | 30 +++++++++++++
src/evaluate.c | 18 ++++++++
src/netlink.c | 84 +++++++++++++++++++++++++++++++++++++
src/rule.c | 47 +++++++++++++++++----
4 files changed, 170 insertions(+), 9 deletions(-)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 5ebe3d8..85d739b 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -101,6 +101,7 @@ enum nf_tables_msg_types {
NFT_MSG_DELSETELEM,
NFT_MSG_NEWGEN,
NFT_MSG_GETGEN,
+ NFT_MSG_TRACE,
NFT_MSG_MAX,
};
@@ -961,4 +962,33 @@ enum nft_gen_attributes {
};
#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1)
+enum nft_trace_attibutes {
+ NFTA_TRACE_UNSPEC,
+ NFTA_TRACE_CHAIN,
+ NFTA_TRACE_ID,
+ NFTA_TRACE_IIF,
+ NFTA_TRACE_OIF,
+ NFTA_TRACE_LL_HEADER,
+ NFTA_TRACE_LL_TYPE,
+ NFTA_TRACE_MARK,
+ NFTA_TRACE_PAYLOAD,
+ NFTA_TRACE_TABLE,
+ NFTA_TRACE_TYPE,
+ NFTA_TRACE_RULE_HANDLE,
+ NFTA_TRACE_VERDICT,
+ NFTA_TRACE_VLAN_TAG,
+ NFTA_TRACE_DEVTYPE,
+ __NFTA_TRACE_MAX
+};
+#define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1)
+
+enum nft_trace_types {
+ NFT_TRACETYPE_UNSPEC,
+ NFT_TRACETYPE_PACKET,
+ NFT_TRACETYPE_POLICY,
+ NFT_TRACETYPE_RETURN,
+ NFT_TRACETYPE_RULE,
+ __NFT_TRACETYPE_MAX
+};
+#define NFT_TRACETYPE_MAX (__NFT_TRACETYPE_MAX - 1)
#endif /* _LINUX_NF_TABLES_H */
diff --git a/src/evaluate.c b/src/evaluate.c
index 48f071f..b1ab8e9 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2279,6 +2279,7 @@ enum {
CMD_MONITOR_EVENT_ANY,
CMD_MONITOR_EVENT_NEW,
CMD_MONITOR_EVENT_DEL,
+ CMD_MONITOR_EVENT_TRACE,
CMD_MONITOR_EVENT_MAX
};
@@ -2320,6 +2321,21 @@ static uint32_t monitor_flags[CMD_MONITOR_EVENT_MAX][CMD_MONITOR_OBJ_MAX] = {
[CMD_MONITOR_OBJ_SETS] = (1 << NFT_MSG_DELSET),
[CMD_MONITOR_OBJ_ELEMS] = (1 << NFT_MSG_DELSETELEM),
},
+ [CMD_MONITOR_EVENT_TRACE] = {
+ [CMD_MONITOR_OBJ_ANY] = (1 << NFT_MSG_NEWTABLE) |
+ (1 << NFT_MSG_NEWCHAIN) |
+ (1 << NFT_MSG_NEWRULE) |
+ (1 << NFT_MSG_DELTABLE) |
+ (1 << NFT_MSG_DELCHAIN) |
+ (1 << NFT_MSG_DELRULE) |
+ (1 << NFT_MSG_TRACE),
+ [CMD_MONITOR_OBJ_TABLES] = (1 << NFT_MSG_NEWTABLE) |
+ (1 << NFT_MSG_DELTABLE),
+ [CMD_MONITOR_OBJ_CHAINS] = (1 << NFT_MSG_NEWCHAIN) |
+ (1 << NFT_MSG_DELCHAIN),
+ [CMD_MONITOR_OBJ_RULES] = (1 << NFT_MSG_NEWRULE) |
+ (1 << NFT_MSG_DELRULE),
+ },
};
static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd)
@@ -2332,6 +2348,8 @@ static int cmd_evaluate_monitor(struct eval_ctx *ctx, struct cmd *cmd)
event = CMD_MONITOR_EVENT_NEW;
else if (strcmp(cmd->monitor->event, "destroy") == 0)
event = CMD_MONITOR_EVENT_DEL;
+ else if (strcmp(cmd->monitor->event, "trace") == 0)
+ event = CMD_MONITOR_EVENT_TRACE;
else {
return monitor_error(ctx, cmd->monitor, "invalid event %s",
cmd->monitor->event);
diff --git a/src/netlink.c b/src/netlink.c
index 974afb1..8ab7bbe 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -18,6 +18,7 @@
#include <stdlib.h>
#include <libnftnl/table.h>
+#include <libnftnl/trace.h>
#include <libnftnl/chain.h>
#include <libnftnl/expr.h>
#include <libnftnl/set.h>
@@ -33,6 +34,7 @@
#include <gmputil.h>
#include <utils.h>
#include <erec.h>
+#include <iface.h>
static struct mnl_socket *nf_sock;
static struct mnl_socket *nf_mon_sock;
@@ -2125,6 +2127,85 @@ static void netlink_events_cache_update(struct netlink_mon_handler *monh,
}
}
+static void trace_print_rule(const struct nftnl_trace *nlt)
+{
+ const struct table *table;
+ uint64_t rule_handle;
+ struct chain *chain;
+ struct handle h;
+
+ h.table = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
+ h.chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
+ h.family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
+
+ if (!h.table)
+ return;
+
+ table = table_lookup(&h);
+ if (!table)
+ return;
+
+ chain = chain_lookup(table, &h);
+ if (!chain)
+ return;
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE)) {
+ struct rule *rule;
+
+ rule_handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
+
+ list_for_each_entry(rule, &chain->rules, list) {
+ if (rule->handle.handle != rule_handle)
+ continue;
+
+ printf("\ntrace id %08x rule ", nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID));
+ rule_print(rule);
+ return;
+ }
+ }
+}
+
+static void trace_print_if(const struct nftnl_trace *nlt, uint16_t attr, const char *str)
+{
+ char __name[IFNAMSIZ];
+ const char *ifname;
+
+ if (!nftnl_trace_is_set(nlt, attr))
+ return;
+
+ ifname = nft_if_indextoname(nftnl_trace_get_u32(nlt, attr), __name);
+ if (ifname)
+ printf(" %s %s", str, ifname);
+ else
+ printf(" %s %d", str, nftnl_trace_get_u32(nlt, attr));
+}
+
+static int netlink_events_trace_cb(const struct nlmsghdr *nlh, int type,
+ struct netlink_mon_handler *monh)
+{
+ struct nftnl_trace *nlt;
+
+ assert(type == NFT_MSG_TRACE);
+
+ nlt = nftnl_trace_alloc();
+ if (!nlt)
+ memory_allocation_error();
+
+ if (nftnl_trace_nlmsg_parse(nlh, nlt) < 0)
+ netlink_abi_error();
+
+ printf("trace ");
+ nftnl_trace_fprintf(stdout, nlt, monh->format);
+
+ trace_print_if(nlt, NFTNL_TRACE_IIF, "iif");
+ trace_print_if(nlt, NFTNL_TRACE_OIF, "oif");
+
+ trace_print_rule(nlt);
+ printf("\n");
+ nftnl_trace_free(nlt);
+ return MNL_CB_OK;
+}
+
static int netlink_events_cb(const struct nlmsghdr *nlh, void *data)
{
int ret = MNL_CB_OK;
@@ -2157,6 +2238,9 @@ static int netlink_events_cb(const struct nlmsghdr *nlh, void *data)
case NFT_MSG_DELRULE:
ret = netlink_events_rule_cb(nlh, type, monh);
break;
+ case NFT_MSG_TRACE:
+ ret = netlink_events_trace_cb(nlh, type, monh);
+ break;
}
fflush(stdout);
diff --git a/src/rule.c b/src/rule.c
index 5d3cd84..553990d 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -1192,27 +1192,56 @@ static int do_command_rename(struct netlink_ctx *ctx, struct cmd *cmd)
return 0;
}
-static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd)
+static bool need_cache(const struct cmd *cmd)
{
- struct table *t;
- struct set *s;
- struct netlink_mon_handler monhandler;
-
- /* cache only needed if monitoring:
+ /*
* - new rules in default format
* - new elements
*/
if (((cmd->monitor->flags & (1 << NFT_MSG_NEWRULE)) &&
(cmd->monitor->format == NFTNL_OUTPUT_DEFAULT)) ||
(cmd->monitor->flags & (1 << NFT_MSG_NEWSETELEM)))
- monhandler.cache_needed = true;
- else
- monhandler.cache_needed = false;
+ return true;
+ if (cmd->monitor->flags & (1 << NFT_MSG_TRACE))
+ return true;
+
+ return false;
+}
+
+static int do_command_monitor(struct netlink_ctx *ctx, struct cmd *cmd)
+{
+ struct table *t;
+ struct set *s;
+ struct netlink_mon_handler monhandler;
+
+ monhandler.cache_needed = need_cache(cmd);
if (monhandler.cache_needed) {
+ struct rule *rule, *nrule;
+ struct chain *chain;
+ int ret;
+
list_for_each_entry(t, &table_list, list) {
list_for_each_entry(s, &t->sets, list)
s->init = set_expr_alloc(&cmd->location);
+
+ if (!(cmd->monitor->flags & (1 << NFT_MSG_TRACE)))
+ continue;
+
+ /* When tracing we'd like to translate the rule handle
+ * we receive in the trace messages to the actual rule
+ * struct to print that out. Populate rule cache now.
+ */
+ ret = netlink_list_table(ctx, &t->handle,
+ &internal_location);
+
+ if (ret != 0) /* shouldn't happen && doesn't break things too badly */
+ continue;
+
+ list_for_each_entry_safe(rule, nrule, &ctx->list, list) {
+ chain = chain_lookup(t, &rule->handle);
+ list_move_tail(&rule->list, &chain->rules);
+ }
}
}
--
2.4.10
--
To unsubscribe from this list: send the line "unsubscribe netfilter-devel" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
next prev parent reply other threads:[~2015-11-24 10:02 UTC|newest]
Thread overview: 80+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-11-24 10:02 [PATCH 0/6] nftables trace support Florian Westphal
2015-11-24 10:02 ` [PATCH nf-next 1/6] netfilter: nf_tables: extend tracing infrastructure Florian Westphal
2015-11-24 10:17 ` Pablo Neira Ayuso
2015-11-24 10:27 ` Florian Westphal
2015-11-24 10:30 ` Pablo Neira Ayuso
2015-11-24 10:35 ` Patrick McHardy
2015-11-24 11:11 ` Florian Westphal
2015-11-24 10:22 ` Pablo Neira Ayuso
2015-11-24 10:28 ` Florian Westphal
2015-11-24 10:33 ` Patrick McHardy
2015-11-24 10:44 ` Pablo Neira Ayuso
2015-11-24 10:45 ` Pablo Neira Ayuso
2015-11-24 10:47 ` Patrick McHardy
2015-11-24 10:36 ` Pablo Neira Ayuso
2015-11-24 10:44 ` Patrick McHardy
2015-11-25 0:55 ` Patrick McHardy
2015-11-25 8:39 ` Florian Westphal
2015-11-25 8:48 ` Florian Westphal
2015-11-25 9:35 ` Patrick McHardy
2015-11-25 10:13 ` Florian Westphal
2015-11-25 11:51 ` Patrick McHardy
2015-11-25 12:20 ` Florian Westphal
2015-11-24 10:02 ` [PATCH nf-next 2/6] netfilter: nf_tables: wrap tracing with a static key Florian Westphal
2015-11-24 10:13 ` Patrick McHardy
2015-11-24 10:21 ` Florian Westphal
2015-11-24 10:28 ` Patrick McHardy
2015-11-24 10:19 ` Pablo Neira Ayuso
2015-11-24 10:02 ` [PATCH nf-next 3/6] netfilter: nf_tables: disable old tracing if listener is present Florian Westphal
2015-11-24 10:16 ` Patrick McHardy
2015-11-24 10:24 ` Pablo Neira Ayuso
2015-11-24 10:31 ` Florian Westphal
2015-11-24 10:39 ` Pablo Neira Ayuso
2015-11-24 10:53 ` Patrick McHardy
2015-11-24 11:10 ` Florian Westphal
2015-11-24 11:33 ` Patrick McHardy
2015-11-24 15:15 ` Florian Westphal
2015-11-24 15:26 ` Patrick McHardy
2015-11-24 15:35 ` Florian Westphal
2015-11-24 15:42 ` Patrick McHardy
2015-11-25 15:06 ` Patrick McHardy
2015-11-25 16:23 ` Pablo Neira Ayuso
2015-11-25 16:34 ` Patrick McHardy
2015-11-25 16:24 ` Florian Westphal
2015-11-25 16:46 ` Patrick McHardy
2015-11-25 17:32 ` Patrick McHardy
2015-11-25 22:27 ` Florian Westphal
2015-11-25 23:04 ` Patrick McHardy
2015-11-25 23:16 ` Florian Westphal
2015-11-25 23:30 ` Patrick McHardy
2015-11-25 23:42 ` Patrick McHardy
2015-11-25 23:56 ` Florian Westphal
2015-11-25 22:52 ` Florian Westphal
2015-11-25 23:15 ` Patrick McHardy
2015-11-25 23:19 ` Florian Westphal
2015-11-26 10:50 ` Patrick McHardy
2015-11-26 11:03 ` Florian Westphal
2015-11-26 11:42 ` Patrick McHardy
2015-11-25 16:49 ` Jan Engelhardt
2015-11-25 16:53 ` Patrick McHardy
2015-11-25 17:14 ` Jan Engelhardt
2015-11-25 17:24 ` Patrick McHardy
2015-11-25 0:57 ` Patrick McHardy
2015-11-24 10:02 ` [PATCH libnftnl 4/6] src: rename EXPORT_SYMBOL to EXPORT_SYMBOL_ALIAS Florian Westphal
2015-11-24 10:11 ` Pablo Neira Ayuso
2015-11-24 10:02 ` [PATCH libnftnl 5/6] src: add trace infrastructure support Florian Westphal
2015-11-24 12:16 ` Patrick McHardy
2015-11-24 14:53 ` Patrick McHardy
2015-11-24 10:02 ` Florian Westphal [this message]
2015-11-24 10:25 ` [PATCH nftables 6/6] src: add trace support to nft monitor mode Patrick McHardy
2015-11-24 10:48 ` Florian Westphal
2015-11-24 10:58 ` Patrick McHardy
2015-11-24 11:01 ` Pablo Neira Ayuso
2015-11-24 11:07 ` Patrick McHardy
2015-11-24 11:14 ` Pablo Neira Ayuso
2015-11-24 11:14 ` Florian Westphal
2015-11-24 11:41 ` Patrick McHardy
2015-11-24 10:53 ` Pablo Neira Ayuso
2015-11-24 11:04 ` Patrick McHardy
2015-11-24 11:12 ` Pablo Neira Ayuso
2015-11-24 11:36 ` Patrick McHardy
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1448359331-12692-7-git-send-email-fw@strlen.de \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).