netfilter-devel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
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

  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).