* [PATCH nft 0/6] ruleset tracing
@ 2016-04-24 21:30 Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 1/6] payload: fix stacked headers protocol context tracking Patrick McHardy
` (6 more replies)
0 siblings, 7 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
The following patches contain the latest version of the ruleset tracing
functionality.
Packets received from the kernel are decoded based on the nft protocol
definitions and are printed in the regular nft syntax. Uninteresting
fields are filtered to reduce the noise.
I've compacted the output so we only show a single line per rule, which
also contains the verdict and mark, if present. Examples can be found in
patch 6/6. This version fully supported stacked headers like VLAN.
The patchset is structured as follows:
* fixed for protocol context tracking of stacked headers, necessary for
proper packet decoding
* header resync
* moving of payload dependency tracking to payload.c to make it usable for
packet decoding
* introduction of a helper function for stacked header decoding
* tracing functionality
I consider this patchset complete. Testing and comments welcome.
Patrick McHardy (6):
payload: fix stacked headers protocol context tracking
nft: resync kernel header files
payload: move payload depedency tracking to payload.c
payload: add payload_is_stacked()
proto: add protocol header fields filter and ordering for packet decoding
nft monitor [ trace ]
include/linux/netfilter/nf_tables.h | 91 +++++++++++-
include/linux/netfilter/nfnetlink.h | 4 +
include/payload.h | 24 ++++
include/proto.h | 5 +
include/rule.h | 1 +
src/evaluate.c | 62 ++++-----
src/netlink.c | 269 +++++++++++++++++++++++++++++++++++-
src/netlink_delinearize.c | 97 +++----------
src/payload.c | 77 ++++++++++-
src/proto.c | 47 ++++++-
src/rule.c | 61 ++++++--
11 files changed, 611 insertions(+), 127 deletions(-)
--
2.5.5
^ permalink raw reply [flat|nested] 12+ messages in thread
* [PATCH nft 1/6] payload: fix stacked headers protocol context tracking
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
@ 2016-04-24 21:30 ` Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 2/6] nft: resync kernel header files Patrick McHardy
` (5 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
The code contains multiple scattered around fragments to fiddle with the
protocol contexts to work around the fact that stacked headers update the
context for the incorrect layer.
Fix this by updating the correct layer in payload_expr_pctx_update() and
also take care of offset adjustments there and only there. Remove all
manual protocol context fiddling and change protocol context debugging to
also print the offset for stacked headers.
All previously successful testcases pass.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
src/evaluate.c | 44 +++++++++++---------------------------------
src/netlink_delinearize.c | 7 ++-----
src/payload.c | 8 ++++++--
src/proto.c | 10 +++++++---
4 files changed, 26 insertions(+), 43 deletions(-)
diff --git a/src/evaluate.c b/src/evaluate.c
index 346e34f..a65e145 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -358,12 +358,6 @@ conflict_resolution_gen_dependency(struct eval_ctx *ctx, int protocol,
return expr_error(ctx->msgs, expr,
"dependency statement is invalid");
- ctx->pctx.protocol[base].desc = expr->payload.desc;
- assert(ctx->pctx.protocol[base].offset == 0);
-
- assert(desc->length);
- ctx->pctx.protocol[base].offset += desc->length;
-
*res = stmt;
return 0;
}
@@ -430,17 +424,6 @@ static int meta_iiftype_gen_dependency(struct eval_ctx *ctx,
return 0;
}
-static void proto_ctx_debunk(struct eval_ctx *ctx,
- const struct proto_desc *desc,
- const struct proto_desc *next,
- struct expr *payload, enum proto_bases base)
-{
- ctx->pctx.protocol[base + 1].desc = NULL;
- ctx->pctx.protocol[base].desc = next;
- ctx->pctx.protocol[base].offset += desc->length;
- payload->payload.offset += desc->length;
-}
-
static bool proto_is_dummy(const struct proto_desc *desc)
{
return desc == &proto_inet || desc == &proto_netdev;
@@ -451,7 +434,6 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx,
struct expr *payload)
{
enum proto_bases base = payload->payload.base;
- const struct proto_desc *next;
struct stmt *nstmt = NULL;
int link, err;
@@ -465,27 +447,17 @@ static int resolve_protocol_conflict(struct eval_ctx *ctx,
}
assert(base < PROTO_BASE_MAX);
- next = ctx->pctx.protocol[base + 1].desc;
-
- /* ether type vlan sets vlan as network protocol, debunk ethernet if it
- * is already there.
- */
- if (payload->payload.desc == next) {
- proto_ctx_debunk(ctx, desc, next, payload, base);
- return 0;
- }
-
/* This payload and the existing context don't match, conflict. */
- if (next != NULL)
+ if (ctx->pctx.protocol[base + 1].desc != NULL)
return 1;
link = proto_find_num(desc, payload->payload.desc);
- if (link < 0 || conflict_resolution_gen_dependency(ctx, link, payload, &nstmt) < 0)
+ if (link < 0 ||
+ conflict_resolution_gen_dependency(ctx, link, payload, &nstmt) < 0)
return 1;
payload->payload.offset += ctx->pctx.protocol[base].offset;
list_add_tail(&nstmt->list, &ctx->stmt->list);
- ctx->pctx.protocol[base + 1].desc = NULL;
return 0;
}
@@ -1622,7 +1594,7 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx,
default:
return stmt_binary_error(ctx, stmt,
&ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR],
- "cannot reject this ether type");
+ "cannot reject this network family");
}
break;
case NFT_REJECT_ICMP_UNREACH:
@@ -1644,7 +1616,7 @@ static int stmt_evaluate_reject_bridge_family(struct eval_ctx *ctx,
default:
return stmt_binary_error(ctx, stmt,
&ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR],
- "cannot reject this ether type");
+ "cannot reject this network family");
}
break;
}
@@ -1657,6 +1629,12 @@ static int stmt_evaluate_reject_bridge(struct eval_ctx *ctx, struct stmt *stmt,
{
const struct proto_desc *desc;
+ desc = ctx->pctx.protocol[PROTO_BASE_LL_HDR].desc;
+ if (desc != &proto_eth)
+ return stmt_binary_error(ctx,
+ &ctx->pctx.protocol[PROTO_BASE_LL_HDR],
+ stmt, "unsupported link layer protocol");
+
desc = ctx->pctx.protocol[PROTO_BASE_NETWORK_HDR].desc;
if (desc != NULL &&
stmt_evaluate_reject_bridge_family(ctx, stmt, desc) < 0)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index ca1c6e6..ee4cf12 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1077,13 +1077,10 @@ static void payload_dependency_save(struct rule_pp_ctx *ctx, unsigned int base,
stacked_header = next && next->base == base;
}
- if (stacked_header) {
- ctx->pctx.protocol[base].desc = next;
- ctx->pctx.protocol[base].offset += desc->length;
+ if (stacked_header)
payload_dependency_store(ctx, nstmt, base - 1);
- } else {
+ else
payload_dependency_store(ctx, nstmt, base);
- }
}
static void payload_match_expand(struct rule_pp_ctx *ctx,
diff --git a/src/payload.c b/src/payload.c
index f6c0a97..45a2ba2 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -85,8 +85,12 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx,
base = ctx->protocol[left->payload.base].desc;
desc = proto_find_upper(base, proto);
- assert(left->payload.base + 1 <= PROTO_BASE_MAX);
- proto_ctx_update(ctx, left->payload.base + 1, &expr->location, desc);
+ assert(desc->base <= PROTO_BASE_MAX);
+ if (desc->base == base->base) {
+ assert(base->length > 0);
+ ctx->protocol[base->base].offset += base->length;
+ }
+ proto_ctx_update(ctx, desc->base, &expr->location, desc);
}
static const struct expr_ops payload_expr_ops = {
diff --git a/src/proto.c b/src/proto.c
index b54a4c1..329d991 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -148,11 +148,15 @@ static void proto_ctx_debug(const struct proto_ctx *ctx, enum proto_bases base)
pr_debug("update %s protocol context:\n", proto_base_names[base]);
for (i = PROTO_BASE_LL_HDR; i <= PROTO_BASE_MAX; i++) {
- pr_debug(" %-20s: %s%s\n",
+ pr_debug(" %-20s: %s",
proto_base_names[i],
ctx->protocol[i].desc ? ctx->protocol[i].desc->name :
- "none",
- i == base ? " <-" : "");
+ "none");
+ if (ctx->protocol[i].offset)
+ pr_debug(" (offset: %u)", ctx->protocol[i].offset);
+ if (i == base)
+ pr_debug(" <-");
+ pr_debug("\n");
}
pr_debug("\n");
#endif
--
2.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 2/6] nft: resync kernel header files
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 1/6] payload: fix stacked headers protocol context tracking Patrick McHardy
@ 2016-04-24 21:30 ` Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 3/6] payload: move payload depedency tracking to payload.c Patrick McHardy
` (4 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/linux/netfilter/nf_tables.h | 91 +++++++++++++++++++++++++++++++++++--
include/linux/netfilter/nfnetlink.h | 4 ++
2 files changed, 90 insertions(+), 5 deletions(-)
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 310c785..eeffde1 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -1,6 +1,7 @@
#ifndef _LINUX_NF_TABLES_H
#define _LINUX_NF_TABLES_H
+#define NFT_TABLE_MAXNAMELEN 32
#define NFT_CHAIN_MAXNAMELEN 32
#define NFT_USERDATA_MAXLEN 256
@@ -82,6 +83,7 @@ enum nft_verdicts {
* @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes)
* @NFT_MSG_NEWGEN: announce a new generation, only for events (enum nft_gen_attributes)
* @NFT_MSG_GETGEN: get the rule-set generation (enum nft_gen_attributes)
+ * @NFT_MSG_TRACE: trace event (enum nft_trace_attributes)
*/
enum nf_tables_msg_types {
NFT_MSG_NEWTABLE,
@@ -101,6 +103,7 @@ enum nf_tables_msg_types {
NFT_MSG_DELSETELEM,
NFT_MSG_NEWGEN,
NFT_MSG_GETGEN,
+ NFT_MSG_TRACE,
NFT_MSG_MAX,
};
@@ -121,11 +124,13 @@ enum nft_list_attributes {
*
* @NFTA_HOOK_HOOKNUM: netfilter hook number (NLA_U32)
* @NFTA_HOOK_PRIORITY: netfilter hook priority (NLA_U32)
+ * @NFTA_HOOK_DEV: netdevice name (NLA_STRING)
*/
enum nft_hook_attributes {
NFTA_HOOK_UNSPEC,
NFTA_HOOK_HOOKNUM,
NFTA_HOOK_PRIORITY,
+ NFTA_HOOK_DEV,
__NFTA_HOOK_MAX
};
#define NFTA_HOOK_MAX (__NFTA_HOOK_MAX - 1)
@@ -237,6 +242,7 @@ enum nft_rule_compat_attributes {
* @NFT_SET_INTERVAL: set contains intervals
* @NFT_SET_MAP: set is used as a dictionary
* @NFT_SET_TIMEOUT: set uses timeouts
+ * @NFT_SET_EVAL: set contains expressions for evaluation
*/
enum nft_set_flags {
NFT_SET_ANONYMOUS = 0x1,
@@ -244,6 +250,7 @@ enum nft_set_flags {
NFT_SET_INTERVAL = 0x4,
NFT_SET_MAP = 0x8,
NFT_SET_TIMEOUT = 0x10,
+ NFT_SET_EVAL = 0x20,
};
/**
@@ -284,6 +291,7 @@ enum nft_set_desc_attributes {
* @NFTA_SET_ID: uniquely identifies a set in a transaction (NLA_U32)
* @NFTA_SET_TIMEOUT: default timeout value (NLA_U64)
* @NFTA_SET_GC_INTERVAL: garbage collection interval (NLA_U32)
+ * @NFTA_SET_USERDATA: user data (NLA_BINARY)
*/
enum nft_set_attributes {
NFTA_SET_UNSPEC,
@@ -299,6 +307,7 @@ enum nft_set_attributes {
NFTA_SET_ID,
NFTA_SET_TIMEOUT,
NFTA_SET_GC_INTERVAL,
+ NFTA_SET_USERDATA,
__NFTA_SET_MAX
};
#define NFTA_SET_MAX (__NFTA_SET_MAX - 1)
@@ -321,6 +330,7 @@ enum nft_set_elem_flags {
* @NFTA_SET_ELEM_TIMEOUT: timeout value (NLA_U64)
* @NFTA_SET_ELEM_EXPIRATION: expiration time (NLA_U64)
* @NFTA_SET_ELEM_USERDATA: user data (NLA_BINARY)
+ * @NFTA_SET_ELEM_EXPR: expression (NLA_NESTED: nft_expr_attributes)
*/
enum nft_set_elem_attributes {
NFTA_SET_ELEM_UNSPEC,
@@ -330,6 +340,7 @@ enum nft_set_elem_attributes {
NFTA_SET_ELEM_TIMEOUT,
NFTA_SET_ELEM_EXPIRATION,
NFTA_SET_ELEM_USERDATA,
+ NFTA_SET_ELEM_EXPR,
__NFTA_SET_ELEM_MAX
};
#define NFTA_SET_ELEM_MAX (__NFTA_SET_ELEM_MAX - 1)
@@ -562,6 +573,7 @@ enum nft_dynset_ops {
* @NFTA_DYNSET_SREG_KEY: source register of the key (NLA_U32)
* @NFTA_DYNSET_SREG_DATA: source register of the data (NLA_U32)
* @NFTA_DYNSET_TIMEOUT: timeout value for the new element (NLA_U64)
+ * @NFTA_DYNSET_EXPR: expression (NLA_NESTED: nft_expr_attributes)
*/
enum nft_dynset_attributes {
NFTA_DYNSET_UNSPEC,
@@ -571,6 +583,7 @@ enum nft_dynset_attributes {
NFTA_DYNSET_SREG_KEY,
NFTA_DYNSET_SREG_DATA,
NFTA_DYNSET_TIMEOUT,
+ NFTA_DYNSET_EXPR,
__NFTA_DYNSET_MAX,
};
#define NFTA_DYNSET_MAX (__NFTA_DYNSET_MAX - 1)
@@ -668,6 +681,7 @@ enum nft_exthdr_attributes {
* @NFT_META_IIFGROUP: packet input interface group
* @NFT_META_OIFGROUP: packet output interface group
* @NFT_META_CGROUP: socket control group (skb->sk->sk_classid)
+ * @NFT_META_PRANDOM: a 32bit pseudo-random number
*/
enum nft_meta_keys {
NFT_META_LEN,
@@ -694,6 +708,7 @@ enum nft_meta_keys {
NFT_META_IIFGROUP,
NFT_META_OIFGROUP,
NFT_META_CGROUP,
+ NFT_META_PRANDOM,
};
/**
@@ -772,7 +787,7 @@ enum nft_limit_type {
};
enum nft_limit_flags {
- NFT_LIMIT_F_INV = (1 << 0),
+ NFT_LIMIT_F_INV = (1 << 0),
};
/**
@@ -936,10 +951,14 @@ enum nft_nat_attributes {
* enum nft_masq_attributes - nf_tables masquerade expression attributes
*
* @NFTA_MASQ_FLAGS: NAT flags (see NF_NAT_RANGE_* in linux/netfilter/nf_nat.h) (NLA_U32)
+ * @NFTA_MASQ_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
+ * @NFTA_MASQ_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
*/
enum nft_masq_attributes {
NFTA_MASQ_UNSPEC,
NFTA_MASQ_FLAGS,
+ NFTA_MASQ_REG_PROTO_MIN,
+ NFTA_MASQ_REG_PROTO_MAX,
__NFTA_MASQ_MAX
};
#define NFTA_MASQ_MAX (__NFTA_MASQ_MAX - 1)
@@ -961,12 +980,12 @@ enum nft_redir_attributes {
#define NFTA_REDIR_MAX (__NFTA_REDIR_MAX - 1)
/**
- * enum nft_tee_attributes - nf_tables tee expression netlink attributes
+ * enum nft_dup_attributes - nf_tables dup expression netlink attributes
*
- * @NFTA_DUP_SREG_ADDR: source register of destination (NLA_U32: nft_registers)
- * @NFTA_DUP_SREG_DEV: output interface name (NLA_U32: nft_register)
+ * @NFTA_DUP_SREG_ADDR: source register of address (NLA_U32: nft_registers)
+ * @NFTA_DUP_SREG_DEV: source register of output interface (NLA_U32: nft_register)
*/
-enum nft_tee_attributes {
+enum nft_dup_attributes {
NFTA_DUP_UNSPEC,
NFTA_DUP_SREG_ADDR,
NFTA_DUP_SREG_DEV,
@@ -975,6 +994,18 @@ enum nft_tee_attributes {
#define NFTA_DUP_MAX (__NFTA_DUP_MAX - 1)
/**
+ * enum nft_fwd_attributes - nf_tables fwd expression netlink attributes
+ *
+ * @NFTA_FWD_SREG_DEV: source register of output interface (NLA_U32: nft_register)
+ */
+enum nft_fwd_attributes {
+ NFTA_FWD_UNSPEC,
+ NFTA_FWD_SREG_DEV,
+ __NFTA_FWD_MAX
+};
+#define NFTA_FWD_MAX (__NFTA_FWD_MAX - 1)
+
+/**
* enum nft_gen_attributes - nf_tables ruleset generation attributes
*
* @NFTA_GEN_ID: Ruleset generation ID (NLA_U32)
@@ -986,4 +1017,54 @@ enum nft_gen_attributes {
};
#define NFTA_GEN_MAX (__NFTA_GEN_MAX - 1)
+/**
+ * enum nft_trace_attributes - nf_tables trace netlink attributes
+ *
+ * @NFTA_TRACE_TABLE: name of the table (NLA_STRING)
+ * @NFTA_TRACE_CHAIN: name of the chain (NLA_STRING)
+ * @NFTA_TRACE_RULE_HANDLE: numeric handle of the rule (NLA_U64)
+ * @NFTA_TRACE_TYPE: type of the event (NLA_U32: nft_trace_types)
+ * @NFTA_TRACE_VERDICT: verdict returned by hook (NLA_NESTED: nft_verdicts)
+ * @NFTA_TRACE_ID: pseudo-id, same for each skb traced (NLA_U32)
+ * @NFTA_TRACE_LL_HEADER: linklayer header (NLA_BINARY)
+ * @NFTA_TRACE_NETWORK_HEADER: network header (NLA_BINARY)
+ * @NFTA_TRACE_TRANSPORT_HEADER: transport header (NLA_BINARY)
+ * @NFTA_TRACE_IIF: indev ifindex (NLA_U32)
+ * @NFTA_TRACE_IIFTYPE: netdev->type of indev (NLA_U16)
+ * @NFTA_TRACE_OIF: outdev ifindex (NLA_U32)
+ * @NFTA_TRACE_OIFTYPE: netdev->type of outdev (NLA_U16)
+ * @NFTA_TRACE_MARK: nfmark (NLA_U32)
+ * @NFTA_TRACE_NFPROTO: nf protocol processed (NLA_U32)
+ * @NFTA_TRACE_POLICY: policy that decided fate of packet (NLA_U32)
+ */
+enum nft_trace_attibutes {
+ NFTA_TRACE_UNSPEC,
+ NFTA_TRACE_TABLE,
+ NFTA_TRACE_CHAIN,
+ NFTA_TRACE_RULE_HANDLE,
+ NFTA_TRACE_TYPE,
+ NFTA_TRACE_VERDICT,
+ NFTA_TRACE_ID,
+ NFTA_TRACE_LL_HEADER,
+ NFTA_TRACE_NETWORK_HEADER,
+ NFTA_TRACE_TRANSPORT_HEADER,
+ NFTA_TRACE_IIF,
+ NFTA_TRACE_IIFTYPE,
+ NFTA_TRACE_OIF,
+ NFTA_TRACE_OIFTYPE,
+ NFTA_TRACE_MARK,
+ NFTA_TRACE_NFPROTO,
+ NFTA_TRACE_POLICY,
+ __NFTA_TRACE_MAX
+};
+#define NFTA_TRACE_MAX (__NFTA_TRACE_MAX - 1)
+
+enum nft_trace_types {
+ NFT_TRACETYPE_UNSPEC,
+ 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/include/linux/netfilter/nfnetlink.h b/include/linux/netfilter/nfnetlink.h
index 06eea26..454f78d 100644
--- a/include/linux/netfilter/nfnetlink.h
+++ b/include/linux/netfilter/nfnetlink.h
@@ -20,6 +20,10 @@ enum nfnetlink_groups {
#define NFNLGRP_CONNTRACK_EXP_DESTROY NFNLGRP_CONNTRACK_EXP_DESTROY
NFNLGRP_NFTABLES,
#define NFNLGRP_NFTABLES NFNLGRP_NFTABLES
+ NFNLGRP_ACCT_QUOTA,
+#define NFNLGRP_ACCT_QUOTA NFNLGRP_ACCT_QUOTA
+ NFNLGRP_NFTRACE,
+#define NFNLGRP_NFTRACE NFNLGRP_NFTRACE
__NFNLGRP_MAX,
};
#define NFNLGRP_MAX (__NFNLGRP_MAX - 1)
--
2.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 3/6] payload: move payload depedency tracking to payload.c
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 1/6] payload: fix stacked headers protocol context tracking Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 2/6] nft: resync kernel header files Patrick McHardy
@ 2016-04-24 21:30 ` Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 4/6] payload: add payload_is_stacked() Patrick McHardy
` (3 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/payload.h | 21 ++++++++++++++
src/netlink_delinearize.c | 70 ++++++++++++++---------------------------------
src/payload.c | 44 +++++++++++++++++++++++++++++
3 files changed, 85 insertions(+), 50 deletions(-)
diff --git a/include/payload.h b/include/payload.h
index fae3c67..eb9ff17 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -17,6 +17,27 @@ extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
extern int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
struct stmt **res);
+/**
+ * struct payload_dep_ctx - payload protocol dependency tracking
+ *
+ * @pbase: protocol base of last dependency match
+ * @pdep: last dependency match
+ * @prev: previous statement
+ */
+struct payload_dep_ctx {
+ enum proto_bases pbase;
+ struct stmt *pdep;
+ struct stmt *prev;
+};
+
+extern void payload_dependency_store(struct payload_dep_ctx *ctx,
+ struct stmt *stmt,
+ enum proto_bases base);
+extern void __payload_dependency_kill(struct payload_dep_ctx *ctx,
+ enum proto_bases base);
+extern void payload_dependency_kill(struct payload_dep_ctx *ctx,
+ struct expr *expr);
+
extern bool payload_can_merge(const struct expr *e1, const struct expr *e2);
extern struct expr *payload_expr_join(const struct expr *e1,
const struct expr *e2);
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index ee4cf12..59e5f3e 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -999,41 +999,11 @@ static int netlink_parse_expr(struct nftnl_expr *nle, void *arg)
struct rule_pp_ctx {
struct proto_ctx pctx;
- enum proto_bases pbase;
- struct stmt *pdep;
+ struct payload_dep_ctx pdctx;
struct stmt *stmt;
- struct stmt *prev;
};
-/*
- * Kill a redundant payload dependecy that is implied by a higher layer payload expression.
- */
-static void __payload_dependency_kill(struct rule_pp_ctx *ctx, enum proto_bases base)
-{
- if (ctx->pbase != PROTO_BASE_INVALID &&
- ctx->pbase == base &&
- ctx->pdep != NULL) {
- list_del(&ctx->pdep->list);
- stmt_free(ctx->pdep);
- ctx->pbase = PROTO_BASE_INVALID;
- if (ctx->pdep == ctx->prev)
- ctx->prev = NULL;
- ctx->pdep = NULL;
- }
-}
-
-static void payload_dependency_kill(struct rule_pp_ctx *ctx, const struct expr *expr)
-{
- __payload_dependency_kill(ctx, expr->payload.base);
-}
-
-static void payload_dependency_store(struct rule_pp_ctx *ctx,
- struct stmt *stmt,
- enum proto_bases base)
-{
- ctx->pbase = base + 1;
- ctx->pdep = stmt;
-}
+static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp);
static void integer_type_postprocess(struct expr *expr)
{
@@ -1078,9 +1048,9 @@ static void payload_dependency_save(struct rule_pp_ctx *ctx, unsigned int base,
}
if (stacked_header)
- payload_dependency_store(ctx, nstmt, base - 1);
+ payload_dependency_store(&ctx->pdctx, nstmt, base - 1);
else
- payload_dependency_store(ctx, nstmt, base);
+ payload_dependency_store(&ctx->pdctx, nstmt, base);
}
static void payload_match_expand(struct rule_pp_ctx *ctx,
@@ -1118,12 +1088,12 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
* kill it later on if made redundant by a higher layer
* payload expression.
*/
- if (ctx->pbase == PROTO_BASE_INVALID &&
+ if (ctx->pdctx.pbase == PROTO_BASE_INVALID &&
expr->op == OP_EQ &&
left->flags & EXPR_F_PROTOCOL) {
payload_dependency_save(ctx, base, nstmt, tmp);
} else {
- payload_dependency_kill(ctx, nexpr->left);
+ payload_dependency_kill(&ctx->pdctx, nexpr->left);
if (left->flags & EXPR_F_PROTOCOL)
payload_dependency_save(ctx, base, nstmt, tmp);
}
@@ -1154,7 +1124,7 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
payload_expr_complete(payload, &ctx->pctx);
expr_set_type(expr->right, payload->dtype,
payload->byteorder);
- payload_dependency_kill(ctx, payload);
+ payload_dependency_kill(&ctx->pdctx, payload);
break;
}
}
@@ -1171,9 +1141,9 @@ static void meta_match_postprocess(struct rule_pp_ctx *ctx,
expr->left->ops->pctx_update(&ctx->pctx, expr);
- if (ctx->pbase == PROTO_BASE_INVALID &&
+ if (ctx->pdctx.pbase == PROTO_BASE_INVALID &&
left->flags & EXPR_F_PROTOCOL)
- payload_dependency_store(ctx, ctx->stmt,
+ payload_dependency_store(&ctx->pdctx, ctx->stmt,
left->meta.base);
break;
case OP_LOOKUP:
@@ -1514,7 +1484,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
break;
case EXPR_PAYLOAD:
payload_expr_complete(expr, &ctx->pctx);
- payload_dependency_kill(ctx, expr);
+ payload_dependency_kill(&ctx->pdctx, expr);
break;
case EXPR_VALUE:
// FIXME
@@ -1537,7 +1507,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx, struct expr **exprp)
expr_postprocess(ctx, &expr->key);
break;
case EXPR_EXTHDR:
- __payload_dependency_kill(ctx, PROTO_BASE_NETWORK_HDR);
+ __payload_dependency_kill(&ctx->pdctx, PROTO_BASE_NETWORK_HDR);
break;
case EXPR_SET_REF:
case EXPR_META:
@@ -1649,20 +1619,20 @@ static void expr_postprocess_range(struct rule_pp_ctx *ctx, enum ops op)
struct stmt *nstmt, *stmt = ctx->stmt;
struct expr *nexpr, *rel;
- nexpr = range_expr_alloc(&ctx->prev->location,
- expr_clone(ctx->prev->expr->right),
+ nexpr = range_expr_alloc(&ctx->pdctx.prev->location,
+ expr_clone(ctx->pdctx.prev->expr->right),
expr_clone(stmt->expr->right));
expr_set_type(nexpr, stmt->expr->right->dtype,
stmt->expr->right->byteorder);
- rel = relational_expr_alloc(&ctx->prev->location, op,
+ rel = relational_expr_alloc(&ctx->pdctx.prev->location, op,
expr_clone(stmt->expr->left), nexpr);
nstmt = expr_stmt_alloc(&stmt->location, rel);
list_add_tail(&nstmt->list, &stmt->list);
- list_del(&ctx->prev->list);
- stmt_free(ctx->prev);
+ list_del(&ctx->pdctx.prev->list);
+ stmt_free(ctx->pdctx.prev);
list_del(&stmt->list);
stmt_free(stmt);
@@ -1675,9 +1645,9 @@ static void stmt_expr_postprocess(struct rule_pp_ctx *ctx)
expr_postprocess(ctx, &ctx->stmt->expr);
- if (ctx->prev && ctx->stmt &&
- ctx->stmt->ops->type == ctx->prev->ops->type &&
- expr_may_merge_range(ctx->stmt->expr, ctx->prev->expr, &op))
+ if (ctx->pdctx.prev && ctx->stmt &&
+ ctx->stmt->ops->type == ctx->pdctx.prev->ops->type &&
+ expr_may_merge_range(ctx->stmt->expr, ctx->pdctx.prev->expr, &op))
expr_postprocess_range(ctx, op);
}
@@ -1740,7 +1710,7 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
default:
break;
}
- rctx.prev = rctx.stmt;
+ rctx.pdctx.prev = rctx.stmt;
}
}
diff --git a/src/payload.c b/src/payload.c
index 45a2ba2..9dca56b 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -322,6 +322,50 @@ int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
}
/**
+ * payload_dependency_store - store a possibly redundant protocol match
+ *
+ * @ctx: payload dependency context
+ * @stmt: payload match
+ * @base: base of payload match
+ */
+void payload_dependency_store(struct payload_dep_ctx *ctx,
+ struct stmt *stmt, enum proto_bases base)
+{
+ ctx->pbase = base + 1;
+ ctx->pdep = stmt;
+}
+
+/**
+ * __payload_dependency_kill - kill a redundant payload depedency
+ *
+ * @ctx: payload dependency context
+ * @expr: higher layer payload expression
+ *
+ * Kill a redundant payload expression if a higher layer payload expression
+ * implies its existance.
+ */
+void __payload_dependency_kill(struct payload_dep_ctx *ctx,
+ enum proto_bases base)
+{
+ if (ctx->pbase != PROTO_BASE_INVALID &&
+ ctx->pbase == base &&
+ ctx->pdep != NULL) {
+ list_del(&ctx->pdep->list);
+ stmt_free(ctx->pdep);
+
+ ctx->pbase = PROTO_BASE_INVALID;
+ if (ctx->pdep == ctx->prev)
+ ctx->prev = NULL;
+ ctx->pdep = NULL;
+ }
+}
+
+void payload_dependency_kill(struct payload_dep_ctx *ctx, struct expr *expr)
+{
+ __payload_dependency_kill(ctx, expr->payload.base);
+}
+
+/**
* payload_expr_complete - fill in type information of a raw payload expr
*
* @expr: the payload expression
--
2.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 4/6] payload: add payload_is_stacked()
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
` (2 preceding siblings ...)
2016-04-24 21:30 ` [PATCH nft 3/6] payload: move payload depedency tracking to payload.c Patrick McHardy
@ 2016-04-24 21:30 ` Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 5/6] proto: add protocol header fields filter and ordering for packet decoding Patrick McHardy
` (2 subsequent siblings)
6 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
Add payload_is_stacked() to determine whether a protocol expression match defines
a stacked protocol on the same layer.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/payload.h | 2 ++
src/netlink_delinearize.c | 28 +++++-----------------------
src/payload.c | 20 ++++++++++++++++++++
3 files changed, 27 insertions(+), 23 deletions(-)
diff --git a/include/payload.h b/include/payload.h
index eb9ff17..b180ff5 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -30,6 +30,8 @@ struct payload_dep_ctx {
struct stmt *prev;
};
+extern bool payload_is_stacked(const struct proto_desc *desc,
+ const struct expr *expr);
extern void payload_dependency_store(struct payload_dep_ctx *ctx,
struct stmt *stmt,
enum proto_bases base);
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 59e5f3e..84f94fc 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -1032,27 +1032,6 @@ static void integer_type_postprocess(struct expr *expr)
}
}
-static void payload_dependency_save(struct rule_pp_ctx *ctx, unsigned int base,
- struct stmt *nstmt, struct expr *tmp)
-{
- unsigned int proto = mpz_get_be16(tmp->value);
- const struct proto_desc *desc, *next;
- bool stacked_header = false;
-
- desc = ctx->pctx.protocol[base].desc;
-
- assert(desc);
- if (desc) {
- next = proto_find_upper(desc, proto);
- stacked_header = next && next->base == base;
- }
-
- if (stacked_header)
- payload_dependency_store(&ctx->pdctx, nstmt, base - 1);
- else
- payload_dependency_store(&ctx->pdctx, nstmt, base);
-}
-
static void payload_match_expand(struct rule_pp_ctx *ctx,
struct expr *expr,
struct expr *payload)
@@ -1063,6 +1042,7 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
struct expr *nexpr = NULL;
enum proto_bases base = left->payload.base;
const struct expr_ops *payload_ops = left->ops;
+ bool stacked;
payload_expr_expand(&list, left, &ctx->pctx);
@@ -1084,6 +1064,8 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
assert(left->payload.base);
assert(base == left->payload.base);
+ stacked = payload_is_stacked(ctx->pctx.protocol[base].desc, nexpr);
+
/* Remember the first payload protocol expression to
* kill it later on if made redundant by a higher layer
* payload expression.
@@ -1091,11 +1073,11 @@ static void payload_match_expand(struct rule_pp_ctx *ctx,
if (ctx->pdctx.pbase == PROTO_BASE_INVALID &&
expr->op == OP_EQ &&
left->flags & EXPR_F_PROTOCOL) {
- payload_dependency_save(ctx, base, nstmt, tmp);
+ payload_dependency_store(&ctx->pdctx, nstmt, base - stacked);
} else {
payload_dependency_kill(&ctx->pdctx, nexpr->left);
if (left->flags & EXPR_F_PROTOCOL)
- payload_dependency_save(ctx, base, nstmt, tmp);
+ payload_dependency_store(&ctx->pdctx, nstmt, base - stacked);
}
}
list_del(&ctx->stmt->list);
diff --git a/src/payload.c b/src/payload.c
index 9dca56b..0bbfb54 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -322,6 +322,26 @@ int exthdr_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
}
/**
+ * payload_is_stacked - return whether a payload protocol match defines a stacked
+ * protocol on the same layer
+ *
+ * @desc: current protocol description on this layer
+ * @expr: payload match
+ */
+bool payload_is_stacked(const struct proto_desc *desc, const struct expr *expr)
+{
+ const struct proto_desc *next;
+
+ if (expr->left->ops->type != EXPR_PAYLOAD ||
+ !(expr->left->flags & EXPR_F_PROTOCOL) ||
+ expr->op != OP_EQ)
+ return false;
+
+ next = proto_find_upper(desc, mpz_get_be16(expr->right->value));
+ return next && next->base == desc->base;
+}
+
+/**
* payload_dependency_store - store a possibly redundant protocol match
*
* @ctx: payload dependency context
--
2.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 5/6] proto: add protocol header fields filter and ordering for packet decoding
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
` (3 preceding siblings ...)
2016-04-24 21:30 ` [PATCH nft 4/6] payload: add payload_is_stacked() Patrick McHardy
@ 2016-04-24 21:30 ` Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 6/6] nft monitor [ trace ] Patrick McHardy
2016-04-24 22:22 ` [PATCH nft 0/6] ruleset tracing Florian Westphal
6 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
The next patch introduces packet decoding for tracing messages based on
the proto definitions. In order to provide a readable output, add a filter
to surpress uninteresting header fields and allow to specify and explicit
output order.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/proto.h | 5 +++++
src/proto.c | 37 +++++++++++++++++++++++++++++++++++++
2 files changed, 42 insertions(+)
diff --git a/include/proto.h b/include/proto.h
index c252a67..2a662a1 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -85,6 +85,11 @@ struct proto_desc {
const struct proto_desc *desc;
} protocols[PROTO_UPPER_MAX];
struct proto_hdr_template templates[PROTO_HDRS_MAX];
+ struct {
+ uint8_t order[PROTO_HDRS_MAX];
+ uint32_t filter;
+ } format;
+
};
#define PROTO_LINK(__num, __desc) { .num = (__num), .desc = (__desc), }
diff --git a/src/proto.c b/src/proto.c
index 329d991..cecde0f 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -244,6 +244,12 @@ const struct proto_desc proto_ah = {
[AHHDR_SPI] = AHHDR_FIELD("spi", spi),
[AHHDR_SEQUENCE] = AHHDR_FIELD("sequence", seq_no),
},
+ .format = {
+ .order = {
+ AHHDR_SPI, AHHDR_HDRLENGTH, AHHDR_NEXTHDR,
+ },
+ .filter = (1 << AHHDR_RESERVED) | (1 << AHHDR_SEQUENCE)
+ },
};
/*
@@ -431,6 +437,11 @@ const struct proto_desc proto_tcp = {
[TCPHDR_CHECKSUM] = TCPHDR_FIELD("checksum", check),
[TCPHDR_URGPTR] = TCPHDR_FIELD("urgptr", urg_ptr),
},
+ .format = {
+ .filter = (1 << TCPHDR_SEQ) | (1 << TCPHDR_ACKSEQ) |
+ (1 << TCPHDR_DOFF) | (1 << TCPHDR_RESERVED) |
+ (1 << TCPHDR_URGPTR),
+ },
};
/*
@@ -535,6 +546,14 @@ const struct proto_desc proto_ip = {
[IPHDR_SADDR] = IPHDR_ADDR("saddr", saddr),
[IPHDR_DADDR] = IPHDR_ADDR("daddr", daddr),
},
+ .format = {
+ .order = {
+ IPHDR_SADDR, IPHDR_DADDR, IPHDR_TOS, IPHDR_TTL,
+ IPHDR_ID, IPHDR_PROTOCOL, IPHDR_LENGTH,
+ },
+ .filter = (1 << IPHDR_VERSION) | (1 << IPHDR_HDRLENGTH) |
+ (1 << IPHDR_FRAG_OFF),
+ },
};
/*
@@ -631,6 +650,14 @@ const struct proto_desc proto_ip6 = {
[IP6HDR_SADDR] = IP6HDR_ADDR("saddr", saddr),
[IP6HDR_DADDR] = IP6HDR_ADDR("daddr", daddr),
},
+ .format = {
+ .order = {
+ IP6HDR_SADDR, IP6HDR_DADDR, IP6HDR_PRIORITY,
+ IP6HDR_HOPLIMIT, IP6HDR_FLOWLABEL, IP6HDR_NEXTHDR,
+ IP6HDR_LENGTH,
+ },
+ .filter = (1 << IP6HDR_VERSION),
+ },
};
/*
@@ -719,6 +746,10 @@ const struct proto_desc proto_arp = {
[ARPHDR_PLN] = ARPHDR_FIELD("plen", ar_pln),
[ARPHDR_OP] = ARPHDR_TYPE("operation", &arpop_type, ar_op),
},
+ .format = {
+ .filter = (1 << ARPHDR_HRD) | (1 << ARPHDR_PRO) |
+ (1 << ARPHDR_HLN) | (1 << ARPHDR_PLN),
+ },
};
/*
@@ -818,6 +849,12 @@ const struct proto_desc proto_eth = {
[ETHHDR_SADDR] = ETHHDR_ADDR("saddr", ether_shost),
[ETHHDR_TYPE] = ETHHDR_TYPE("type", ether_type),
},
+ .format = {
+ .order = {
+ ETHHDR_SADDR, ETHHDR_DADDR, ETHHDR_TYPE,
+ },
+ },
+
};
/*
--
2.5.5
^ permalink raw reply related [flat|nested] 12+ messages in thread
* [PATCH nft 6/6] nft monitor [ trace ]
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
` (4 preceding siblings ...)
2016-04-24 21:30 ` [PATCH nft 5/6] proto: add protocol header fields filter and ordering for packet decoding Patrick McHardy
@ 2016-04-24 21:30 ` Patrick McHardy
2016-04-24 22:22 ` [PATCH nft 0/6] ruleset tracing Florian Westphal
6 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 21:30 UTC (permalink / raw)
To: pablo, fw; +Cc: netfilter-devel
... can now display nftables nftrace debug information.
$ nft filter input tcp dport 10000 nftrace set 1
$ nft filter input icmp type echo-request nftrace set 1
$ nft -nn monitor trace
trace id e1f5055f ip filter input packet: iif eth0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 ip saddr 192.168.122.1 ip daddr 192.168.122.83 ip tos 0 ip ttl 64 ip id 32315 ip length 84 icmp type echo-request icmp code 0 icmp id 10087 icmp sequence 1
trace id e1f5055f ip filter input rule icmp type echo-request nftrace set 1 (verdict continue)
trace id e1f5055f ip filter input verdict continue
trace id e1f5055f ip filter input
trace id 74e47ad2 ip filter input packet: iif vlan0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 vlan pcp 0 vlan cfi 1 vlan id 1000 ip saddr 10.0.0.1 ip daddr 10.0.0.2 ip tos 0 ip ttl 64 ip id 49030 ip length 84 icmp type echo-request icmp code 0 icmp id 10095 icmp sequence 1
trace id 74e47ad2 ip filter input rule icmp type echo-request nftrace set 1 (verdict continue)
trace id 74e47ad2 ip filter input verdict continue
trace id 74e47ad2 ip filter input
trace id 3030de23 ip filter input packet: iif vlan0 ether saddr 63:f6:4b:00:54:52 ether daddr c9:4b:a9:00:54:52 vlan pcp 0 vlan cfi 1 vlan id 1000 ip saddr 10.0.0.1 ip daddr 10.0.0.2 ip tos 16 ip ttl 64 ip id 59062 ip length 60 tcp sport 55438 tcp dport 10000 tcp flags == syn tcp window 29200
trace id 3030de23 ip filter input rule tcp dport 10000 nftrace set 1 (verdict continue)
trace id 3030de23 ip filter input verdict continue
trace id 3030de23 ip filter input
Based on a patch from Florian Westphal, which again was based on a patch
from Markus Kötter.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/payload.h | 1 +
include/rule.h | 1 +
src/evaluate.c | 18 ++++
src/netlink.c | 269 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/payload.c | 5 +
src/rule.c | 61 +++++++++++--
6 files changed, 345 insertions(+), 10 deletions(-)
diff --git a/include/payload.h b/include/payload.h
index b180ff5..37375c1 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -9,6 +9,7 @@ extern struct expr *payload_expr_alloc(const struct location *loc,
unsigned int type);
extern void payload_init_raw(struct expr *expr, enum proto_bases base,
unsigned int offset, unsigned int len);
+extern unsigned int payload_hdr_field(const struct expr *expr);
struct eval_ctx;
struct stmt;
diff --git a/include/rule.h b/include/rule.h
index 6dbde13..09b3ff7 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -192,6 +192,7 @@ extern struct rule *rule_alloc(const struct location *loc,
const struct handle *h);
extern void rule_free(struct rule *rule);
extern void rule_print(const struct rule *rule);
+extern struct rule *rule_lookup(const struct chain *chain, uint64_t handle);
/**
* enum set_flags
diff --git a/src/evaluate.c b/src/evaluate.c
index a65e145..63c0091 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2479,6 +2479,7 @@ enum {
CMD_MONITOR_EVENT_ANY,
CMD_MONITOR_EVENT_NEW,
CMD_MONITOR_EVENT_DEL,
+ CMD_MONITOR_EVENT_TRACE,
CMD_MONITOR_EVENT_MAX
};
@@ -2520,6 +2521,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)
@@ -2537,6 +2553,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 e3ba2ed..890e9b9 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>
@@ -30,9 +31,11 @@
#include <netlink.h>
#include <mnl.h>
#include <expression.h>
+#include <statement.h>
#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;
@@ -2109,6 +2112,266 @@ static void netlink_events_cache_update(struct netlink_mon_handler *monh,
}
}
+static void trace_print_hdr(const struct nftnl_trace *nlt)
+{
+ printf("trace id %08x ", nftnl_trace_get_u32(nlt, NFTNL_TRACE_ID));
+ printf("%s ", family2str(nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY)));
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_TABLE))
+ printf("%s ", nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE));
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_CHAIN))
+ printf("%s ", nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN));
+}
+
+static void trace_print_expr(const struct nftnl_trace *nlt, unsigned int attr,
+ struct expr *lhs)
+{
+ struct expr *rhs, *rel;
+ const void *data;
+ uint32_t len;
+
+ data = nftnl_trace_get_data(nlt, attr, &len);
+ rhs = constant_expr_alloc(&netlink_location,
+ lhs->dtype, lhs->byteorder,
+ len * BITS_PER_BYTE, data);
+ rel = relational_expr_alloc(&netlink_location, OP_EQ, lhs, rhs);
+
+ expr_print(rel);
+ printf(" ");
+ expr_free(rel);
+}
+
+static void trace_print_verdict(const struct nftnl_trace *nlt)
+{
+ const char *chain = NULL;
+ unsigned int verdict;
+ struct expr *expr;
+
+ verdict = nftnl_trace_get_u32(nlt, NFTNL_TRACE_VERDICT);
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_JUMP_TARGET))
+ chain = xstrdup(nftnl_trace_get_str(nlt, NFTNL_TRACE_JUMP_TARGET));
+ expr = verdict_expr_alloc(&netlink_location, verdict, chain);
+
+ printf("verdict ");
+ expr_print(expr);
+ expr_free(expr);
+}
+
+static void trace_print_rule(const struct nftnl_trace *nlt)
+{
+ const struct table *table;
+ uint64_t rule_handle;
+ struct chain *chain;
+ struct rule *rule;
+ struct handle h;
+
+ h.family = nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY);
+ h.table = nftnl_trace_get_str(nlt, NFTNL_TRACE_TABLE);
+ h.chain = nftnl_trace_get_str(nlt, NFTNL_TRACE_CHAIN);
+
+ if (!h.table)
+ return;
+
+ table = table_lookup(&h);
+ if (!table)
+ return;
+
+ chain = chain_lookup(table, &h);
+ if (!chain)
+ return;
+
+ rule_handle = nftnl_trace_get_u64(nlt, NFTNL_TRACE_RULE_HANDLE);
+ rule = rule_lookup(chain, rule_handle);
+ if (!rule)
+ return;
+
+ trace_print_hdr(nlt);
+ printf("rule ");
+ rule_print(rule);
+ printf(" (");
+ trace_print_verdict(nlt);
+ printf(")\n");
+}
+
+static void trace_gen_stmts(struct list_head *stmts,
+ struct proto_ctx *ctx, struct payload_dep_ctx *pctx,
+ const struct nftnl_trace *nlt, unsigned int attr,
+ enum proto_bases base)
+{
+ struct list_head unordered = LIST_HEAD_INIT(unordered);
+ struct list_head list;
+ struct expr *rel, *lhs, *rhs, *tmp, *nexpr;
+ struct stmt *stmt;
+ const struct proto_desc *desc;
+ const void *hdr;
+ uint32_t hlen;
+ unsigned int n;
+ bool stacked;
+
+ if (!nftnl_trace_is_set(nlt, attr))
+ return;
+ hdr = nftnl_trace_get_data(nlt, attr, &hlen);
+
+ lhs = payload_expr_alloc(&netlink_location, NULL, 0);
+ payload_init_raw(lhs, base, 0, hlen * BITS_PER_BYTE);
+ rhs = constant_expr_alloc(&netlink_location,
+ &invalid_type, BYTEORDER_INVALID,
+ hlen * BITS_PER_BYTE, hdr);
+
+restart:
+ init_list_head(&list);
+ payload_expr_expand(&list, lhs, ctx);
+ expr_free(lhs);
+
+ desc = NULL;
+ list_for_each_entry_safe(lhs, nexpr, &list, list) {
+ if (desc && desc != ctx->protocol[base].desc) {
+ /* Chained protocols */
+ lhs->payload.offset = 0;
+ if (ctx->protocol[base].desc == NULL)
+ break;
+ goto restart;
+ }
+
+ tmp = constant_expr_splice(rhs, lhs->len);
+ expr_set_type(tmp, lhs->dtype, lhs->byteorder);
+
+ /* Skip unknown and filtered expressions */
+ desc = lhs->payload.desc;
+ if (lhs->dtype == &invalid_type ||
+ desc->checksum_key == payload_hdr_field(lhs) ||
+ desc->format.filter & (1 << payload_hdr_field(lhs))) {
+ expr_free(lhs);
+ expr_free(tmp);
+ continue;
+ }
+
+ rel = relational_expr_alloc(&lhs->location, OP_EQ, lhs, tmp);
+ stmt = expr_stmt_alloc(&rel->location, rel);
+ list_add_tail(&stmt->list, &unordered);
+
+ desc = ctx->protocol[base].desc;
+ lhs->ops->pctx_update(ctx, rel);
+ }
+
+ expr_free(rhs);
+
+ n = 0;
+next:
+ list_for_each_entry(stmt, &unordered, list) {
+ rel = stmt->expr;
+ lhs = rel->left;
+
+ /* Move statements to result list in defined order */
+ desc = lhs->payload.desc;
+ if (desc->format.order[n] &&
+ desc->format.order[n] != payload_hdr_field(lhs))
+ continue;
+
+ list_move_tail(&stmt->list, stmts);
+ n++;
+
+ stacked = payload_is_stacked(desc, rel);
+
+ if (lhs->flags & EXPR_F_PROTOCOL &&
+ pctx->pbase == PROTO_BASE_INVALID) {
+ payload_dependency_store(pctx, stmt, base - stacked);
+ } else {
+ payload_dependency_kill(pctx, lhs);
+ if (lhs->flags & EXPR_F_PROTOCOL)
+ payload_dependency_store(pctx, stmt, base - stacked);
+ }
+
+ goto next;
+ }
+}
+
+static void trace_print_packet(const struct nftnl_trace *nlt)
+{
+ struct list_head stmts = LIST_HEAD_INIT(stmts);
+ struct payload_dep_ctx pctx = {};
+ struct proto_ctx ctx;
+ uint16_t dev_type;
+ struct stmt *stmt, *next;
+
+ trace_print_hdr(nlt);
+
+ printf("packet: ");
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_IIF))
+ trace_print_expr(nlt, NFTNL_TRACE_IIF,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_IIF));
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_OIF))
+ trace_print_expr(nlt, NFTNL_TRACE_OIF,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_OIF));
+
+ proto_ctx_init(&ctx, nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY));
+ if (ctx.protocol[PROTO_BASE_LL_HDR].desc == NULL &&
+ nftnl_trace_is_set(nlt, NFTNL_TRACE_IIFTYPE)) {
+ dev_type = nftnl_trace_get_u16(nlt, NFTNL_TRACE_IIFTYPE);
+ proto_ctx_update(&ctx, PROTO_BASE_LL_HDR, &netlink_location,
+ proto_dev_desc(dev_type));
+ }
+
+ trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_LL_HEADER,
+ PROTO_BASE_LL_HDR);
+ trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_NETWORK_HEADER,
+ PROTO_BASE_NETWORK_HDR);
+ trace_gen_stmts(&stmts, &ctx, &pctx, nlt, NFTNL_TRACE_TRANSPORT_HEADER,
+ PROTO_BASE_TRANSPORT_HDR);
+
+ list_for_each_entry_safe(stmt, next, &stmts, list) {
+ stmt_print(stmt);
+ printf(" ");
+ stmt_free(stmt);
+ }
+ printf("\n");
+}
+
+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();
+
+ switch (nftnl_trace_get_u32(nlt, NFTNL_TRACE_TYPE)) {
+ case NFT_TRACETYPE_RULE:
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_LL_HEADER) ||
+ nftnl_trace_is_set(nlt, NFTNL_TRACE_NETWORK_HEADER))
+ trace_print_packet(nlt);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_RULE_HANDLE))
+ trace_print_rule(nlt);
+ break;
+ case NFT_TRACETYPE_POLICY:
+ case NFT_TRACETYPE_RETURN:
+ trace_print_hdr(nlt);
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_VERDICT)) {
+ trace_print_verdict(nlt);
+ printf(" ");
+ }
+
+ if (nftnl_trace_is_set(nlt, NFTNL_TRACE_MARK))
+ trace_print_expr(nlt, NFTNL_TRACE_MARK,
+ meta_expr_alloc(&netlink_location,
+ NFT_META_MARK));
+ printf("\n");
+ break;
+ }
+
+ nftnl_trace_free(nlt);
+ return MNL_CB_OK;
+}
+
static int netlink_events_cb(const struct nlmsghdr *nlh, void *data)
{
int ret = MNL_CB_OK;
@@ -2141,6 +2404,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);
@@ -2151,7 +2417,8 @@ int netlink_monitor(struct netlink_mon_handler *monhandler)
{
netlink_open_mon_sock();
- if (mnl_socket_bind(nf_mon_sock, (1 << (NFNLGRP_NFTABLES-1)),
+ if (mnl_socket_bind(nf_mon_sock, (1 << (NFNLGRP_NFTABLES-1)) |
+ (1 << (NFNLGRP_NFTRACE-1)),
MNL_SOCKET_AUTOPID) < 0)
return netlink_io_error(monhandler->ctx, monhandler->loc,
"Could not bind to netlink socket %s",
diff --git a/src/payload.c b/src/payload.c
index 0bbfb54..ac0e917 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -142,6 +142,11 @@ void payload_init_raw(struct expr *expr, enum proto_bases base,
expr->len = len;
}
+unsigned int payload_hdr_field(const struct expr *expr)
+{
+ return expr->payload.tmpl - expr->payload.desc->templates;
+}
+
static void payload_stmt_print(const struct stmt *stmt)
{
expr_print(stmt->payload.expr);
diff --git a/src/rule.c b/src/rule.c
index 2fe6745..cd7f84e 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -396,6 +396,17 @@ void rule_print(const struct rule *rule)
printf(" # handle %" PRIu64, rule->handle.handle.id);
}
+struct rule *rule_lookup(const struct chain *chain, uint64_t handle)
+{
+ struct rule *rule;
+
+ list_for_each_entry(rule, &chain->rules, list) {
+ if (rule->handle.handle.id == handle)
+ return rule;
+ }
+ return NULL;
+}
+
struct scope *scope_init(struct scope *scope, const struct scope *parent)
{
scope->parent = parent;
@@ -1198,27 +1209,59 @@ 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 and 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.5.5
--
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
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH nft 0/6] ruleset tracing
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
` (5 preceding siblings ...)
2016-04-24 21:30 ` [PATCH nft 6/6] nft monitor [ trace ] Patrick McHardy
@ 2016-04-24 22:22 ` Florian Westphal
2016-04-24 22:57 ` Patrick McHardy
6 siblings, 1 reply; 12+ messages in thread
From: Florian Westphal @ 2016-04-24 22:22 UTC (permalink / raw)
To: Patrick McHardy; +Cc: pablo, fw, netfilter-devel
Patrick McHardy <kaber@trash.net> wrote:
> The following patches contain the latest version of the ruleset tracing
> functionality.
> I consider this patchset complete. Testing and comments welcome.
Seems it doesn't work with inet table, I get segfault in expr_print
(EXPR_VALUE expr with expr->dtype == NULL).
Callchain that produces this expression is:
trace_gen_stmts -> payload_expr_expand -> payload_expr_alloc
desc argument to payload_expr_alloc is the inet one, which
has no template for types != 0, so tmpl->dtype that gets passed
to expr_alloc is NULL.
Works fine without inet table. Only "problem" I found is that
nft displays the ether addr reversed vs. what 'ip link' shows,
i.e. if ip link says 1:2:3:4:5:6 nft shows 6:5:4:3:2:1.
I'll do more tests tomorrow and will double check that its not
a kernel bug.
Thanks for working on this!
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH nft 0/6] ruleset tracing
2016-04-24 22:22 ` [PATCH nft 0/6] ruleset tracing Florian Westphal
@ 2016-04-24 22:57 ` Patrick McHardy
2016-04-25 0:23 ` Patrick McHardy
0 siblings, 1 reply; 12+ messages in thread
From: Patrick McHardy @ 2016-04-24 22:57 UTC (permalink / raw)
To: Florian Westphal; +Cc: pablo, netfilter-devel
On 25.04, Florian Westphal wrote:
> Patrick McHardy <kaber@trash.net> wrote:
> > The following patches contain the latest version of the ruleset tracing
> > functionality.
> > I consider this patchset complete. Testing and comments welcome.
>
> Seems it doesn't work with inet table, I get segfault in expr_print
> (EXPR_VALUE expr with expr->dtype == NULL).
>
> Callchain that produces this expression is:
>
> trace_gen_stmts -> payload_expr_expand -> payload_expr_alloc
>
> desc argument to payload_expr_alloc is the inet one, which
> has no template for types != 0, so tmpl->dtype that gets passed
> to expr_alloc is NULL.
Thanks, I'll look into that.
> Works fine without inet table. Only "problem" I found is that
> nft displays the ether addr reversed vs. what 'ip link' shows,
> i.e. if ip link says 1:2:3:4:5:6 nft shows 6:5:4:3:2:1.
>
> I'll do more tests tomorrow and will double check that its not
> a kernel bug.
That's just a missing byte order conversion, I've fixed it locally.
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH nft 0/6] ruleset tracing
2016-04-24 22:57 ` Patrick McHardy
@ 2016-04-25 0:23 ` Patrick McHardy
2016-04-25 9:49 ` Florian Westphal
0 siblings, 1 reply; 12+ messages in thread
From: Patrick McHardy @ 2016-04-25 0:23 UTC (permalink / raw)
To: Florian Westphal; +Cc: pablo, netfilter-devel
[-- Attachment #1: Type: text/plain, Size: 1124 bytes --]
On 24.04, Patrick McHardy wrote:
> On 25.04, Florian Westphal wrote:
> > Patrick McHardy <kaber@trash.net> wrote:
> > > The following patches contain the latest version of the ruleset tracing
> > > functionality.
> > > I consider this patchset complete. Testing and comments welcome.
> >
> > Seems it doesn't work with inet table, I get segfault in expr_print
> > (EXPR_VALUE expr with expr->dtype == NULL).
> >
> > Callchain that produces this expression is:
> >
> > trace_gen_stmts -> payload_expr_expand -> payload_expr_alloc
> >
> > desc argument to payload_expr_alloc is the inet one, which
> > has no template for types != 0, so tmpl->dtype that gets passed
> > to expr_alloc is NULL.
>
> Thanks, I'll look into that.
>
> > Works fine without inet table. Only "problem" I found is that
> > nft displays the ether addr reversed vs. what 'ip link' shows,
> > i.e. if ip link says 1:2:3:4:5:6 nft shows 6:5:4:3:2:1.
> >
> > I'll do more tests tomorrow and will double check that its not
> > a kernel bug.
>
> That's just a missing byte order conversion, I've fixed it locally.
This patch should fix both issues.
[-- Attachment #2: x.diff --]
[-- Type: text/plain, Size: 1414 bytes --]
diff --git a/src/netlink.c b/src/netlink.c
index 890e9b9..761c7b4 100644
--- a/src/netlink.c
+++ b/src/netlink.c
@@ -2234,6 +2234,8 @@ restart:
tmp = constant_expr_splice(rhs, lhs->len);
expr_set_type(tmp, lhs->dtype, lhs->byteorder);
+ if (tmp->byteorder == BYTEORDER_HOST_ENDIAN)
+ mpz_switch_byteorder(tmp->value, tmp->len / BITS_PER_BYTE);
/* Skip unknown and filtered expressions */
desc = lhs->payload.desc;
@@ -2290,6 +2292,7 @@ static void trace_print_packet(const struct nftnl_trace *nlt)
struct list_head stmts = LIST_HEAD_INIT(stmts);
struct payload_dep_ctx pctx = {};
struct proto_ctx ctx;
+ uint32_t nfproto;
uint16_t dev_type;
struct stmt *stmt, *next;
@@ -2306,6 +2309,13 @@ static void trace_print_packet(const struct nftnl_trace *nlt)
NFT_META_OIF));
proto_ctx_init(&ctx, nftnl_trace_get_u32(nlt, NFTNL_TRACE_FAMILY));
+ if (ctx.protocol[PROTO_BASE_LL_HDR].desc == &proto_inet &&
+ nftnl_trace_is_set(nlt, NFTNL_TRACE_NFPROTO)) {
+ nfproto = nftnl_trace_get_u32(nlt, NFTNL_TRACE_NFPROTO);
+ proto_ctx_update(&ctx, PROTO_BASE_LL_HDR, &netlink_location, NULL);
+ proto_ctx_update(&ctx, PROTO_BASE_NETWORK_HDR, &netlink_location,
+ proto_find_upper(&proto_inet, nfproto));
+ }
if (ctx.protocol[PROTO_BASE_LL_HDR].desc == NULL &&
nftnl_trace_is_set(nlt, NFTNL_TRACE_IIFTYPE)) {
dev_type = nftnl_trace_get_u16(nlt, NFTNL_TRACE_IIFTYPE);
^ permalink raw reply related [flat|nested] 12+ messages in thread
* Re: [PATCH nft 0/6] ruleset tracing
2016-04-25 0:23 ` Patrick McHardy
@ 2016-04-25 9:49 ` Florian Westphal
2016-04-25 10:28 ` Patrick McHardy
0 siblings, 1 reply; 12+ messages in thread
From: Florian Westphal @ 2016-04-25 9:49 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Florian Westphal, pablo, netfilter-devel
Patrick McHardy <kaber@trash.net> wrote:
> On 24.04, Patrick McHardy wrote:
> > On 25.04, Florian Westphal wrote:
> > > Patrick McHardy <kaber@trash.net> wrote:
> > > > The following patches contain the latest version of the ruleset tracing
> > > > functionality.
> > > > I consider this patchset complete. Testing and comments welcome.
> > >
> > > Seems it doesn't work with inet table, I get segfault in expr_print
> > > (EXPR_VALUE expr with expr->dtype == NULL).
> > >
> > > Callchain that produces this expression is:
> > >
> > > trace_gen_stmts -> payload_expr_expand -> payload_expr_alloc
> > >
> > > desc argument to payload_expr_alloc is the inet one, which
> > > has no template for types != 0, so tmpl->dtype that gets passed
> > > to expr_alloc is NULL.
> >
> > Thanks, I'll look into that.
> >
> > > Works fine without inet table. Only "problem" I found is that
> > > nft displays the ether addr reversed vs. what 'ip link' shows,
> > > i.e. if ip link says 1:2:3:4:5:6 nft shows 6:5:4:3:2:1.
> > >
> > > I'll do more tests tomorrow and will double check that its not
> > > a kernel bug.
> >
> > That's just a missing byte order conversion, I've fixed it locally.
>
> This patch should fix both issues.
It does, thanks!
Seems to work fine now, only missing enhancement would be to add new
rules to the cache; currently when nft monitor is running it
will print out a added rules, but they are not printed out in new trace
events (restarting the nft monitor process works fine).
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: [PATCH nft 0/6] ruleset tracing
2016-04-25 9:49 ` Florian Westphal
@ 2016-04-25 10:28 ` Patrick McHardy
0 siblings, 0 replies; 12+ messages in thread
From: Patrick McHardy @ 2016-04-25 10:28 UTC (permalink / raw)
To: Florian Westphal; +Cc: pablo, netfilter-devel
On 25.04, Florian Westphal wrote:
> Patrick McHardy <kaber@trash.net> wrote:
> > On 24.04, Patrick McHardy wrote:
> > > On 25.04, Florian Westphal wrote:
> > > > Patrick McHardy <kaber@trash.net> wrote:
> > > > > The following patches contain the latest version of the ruleset tracing
> > > > > functionality.
> > > > > I consider this patchset complete. Testing and comments welcome.
> > > >
> > > > Seems it doesn't work with inet table, I get segfault in expr_print
> > > > (EXPR_VALUE expr with expr->dtype == NULL).
> > > >
> > > > Callchain that produces this expression is:
> > > >
> > > > trace_gen_stmts -> payload_expr_expand -> payload_expr_alloc
> > > >
> > > > desc argument to payload_expr_alloc is the inet one, which
> > > > has no template for types != 0, so tmpl->dtype that gets passed
> > > > to expr_alloc is NULL.
> > >
> > > Thanks, I'll look into that.
> > >
> > > > Works fine without inet table. Only "problem" I found is that
> > > > nft displays the ether addr reversed vs. what 'ip link' shows,
> > > > i.e. if ip link says 1:2:3:4:5:6 nft shows 6:5:4:3:2:1.
> > > >
> > > > I'll do more tests tomorrow and will double check that its not
> > > > a kernel bug.
> > >
> > > That's just a missing byte order conversion, I've fixed it locally.
> >
> > This patch should fix both issues.
>
> It does, thanks!
Thanks, I've pushed out the patches.
> Seems to work fine now, only missing enhancement would be to add new
> rules to the cache; currently when nft monitor is running it
> will print out a added rules, but they are not printed out in new trace
> events (restarting the nft monitor process works fine).
Yes, that would be good to have. Looks like a bit more effort though, we
also need to keep all other objects in sync.
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2016-04-25 10:28 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2016-04-24 21:30 [PATCH nft 0/6] ruleset tracing Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 1/6] payload: fix stacked headers protocol context tracking Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 2/6] nft: resync kernel header files Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 3/6] payload: move payload depedency tracking to payload.c Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 4/6] payload: add payload_is_stacked() Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 5/6] proto: add protocol header fields filter and ordering for packet decoding Patrick McHardy
2016-04-24 21:30 ` [PATCH nft 6/6] nft monitor [ trace ] Patrick McHardy
2016-04-24 22:22 ` [PATCH nft 0/6] ruleset tracing Florian Westphal
2016-04-24 22:57 ` Patrick McHardy
2016-04-25 0:23 ` Patrick McHardy
2016-04-25 9:49 ` Florian Westphal
2016-04-25 10:28 ` Patrick McHardy
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).