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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.