* [PATCH 08/12] nftables: add support for the "inet" family
2014-01-06 17:27 [RFC PATCH 00/12] nftables: generic protocol contexts, "inet" family support Patrick McHardy
@ 2014-01-06 17:27 ` Patrick McHardy
0 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-06 17:27 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add support for the mixed IPv4/IPv6 "inet" family. This mainly consist
of adding the "inet" <-> NFPROTO_INET mapping in the parser and netlink
support functions.
Additionally add the definitions for the inet filter table.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
files/nftables/inet-filter | 7 +++++++
src/evaluate.c | 1 +
src/parser.y | 3 +++
src/rule.c | 3 +++
src/scanner.l | 2 ++
5 files changed, 16 insertions(+)
create mode 100644 files/nftables/inet-filter
diff --git a/files/nftables/inet-filter b/files/nftables/inet-filter
new file mode 100644
index 0000000..9f3108f
--- /dev/null
+++ b/files/nftables/inet-filter
@@ -0,0 +1,7 @@
+#! nft -f
+
+table inet filter {
+ chain input { type filter hook input priority 0; }
+ chain forward { type filter hook forward priority 0; }
+ chain output { type filter hook output priority 0; }
+}
diff --git a/src/evaluate.c b/src/evaluate.c
index 0f1cc4c..bf61b63 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1271,6 +1271,7 @@ static uint32_t str2hooknum(uint32_t family, const char *hook)
case NFPROTO_IPV4:
case NFPROTO_BRIDGE:
case NFPROTO_IPV6:
+ case NFPROTO_INET:
/* These families have overlapping values for each hook */
if (!strcmp(hook, "prerouting"))
return NF_INET_PRE_ROUTING;
diff --git a/src/parser.y b/src/parser.y
index b299b9d..6671804 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -166,6 +166,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token MAP "map"
%token HANDLE "handle"
+%token INET "inet"
+
%token ADD "add"
%token INSERT "insert"
%token DELETE "delete"
@@ -818,6 +820,7 @@ string : STRING
family_spec : /* empty */ { $$ = NFPROTO_IPV4; }
| IP { $$ = NFPROTO_IPV4; }
| IP6 { $$ = NFPROTO_IPV6; }
+ | INET { $$ = NFPROTO_INET; }
| ARP { $$ = NFPROTO_ARP; }
| BRIDGE { $$ = NFPROTO_BRIDGE; }
;
diff --git a/src/rule.c b/src/rule.c
index ec8b6a4..a16c2de 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -276,6 +276,8 @@ static const char *family2str(unsigned int family)
return "ip";
case NFPROTO_IPV6:
return "ip6";
+ case NFPROTO_INET:
+ return "inet";
case NFPROTO_ARP:
return "arp";
case NFPROTO_BRIDGE:
@@ -292,6 +294,7 @@ static const char *hooknum2str(unsigned int family, unsigned int hooknum)
case NFPROTO_IPV4:
case NFPROTO_BRIDGE:
case NFPROTO_IPV6:
+ case NFPROTO_INET:
switch (hooknum) {
case NF_INET_PRE_ROUTING:
return "prerouting";
diff --git a/src/scanner.l b/src/scanner.l
index cee6aa6..0c62729 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -236,6 +236,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"return" { return RETURN; }
"queue" { return QUEUE; }
+"inet" { return INET; }
+
"add" { return ADD; }
"insert" { return INSERT; }
"delete" { return DELETE; }
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 00/12] nftables: generic protocol contexts, "inet" family
@ 2014-01-08 13:08 Patrick McHardy
2014-01-08 13:08 ` [PATCH 01/12] expr: replace PAYLOAD_PROTOCOL_EXPR by generic flag Patrick McHardy
` (11 more replies)
0 siblings, 12 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
The following patches implement the necessary support for the mixed IPv4/IPv6
"inet" family. The patchset consists of two major parts:
- introduction of generic protocol contexts
- support for the inet family and nfproto/l4proto meta expression types
The generic protocol contexts are a generalization of the payload contexts.
Since not only the payload expression, but also the ct and meta expression
can imply higher or lower layer protocols, the context tracking is
generalized. A small patch for the ct expression for context dependant
parsing of ct-src, ct-dst, ct-proto-src and ct-proto-dst is also included.
Support for the inet family mainly consist of adding a mapping for the
parser and netlink support for "inet" <-> NFPROTO_INET and adding support
for the meta nfproto and l4proto types.
With this in place, we can create rules like:
inet filter output tcp dport ssh counter
to match on ssh traffic for both IPv4 and IPv6.
inet filter output nfproto ipv4 tcp dport ssh
to match on ssh traffic for only IPv4.
Sets etc. have been verified to work as expected.
I've rebased the patches on the next-3.14 branch and will push them to
the nftables tree shortly.
Patrick McHardy (12):
expr: replace PAYLOAD_PROTOCOL_EXPR by generic flag
nftables: generic procotol contexts
expr: add protocol context update callback
proto: add helper function to update protocol context
proto: add debugging for protocol context updates
ct expr: protocol context updates and dynamic typing
include: resync nftables.h with kernel
nftables: add support for the "inet" family
netlink_delinearize: remove implied meta expressions
proto: add support for meta templates
meta: add nfproto support
meta: add l4proto support
include/ct.h | 1 +
include/datatype.h | 3 +
include/expression.h | 18 +-
include/exthdr.h | 6 +-
include/linux/netfilter.h | 22 +-
include/linux/netfilter/nf_tables.h | 116 ++++-
include/nftables.h | 1 +
include/payload.h | 288 +-----------
include/proto.h | 304 +++++++++++++
include/rule.h | 2 +-
src/Makefile.in | 1 +
src/ct.c | 58 +++
src/datatype.c | 18 +
src/evaluate.c | 47 +-
src/exthdr.c | 26 +-
src/main.c | 6 +-
src/meta.c | 70 +++
src/netlink_delinearize.c | 43 +-
src/parser.y | 43 +-
src/payload.c | 855 +++---------------------------------
src/proto.c | 814 ++++++++++++++++++++++++++++++++++
src/rule.c | 3 +
src/scanner.l | 4 +
23 files changed, 1581 insertions(+), 1168 deletions(-)
^ permalink raw reply [flat|nested] 16+ messages in thread
* [PATCH 01/12] expr: replace PAYLOAD_PROTOCOL_EXPR by generic flag
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 02/12] nftables: generic procotol contexts Patrick McHardy
` (10 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Introduce a generic flag to indicate that an expression describes the
upper layer protocol as replacement for the payload specific flag.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/expression.h | 5 +++--
include/payload.h | 9 ---------
src/netlink_delinearize.c | 2 +-
src/payload.c | 9 +++++----
4 files changed, 9 insertions(+), 16 deletions(-)
diff --git a/include/expression.h b/include/expression.h
index f0eb799..d8f2868 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -135,12 +135,14 @@ struct expr_ops {
*
* @EXPR_F_CONSTANT: constant expression
* @EXPR_F_SINGLETON: singleton (implies primary and constant)
+ * @EXPR_F_PROTOCOL: expressions describes upper layer protocol
* @EXPR_F_INTERVAL_END: set member ends an open interval
*/
enum expr_flags {
EXPR_F_CONSTANT = 0x1,
EXPR_F_SINGLETON = 0x2,
- EXPR_F_INTERVAL_END = 0x4,
+ EXPR_F_PROTOCOL = 0x4,
+ EXPR_F_INTERVAL_END = 0x8,
};
#include <payload.h>
@@ -227,7 +229,6 @@ struct expr {
const struct payload_template *tmpl;
enum payload_bases base;
unsigned int offset;
- unsigned int flags;
} payload;
struct {
/* EXPR_EXTHDR */
diff --git a/include/payload.h b/include/payload.h
index c9cc84f..fa8d82e 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -21,15 +21,6 @@ enum payload_bases {
#define PAYLOAD_BASE_MAX (__PAYLOAD_BASE_MAX - 1)
/**
- * enum payload_expr_flags
- *
- * @PAYLOAD_PROTOCOL_EXPR: payload expression contains upper layer protocol
- */
-enum payload_expr_flags {
- PAYLOAD_PROTOCOL_EXPR = 0x1,
-};
-
-/**
* struct payload_template - template for a payload header expression
*
* @token: parser token describing the header field
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index b771da5..8545273 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -622,7 +622,7 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
* payload expression.
*/
if (ctx->pbase == PAYLOAD_BASE_INVALID &&
- left->payload.flags & PAYLOAD_PROTOCOL_EXPR) {
+ left->flags & EXPR_F_PROTOCOL) {
ctx->pbase = left->payload.base;
ctx->pdep = nstmt;
} else
diff --git a/src/payload.c b/src/payload.c
index ea0d4e2..2a60a76 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -69,7 +69,6 @@ static void payload_expr_clone(struct expr *new, const struct expr *expr)
new->payload.tmpl = expr->payload.tmpl;
new->payload.base = expr->payload.base;
new->payload.offset = expr->payload.offset;
- new->payload.flags = expr->payload.flags;
}
static const struct expr_ops payload_expr_ops = {
@@ -92,7 +91,7 @@ struct expr *payload_expr_alloc(const struct location *loc,
tmpl = &desc->templates[type];
base = desc->base;
if (type == desc->protocol_key)
- flags = PAYLOAD_PROTOCOL_EXPR;
+ flags = EXPR_F_PROTOCOL;
} else {
tmpl = &payload_unknown_template;
base = PAYLOAD_BASE_INVALID;
@@ -100,11 +99,13 @@ struct expr *payload_expr_alloc(const struct location *loc,
expr = expr_alloc(loc, &payload_expr_ops, tmpl->dtype,
tmpl->dtype->byteorder, tmpl->len);
+ expr->flags |= flags;
+
expr->payload.desc = desc;
expr->payload.tmpl = tmpl;
expr->payload.base = base;
expr->payload.offset = tmpl->offset;
- expr->payload.flags = flags;
+
return expr;
}
@@ -256,7 +257,7 @@ void payload_ctx_update(struct payload_ctx *ctx, const struct expr *expr)
const struct expr *left = expr->left, *right = expr->right;
const struct payload_desc *base, *desc;
- if (!(left->payload.flags & PAYLOAD_PROTOCOL_EXPR))
+ if (!(left->flags & EXPR_F_PROTOCOL))
return;
assert(expr->op == OP_EQ);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 02/12] nftables: generic procotol contexts
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
2014-01-08 13:08 ` [PATCH 01/12] expr: replace PAYLOAD_PROTOCOL_EXPR by generic flag Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 03/12] expr: add protocol context update callback Patrick McHardy
` (9 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Currently the context of higher layer protocols is specific to payload
expressions with some special cases for meta IIFTYPE expressions. This
approach has a few shortcomings, concretely there are more expression
types which define upper layer protocols like the ct expression and two
upcoming new types for the meta expression.
Replace the payload context by a generic protocol context to deal with
this. This patch just splits off the requires parts from the payload
expression without any functional changes, the following patches will
add further functionality for other expressions.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/expression.h | 8 +-
include/exthdr.h | 6 +-
include/meta.h | 2 +
include/payload.h | 280 +---------------
include/proto.h | 287 +++++++++++++++++
include/rule.h | 2 +-
src/Makefile.in | 1 +
src/evaluate.c | 16 +-
src/exthdr.c | 26 +-
src/meta.c | 29 ++
src/netlink_delinearize.c | 16 +-
src/parser.y | 36 +--
src/payload.c | 799 ++--------------------------------------------
src/proto.c | 731 ++++++++++++++++++++++++++++++++++++++++++
14 files changed, 1144 insertions(+), 1095 deletions(-)
create mode 100644 include/proto.h
create mode 100644 src/proto.c
diff --git a/include/expression.h b/include/expression.h
index d8f2868..2b7b379 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -225,15 +225,15 @@ struct expr {
struct {
/* EXPR_PAYLOAD */
- const struct payload_desc *desc;
- const struct payload_template *tmpl;
- enum payload_bases base;
+ const struct proto_desc *desc;
+ const struct proto_hdr_template *tmpl;
+ enum proto_bases base;
unsigned int offset;
} payload;
struct {
/* EXPR_EXTHDR */
const struct exthdr_desc *desc;
- const struct payload_template *tmpl;
+ const struct proto_hdr_template *tmpl;
} exthdr;
struct {
/* EXPR_META */
diff --git a/include/exthdr.h b/include/exthdr.h
index 62e69bd..87c4285 100644
--- a/include/exthdr.h
+++ b/include/exthdr.h
@@ -1,17 +1,19 @@
#ifndef NFTABLES_EXTHDR_H
#define NFTABLES_EXTHDR_H
+#include <proto.h>
+
/**
* struct exthdr_desc - extension header description
*
* @name: extension header name
* @type: extension header protocol value
- * @templates: header templates
+ * @templates: header field templates
*/
struct exthdr_desc {
const char *name;
uint8_t type;
- struct payload_template templates[10];
+ struct proto_hdr_template templates[10];
};
extern struct expr *exthdr_expr_alloc(const struct location *loc,
diff --git a/include/meta.h b/include/meta.h
index 459221f..23f78cf 100644
--- a/include/meta.h
+++ b/include/meta.h
@@ -25,5 +25,7 @@ struct meta_template {
extern struct expr *meta_expr_alloc(const struct location *loc,
enum nft_meta_keys key);
+extern void meta_expr_pctx_update(struct proto_ctx *ctx,
+ const struct expr *expr);
#endif /* NFTABLES_META_H */
diff --git a/include/payload.h b/include/payload.h
index fa8d82e..54d8d54 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -2,128 +2,16 @@
#define NFTABLES_PAYLOAD_H
#include <nftables.h>
-
-/**
- * enum payload_bases
- *
- * @PAYLOAD_BASE_INVALID: uninitialised, does not happen
- * @PAYLOAD_BASE_LL_HDR: link layer header
- * @PAYLOAD_BASE_NETWORK_HDR: network layer header
- * @PAYLOAD_BASE_TRANSPORT_HDR: transport layer header
- */
-enum payload_bases {
- PAYLOAD_BASE_INVALID,
- PAYLOAD_BASE_LL_HDR,
- PAYLOAD_BASE_NETWORK_HDR,
- PAYLOAD_BASE_TRANSPORT_HDR,
- __PAYLOAD_BASE_MAX
-};
-#define PAYLOAD_BASE_MAX (__PAYLOAD_BASE_MAX - 1)
-
-/**
- * struct payload_template - template for a payload header expression
- *
- * @token: parser token describing the header field
- * @dtype: data type of the expression
- * @offset: offset from base
- * @len: length of header field
- */
-struct payload_template {
- const char *token;
- const struct datatype *dtype;
- uint16_t offset;
- uint16_t len;
-};
-
-#define PAYLOAD_TEMPLATE(__token, __dtype, __offset, __len) \
- { \
- .token = (__token), \
- .dtype = (__dtype), \
- .offset = (__offset), \
- .len = (__len), \
- }
-
-#define PAYLOAD_PROTO_MAX 16
-#define PAYLOAD_TEMPLATE_MAX 20
-
-/**
- * struct payload_desc - payload protocol description
- *
- * @name: protocol name
- * @base: header base
- * @protocol_key: key of template containing upper layer protocol description
- * @protocols: link to upper layer protocol description indexed by protocol value
- * @templates: header templates
- */
-struct payload_desc {
- const char *name;
- enum payload_bases base;
- unsigned int protocol_key;
- struct {
- unsigned int num;
- const struct payload_desc *desc;
- } protocols[PAYLOAD_PROTO_MAX];
- struct payload_template templates[PAYLOAD_TEMPLATE_MAX];
-};
-
-#define PAYLOAD_PROTO(__num, __desc) { .num = (__num), .desc = (__desc), }
-
-/**
- * struct payload_hook_desc - description of constraints imposed by hook family
- *
- * @base: protocol base of packets
- * @desc: protocol description of packets
- */
-struct payload_hook_desc {
- enum payload_bases base;
- const struct payload_desc *desc;
-};
-
-#define PAYLOAD_HOOK(__base, __desc) { .base = (__base), .desc = (__desc), }
-
-/**
- * struct dev_payload_desc - description of device LL protocol
- *
- * @desc: protocol description
- * @type: arphrd value
- */
-struct dev_payload_desc {
- const struct payload_desc *desc;
- uint16_t type;
-};
-
-#define DEV_PAYLOAD_DESC(__type, __desc) { .type = (__type), .desc = (__desc), }
-
-/**
- * struct payload_ctx - payload expression protocol context
- *
- * @family: hook family
- * @location: location of expression defining the context
- * @desc: payload description for this layer
- *
- * The location of the context is the location of the relational expression
- * defining it, either directly through a protocol match or indirectly
- * through a dependency.
- */
-struct payload_ctx {
- unsigned int family;
- struct {
- struct location location;
- const struct payload_desc *desc;
- } protocol[PAYLOAD_BASE_MAX + 1];
-};
+#include <proto.h>
extern struct expr *payload_expr_alloc(const struct location *loc,
- const struct payload_desc *desc,
+ const struct proto_desc *desc,
unsigned int type);
-extern void payload_init_raw(struct expr *expr, enum payload_bases base,
+extern void payload_init_raw(struct expr *expr, enum proto_bases base,
unsigned int offset, unsigned int len);
-extern void payload_ctx_init(struct payload_ctx *ctx, unsigned int family);
-extern void payload_ctx_update_meta(struct payload_ctx *ctx,
- const struct expr *expr);
-extern void payload_ctx_update(struct payload_ctx *ctx,
- const struct expr *expr);
+extern void payload_expr_pctx_update(struct proto_ctx *ctx,
+ const struct expr *expr);
struct eval_ctx;
extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
@@ -134,162 +22,8 @@ extern struct expr *payload_expr_join(const struct expr *e1,
const struct expr *e2);
extern void payload_expr_expand(struct list_head *list, struct expr *expr,
- const struct payload_ctx *ctx);
+ const struct proto_ctx *ctx);
extern void payload_expr_complete(struct expr *expr,
- const struct payload_ctx *ctx);
-
-enum eth_hdr_fields {
- ETHHDR_INVALID,
- ETHHDR_DADDR,
- ETHHDR_SADDR,
- ETHHDR_TYPE,
-};
-
-enum vlan_hdr_fields {
- VLANHDR_INVALID,
- VLANHDR_VID,
- VLANHDR_CFI,
- VLANHDR_PCP,
- VLANHDR_TYPE,
-};
-
-enum arp_hdr_fields {
- ARPHDR_INVALID,
- ARPHDR_HRD,
- ARPHDR_PRO,
- ARPHDR_HLN,
- ARPHDR_PLN,
- ARPHDR_OP,
-};
-
-enum ip_hdr_fields {
- IPHDR_INVALID,
- IPHDR_VERSION,
- IPHDR_HDRLENGTH,
- IPHDR_TOS,
- IPHDR_LENGTH,
- IPHDR_ID,
- IPHDR_FRAG_OFF,
- IPHDR_TTL,
- IPHDR_PROTOCOL,
- IPHDR_CHECKSUM,
- IPHDR_SADDR,
- IPHDR_DADDR,
-};
-
-enum icmp_hdr_fields {
- ICMPHDR_INVALID,
- ICMPHDR_TYPE,
- ICMPHDR_CODE,
- ICMPHDR_CHECKSUM,
- ICMPHDR_ID,
- ICMPHDR_SEQ,
- ICMPHDR_GATEWAY,
- ICMPHDR_MTU,
-};
-
-enum icmp6_hdr_fields {
- ICMP6HDR_INVALID,
- ICMP6HDR_TYPE,
- ICMP6HDR_CODE,
- ICMP6HDR_CHECKSUM,
- ICMP6HDR_PPTR,
- ICMP6HDR_MTU,
- ICMP6HDR_ID,
- ICMP6HDR_SEQ,
- ICMP6HDR_MAXDELAY,
-};
-
-enum ip6_hdr_fields {
- IP6HDR_INVALID,
- IP6HDR_VERSION,
- IP6HDR_PRIORITY,
- IP6HDR_FLOWLABEL,
- IP6HDR_LENGTH,
- IP6HDR_NEXTHDR,
- IP6HDR_HOPLIMIT,
- IP6HDR_SADDR,
- IP6HDR_DADDR,
- IP6HDR_PROTOCOL,
-};
-
-enum ah_hdr_fields {
- AHHDR_INVALID,
- AHHDR_NEXTHDR,
- AHHDR_HDRLENGTH,
- AHHDR_RESERVED,
- AHHDR_SPI,
- AHHDR_SEQUENCE,
-};
-
-enum esp_hdr_fields {
- ESPHDR_INVALID,
- ESPHDR_SPI,
- ESPHDR_SEQUENCE,
-};
-
-enum comp_hdr_fields {
- COMPHDR_INVALID,
- COMPHDR_NEXTHDR,
- COMPHDR_FLAGS,
- COMPHDR_CPI,
-};
-
-enum udp_hdr_fields {
- UDPHDR_INVALID,
- UDPHDR_SPORT,
- UDPHDR_DPORT,
- UDPHDR_LENGTH,
- UDPHDR_CSUMCOV = UDPHDR_LENGTH,
- UDPHDR_CHECKSUM,
-};
-
-enum tcp_hdr_fields {
- TCPHDR_INVALID,
- TCPHDR_SPORT,
- TCPHDR_DPORT,
- TCPHDR_SEQ,
- TCPHDR_ACKSEQ,
- TCPHDR_DOFF,
- TCPHDR_RESERVED,
- TCPHDR_FLAGS,
- TCPHDR_WINDOW,
- TCPHDR_CHECKSUM,
- TCPHDR_URGPTR,
-};
-
-enum dccp_hdr_fields {
- DCCPHDR_INVALID,
- DCCPHDR_SPORT,
- DCCPHDR_DPORT,
- DCCPHDR_TYPE,
-};
-
-enum sctp_hdr_fields {
- SCTPHDR_INVALID,
- SCTPHDR_SPORT,
- SCTPHDR_DPORT,
- SCTPHDR_VTAG,
- SCTPHDR_CHECKSUM,
-};
-
-extern const struct payload_desc payload_icmp;
-extern const struct payload_desc payload_ah;
-extern const struct payload_desc payload_esp;
-extern const struct payload_desc payload_comp;
-extern const struct payload_desc payload_udp;
-extern const struct payload_desc payload_udplite;
-extern const struct payload_desc payload_tcp;
-extern const struct payload_desc payload_dccp;
-extern const struct payload_desc payload_sctp;
-extern const struct payload_desc payload_icmp6;
-
-extern const struct payload_desc payload_ip;
-extern const struct payload_desc payload_ip6;
-
-extern const struct payload_desc payload_arp;
-
-extern const struct payload_desc payload_vlan;
-extern const struct payload_desc payload_eth;
+ const struct proto_ctx *ctx);
#endif /* NFTABLES_PAYLOAD_H */
diff --git a/include/proto.h b/include/proto.h
new file mode 100644
index 0000000..037ef09
--- /dev/null
+++ b/include/proto.h
@@ -0,0 +1,287 @@
+#ifndef NFTABLES_PROTO_H
+#define NFTABLES_PROTO_H
+
+#include <nftables.h>
+
+/**
+ * enum proto_bases - protocol bases
+ *
+ * @PROTO_BASE_INVALID: uninitialised, does not happen
+ * @PROTO_BASE_LL_HDR: link layer header
+ * @PROTO_BASE_NETWORK_HDR: network layer header
+ * @PROTO_BASE_TRANSPORT_HDR: transport layer header
+ */
+enum proto_bases {
+ PROTO_BASE_INVALID,
+ PROTO_BASE_LL_HDR,
+ PROTO_BASE_NETWORK_HDR,
+ PROTO_BASE_TRANSPORT_HDR,
+ __PROTO_BASE_MAX
+};
+#define PROTO_BASE_MAX (__PROTO_BASE_MAX - 1)
+
+extern const char *proto_base_names[];
+extern const char *proto_base_tokens[];
+
+/**
+ * struct proto_hdr_template - protocol header field description
+ *
+ * @token: parser token describing the header field
+ * @dtype: data type of the header field
+ * @offset: offset of the header field from base
+ * @len: length of header field
+ */
+struct proto_hdr_template {
+ const char *token;
+ const struct datatype *dtype;
+ uint16_t offset;
+ uint16_t len;
+};
+
+#define PROTO_HDR_TEMPLATE(__token, __dtype, __offset, __len) \
+ { \
+ .token = (__token), \
+ .dtype = (__dtype), \
+ .offset = (__offset), \
+ .len = (__len), \
+ }
+
+#define PROTO_UPPER_MAX 16
+#define PROTO_HDRS_MAX 20
+
+/**
+ * struct proto_desc - protocol header description
+ *
+ * @name: protocol name
+ * @base: header base
+ * @protocol_key: key of template containing upper layer protocol description
+ * @protocols: link to upper layer protocol descriptions indexed by protocol value
+ * @templates: header templates
+ */
+struct proto_desc {
+ const char *name;
+ enum proto_bases base;
+ unsigned int protocol_key;
+ struct {
+ unsigned int num;
+ const struct proto_desc *desc;
+ } protocols[PROTO_UPPER_MAX];
+ struct proto_hdr_template templates[PROTO_HDRS_MAX];
+};
+
+#define PROTO_LINK(__num, __desc) { .num = (__num), .desc = (__desc), }
+
+/**
+ * struct hook_proto_desc - description of protocol constraints imposed by hook family
+ *
+ * @base: protocol base of packets
+ * @desc: protocol description of packets
+ */
+struct hook_proto_desc {
+ enum proto_bases base;
+ const struct proto_desc *desc;
+};
+
+#define HOOK_PROTO_DESC(__base, __desc) { .base = (__base), .desc = (__desc), }
+
+extern const struct hook_proto_desc hook_proto_desc[];
+
+/**
+ * struct dev_proto_desc - description of device LL protocol
+ *
+ * @desc: protocol description
+ * @type: arphrd value
+ */
+struct dev_proto_desc {
+ const struct proto_desc *desc;
+ uint16_t type;
+};
+
+#define DEV_PROTO_DESC(__type, __desc) { .type = (__type), .desc = (__desc), }
+
+extern int proto_dev_type(const struct proto_desc *desc, uint16_t *res);
+extern const struct proto_desc *proto_dev_desc(uint16_t type);
+
+/**
+ * struct proto_ctx - protocol context
+ *
+ * @family: hook family
+ * @location: location of the relational expression defining the context
+ * @desc: protocol description for this layer
+ *
+ * The location of the context is the location of the relational expression
+ * defining it, either directly through a protocol match or indirectly
+ * through a dependency.
+ */
+struct proto_ctx {
+ unsigned int family;
+ struct {
+ struct location location;
+ const struct proto_desc *desc;
+ } protocol[PROTO_BASE_MAX + 1];
+};
+
+extern void proto_ctx_init(struct proto_ctx *ctx, unsigned int family);
+extern const struct proto_desc *proto_find_upper(const struct proto_desc *base,
+ unsigned int num);
+extern int proto_find_num(const struct proto_desc *base,
+ const struct proto_desc *desc);
+
+enum eth_hdr_fields {
+ ETHHDR_INVALID,
+ ETHHDR_DADDR,
+ ETHHDR_SADDR,
+ ETHHDR_TYPE,
+};
+
+enum vlan_hdr_fields {
+ VLANHDR_INVALID,
+ VLANHDR_VID,
+ VLANHDR_CFI,
+ VLANHDR_PCP,
+ VLANHDR_TYPE,
+};
+
+enum arp_hdr_fields {
+ ARPHDR_INVALID,
+ ARPHDR_HRD,
+ ARPHDR_PRO,
+ ARPHDR_HLN,
+ ARPHDR_PLN,
+ ARPHDR_OP,
+};
+
+enum ip_hdr_fields {
+ IPHDR_INVALID,
+ IPHDR_VERSION,
+ IPHDR_HDRLENGTH,
+ IPHDR_TOS,
+ IPHDR_LENGTH,
+ IPHDR_ID,
+ IPHDR_FRAG_OFF,
+ IPHDR_TTL,
+ IPHDR_PROTOCOL,
+ IPHDR_CHECKSUM,
+ IPHDR_SADDR,
+ IPHDR_DADDR,
+};
+
+enum icmp_hdr_fields {
+ ICMPHDR_INVALID,
+ ICMPHDR_TYPE,
+ ICMPHDR_CODE,
+ ICMPHDR_CHECKSUM,
+ ICMPHDR_ID,
+ ICMPHDR_SEQ,
+ ICMPHDR_GATEWAY,
+ ICMPHDR_MTU,
+};
+
+enum icmp6_hdr_fields {
+ ICMP6HDR_INVALID,
+ ICMP6HDR_TYPE,
+ ICMP6HDR_CODE,
+ ICMP6HDR_CHECKSUM,
+ ICMP6HDR_PPTR,
+ ICMP6HDR_MTU,
+ ICMP6HDR_ID,
+ ICMP6HDR_SEQ,
+ ICMP6HDR_MAXDELAY,
+};
+
+enum ip6_hdr_fields {
+ IP6HDR_INVALID,
+ IP6HDR_VERSION,
+ IP6HDR_PRIORITY,
+ IP6HDR_FLOWLABEL,
+ IP6HDR_LENGTH,
+ IP6HDR_NEXTHDR,
+ IP6HDR_HOPLIMIT,
+ IP6HDR_SADDR,
+ IP6HDR_DADDR,
+ IP6HDR_PROTOCOL,
+};
+
+enum ah_hdr_fields {
+ AHHDR_INVALID,
+ AHHDR_NEXTHDR,
+ AHHDR_HDRLENGTH,
+ AHHDR_RESERVED,
+ AHHDR_SPI,
+ AHHDR_SEQUENCE,
+};
+
+enum esp_hdr_fields {
+ ESPHDR_INVALID,
+ ESPHDR_SPI,
+ ESPHDR_SEQUENCE,
+};
+
+enum comp_hdr_fields {
+ COMPHDR_INVALID,
+ COMPHDR_NEXTHDR,
+ COMPHDR_FLAGS,
+ COMPHDR_CPI,
+};
+
+enum udp_hdr_fields {
+ UDPHDR_INVALID,
+ UDPHDR_SPORT,
+ UDPHDR_DPORT,
+ UDPHDR_LENGTH,
+ UDPHDR_CSUMCOV = UDPHDR_LENGTH,
+ UDPHDR_CHECKSUM,
+};
+
+enum tcp_hdr_fields {
+ TCPHDR_INVALID,
+ TCPHDR_SPORT,
+ TCPHDR_DPORT,
+ TCPHDR_SEQ,
+ TCPHDR_ACKSEQ,
+ TCPHDR_DOFF,
+ TCPHDR_RESERVED,
+ TCPHDR_FLAGS,
+ TCPHDR_WINDOW,
+ TCPHDR_CHECKSUM,
+ TCPHDR_URGPTR,
+};
+
+enum dccp_hdr_fields {
+ DCCPHDR_INVALID,
+ DCCPHDR_SPORT,
+ DCCPHDR_DPORT,
+ DCCPHDR_TYPE,
+};
+
+enum sctp_hdr_fields {
+ SCTPHDR_INVALID,
+ SCTPHDR_SPORT,
+ SCTPHDR_DPORT,
+ SCTPHDR_VTAG,
+ SCTPHDR_CHECKSUM,
+};
+
+extern const struct proto_desc proto_icmp;
+extern const struct proto_desc proto_ah;
+extern const struct proto_desc proto_esp;
+extern const struct proto_desc proto_comp;
+extern const struct proto_desc proto_udp;
+extern const struct proto_desc proto_udplite;
+extern const struct proto_desc proto_tcp;
+extern const struct proto_desc proto_dccp;
+extern const struct proto_desc proto_sctp;
+extern const struct proto_desc proto_icmp6;
+
+extern const struct proto_desc proto_ip;
+extern const struct proto_desc proto_ip6;
+
+extern const struct proto_desc proto_arp;
+
+extern const struct proto_desc proto_vlan;
+extern const struct proto_desc proto_eth;
+
+extern const struct proto_desc proto_unknown;
+extern const struct proto_hdr_template proto_unknown_template;
+
+#endif /* NFTABLES_PROTO_H */
diff --git a/include/rule.h b/include/rule.h
index 6ad8af3..2a7b798 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -292,7 +292,7 @@ struct eval_ctx {
struct set *set;
struct stmt *stmt;
struct expr_ctx ectx;
- struct payload_ctx pctx;
+ struct proto_ctx pctx;
};
extern int evaluate(struct eval_ctx *ctx, struct list_head *commands);
diff --git a/src/Makefile.in b/src/Makefile.in
index 658e9b3..8ac2b46 100644
--- a/src/Makefile.in
+++ b/src/Makefile.in
@@ -9,6 +9,7 @@ nft-obj += statement.o
nft-obj += datatype.o
nft-obj += expression.o
nft-obj += evaluate.o
+nft-obj += proto.o
nft-obj += payload.o
nft-obj += exthdr.o
nft-obj += meta.o
diff --git a/src/evaluate.c b/src/evaluate.c
index d4f8339..112fc94 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -269,7 +269,7 @@ static int expr_evaluate_primary(struct eval_ctx *ctx, struct expr **expr)
static int expr_evaluate_payload(struct eval_ctx *ctx, struct expr **expr)
{
struct expr *payload = *expr;
- enum payload_bases base = payload->payload.base;
+ enum proto_bases base = payload->payload.base;
struct stmt *nstmt;
struct expr *nexpr;
@@ -916,15 +916,15 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
left->dtype->desc,
right->dtype->desc);
/*
- * Update payload context for payload and meta iiftype equality
- * expressions.
+ * Update protocol context for payload and meta iiftype
+ * equality expressions.
*/
switch (left->ops->type) {
case EXPR_PAYLOAD:
- payload_ctx_update(&ctx->pctx, rel);
+ payload_expr_pctx_update(&ctx->pctx, rel);
break;
case EXPR_META:
- payload_ctx_update_meta(&ctx->pctx, rel);
+ meta_expr_pctx_update(&ctx->pctx, rel);
break;
case EXPR_CONCAT:
return 0;
@@ -1117,7 +1117,7 @@ static int stmt_evaluate_reject(struct eval_ctx *ctx, struct stmt *stmt)
static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
{
- struct payload_ctx *pctx = &ctx->pctx;
+ struct proto_ctx *pctx = &ctx->pctx;
int err;
if (stmt->nat.addr != NULL) {
@@ -1133,7 +1133,7 @@ static int stmt_evaluate_nat(struct eval_ctx *ctx, struct stmt *stmt)
}
if (stmt->nat.proto != NULL) {
- if (pctx->protocol[PAYLOAD_BASE_TRANSPORT_HDR].desc == NULL)
+ if (pctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc == NULL)
return stmt_binary_error(ctx, stmt->nat.proto, stmt,
"transport protocol mapping is only "
"valid after transport protocol match");
@@ -1232,7 +1232,7 @@ static int rule_evaluate(struct eval_ctx *ctx, struct rule *rule)
struct stmt *stmt, *tstmt = NULL;
struct error_record *erec;
- payload_ctx_init(&ctx->pctx, rule->handle.family);
+ proto_ctx_init(&ctx->pctx, rule->handle.family);
memset(&ctx->ectx, 0, sizeof(ctx->ectx));
list_for_each_entry(stmt, &rule->stmts, list) {
diff --git a/src/exthdr.c b/src/exthdr.c
index 3d01c3a..458f9d6 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -40,14 +40,14 @@ static const struct expr_ops exthdr_expr_ops = {
.clone = exthdr_expr_clone,
};
-static const struct payload_template exthdr_unknown_template =
- PAYLOAD_TEMPLATE("unknown", &invalid_type, 0, 0);
+static const struct proto_hdr_template exthdr_unknown_template =
+ PROTO_HDR_TEMPLATE("unknown", &invalid_type, 0, 0);
struct expr *exthdr_expr_alloc(const struct location *loc,
const struct exthdr_desc *desc,
uint8_t type)
{
- const struct payload_template *tmpl;
+ const struct proto_hdr_template *tmpl;
struct expr *expr;
if (desc != NULL)
@@ -73,7 +73,7 @@ static const struct exthdr_desc *exthdr_protocols[IPPROTO_MAX] = {
void exthdr_init_raw(struct expr *expr, uint8_t type,
unsigned int offset, unsigned int len)
{
- const struct payload_template *tmpl;
+ const struct proto_hdr_template *tmpl;
unsigned int i;
assert(expr->ops->type == EXPR_EXTHDR);
@@ -94,9 +94,9 @@ void exthdr_init_raw(struct expr *expr, uint8_t type,
}
#define HDR_TEMPLATE(__name, __dtype, __type, __member) \
- PAYLOAD_TEMPLATE(__name, __dtype, \
- offsetof(__type, __member) * 8, \
- field_sizeof(__type, __member) * 8)
+ PROTO_HDR_TEMPLATE(__name, __dtype, \
+ offsetof(__type, __member) * 8, \
+ field_sizeof(__type, __member) * 8)
/*
* Hop-by-hop options
@@ -171,12 +171,12 @@ const struct exthdr_desc exthdr_frag = {
.templates = {
[FRAGHDR_NEXTHDR] = FRAG_FIELD("nexthdr", ip6f_nxt, &inet_protocol_type),
[FRAGHDR_RESERVED] = FRAG_FIELD("reserved", ip6f_reserved, &integer_type),
- [FRAGHDR_FRAG_OFF] = PAYLOAD_TEMPLATE("frag-off", &integer_type,
- 16, 13),
- [FRAGHDR_RESERVED2] = PAYLOAD_TEMPLATE("reserved2", &integer_type,
- 29, 2),
- [FRAGHDR_MFRAGS] = PAYLOAD_TEMPLATE("more-fragments", &integer_type,
- 31, 1),
+ [FRAGHDR_FRAG_OFF] = PROTO_HDR_TEMPLATE("frag-off", &integer_type,
+ 16, 13),
+ [FRAGHDR_RESERVED2] = PROTO_HDR_TEMPLATE("reserved2", &integer_type,
+ 29, 2),
+ [FRAGHDR_MFRAGS] = PROTO_HDR_TEMPLATE("more-fragments", &integer_type,
+ 31, 1),
[FRAGHDR_ID] = FRAG_FIELD("id", ip6f_ident, &integer_type),
},
};
diff --git a/src/meta.c b/src/meta.c
index 32f3012..343f9a3 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -341,6 +341,35 @@ static void meta_expr_clone(struct expr *new, const struct expr *expr)
new->meta.key = expr->meta.key;
}
+/**
+ * meta_expr_pctx_update - update protocol context based on meta match
+ *
+ * @ctx: protocol context
+ * @expr: relational meta expression
+ *
+ * Update LL protocol context based on IIFTYPE meta match in non-LL hooks.
+ */
+void meta_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
+{
+ const struct hook_proto_desc *h = &hook_proto_desc[ctx->family];
+ const struct expr *left = expr->left, *right = expr->right;
+ const struct proto_desc *desc;
+
+ if (left->meta.key != NFT_META_IIFTYPE)
+ return;
+
+ assert(expr->op == OP_EQ);
+ if (h->base < PROTO_BASE_NETWORK_HDR)
+ return;
+
+ desc = proto_dev_desc(mpz_get_uint16(right->value));
+ if (desc == NULL)
+ desc = &proto_unknown;
+
+ ctx->protocol[PROTO_BASE_LL_HDR].location = expr->location;
+ ctx->protocol[PROTO_BASE_LL_HDR].desc = desc;
+}
+
static const struct expr_ops meta_expr_ops = {
.type = EXPR_META,
.name = "meta",
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 8545273..982377f 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -573,8 +573,8 @@ static int netlink_parse_expr(struct nft_rule_expr *nle, void *arg)
}
struct rule_pp_ctx {
- struct payload_ctx pctx;
- enum payload_bases pbase;
+ struct proto_ctx pctx;
+ enum proto_bases pbase;
struct stmt *pdep;
};
@@ -583,7 +583,7 @@ struct rule_pp_ctx {
*/
static void payload_dependency_kill(struct rule_pp_ctx *ctx, struct expr *expr)
{
- if (ctx->pbase != PAYLOAD_BASE_INVALID &&
+ if (ctx->pbase != PROTO_BASE_INVALID &&
ctx->pbase == expr->payload.base - 1 &&
ctx->pdep != NULL) {
list_del(&ctx->pdep->list);
@@ -612,7 +612,7 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
nexpr = relational_expr_alloc(&expr->location, expr->op,
left, tmp);
- payload_ctx_update(&ctx->pctx, nexpr);
+ payload_expr_pctx_update(&ctx->pctx, nexpr);
nstmt = expr_stmt_alloc(&stmt->location, nexpr);
list_add_tail(&nstmt->list, &stmt->list);
@@ -621,7 +621,7 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
* kill it later on if made redundant by a higher layer
* payload expression.
*/
- if (ctx->pbase == PAYLOAD_BASE_INVALID &&
+ if (ctx->pbase == PROTO_BASE_INVALID &&
left->flags & EXPR_F_PROTOCOL) {
ctx->pbase = left->payload.base;
ctx->pdep = nstmt;
@@ -639,12 +639,12 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
}
}
-static void meta_match_postprocess(struct payload_ctx *ctx,
+static void meta_match_postprocess(struct proto_ctx *ctx,
const struct expr *expr)
{
switch (expr->op) {
case OP_EQ:
- payload_ctx_update_meta(ctx, expr);
+ meta_expr_pctx_update(ctx, expr);
break;
default:
break;
@@ -821,7 +821,7 @@ static void rule_parse_postprocess(struct netlink_parse_ctx *ctx, struct rule *r
struct stmt *stmt, *next;
memset(&rctx, 0, sizeof(rctx));
- payload_ctx_init(&rctx.pctx, rule->handle.family);
+ proto_ctx_init(&rctx.pctx, rule->handle.family);
list_for_each_entry_safe(stmt, next, &rule->stmts, list) {
switch (stmt->ops->type) {
diff --git a/src/parser.y b/src/parser.y
index 9320f2d..7778d50 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -1444,14 +1444,14 @@ payload_raw_expr : AT payload_base_spec COMMA NUM COMMA NUM
}
;
-payload_base_spec : LL_HDR { $$ = PAYLOAD_BASE_LL_HDR; }
- | NETWORK_HDR { $$ = PAYLOAD_BASE_NETWORK_HDR; }
- | TRANSPORT_HDR { $$ = PAYLOAD_BASE_TRANSPORT_HDR; }
+payload_base_spec : LL_HDR { $$ = PROTO_BASE_LL_HDR; }
+ | NETWORK_HDR { $$ = PROTO_BASE_NETWORK_HDR; }
+ | TRANSPORT_HDR { $$ = PROTO_BASE_TRANSPORT_HDR; }
;
eth_hdr_expr : ETH eth_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_eth, $2);
+ $$ = payload_expr_alloc(&@$, &proto_eth, $2);
}
;
@@ -1462,7 +1462,7 @@ eth_hdr_field : SADDR { $$ = ETHHDR_SADDR; }
vlan_hdr_expr : VLAN vlan_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_vlan, $2);
+ $$ = payload_expr_alloc(&@$, &proto_vlan, $2);
}
;
@@ -1474,7 +1474,7 @@ vlan_hdr_field : ID { $$ = VLANHDR_VID; }
arp_hdr_expr : ARP arp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_arp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_arp, $2);
}
;
@@ -1487,7 +1487,7 @@ arp_hdr_field : HTYPE { $$ = ARPHDR_HRD; }
ip_hdr_expr : IP ip_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_ip, $2);
+ $$ = payload_expr_alloc(&@$, &proto_ip, $2);
}
;
@@ -1506,7 +1506,7 @@ ip_hdr_field : VERSION { $$ = IPHDR_VERSION; }
icmp_hdr_expr : ICMP icmp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_icmp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_icmp, $2);
}
| ICMP
{
@@ -1528,7 +1528,7 @@ icmp_hdr_field : TYPE { $$ = ICMPHDR_TYPE; }
ip6_hdr_expr : IP6 ip6_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_ip6, $2);
+ $$ = payload_expr_alloc(&@$, &proto_ip6, $2);
}
;
@@ -1543,7 +1543,7 @@ ip6_hdr_field : VERSION { $$ = IP6HDR_VERSION; }
;
icmp6_hdr_expr : ICMP6 icmp6_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_icmp6, $2);
+ $$ = payload_expr_alloc(&@$, &proto_icmp6, $2);
}
| ICMP6
{
@@ -1566,7 +1566,7 @@ icmp6_hdr_field : TYPE { $$ = ICMP6HDR_TYPE; }
auth_hdr_expr : AH auth_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_ah, $2);
+ $$ = payload_expr_alloc(&@$, &proto_ah, $2);
}
| AH
{
@@ -1586,7 +1586,7 @@ auth_hdr_field : NEXTHDR { $$ = AHHDR_NEXTHDR; }
esp_hdr_expr : ESP esp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_esp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_esp, $2);
}
| ESP
{
@@ -1603,7 +1603,7 @@ esp_hdr_field : SPI { $$ = ESPHDR_SPI; }
comp_hdr_expr : COMP comp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_comp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_comp, $2);
}
| COMP
{
@@ -1621,7 +1621,7 @@ comp_hdr_field : NEXTHDR { $$ = COMPHDR_NEXTHDR; }
udp_hdr_expr : UDP udp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_udp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_udp, $2);
}
| UDP
{
@@ -1640,7 +1640,7 @@ udp_hdr_field : SPORT { $$ = UDPHDR_SPORT; }
udplite_hdr_expr : UDPLITE udplite_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_udplite, $2);
+ $$ = payload_expr_alloc(&@$, &proto_udplite, $2);
}
| UDPLITE
{
@@ -1659,7 +1659,7 @@ udplite_hdr_field : SPORT { $$ = UDPHDR_SPORT; }
tcp_hdr_expr : TCP tcp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_tcp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_tcp, $2);
}
| TCP
{
@@ -1684,7 +1684,7 @@ tcp_hdr_field : SPORT { $$ = TCPHDR_SPORT; }
dccp_hdr_expr : DCCP dccp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_dccp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_dccp, $2);
}
| DCCP
{
@@ -1702,7 +1702,7 @@ dccp_hdr_field : SPORT { $$ = DCCPHDR_SPORT; }
sctp_hdr_expr : SCTP sctp_hdr_field
{
- $$ = payload_expr_alloc(&@$, &payload_sctp, $2);
+ $$ = payload_expr_alloc(&@$, &proto_sctp, $2);
}
| SCTP
{
diff --git a/src/payload.c b/src/payload.c
index 2a60a76..7721b75 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -1,5 +1,5 @@
/*
- * Payload expression protocol and type definitions and related functions.
+ * Payload expression and related functions.
*
* Copyright (c) 2008 Patrick McHardy <kaber@trash.net>
*
@@ -22,36 +22,13 @@
#include <rule.h>
#include <expression.h>
#include <payload.h>
-#include <headers.h>
#include <gmputil.h>
#include <utils.h>
-static const char *payload_base_names[] = {
- [PAYLOAD_BASE_INVALID] = "invalid",
- [PAYLOAD_BASE_LL_HDR] = "link layer",
- [PAYLOAD_BASE_NETWORK_HDR] = "network layer",
- [PAYLOAD_BASE_TRANSPORT_HDR] = "transport layer",
-};
-
-static const char *payload_base_tokens[] = {
- [PAYLOAD_BASE_INVALID] = "invalid",
- [PAYLOAD_BASE_LL_HDR] = "ll",
- [PAYLOAD_BASE_NETWORK_HDR] = "nh",
- [PAYLOAD_BASE_TRANSPORT_HDR] = "th",
-};
-
-static const struct payload_template payload_unknown_template =
- PAYLOAD_TEMPLATE("unknown", &invalid_type, 0, 0);
-
-static const struct payload_desc payload_unknown_desc = {
- .name = "unknown",
- .base = PAYLOAD_BASE_INVALID,
-};
-
static void payload_expr_print(const struct expr *expr)
{
- const struct payload_desc *desc;
- const struct payload_template *tmpl;
+ const struct proto_desc *desc;
+ const struct proto_hdr_template *tmpl;
desc = expr->payload.desc;
tmpl = expr->payload.tmpl;
@@ -59,7 +36,7 @@ static void payload_expr_print(const struct expr *expr)
printf("%s %s", desc->name, tmpl->token);
else
printf("payload @%s,%u,%u",
- payload_base_tokens[expr->payload.base],
+ proto_base_tokens[expr->payload.base],
expr->payload.offset, expr->len);
}
@@ -79,11 +56,11 @@ static const struct expr_ops payload_expr_ops = {
};
struct expr *payload_expr_alloc(const struct location *loc,
- const struct payload_desc *desc,
+ const struct proto_desc *desc,
unsigned int type)
{
- const struct payload_template *tmpl;
- enum payload_bases base;
+ const struct proto_hdr_template *tmpl;
+ enum proto_bases base;
struct expr *expr;
unsigned int flags = 0;
@@ -93,8 +70,8 @@ struct expr *payload_expr_alloc(const struct location *loc,
if (type == desc->protocol_key)
flags = EXPR_F_PROTOCOL;
} else {
- tmpl = &payload_unknown_template;
- base = PAYLOAD_BASE_INVALID;
+ tmpl = &proto_unknown_template;
+ base = PROTO_BASE_INVALID;
}
expr = expr_alloc(loc, &payload_expr_ops, tmpl->dtype,
@@ -109,7 +86,7 @@ struct expr *payload_expr_alloc(const struct location *loc,
return expr;
}
-void payload_init_raw(struct expr *expr, enum payload_bases base,
+void payload_init_raw(struct expr *expr, enum proto_bases base,
unsigned int offset, unsigned int len)
{
expr->payload.base = base;
@@ -118,151 +95,24 @@ void payload_init_raw(struct expr *expr, enum payload_bases base,
}
/**
- * payload_select_proto - find protocol description by protocol value linking
- * it to lower layer protocol
- *
- * @base: lower layer protocol description
- * @num: protocol value
- */
-static const struct payload_desc *
-payload_select_proto(const struct payload_desc *base, unsigned int num)
-{
- unsigned int i;
-
- for (i = 0; i < array_size(base->protocols); i++) {
- if (base->protocols[i].num == num)
- return base->protocols[i].desc;
- }
- return NULL;
-}
-
-/**
- * payload_proto_val - return protocol number linking two protocols together
- *
- * @base: lower layer protocol description
- * @desc: upper layer protocol description
- */
-static int payload_proto_val(const struct payload_desc *base,
- const struct payload_desc *desc)
-{
- unsigned int i;
-
- for (i = 0; i < array_size(base->protocols); i++) {
- if (base->protocols[i].desc == desc)
- return base->protocols[i].num;
- }
- return -1;
-}
-
-static const struct dev_payload_desc dev_payload_desc[] = {
- DEV_PAYLOAD_DESC(ARPHRD_ETHER, &payload_eth),
-};
-
-/**
- * payload_dev_type - return arphrd type linking a device and a protocol together
- *
- * @desc: the protocol description
- * @res: pointer to result
- */
-static int payload_dev_type(const struct payload_desc *desc, uint16_t *res)
-{
- unsigned int i;
-
- for (i = 0; i < array_size(dev_payload_desc); i++) {
- if (dev_payload_desc[i].desc == desc) {
- *res = dev_payload_desc[i].type;
- return 0;
- }
- }
- return -1;
-}
-
-/**
- * payload_dev_desc - return protocol description for an arphrd type
- *
- * @type: the arphrd type
- */
-static const struct payload_desc *payload_dev_desc(uint16_t type)
-{
- unsigned int i;
-
- for (i = 0; i < array_size(dev_payload_desc); i++) {
- if (dev_payload_desc[i].type == type)
- return dev_payload_desc[i].desc;
- }
- return NULL;
-}
-
-static const struct payload_hook_desc payload_hooks[] = {
- [NFPROTO_BRIDGE] = PAYLOAD_HOOK(PAYLOAD_BASE_LL_HDR, &payload_eth),
- [NFPROTO_IPV4] = PAYLOAD_HOOK(PAYLOAD_BASE_NETWORK_HDR, &payload_ip),
- [NFPROTO_IPV6] = PAYLOAD_HOOK(PAYLOAD_BASE_NETWORK_HDR, &payload_ip6),
- [NFPROTO_ARP] = PAYLOAD_HOOK(PAYLOAD_BASE_NETWORK_HDR, &payload_arp),
-};
-
-/**
- * payload_ctx_init - initialize payload context for a given hook family
- *
- * @ctx: payload context
- * @family: hook family
- */
-void payload_ctx_init(struct payload_ctx *ctx, unsigned int family)
-{
- const struct payload_hook_desc *h = &payload_hooks[family];
-
- memset(ctx, 0, sizeof(*ctx));
- ctx->family = family;
- ctx->protocol[h->base].desc = h->desc;
-}
-
-/**
- * payload_ctx_update_meta - update payload context with meta expression
- *
- * @ctx: payload context
- * @expr: relational meta expression
- *
- * Update LL payload context based on IIFTYPE meta match in non-LL hooks.
- */
-void payload_ctx_update_meta(struct payload_ctx *ctx, const struct expr *expr)
-{
- const struct payload_hook_desc *h = &payload_hooks[ctx->family];
- const struct expr *left = expr->left, *right = expr->right;
- const struct payload_desc *desc;
-
- if (left->meta.key != NFT_META_IIFTYPE)
- return;
-
- assert(expr->op == OP_EQ);
- if (h->base < PAYLOAD_BASE_NETWORK_HDR)
- return;
-
- desc = payload_dev_desc(mpz_get_uint16(right->value));
- if (desc == NULL)
- desc = &payload_unknown_desc;
-
- ctx->protocol[PAYLOAD_BASE_LL_HDR].location = expr->location;
- ctx->protocol[PAYLOAD_BASE_LL_HDR].desc = desc;
-}
-
-/**
- * payload_ctx_update - update payload context
+ * payload_expr_pctx_update - update protocol context based on payload match
*
- * @ctx: payload context
+ * @ctx: protocol context
* @expr: relational payload expression
*
- * Update payload context for relational payload expressions.
+ * Update protocol context for relational payload expressions.
*/
-void payload_ctx_update(struct payload_ctx *ctx, const struct expr *expr)
+void payload_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
{
const struct expr *left = expr->left, *right = expr->right;
- const struct payload_desc *base, *desc;
+ const struct proto_desc *base, *desc;
if (!(left->flags & EXPR_F_PROTOCOL))
return;
assert(expr->op == OP_EQ);
base = ctx->protocol[left->payload.base].desc;
- desc = payload_select_proto(base, mpz_get_uint32(right->value));
+ desc = proto_find_upper(base, mpz_get_uint32(right->value));
ctx->protocol[left->payload.base + 1].location = expr->location;
ctx->protocol[left->payload.base + 1].desc = desc;
@@ -294,9 +144,9 @@ void payload_ctx_update(struct payload_ctx *ctx, const struct expr *expr)
int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
struct expr **res)
{
- const struct payload_hook_desc *h = &payload_hooks[ctx->pctx.family];
- const struct payload_desc *desc;
- const struct payload_template *tmpl;
+ const struct hook_proto_desc *h = &hook_proto_desc[ctx->pctx.family];
+ const struct proto_desc *desc;
+ const struct proto_hdr_template *tmpl;
struct expr *dep, *left, *right;
int protocol;
uint16_t type;
@@ -307,7 +157,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
"payload base is invalid for this "
"family");
- if (payload_dev_type(expr->payload.desc, &type) < 0)
+ if (proto_dev_type(expr->payload.desc, &type) < 0)
return expr_error(ctx, expr,
"protocol specification is invalid "
"for this family");
@@ -327,9 +177,9 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
return expr_error(ctx, expr,
"ambiguous payload specification: "
"no %s protocol specified",
- payload_base_names[expr->payload.base - 1]);
+ proto_base_names[expr->payload.base - 1]);
- protocol = payload_proto_val(desc, expr->payload.desc);
+ protocol = proto_find_num(desc, expr->payload.desc);
if (protocol < 0)
return expr_error(ctx, expr,
"conflicting protocols specified: %s vs. %s",
@@ -342,7 +192,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
tmpl->len, &protocol);
dep = relational_expr_alloc(&expr->location, OP_EQ, left, right);
- payload_ctx_update(&ctx->pctx, dep);
+ payload_expr_pctx_update(&ctx->pctx, dep);
*res = dep;
return 0;
}
@@ -351,15 +201,15 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
* payload_expr_complete - fill in type information of a raw payload expr
*
* @expr: the payload expression
- * @ctx: payload context
+ * @ctx: protocol context
*
* Complete the type of a raw payload expression based on the context. If
* insufficient information is available the expression remains unchanged.
*/
-void payload_expr_complete(struct expr *expr, const struct payload_ctx *ctx)
+void payload_expr_complete(struct expr *expr, const struct proto_ctx *ctx)
{
- const struct payload_desc *desc;
- const struct payload_template *tmpl;
+ const struct proto_desc *desc;
+ const struct proto_hdr_template *tmpl;
unsigned int i;
assert(expr->ops->type == EXPR_PAYLOAD);
@@ -387,7 +237,7 @@ void payload_expr_complete(struct expr *expr, const struct payload_ctx *ctx)
*
* @list: list to append expanded payload expressions to
* @expr: the payload expression to expand
- * @ctx: payload context
+ * @ctx: protocol context
*
* Expand a merged adjacent payload expression into its original components
* by splitting elements off the beginning matching a payload template.
@@ -396,10 +246,10 @@ void payload_expr_complete(struct expr *expr, const struct payload_ctx *ctx)
* offset order.
*/
void payload_expr_expand(struct list_head *list, struct expr *expr,
- const struct payload_ctx *ctx)
+ const struct proto_ctx *ctx)
{
- const struct payload_desc *desc;
- const struct payload_template *tmpl;
+ const struct proto_desc *desc;
+ const struct proto_hdr_template *tmpl;
struct expr *new;
unsigned int i;
@@ -465,590 +315,3 @@ struct expr *payload_expr_join(const struct expr *e1, const struct expr *e2)
expr->len = e1->len + e2->len;
return expr;
}
-
-#define HDR_TEMPLATE(__name, __dtype, __type, __member) \
- PAYLOAD_TEMPLATE(__name, __dtype, \
- offsetof(__type, __member) * 8, \
- field_sizeof(__type, __member) * 8)
-
-#define HDR_FIELD(__name, __struct, __member) \
- HDR_TEMPLATE(__name, &integer_type, __struct, __member)
-#define HDR_BITFIELD(__name, __dtype, __offset, __len) \
- PAYLOAD_TEMPLATE(__name, __dtype, __offset, __len)
-#define HDR_TYPE(__name, __dtype, __struct, __member) \
- HDR_TEMPLATE(__name, __dtype, __struct, __member)
-
-#define INET_PROTOCOL(__name, __struct, __member) \
- HDR_TYPE(__name, &inet_protocol_type, __struct, __member)
-#define INET_SERVICE(__name, __struct, __member) \
- HDR_TYPE(__name, &inet_service_type, __struct, __member)
-
-/*
- * AH
- */
-
-#define AHHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct ip_auth_hdr, __member)
-
-const struct payload_desc payload_ah = {
- .name = "ah",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .protocol_key = AHHDR_NEXTHDR,
- .protocols = {
- PAYLOAD_PROTO(IPPROTO_ESP, &payload_esp),
- PAYLOAD_PROTO(IPPROTO_AH, &payload_ah),
- PAYLOAD_PROTO(IPPROTO_COMP, &payload_comp),
- PAYLOAD_PROTO(IPPROTO_UDP, &payload_udp),
- PAYLOAD_PROTO(IPPROTO_UDPLITE, &payload_udplite),
- PAYLOAD_PROTO(IPPROTO_TCP, &payload_tcp),
- PAYLOAD_PROTO(IPPROTO_DCCP, &payload_dccp),
- PAYLOAD_PROTO(IPPROTO_SCTP, &payload_sctp),
- },
- .templates = {
- [AHHDR_NEXTHDR] = INET_PROTOCOL("nexthdr", struct ip_auth_hdr, nexthdr),
- [AHHDR_HDRLENGTH] = AHHDR_FIELD("hdrlength", hdrlen),
- [AHHDR_RESERVED] = AHHDR_FIELD("reserved", reserved),
- [AHHDR_SPI] = AHHDR_FIELD("spi", spi),
- [AHHDR_SEQUENCE] = AHHDR_FIELD("sequence", seq_no),
- },
-};
-
-/*
- * ESP
- */
-
-#define ESPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct ip_esp_hdr, __member)
-
-const struct payload_desc payload_esp = {
- .name = "esp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [ESPHDR_SPI] = ESPHDR_FIELD("spi", spi),
- [ESPHDR_SEQUENCE] = ESPHDR_FIELD("sequence", seq_no),
- },
-};
-
-/*
- * IPCOMP
- */
-
-#define COMPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct ip_comp_hdr, __member)
-
-const struct payload_desc payload_comp = {
- .name = "comp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .protocol_key = COMPHDR_NEXTHDR,
- .protocols = {
- PAYLOAD_PROTO(IPPROTO_ESP, &payload_esp),
- PAYLOAD_PROTO(IPPROTO_AH, &payload_ah),
- PAYLOAD_PROTO(IPPROTO_COMP, &payload_comp),
- PAYLOAD_PROTO(IPPROTO_UDP, &payload_udp),
- PAYLOAD_PROTO(IPPROTO_UDPLITE, &payload_udplite),
- PAYLOAD_PROTO(IPPROTO_TCP, &payload_tcp),
- PAYLOAD_PROTO(IPPROTO_DCCP, &payload_dccp),
- PAYLOAD_PROTO(IPPROTO_SCTP, &payload_sctp),
- },
- .templates = {
- [COMPHDR_NEXTHDR] = INET_PROTOCOL("nexthdr", struct ip_comp_hdr, nexthdr),
- [COMPHDR_FLAGS] = COMPHDR_FIELD("flags", flags),
- [COMPHDR_CPI] = COMPHDR_FIELD("cpi", cpi),
- },
-};
-
-/*
- * ICMP
- */
-
-#include <netinet/ip_icmp.h>
-
-static const struct symbol_table icmp_type_tbl = {
- .symbols = {
- SYMBOL("echo-reply", ICMP_ECHOREPLY),
- SYMBOL("destination-unreachable", ICMP_DEST_UNREACH),
- SYMBOL("source-quench", ICMP_SOURCE_QUENCH),
- SYMBOL("redirect", ICMP_REDIRECT),
- SYMBOL("echo-request", ICMP_ECHO),
- SYMBOL("time-exceeded", ICMP_TIME_EXCEEDED),
- SYMBOL("parameter-problem", ICMP_PARAMETERPROB),
- SYMBOL("timestamp-request", ICMP_TIMESTAMP),
- SYMBOL("timestamp-reply", ICMP_TIMESTAMPREPLY),
- SYMBOL("info-request", ICMP_INFO_REQUEST),
- SYMBOL("info-reply", ICMP_INFO_REPLY),
- SYMBOL("address-mask-request", ICMP_ADDRESS),
- SYMBOL("address-mask-reply", ICMP_ADDRESSREPLY),
- SYMBOL_LIST_END
- },
-};
-
-static const struct datatype icmp_type_type = {
- .type = TYPE_ICMP_TYPE,
- .name = "icmp_type",
- .desc = "ICMP type",
- .byteorder = BYTEORDER_BIG_ENDIAN,
- .size = BITS_PER_BYTE,
- .basetype = &integer_type,
- .sym_tbl = &icmp_type_tbl,
-};
-
-#define ICMPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct icmphdr, __member)
-#define ICMPHDR_TYPE(__name, __type, __member) \
- HDR_TYPE(__name, __type, struct icmphdr, __member)
-
-const struct payload_desc payload_icmp = {
- .name = "icmp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type),
- [ICMPHDR_CODE] = ICMPHDR_FIELD("code", code),
- [ICMPHDR_CHECKSUM] = ICMPHDR_FIELD("checksum", checksum),
- [ICMPHDR_ID] = ICMPHDR_FIELD("id", un.echo.id),
- [ICMPHDR_SEQ] = ICMPHDR_FIELD("sequence", un.echo.sequence),
- [ICMPHDR_GATEWAY] = ICMPHDR_FIELD("gateway", un.gateway),
- [ICMPHDR_MTU] = ICMPHDR_FIELD("mtu", un.frag.mtu),
- },
-};
-
-/*
- * UDP/UDP-Lite
- */
-
-#include <netinet/udp.h>
-#define UDPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct udphdr, __member)
-
-const struct payload_desc payload_udp = {
- .name = "udp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
- [UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
- [UDPHDR_LENGTH] = UDPHDR_FIELD("length", len),
- [UDPHDR_CHECKSUM] = UDPHDR_FIELD("checksum", check),
- },
-};
-
-const struct payload_desc payload_udplite = {
- .name = "udplite",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
- [UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
- [UDPHDR_CSUMCOV] = UDPHDR_FIELD("csumcov", len),
- [UDPHDR_CHECKSUM] = UDPHDR_FIELD("checksum", check),
- },
-};
-
-/*
- * TCP
- */
-
-#include <netinet/tcp.h>
-
-static const struct symbol_table tcp_flag_tbl = {
- .symbols = {
- SYMBOL("fin", TCP_FLAG_FIN),
- SYMBOL("syn", TCP_FLAG_SYN),
- SYMBOL("rst", TCP_FLAG_RST),
- SYMBOL("psh", TCP_FLAG_PSH),
- SYMBOL("ack", TCP_FLAG_ACK),
- SYMBOL("urg", TCP_FLAG_URG),
- SYMBOL("ecn", TCP_FLAG_ECN),
- SYMBOL("cwr", TCP_FLAG_CWR),
- SYMBOL_LIST_END
- },
-};
-
-static const struct datatype tcp_flag_type = {
- .type = TYPE_TCP_FLAG,
- .name = "tcp_flag",
- .desc = "TCP flag",
- .byteorder = BYTEORDER_BIG_ENDIAN,
- .size = BITS_PER_BYTE,
- .basetype = &bitmask_type,
- .sym_tbl = &tcp_flag_tbl,
-};
-
-#define TCPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct tcphdr, __member)
-
-const struct payload_desc payload_tcp = {
- .name = "tcp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [TCPHDR_SPORT] = INET_SERVICE("sport", struct tcphdr, source),
- [TCPHDR_DPORT] = INET_SERVICE("dport", struct tcphdr, dest),
- [TCPHDR_SEQ] = TCPHDR_FIELD("sequence", seq),
- [TCPHDR_ACKSEQ] = TCPHDR_FIELD("ackseq", ack_seq),
- [TCPHDR_DOFF] = {},
- [TCPHDR_RESERVED] = {},
- [TCPHDR_FLAGS] = HDR_BITFIELD("flags", &tcp_flag_type,
- 13 * BITS_PER_BYTE,
- BITS_PER_BYTE),
- [TCPHDR_WINDOW] = TCPHDR_FIELD("window", window),
- [TCPHDR_CHECKSUM] = TCPHDR_FIELD("checksum", check),
- [TCPHDR_URGPTR] = TCPHDR_FIELD("urgptr", urg_ptr),
- },
-};
-
-/*
- * DCCP
- */
-
-static const struct symbol_table dccp_pkttype_tbl = {
- .symbols = {
- SYMBOL("request", DCCP_PKT_REQUEST),
- SYMBOL("response", DCCP_PKT_RESPONSE),
- SYMBOL("data", DCCP_PKT_DATA),
- SYMBOL("ack", DCCP_PKT_ACK),
- SYMBOL("dataack", DCCP_PKT_DATAACK),
- SYMBOL("closereq", DCCP_PKT_CLOSEREQ),
- SYMBOL("close", DCCP_PKT_CLOSE),
- SYMBOL("reset", DCCP_PKT_RESET),
- SYMBOL("sync", DCCP_PKT_SYNC),
- SYMBOL("syncack", DCCP_PKT_SYNCACK),
- SYMBOL_LIST_END
- },
-};
-
-static const struct datatype dccp_pkttype_type = {
- .type = TYPE_DCCP_PKTTYPE,
- .name = "dccp_pkttype",
- .desc = "DCCP packet type",
- .byteorder = BYTEORDER_INVALID,
- .size = 4,
- .basetype = &integer_type,
- .sym_tbl = &dccp_pkttype_tbl,
-};
-
-
-#define DCCPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct dccp_hdr, __member)
-
-const struct payload_desc payload_dccp = {
- .name = "dccp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [DCCPHDR_SPORT] = INET_SERVICE("sport", struct dccp_hdr, dccph_sport),
- [DCCPHDR_DPORT] = INET_SERVICE("dport", struct dccp_hdr, dccph_dport),
- [DCCPHDR_TYPE] = HDR_BITFIELD("type", &dccp_pkttype_type, 67, 4),
- },
-};
-
-/*
- * SCTP
- */
-
-#define SCTPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct sctphdr, __member)
-
-const struct payload_desc payload_sctp = {
- .name = "sctp",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [SCTPHDR_SPORT] = INET_SERVICE("sport", struct sctphdr, source),
- [SCTPHDR_DPORT] = INET_SERVICE("dport", struct sctphdr, dest),
- [SCTPHDR_VTAG] = SCTPHDR_FIELD("vtag", vtag),
- [SCTPHDR_CHECKSUM] = SCTPHDR_FIELD("checksum", checksum),
- },
-};
-
-/*
- * IPv4
- */
-
-#include <netinet/ip.h>
-#define IPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct iphdr, __member)
-#define IPHDR_ADDR(__name, __member) \
- HDR_TYPE(__name, &ipaddr_type, struct iphdr, __member)
-
-const struct payload_desc payload_ip = {
- .name = "ip",
- .base = PAYLOAD_BASE_NETWORK_HDR,
- .protocol_key = IPHDR_PROTOCOL,
- .protocols = {
- PAYLOAD_PROTO(IPPROTO_ICMP, &payload_icmp),
- PAYLOAD_PROTO(IPPROTO_ESP, &payload_esp),
- PAYLOAD_PROTO(IPPROTO_AH, &payload_ah),
- PAYLOAD_PROTO(IPPROTO_COMP, &payload_comp),
- PAYLOAD_PROTO(IPPROTO_UDP, &payload_udp),
- PAYLOAD_PROTO(IPPROTO_UDPLITE, &payload_udplite),
- PAYLOAD_PROTO(IPPROTO_TCP, &payload_tcp),
- PAYLOAD_PROTO(IPPROTO_DCCP, &payload_dccp),
- PAYLOAD_PROTO(IPPROTO_SCTP, &payload_sctp),
- },
- .templates = {
- [IPHDR_VERSION] = HDR_BITFIELD("version", &integer_type, 0, 4),
- [IPHDR_HDRLENGTH] = HDR_BITFIELD("hdrlength", &integer_type, 4, 4),
- [IPHDR_TOS] = IPHDR_FIELD("tos", tos),
- [IPHDR_LENGTH] = IPHDR_FIELD("length", tot_len),
- [IPHDR_ID] = IPHDR_FIELD("id", id),
- [IPHDR_FRAG_OFF] = IPHDR_FIELD("frag-off", frag_off),
- [IPHDR_TTL] = IPHDR_FIELD("ttl", ttl),
- [IPHDR_PROTOCOL] = INET_PROTOCOL("protocol", struct iphdr, protocol),
- [IPHDR_CHECKSUM] = IPHDR_FIELD("checksum", check),
- [IPHDR_SADDR] = IPHDR_ADDR("saddr", saddr),
- [IPHDR_DADDR] = IPHDR_ADDR("daddr", daddr),
- },
-};
-
-/*
- * ICMPv6
- */
-
-#include <netinet/icmp6.h>
-
-static const struct symbol_table icmp6_type_tbl = {
- .symbols = {
- SYMBOL("destination-unreachable", ICMP6_DST_UNREACH),
- SYMBOL("packet-too-big", ICMP6_PACKET_TOO_BIG),
- SYMBOL("time-exceeded", ICMP6_TIME_EXCEEDED),
- SYMBOL("param-problem", ICMP6_PARAM_PROB),
- SYMBOL("echo-request", ICMP6_ECHO_REQUEST),
- SYMBOL("echo-reply", ICMP6_ECHO_REPLY),
- SYMBOL("mld-listener-query", MLD_LISTENER_QUERY),
- SYMBOL("mld-listener-report", MLD_LISTENER_REPORT),
- SYMBOL("mld-listener-reduction", MLD_LISTENER_REDUCTION),
- SYMBOL("nd-router-solicit", ND_ROUTER_SOLICIT),
- SYMBOL("nd-router-advert", ND_ROUTER_ADVERT),
- SYMBOL("nd-neighbor-solicit", ND_NEIGHBOR_SOLICIT),
- SYMBOL("nd-neighbor-advert", ND_NEIGHBOR_ADVERT),
- SYMBOL("nd-redirect", ND_REDIRECT),
- SYMBOL("router-renumbering", ICMP6_ROUTER_RENUMBERING),
- SYMBOL_LIST_END
- },
-};
-
-static const struct datatype icmp6_type_type = {
- .type = TYPE_ICMP6_TYPE,
- .name = "icmpv6_type",
- .desc = "ICMPv6 type",
- .byteorder = BYTEORDER_BIG_ENDIAN,
- .size = BITS_PER_BYTE,
- .basetype = &integer_type,
- .sym_tbl = &icmp6_type_tbl,
-};
-
-#define ICMP6HDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct icmp6_hdr, __member)
-#define ICMP6HDR_TYPE(__name, __type, __member) \
- HDR_TYPE(__name, __type, struct icmp6_hdr, __member)
-
-const struct payload_desc payload_icmp6 = {
- .name = "icmpv6",
- .base = PAYLOAD_BASE_TRANSPORT_HDR,
- .templates = {
- [ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type),
- [ICMP6HDR_CODE] = ICMP6HDR_FIELD("code", icmp6_code),
- [ICMP6HDR_CHECKSUM] = ICMP6HDR_FIELD("checksum", icmp6_cksum),
- [ICMP6HDR_PPTR] = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr),
- [ICMP6HDR_MTU] = ICMP6HDR_FIELD("packet-too-big", icmp6_mtu),
- [ICMP6HDR_ID] = ICMP6HDR_FIELD("id", icmp6_id),
- [ICMP6HDR_SEQ] = ICMP6HDR_FIELD("sequence", icmp6_seq),
- [ICMP6HDR_MAXDELAY] = ICMP6HDR_FIELD("max-delay", icmp6_maxdelay),
- },
-};
-
-/*
- * IPv6
- */
-
-#define IP6HDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct ipv6hdr, __member)
-#define IP6HDR_ADDR(__name, __member) \
- HDR_TYPE(__name, &ip6addr_type, struct ipv6hdr, __member)
-#define IP6HDR_PROTOCOL(__name, __member) \
- HDR_TYPE(__name, &inet_service_type, struct ipv6hdr, __member)
-
-const struct payload_desc payload_ip6 = {
- .name = "ip6",
- .base = PAYLOAD_BASE_NETWORK_HDR,
- .protocol_key = IP6HDR_NEXTHDR,
- .protocols = {
- PAYLOAD_PROTO(IPPROTO_ESP, &payload_esp),
- PAYLOAD_PROTO(IPPROTO_AH, &payload_ah),
- PAYLOAD_PROTO(IPPROTO_COMP, &payload_comp),
- PAYLOAD_PROTO(IPPROTO_UDP, &payload_udp),
- PAYLOAD_PROTO(IPPROTO_UDPLITE, &payload_udplite),
- PAYLOAD_PROTO(IPPROTO_TCP, &payload_tcp),
- PAYLOAD_PROTO(IPPROTO_DCCP, &payload_dccp),
- PAYLOAD_PROTO(IPPROTO_SCTP, &payload_sctp),
- PAYLOAD_PROTO(IPPROTO_ICMPV6, &payload_icmp6),
- },
- .templates = {
- [IP6HDR_VERSION] = HDR_BITFIELD("version", &integer_type, 0, 4),
- [IP6HDR_PRIORITY] = HDR_BITFIELD("priority", &integer_type, 4, 4),
- [IP6HDR_FLOWLABEL] = IP6HDR_FIELD("flowlabel", flow_lbl),
- [IP6HDR_LENGTH] = IP6HDR_FIELD("length", payload_len),
- [IP6HDR_NEXTHDR] = INET_PROTOCOL("nexthdr", struct ipv6hdr, nexthdr),
- [IP6HDR_HOPLIMIT] = IP6HDR_FIELD("hoplimit", hop_limit),
- [IP6HDR_SADDR] = IP6HDR_ADDR("saddr", saddr),
- [IP6HDR_DADDR] = IP6HDR_ADDR("daddr", daddr),
- },
-};
-
-/*
- * ARP
- */
-
-#include <net/if_arp.h>
-
-static const struct symbol_table arpop_tbl = {
- .symbols = {
- SYMBOL("request", ARPOP_REQUEST),
- SYMBOL("reply", ARPOP_REPLY),
- SYMBOL("rrequest", ARPOP_RREQUEST),
- SYMBOL("rreply", ARPOP_REPLY),
- SYMBOL("inrequest", ARPOP_InREQUEST),
- SYMBOL("inreply", ARPOP_InREPLY),
- SYMBOL("nak", ARPOP_NAK),
- SYMBOL_LIST_END
- },
-};
-
-static const struct datatype arpop_type = {
- .type = TYPE_ARPOP,
- .name = "arp_op",
- .desc = "ARP operation",
- .byteorder = BYTEORDER_BIG_ENDIAN,
- .size = 2 * BITS_PER_BYTE,
- .basetype = &integer_type,
- .sym_tbl = &arpop_tbl,
-};
-
-#define ARPHDR_TYPE(__name, __type, __member) \
- HDR_TYPE(__name, __type, struct arphdr, __member)
-#define ARPHDR_FIELD(__name, __member) \
- HDR_FIELD(__name, struct arphdr, __member)
-
-const struct payload_desc payload_arp = {
- .name = "arp",
- .base = PAYLOAD_BASE_NETWORK_HDR,
- .templates = {
- [ARPHDR_HRD] = ARPHDR_FIELD("htype", ar_hrd),
- [ARPHDR_PRO] = ARPHDR_TYPE("ptype", ðertype_type, ar_pro),
- [ARPHDR_HLN] = ARPHDR_FIELD("hlen", ar_hln),
- [ARPHDR_PLN] = ARPHDR_FIELD("plen", ar_pln),
- [ARPHDR_OP] = ARPHDR_TYPE("operation", &arpop_type, ar_op),
- },
-};
-
-/*
- * VLAN
- */
-
-#include <net/ethernet.h>
-
-#define VLANHDR_BITFIELD(__name, __offset, __len) \
- HDR_BITFIELD(__name, &integer_type, __offset, __len)
-#define VLANHDR_TYPE(__name, __type, __member) \
- HDR_TYPE(__name, __type, struct vlan_hdr, __member)
-
-const struct payload_desc payload_vlan = {
- .name = "vlan",
- .base = PAYLOAD_BASE_LL_HDR,
- .protocol_key = VLANHDR_TYPE,
- .protocols = {
- PAYLOAD_PROTO(ETH_P_IP, &payload_ip),
- PAYLOAD_PROTO(ETH_P_ARP, &payload_arp),
- PAYLOAD_PROTO(ETH_P_IPV6, &payload_ip6),
- PAYLOAD_PROTO(ETH_P_8021Q, &payload_vlan),
-
- },
- .templates = {
- [VLANHDR_VID] = VLANHDR_BITFIELD("id", 0, 12),
- [VLANHDR_CFI] = VLANHDR_BITFIELD("cfi", 12, 1),
- [VLANHDR_PCP] = VLANHDR_BITFIELD("pcp", 13, 3),
- [VLANHDR_TYPE] = VLANHDR_TYPE("type", ðertype_type, vlan_type),
- },
-};
-
-/*
- * Ethernet
- */
-
-const struct datatype etheraddr_type = {
- .type = TYPE_ETHERADDR,
- .name = "etheraddr",
- .desc = "Ethernet address",
- .byteorder = BYTEORDER_HOST_ENDIAN,
- .size = ETH_ALEN * BITS_PER_BYTE,
- .basetype = &lladdr_type,
-};
-
-static const struct symbol_table ethertype_tbl = {
- .symbols = {
- SYMBOL("ip", ETH_P_IP),
- SYMBOL("arp", ETH_P_ARP),
- SYMBOL("ipv6", ETH_P_IPV6),
- SYMBOL("vlan", ETH_P_8021Q),
- SYMBOL_LIST_END
- },
-};
-
-static struct error_record *ethertype_parse(const struct expr *sym,
- struct expr **res)
-{
- struct error_record *erec;
-
- erec = sym->dtype->basetype->parse(sym, res);
- if (erec != NULL)
- return erec;
- if (*res)
- return NULL;
- return symbolic_constant_parse(sym, ðertype_tbl, res);
-}
-
-static void ethertype_print(const struct expr *expr)
-{
- return symbolic_constant_print(ðertype_tbl, expr);
-}
-
-const struct datatype ethertype_type = {
- .type = TYPE_ETHERTYPE,
- .name = "ethertype",
- .desc = "Ethernet protocol",
- .byteorder = BYTEORDER_BIG_ENDIAN,
- .size = 2 * BITS_PER_BYTE,
- .basetype = &integer_type,
- .basefmt = "0x%.4Zx",
- .print = ethertype_print,
- .parse = ethertype_parse,
-};
-
-#define ETHHDR_TEMPLATE(__name, __dtype, __member) \
- HDR_TEMPLATE(__name, __dtype, struct ether_header, __member)
-#define ETHHDR_TYPE(__name, __member) \
- ETHHDR_TEMPLATE(__name, ðertype_type, __member)
-#define ETHHDR_ADDR(__name, __member) \
- ETHHDR_TEMPLATE(__name, ðeraddr_type, __member)
-
-const struct payload_desc payload_eth = {
- .name = "eth",
- .base = PAYLOAD_BASE_LL_HDR,
- .protocol_key = ETHHDR_TYPE,
- .protocols = {
- PAYLOAD_PROTO(ETH_P_IP, &payload_ip),
- PAYLOAD_PROTO(ETH_P_ARP, &payload_arp),
- PAYLOAD_PROTO(ETH_P_IPV6, &payload_ip6),
- PAYLOAD_PROTO(ETH_P_8021Q, &payload_vlan),
- },
- .templates = {
- [ETHHDR_DADDR] = ETHHDR_ADDR("daddr", ether_dhost),
- [ETHHDR_SADDR] = ETHHDR_ADDR("saddr", ether_shost),
- [ETHHDR_TYPE] = ETHHDR_TYPE("type", ether_type),
- },
-};
-
-static void __init payload_init(void)
-{
- datatype_register(&icmp_type_type);
- datatype_register(&tcp_flag_type);
- datatype_register(&dccp_pkttype_type);
- datatype_register(&arpop_type);
- datatype_register(ðertype_type);
- datatype_register(&icmp6_type_type);
-}
diff --git a/src/proto.c b/src/proto.c
new file mode 100644
index 0000000..c6428e4
--- /dev/null
+++ b/src/proto.c
@@ -0,0 +1,731 @@
+/*
+ * Protocol header and type definitions and related functions.
+ *
+ * Copyright (c) 2014 Patrick McHardy <kaber@trash.net>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+#include <stddef.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <net/if_arp.h>
+#include <arpa/inet.h>
+#include <linux/netfilter.h>
+
+#include <expression.h>
+#include <headers.h>
+#include <proto.h>
+#include <gmputil.h>
+#include <utils.h>
+
+const char *proto_base_names[] = {
+ [PROTO_BASE_INVALID] = "invalid",
+ [PROTO_BASE_LL_HDR] = "link layer",
+ [PROTO_BASE_NETWORK_HDR] = "network layer",
+ [PROTO_BASE_TRANSPORT_HDR] = "transport layer",
+};
+
+const char *proto_base_tokens[] = {
+ [PROTO_BASE_INVALID] = "invalid",
+ [PROTO_BASE_LL_HDR] = "ll",
+ [PROTO_BASE_NETWORK_HDR] = "nh",
+ [PROTO_BASE_TRANSPORT_HDR] = "th",
+};
+
+const struct proto_hdr_template proto_unknown_template =
+ PROTO_HDR_TEMPLATE("unknown", &invalid_type, 0, 0);
+
+const struct proto_desc proto_unknown = {
+ .name = "unknown",
+ .base = PROTO_BASE_INVALID,
+};
+
+/**
+ * proto_find_upper - find higher layer protocol description by protocol value
+ * linking it to the lower layer protocol
+ *
+ * @base: lower layer protocol description
+ * @num: protocol value
+ */
+const struct proto_desc *
+proto_find_upper(const struct proto_desc *base, unsigned int num)
+{
+ unsigned int i;
+
+ for (i = 0; i < array_size(base->protocols); i++) {
+ if (base->protocols[i].num == num)
+ return base->protocols[i].desc;
+ }
+ return NULL;
+}
+
+/**
+ * proto_find_num - return protocol number linking two protocols together
+ *
+ * @base: lower layer protocol description
+ * @desc: upper layer protocol description
+ */
+int proto_find_num(const struct proto_desc *base,
+ const struct proto_desc *desc)
+{
+ unsigned int i;
+
+ for (i = 0; i < array_size(base->protocols); i++) {
+ if (base->protocols[i].desc == desc)
+ return base->protocols[i].num;
+ }
+ return -1;
+}
+
+static const struct dev_proto_desc dev_proto_desc[] = {
+ DEV_PROTO_DESC(ARPHRD_ETHER, &proto_eth),
+};
+
+/**
+ * proto_dev_type - return arphrd type linking a device and a protocol together
+ *
+ * @desc: the protocol description
+ * @res: pointer to result
+ */
+int proto_dev_type(const struct proto_desc *desc, uint16_t *res)
+{
+ unsigned int i;
+
+ for (i = 0; i < array_size(dev_proto_desc); i++) {
+ if (dev_proto_desc[i].desc == desc) {
+ *res = dev_proto_desc[i].type;
+ return 0;
+ }
+ }
+ return -1;
+}
+
+/**
+ * proto_dev_desc - return protocol description for an arphrd type
+ *
+ * @type: the arphrd type
+ */
+const struct proto_desc *proto_dev_desc(uint16_t type)
+{
+ unsigned int i;
+
+ for (i = 0; i < array_size(dev_proto_desc); i++) {
+ if (dev_proto_desc[i].type == type)
+ return dev_proto_desc[i].desc;
+ }
+ return NULL;
+}
+
+const struct hook_proto_desc hook_proto_desc[] = {
+ [NFPROTO_BRIDGE] = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR, &proto_eth),
+ [NFPROTO_IPV4] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip),
+ [NFPROTO_IPV6] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip6),
+ [NFPROTO_ARP] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_arp),
+};
+
+/**
+ * proto_ctx_init - initialize protocol context for a given hook family
+ *
+ * @ctx: protocol context
+ * @family: hook family
+ */
+void proto_ctx_init(struct proto_ctx *ctx, unsigned int family)
+{
+ const struct hook_proto_desc *h = &hook_proto_desc[family];
+
+ memset(ctx, 0, sizeof(*ctx));
+ ctx->family = family;
+ ctx->protocol[h->base].desc = h->desc;
+}
+
+#define HDR_TEMPLATE(__name, __dtype, __type, __member) \
+ PROTO_HDR_TEMPLATE(__name, __dtype, \
+ offsetof(__type, __member) * 8, \
+ field_sizeof(__type, __member) * 8)
+
+#define HDR_FIELD(__name, __struct, __member) \
+ HDR_TEMPLATE(__name, &integer_type, __struct, __member)
+#define HDR_BITFIELD(__name, __dtype, __offset, __len) \
+ PROTO_HDR_TEMPLATE(__name, __dtype, __offset, __len)
+#define HDR_TYPE(__name, __dtype, __struct, __member) \
+ HDR_TEMPLATE(__name, __dtype, __struct, __member)
+
+#define INET_PROTOCOL(__name, __struct, __member) \
+ HDR_TYPE(__name, &inet_protocol_type, __struct, __member)
+#define INET_SERVICE(__name, __struct, __member) \
+ HDR_TYPE(__name, &inet_service_type, __struct, __member)
+
+/*
+ * AH
+ */
+
+#define AHHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct ip_auth_hdr, __member)
+
+const struct proto_desc proto_ah = {
+ .name = "ah",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .protocol_key = AHHDR_NEXTHDR,
+ .protocols = {
+ PROTO_LINK(IPPROTO_ESP, &proto_esp),
+ PROTO_LINK(IPPROTO_AH, &proto_ah),
+ PROTO_LINK(IPPROTO_COMP, &proto_comp),
+ PROTO_LINK(IPPROTO_UDP, &proto_udp),
+ PROTO_LINK(IPPROTO_UDPLITE, &proto_udplite),
+ PROTO_LINK(IPPROTO_TCP, &proto_tcp),
+ PROTO_LINK(IPPROTO_DCCP, &proto_dccp),
+ PROTO_LINK(IPPROTO_SCTP, &proto_sctp),
+ },
+ .templates = {
+ [AHHDR_NEXTHDR] = INET_PROTOCOL("nexthdr", struct ip_auth_hdr, nexthdr),
+ [AHHDR_HDRLENGTH] = AHHDR_FIELD("hdrlength", hdrlen),
+ [AHHDR_RESERVED] = AHHDR_FIELD("reserved", reserved),
+ [AHHDR_SPI] = AHHDR_FIELD("spi", spi),
+ [AHHDR_SEQUENCE] = AHHDR_FIELD("sequence", seq_no),
+ },
+};
+
+/*
+ * ESP
+ */
+
+#define ESPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct ip_esp_hdr, __member)
+
+const struct proto_desc proto_esp = {
+ .name = "esp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [ESPHDR_SPI] = ESPHDR_FIELD("spi", spi),
+ [ESPHDR_SEQUENCE] = ESPHDR_FIELD("sequence", seq_no),
+ },
+};
+
+/*
+ * IPCOMP
+ */
+
+#define COMPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct ip_comp_hdr, __member)
+
+const struct proto_desc proto_comp = {
+ .name = "comp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .protocol_key = COMPHDR_NEXTHDR,
+ .protocols = {
+ PROTO_LINK(IPPROTO_ESP, &proto_esp),
+ PROTO_LINK(IPPROTO_AH, &proto_ah),
+ PROTO_LINK(IPPROTO_COMP, &proto_comp),
+ PROTO_LINK(IPPROTO_UDP, &proto_udp),
+ PROTO_LINK(IPPROTO_UDPLITE, &proto_udplite),
+ PROTO_LINK(IPPROTO_TCP, &proto_tcp),
+ PROTO_LINK(IPPROTO_DCCP, &proto_dccp),
+ PROTO_LINK(IPPROTO_SCTP, &proto_sctp),
+ },
+ .templates = {
+ [COMPHDR_NEXTHDR] = INET_PROTOCOL("nexthdr", struct ip_comp_hdr, nexthdr),
+ [COMPHDR_FLAGS] = COMPHDR_FIELD("flags", flags),
+ [COMPHDR_CPI] = COMPHDR_FIELD("cpi", cpi),
+ },
+};
+
+/*
+ * ICMP
+ */
+
+#include <netinet/ip_icmp.h>
+
+static const struct symbol_table icmp_type_tbl = {
+ .symbols = {
+ SYMBOL("echo-reply", ICMP_ECHOREPLY),
+ SYMBOL("destination-unreachable", ICMP_DEST_UNREACH),
+ SYMBOL("source-quench", ICMP_SOURCE_QUENCH),
+ SYMBOL("redirect", ICMP_REDIRECT),
+ SYMBOL("echo-request", ICMP_ECHO),
+ SYMBOL("time-exceeded", ICMP_TIME_EXCEEDED),
+ SYMBOL("parameter-problem", ICMP_PARAMETERPROB),
+ SYMBOL("timestamp-request", ICMP_TIMESTAMP),
+ SYMBOL("timestamp-reply", ICMP_TIMESTAMPREPLY),
+ SYMBOL("info-request", ICMP_INFO_REQUEST),
+ SYMBOL("info-reply", ICMP_INFO_REPLY),
+ SYMBOL("address-mask-request", ICMP_ADDRESS),
+ SYMBOL("address-mask-reply", ICMP_ADDRESSREPLY),
+ SYMBOL_LIST_END
+ },
+};
+
+static const struct datatype icmp_type_type = {
+ .type = TYPE_ICMP_TYPE,
+ .name = "icmp_type",
+ .desc = "ICMP type",
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .size = BITS_PER_BYTE,
+ .basetype = &integer_type,
+ .sym_tbl = &icmp_type_tbl,
+};
+
+#define ICMPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct icmphdr, __member)
+#define ICMPHDR_TYPE(__name, __type, __member) \
+ HDR_TYPE(__name, __type, struct icmphdr, __member)
+
+const struct proto_desc proto_icmp = {
+ .name = "icmp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [ICMPHDR_TYPE] = ICMPHDR_TYPE("type", &icmp_type_type, type),
+ [ICMPHDR_CODE] = ICMPHDR_FIELD("code", code),
+ [ICMPHDR_CHECKSUM] = ICMPHDR_FIELD("checksum", checksum),
+ [ICMPHDR_ID] = ICMPHDR_FIELD("id", un.echo.id),
+ [ICMPHDR_SEQ] = ICMPHDR_FIELD("sequence", un.echo.sequence),
+ [ICMPHDR_GATEWAY] = ICMPHDR_FIELD("gateway", un.gateway),
+ [ICMPHDR_MTU] = ICMPHDR_FIELD("mtu", un.frag.mtu),
+ },
+};
+
+/*
+ * UDP/UDP-Lite
+ */
+
+#include <netinet/udp.h>
+#define UDPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct udphdr, __member)
+
+const struct proto_desc proto_udp = {
+ .name = "udp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
+ [UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
+ [UDPHDR_LENGTH] = UDPHDR_FIELD("length", len),
+ [UDPHDR_CHECKSUM] = UDPHDR_FIELD("checksum", check),
+ },
+};
+
+const struct proto_desc proto_udplite = {
+ .name = "udplite",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [UDPHDR_SPORT] = INET_SERVICE("sport", struct udphdr, source),
+ [UDPHDR_DPORT] = INET_SERVICE("dport", struct udphdr, dest),
+ [UDPHDR_CSUMCOV] = UDPHDR_FIELD("csumcov", len),
+ [UDPHDR_CHECKSUM] = UDPHDR_FIELD("checksum", check),
+ },
+};
+
+/*
+ * TCP
+ */
+
+#include <netinet/tcp.h>
+
+static const struct symbol_table tcp_flag_tbl = {
+ .symbols = {
+ SYMBOL("fin", TCP_FLAG_FIN),
+ SYMBOL("syn", TCP_FLAG_SYN),
+ SYMBOL("rst", TCP_FLAG_RST),
+ SYMBOL("psh", TCP_FLAG_PSH),
+ SYMBOL("ack", TCP_FLAG_ACK),
+ SYMBOL("urg", TCP_FLAG_URG),
+ SYMBOL("ecn", TCP_FLAG_ECN),
+ SYMBOL("cwr", TCP_FLAG_CWR),
+ SYMBOL_LIST_END
+ },
+};
+
+static const struct datatype tcp_flag_type = {
+ .type = TYPE_TCP_FLAG,
+ .name = "tcp_flag",
+ .desc = "TCP flag",
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .size = BITS_PER_BYTE,
+ .basetype = &bitmask_type,
+ .sym_tbl = &tcp_flag_tbl,
+};
+
+#define TCPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct tcphdr, __member)
+
+const struct proto_desc proto_tcp = {
+ .name = "tcp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [TCPHDR_SPORT] = INET_SERVICE("sport", struct tcphdr, source),
+ [TCPHDR_DPORT] = INET_SERVICE("dport", struct tcphdr, dest),
+ [TCPHDR_SEQ] = TCPHDR_FIELD("sequence", seq),
+ [TCPHDR_ACKSEQ] = TCPHDR_FIELD("ackseq", ack_seq),
+ [TCPHDR_DOFF] = {},
+ [TCPHDR_RESERVED] = {},
+ [TCPHDR_FLAGS] = HDR_BITFIELD("flags", &tcp_flag_type,
+ 13 * BITS_PER_BYTE,
+ BITS_PER_BYTE),
+ [TCPHDR_WINDOW] = TCPHDR_FIELD("window", window),
+ [TCPHDR_CHECKSUM] = TCPHDR_FIELD("checksum", check),
+ [TCPHDR_URGPTR] = TCPHDR_FIELD("urgptr", urg_ptr),
+ },
+};
+
+/*
+ * DCCP
+ */
+
+static const struct symbol_table dccp_pkttype_tbl = {
+ .symbols = {
+ SYMBOL("request", DCCP_PKT_REQUEST),
+ SYMBOL("response", DCCP_PKT_RESPONSE),
+ SYMBOL("data", DCCP_PKT_DATA),
+ SYMBOL("ack", DCCP_PKT_ACK),
+ SYMBOL("dataack", DCCP_PKT_DATAACK),
+ SYMBOL("closereq", DCCP_PKT_CLOSEREQ),
+ SYMBOL("close", DCCP_PKT_CLOSE),
+ SYMBOL("reset", DCCP_PKT_RESET),
+ SYMBOL("sync", DCCP_PKT_SYNC),
+ SYMBOL("syncack", DCCP_PKT_SYNCACK),
+ SYMBOL_LIST_END
+ },
+};
+
+static const struct datatype dccp_pkttype_type = {
+ .type = TYPE_DCCP_PKTTYPE,
+ .name = "dccp_pkttype",
+ .desc = "DCCP packet type",
+ .byteorder = BYTEORDER_INVALID,
+ .size = 4,
+ .basetype = &integer_type,
+ .sym_tbl = &dccp_pkttype_tbl,
+};
+
+
+#define DCCPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct dccp_hdr, __member)
+
+const struct proto_desc proto_dccp = {
+ .name = "dccp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [DCCPHDR_SPORT] = INET_SERVICE("sport", struct dccp_hdr, dccph_sport),
+ [DCCPHDR_DPORT] = INET_SERVICE("dport", struct dccp_hdr, dccph_dport),
+ [DCCPHDR_TYPE] = HDR_BITFIELD("type", &dccp_pkttype_type, 67, 4),
+ },
+};
+
+/*
+ * SCTP
+ */
+
+#define SCTPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct sctphdr, __member)
+
+const struct proto_desc proto_sctp = {
+ .name = "sctp",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [SCTPHDR_SPORT] = INET_SERVICE("sport", struct sctphdr, source),
+ [SCTPHDR_DPORT] = INET_SERVICE("dport", struct sctphdr, dest),
+ [SCTPHDR_VTAG] = SCTPHDR_FIELD("vtag", vtag),
+ [SCTPHDR_CHECKSUM] = SCTPHDR_FIELD("checksum", checksum),
+ },
+};
+
+/*
+ * IPv4
+ */
+
+#include <netinet/ip.h>
+#define IPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct iphdr, __member)
+#define IPHDR_ADDR(__name, __member) \
+ HDR_TYPE(__name, &ipaddr_type, struct iphdr, __member)
+
+const struct proto_desc proto_ip = {
+ .name = "ip",
+ .base = PROTO_BASE_NETWORK_HDR,
+ .protocol_key = IPHDR_PROTOCOL,
+ .protocols = {
+ PROTO_LINK(IPPROTO_ICMP, &proto_icmp),
+ PROTO_LINK(IPPROTO_ESP, &proto_esp),
+ PROTO_LINK(IPPROTO_AH, &proto_ah),
+ PROTO_LINK(IPPROTO_COMP, &proto_comp),
+ PROTO_LINK(IPPROTO_UDP, &proto_udp),
+ PROTO_LINK(IPPROTO_UDPLITE, &proto_udplite),
+ PROTO_LINK(IPPROTO_TCP, &proto_tcp),
+ PROTO_LINK(IPPROTO_DCCP, &proto_dccp),
+ PROTO_LINK(IPPROTO_SCTP, &proto_sctp),
+ },
+ .templates = {
+ [IPHDR_VERSION] = HDR_BITFIELD("version", &integer_type, 0, 4),
+ [IPHDR_HDRLENGTH] = HDR_BITFIELD("hdrlength", &integer_type, 4, 4),
+ [IPHDR_TOS] = IPHDR_FIELD("tos", tos),
+ [IPHDR_LENGTH] = IPHDR_FIELD("length", tot_len),
+ [IPHDR_ID] = IPHDR_FIELD("id", id),
+ [IPHDR_FRAG_OFF] = IPHDR_FIELD("frag-off", frag_off),
+ [IPHDR_TTL] = IPHDR_FIELD("ttl", ttl),
+ [IPHDR_PROTOCOL] = INET_PROTOCOL("protocol", struct iphdr, protocol),
+ [IPHDR_CHECKSUM] = IPHDR_FIELD("checksum", check),
+ [IPHDR_SADDR] = IPHDR_ADDR("saddr", saddr),
+ [IPHDR_DADDR] = IPHDR_ADDR("daddr", daddr),
+ },
+};
+
+/*
+ * ICMPv6
+ */
+
+#include <netinet/icmp6.h>
+
+static const struct symbol_table icmp6_type_tbl = {
+ .symbols = {
+ SYMBOL("destination-unreachable", ICMP6_DST_UNREACH),
+ SYMBOL("packet-too-big", ICMP6_PACKET_TOO_BIG),
+ SYMBOL("time-exceeded", ICMP6_TIME_EXCEEDED),
+ SYMBOL("param-problem", ICMP6_PARAM_PROB),
+ SYMBOL("echo-request", ICMP6_ECHO_REQUEST),
+ SYMBOL("echo-reply", ICMP6_ECHO_REPLY),
+ SYMBOL("mld-listener-query", MLD_LISTENER_QUERY),
+ SYMBOL("mld-listener-report", MLD_LISTENER_REPORT),
+ SYMBOL("mld-listener-reduction", MLD_LISTENER_REDUCTION),
+ SYMBOL("nd-router-solicit", ND_ROUTER_SOLICIT),
+ SYMBOL("nd-router-advert", ND_ROUTER_ADVERT),
+ SYMBOL("nd-neighbor-solicit", ND_NEIGHBOR_SOLICIT),
+ SYMBOL("nd-neighbor-advert", ND_NEIGHBOR_ADVERT),
+ SYMBOL("nd-redirect", ND_REDIRECT),
+ SYMBOL("router-renumbering", ICMP6_ROUTER_RENUMBERING),
+ SYMBOL_LIST_END
+ },
+};
+
+static const struct datatype icmp6_type_type = {
+ .type = TYPE_ICMP6_TYPE,
+ .name = "icmpv6_type",
+ .desc = "ICMPv6 type",
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .size = BITS_PER_BYTE,
+ .basetype = &integer_type,
+ .sym_tbl = &icmp6_type_tbl,
+};
+
+#define ICMP6HDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct icmp6_hdr, __member)
+#define ICMP6HDR_TYPE(__name, __type, __member) \
+ HDR_TYPE(__name, __type, struct icmp6_hdr, __member)
+
+const struct proto_desc proto_icmp6 = {
+ .name = "icmpv6",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .templates = {
+ [ICMP6HDR_TYPE] = ICMP6HDR_TYPE("type", &icmp6_type_type, icmp6_type),
+ [ICMP6HDR_CODE] = ICMP6HDR_FIELD("code", icmp6_code),
+ [ICMP6HDR_CHECKSUM] = ICMP6HDR_FIELD("checksum", icmp6_cksum),
+ [ICMP6HDR_PPTR] = ICMP6HDR_FIELD("parameter-problem", icmp6_pptr),
+ [ICMP6HDR_MTU] = ICMP6HDR_FIELD("packet-too-big", icmp6_mtu),
+ [ICMP6HDR_ID] = ICMP6HDR_FIELD("id", icmp6_id),
+ [ICMP6HDR_SEQ] = ICMP6HDR_FIELD("sequence", icmp6_seq),
+ [ICMP6HDR_MAXDELAY] = ICMP6HDR_FIELD("max-delay", icmp6_maxdelay),
+ },
+};
+
+/*
+ * IPv6
+ */
+
+#define IP6HDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct ipv6hdr, __member)
+#define IP6HDR_ADDR(__name, __member) \
+ HDR_TYPE(__name, &ip6addr_type, struct ipv6hdr, __member)
+#define IP6HDR_PROTOCOL(__name, __member) \
+ HDR_TYPE(__name, &inet_service_type, struct ipv6hdr, __member)
+
+const struct proto_desc proto_ip6 = {
+ .name = "ip6",
+ .base = PROTO_BASE_NETWORK_HDR,
+ .protocol_key = IP6HDR_NEXTHDR,
+ .protocols = {
+ PROTO_LINK(IPPROTO_ESP, &proto_esp),
+ PROTO_LINK(IPPROTO_AH, &proto_ah),
+ PROTO_LINK(IPPROTO_COMP, &proto_comp),
+ PROTO_LINK(IPPROTO_UDP, &proto_udp),
+ PROTO_LINK(IPPROTO_UDPLITE, &proto_udplite),
+ PROTO_LINK(IPPROTO_TCP, &proto_tcp),
+ PROTO_LINK(IPPROTO_DCCP, &proto_dccp),
+ PROTO_LINK(IPPROTO_SCTP, &proto_sctp),
+ PROTO_LINK(IPPROTO_ICMPV6, &proto_icmp6),
+ },
+ .templates = {
+ [IP6HDR_VERSION] = HDR_BITFIELD("version", &integer_type, 0, 4),
+ [IP6HDR_PRIORITY] = HDR_BITFIELD("priority", &integer_type, 4, 4),
+ [IP6HDR_FLOWLABEL] = IP6HDR_FIELD("flowlabel", flow_lbl),
+ [IP6HDR_LENGTH] = IP6HDR_FIELD("length", payload_len),
+ [IP6HDR_NEXTHDR] = INET_PROTOCOL("nexthdr", struct ipv6hdr, nexthdr),
+ [IP6HDR_HOPLIMIT] = IP6HDR_FIELD("hoplimit", hop_limit),
+ [IP6HDR_SADDR] = IP6HDR_ADDR("saddr", saddr),
+ [IP6HDR_DADDR] = IP6HDR_ADDR("daddr", daddr),
+ },
+};
+
+/*
+ * ARP
+ */
+
+#include <net/if_arp.h>
+
+static const struct symbol_table arpop_tbl = {
+ .symbols = {
+ SYMBOL("request", ARPOP_REQUEST),
+ SYMBOL("reply", ARPOP_REPLY),
+ SYMBOL("rrequest", ARPOP_RREQUEST),
+ SYMBOL("rreply", ARPOP_REPLY),
+ SYMBOL("inrequest", ARPOP_InREQUEST),
+ SYMBOL("inreply", ARPOP_InREPLY),
+ SYMBOL("nak", ARPOP_NAK),
+ SYMBOL_LIST_END
+ },
+};
+
+static const struct datatype arpop_type = {
+ .type = TYPE_ARPOP,
+ .name = "arp_op",
+ .desc = "ARP operation",
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .size = 2 * BITS_PER_BYTE,
+ .basetype = &integer_type,
+ .sym_tbl = &arpop_tbl,
+};
+
+#define ARPHDR_TYPE(__name, __type, __member) \
+ HDR_TYPE(__name, __type, struct arphdr, __member)
+#define ARPHDR_FIELD(__name, __member) \
+ HDR_FIELD(__name, struct arphdr, __member)
+
+const struct proto_desc proto_arp = {
+ .name = "arp",
+ .base = PROTO_BASE_NETWORK_HDR,
+ .templates = {
+ [ARPHDR_HRD] = ARPHDR_FIELD("htype", ar_hrd),
+ [ARPHDR_PRO] = ARPHDR_TYPE("ptype", ðertype_type, ar_pro),
+ [ARPHDR_HLN] = ARPHDR_FIELD("hlen", ar_hln),
+ [ARPHDR_PLN] = ARPHDR_FIELD("plen", ar_pln),
+ [ARPHDR_OP] = ARPHDR_TYPE("operation", &arpop_type, ar_op),
+ },
+};
+
+/*
+ * VLAN
+ */
+
+#include <net/ethernet.h>
+
+#define VLANHDR_BITFIELD(__name, __offset, __len) \
+ HDR_BITFIELD(__name, &integer_type, __offset, __len)
+#define VLANHDR_TYPE(__name, __type, __member) \
+ HDR_TYPE(__name, __type, struct vlan_hdr, __member)
+
+const struct proto_desc proto_vlan = {
+ .name = "vlan",
+ .base = PROTO_BASE_LL_HDR,
+ .protocol_key = VLANHDR_TYPE,
+ .protocols = {
+ PROTO_LINK(ETH_P_IP, &proto_ip),
+ PROTO_LINK(ETH_P_ARP, &proto_arp),
+ PROTO_LINK(ETH_P_IPV6, &proto_ip6),
+ PROTO_LINK(ETH_P_8021Q, &proto_vlan),
+
+ },
+ .templates = {
+ [VLANHDR_VID] = VLANHDR_BITFIELD("id", 0, 12),
+ [VLANHDR_CFI] = VLANHDR_BITFIELD("cfi", 12, 1),
+ [VLANHDR_PCP] = VLANHDR_BITFIELD("pcp", 13, 3),
+ [VLANHDR_TYPE] = VLANHDR_TYPE("type", ðertype_type, vlan_type),
+ },
+};
+
+/*
+ * Ethernet
+ */
+
+const struct datatype etheraddr_type = {
+ .type = TYPE_ETHERADDR,
+ .name = "etheraddr",
+ .desc = "Ethernet address",
+ .byteorder = BYTEORDER_HOST_ENDIAN,
+ .size = ETH_ALEN * BITS_PER_BYTE,
+ .basetype = &lladdr_type,
+};
+
+static const struct symbol_table ethertype_tbl = {
+ .symbols = {
+ SYMBOL("ip", ETH_P_IP),
+ SYMBOL("arp", ETH_P_ARP),
+ SYMBOL("ipv6", ETH_P_IPV6),
+ SYMBOL("vlan", ETH_P_8021Q),
+ SYMBOL_LIST_END
+ },
+};
+
+static struct error_record *ethertype_parse(const struct expr *sym,
+ struct expr **res)
+{
+ struct error_record *erec;
+
+ erec = sym->dtype->basetype->parse(sym, res);
+ if (erec != NULL)
+ return erec;
+ if (*res)
+ return NULL;
+ return symbolic_constant_parse(sym, ðertype_tbl, res);
+}
+
+static void ethertype_print(const struct expr *expr)
+{
+ return symbolic_constant_print(ðertype_tbl, expr);
+}
+
+const struct datatype ethertype_type = {
+ .type = TYPE_ETHERTYPE,
+ .name = "ethertype",
+ .desc = "Ethernet protocol",
+ .byteorder = BYTEORDER_BIG_ENDIAN,
+ .size = 2 * BITS_PER_BYTE,
+ .basetype = &integer_type,
+ .basefmt = "0x%.4Zx",
+ .print = ethertype_print,
+ .parse = ethertype_parse,
+};
+
+#define ETHHDR_TEMPLATE(__name, __dtype, __member) \
+ HDR_TEMPLATE(__name, __dtype, struct ether_header, __member)
+#define ETHHDR_TYPE(__name, __member) \
+ ETHHDR_TEMPLATE(__name, ðertype_type, __member)
+#define ETHHDR_ADDR(__name, __member) \
+ ETHHDR_TEMPLATE(__name, ðeraddr_type, __member)
+
+const struct proto_desc proto_eth = {
+ .name = "eth",
+ .base = PROTO_BASE_LL_HDR,
+ .protocol_key = ETHHDR_TYPE,
+ .protocols = {
+ PROTO_LINK(ETH_P_IP, &proto_ip),
+ PROTO_LINK(ETH_P_ARP, &proto_arp),
+ PROTO_LINK(ETH_P_IPV6, &proto_ip6),
+ PROTO_LINK(ETH_P_8021Q, &proto_vlan),
+ },
+ .templates = {
+ [ETHHDR_DADDR] = ETHHDR_ADDR("daddr", ether_dhost),
+ [ETHHDR_SADDR] = ETHHDR_ADDR("saddr", ether_shost),
+ [ETHHDR_TYPE] = ETHHDR_TYPE("type", ether_type),
+ },
+};
+
+static void __init proto_init(void)
+{
+ datatype_register(&icmp_type_type);
+ datatype_register(&tcp_flag_type);
+ datatype_register(&dccp_pkttype_type);
+ datatype_register(&arpop_type);
+ datatype_register(ðertype_type);
+ datatype_register(&icmp6_type_type);
+}
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 03/12] expr: add protocol context update callback
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
2014-01-08 13:08 ` [PATCH 01/12] expr: replace PAYLOAD_PROTOCOL_EXPR by generic flag Patrick McHardy
2014-01-08 13:08 ` [PATCH 02/12] nftables: generic procotol contexts Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 04/12] proto: add helper function to update protocol context Patrick McHardy
` (8 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add a callback function to the expression ops to update the protocol
context for relational protocol expressions (EXPR_F_PROTOCOL).
Also set the EXPR_F_PROTOCOL flag for IIFTYPE meta expressions to make
sure the callback is invoked when necessary.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/expression.h | 4 ++++
include/meta.h | 2 --
include/payload.h | 3 ---
src/evaluate.c | 18 +++++++----------
src/meta.c | 13 +++++++++++-
src/netlink_delinearize.c | 4 ++--
src/payload.c | 50 ++++++++++++++++++++++++-----------------------
7 files changed, 51 insertions(+), 43 deletions(-)
diff --git a/include/expression.h b/include/expression.h
index 2b7b379..59b27c0 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -118,7 +118,9 @@ static inline void expr_set_context(struct expr_ctx *ctx,
* @destroy: destructor, must release inner expressions
* @set_type: function to promote type and byteorder of inner types
* @print: function to print the expression
+ * @pctx_update:update protocol context
*/
+struct proto_ctx;
struct expr_ops {
enum expr_types type;
const char *name;
@@ -128,6 +130,8 @@ struct expr_ops {
const struct datatype *dtype,
enum byteorder byteorder);
void (*print)(const struct expr *expr);
+ void (*pctx_update)(struct proto_ctx *ctx,
+ const struct expr *expr);
};
/**
diff --git a/include/meta.h b/include/meta.h
index 23f78cf..459221f 100644
--- a/include/meta.h
+++ b/include/meta.h
@@ -25,7 +25,5 @@ struct meta_template {
extern struct expr *meta_expr_alloc(const struct location *loc,
enum nft_meta_keys key);
-extern void meta_expr_pctx_update(struct proto_ctx *ctx,
- const struct expr *expr);
#endif /* NFTABLES_META_H */
diff --git a/include/payload.h b/include/payload.h
index 54d8d54..d47e564 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -10,9 +10,6 @@ extern struct expr *payload_expr_alloc(const struct location *loc,
extern void payload_init_raw(struct expr *expr, enum proto_bases base,
unsigned int offset, unsigned int len);
-extern void payload_expr_pctx_update(struct proto_ctx *ctx,
- const struct expr *expr);
-
struct eval_ctx;
extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
struct expr **res);
diff --git a/src/evaluate.c b/src/evaluate.c
index 112fc94..3fe9da4 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -919,18 +919,14 @@ static int expr_evaluate_relational(struct eval_ctx *ctx, struct expr **expr)
* Update protocol context for payload and meta iiftype
* equality expressions.
*/
- switch (left->ops->type) {
- case EXPR_PAYLOAD:
- payload_expr_pctx_update(&ctx->pctx, rel);
- break;
- case EXPR_META:
- meta_expr_pctx_update(&ctx->pctx, rel);
- break;
- case EXPR_CONCAT:
+ if (left->flags & EXPR_F_PROTOCOL &&
+ left->ops->pctx_update)
+ left->ops->pctx_update(&ctx->pctx, rel);
+
+ if (left->ops->type == EXPR_CONCAT)
return 0;
- default:
- break;
- }
+
+ /* fall through */
case OP_NEQ:
case OP_FLAGCMP:
if (!datatype_equal(left->dtype, right->dtype))
diff --git a/src/meta.c b/src/meta.c
index 343f9a3..9173c30 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -349,7 +349,8 @@ static void meta_expr_clone(struct expr *new, const struct expr *expr)
*
* Update LL protocol context based on IIFTYPE meta match in non-LL hooks.
*/
-void meta_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
+static void meta_expr_pctx_update(struct proto_ctx *ctx,
+ const struct expr *expr)
{
const struct hook_proto_desc *h = &hook_proto_desc[ctx->family];
const struct expr *left = expr->left, *right = expr->right;
@@ -375,6 +376,7 @@ static const struct expr_ops meta_expr_ops = {
.name = "meta",
.print = meta_expr_print,
.clone = meta_expr_clone,
+ .pctx_update = meta_expr_pctx_update,
};
struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
@@ -385,6 +387,15 @@ struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
expr = expr_alloc(loc, &meta_expr_ops, tmpl->dtype,
tmpl->byteorder, tmpl->len);
expr->meta.key = key;
+
+ switch (key) {
+ case NFT_META_IIFTYPE:
+ expr->flags |= EXPR_F_PROTOCOL;
+ break;
+ default:
+ break;
+ }
+
return expr;
}
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 982377f..c02f133 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -612,7 +612,7 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
nexpr = relational_expr_alloc(&expr->location, expr->op,
left, tmp);
- payload_expr_pctx_update(&ctx->pctx, nexpr);
+ left->ops->pctx_update(&ctx->pctx, nexpr);
nstmt = expr_stmt_alloc(&stmt->location, nexpr);
list_add_tail(&nstmt->list, &stmt->list);
@@ -644,7 +644,7 @@ static void meta_match_postprocess(struct proto_ctx *ctx,
{
switch (expr->op) {
case OP_EQ:
- meta_expr_pctx_update(ctx, expr);
+ expr->left->ops->pctx_update(ctx, expr);
break;
default:
break;
diff --git a/src/payload.c b/src/payload.c
index 7721b75..426adc3 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -48,11 +48,37 @@ static void payload_expr_clone(struct expr *new, const struct expr *expr)
new->payload.offset = expr->payload.offset;
}
+/**
+ * payload_expr_pctx_update - update protocol context based on payload match
+ *
+ * @ctx: protocol context
+ * @expr: relational payload expression
+ *
+ * Update protocol context for relational payload expressions.
+ */
+static void payload_expr_pctx_update(struct proto_ctx *ctx,
+ const struct expr *expr)
+{
+ const struct expr *left = expr->left, *right = expr->right;
+ const struct proto_desc *base, *desc;
+
+ if (!(left->flags & EXPR_F_PROTOCOL))
+ return;
+
+ assert(expr->op == OP_EQ);
+ base = ctx->protocol[left->payload.base].desc;
+ desc = proto_find_upper(base, mpz_get_uint32(right->value));
+
+ ctx->protocol[left->payload.base + 1].location = expr->location;
+ ctx->protocol[left->payload.base + 1].desc = desc;
+}
+
static const struct expr_ops payload_expr_ops = {
.type = EXPR_PAYLOAD,
.name = "payload",
.print = payload_expr_print,
.clone = payload_expr_clone,
+ .pctx_update = payload_expr_pctx_update,
};
struct expr *payload_expr_alloc(const struct location *loc,
@@ -95,30 +121,6 @@ void payload_init_raw(struct expr *expr, enum proto_bases base,
}
/**
- * payload_expr_pctx_update - update protocol context based on payload match
- *
- * @ctx: protocol context
- * @expr: relational payload expression
- *
- * Update protocol context for relational payload expressions.
- */
-void payload_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
-{
- const struct expr *left = expr->left, *right = expr->right;
- const struct proto_desc *base, *desc;
-
- if (!(left->flags & EXPR_F_PROTOCOL))
- return;
-
- assert(expr->op == OP_EQ);
- base = ctx->protocol[left->payload.base].desc;
- desc = proto_find_upper(base, mpz_get_uint32(right->value));
-
- ctx->protocol[left->payload.base + 1].location = expr->location;
- ctx->protocol[left->payload.base + 1].desc = desc;
-}
-
-/**
* payload_gen_dependency - generate match expression on payload dependency
*
* @ctx: evaluation context
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 04/12] proto: add helper function to update protocol context
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (2 preceding siblings ...)
2014-01-08 13:08 ` [PATCH 03/12] expr: add protocol context update callback Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 05/12] proto: add debugging for protocol context updates Patrick McHardy
` (7 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add a helper function which is to be used to update the protocol update.
Signed-off-by: Patrick McHardy <ksber@trash.net<
---
include/proto.h | 3 +++
src/meta.c | 3 +--
src/payload.c | 3 +--
src/proto.c | 16 ++++++++++++++++
4 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/include/proto.h b/include/proto.h
index 037ef09..de58d4c 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -122,6 +122,9 @@ struct proto_ctx {
};
extern void proto_ctx_init(struct proto_ctx *ctx, unsigned int family);
+extern void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base,
+ const struct location *loc,
+ const struct proto_desc *desc);
extern const struct proto_desc *proto_find_upper(const struct proto_desc *base,
unsigned int num);
extern int proto_find_num(const struct proto_desc *base,
diff --git a/src/meta.c b/src/meta.c
index 9173c30..e0ae950 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -367,8 +367,7 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
if (desc == NULL)
desc = &proto_unknown;
- ctx->protocol[PROTO_BASE_LL_HDR].location = expr->location;
- ctx->protocol[PROTO_BASE_LL_HDR].desc = desc;
+ proto_ctx_update(ctx, PROTO_BASE_LL_HDR, &expr->location, desc);
}
static const struct expr_ops meta_expr_ops = {
diff --git a/src/payload.c b/src/payload.c
index 426adc3..0ef3c79 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -69,8 +69,7 @@ static void payload_expr_pctx_update(struct proto_ctx *ctx,
base = ctx->protocol[left->payload.base].desc;
desc = proto_find_upper(base, mpz_get_uint32(right->value));
- ctx->protocol[left->payload.base + 1].location = expr->location;
- ctx->protocol[left->payload.base + 1].desc = desc;
+ proto_ctx_update(ctx, left->payload.base + 1, &expr->location, desc);
}
static const struct expr_ops payload_expr_ops = {
diff --git a/src/proto.c b/src/proto.c
index c6428e4..f611c97 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -143,6 +143,22 @@ void proto_ctx_init(struct proto_ctx *ctx, unsigned int family)
ctx->protocol[h->base].desc = h->desc;
}
+/**
+ * proto_ctx_update: update protocol context for given protocol base
+ *
+ * @ctx: protocol context
+ * @base: protocol base
+ * @loc: location of the relational expression definiting the context
+ * @desc: protocol description for the given layer
+ */
+void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base,
+ const struct location *loc,
+ const struct proto_desc *desc)
+{
+ ctx->protocol[base].location = *loc;
+ ctx->protocol[base].desc = desc;
+}
+
#define HDR_TEMPLATE(__name, __dtype, __type, __member) \
PROTO_HDR_TEMPLATE(__name, __dtype, \
offsetof(__type, __member) * 8, \
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 05/12] proto: add debugging for protocol context updates
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (3 preceding siblings ...)
2014-01-08 13:08 ` [PATCH 04/12] proto: add helper function to update protocol context Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 06/12] ct expr: protocol context updates and dynamic typing Patrick McHardy
` (6 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add a new debugging level to debug updates to the protocol context.
Sample output:
<cmdline>:1:15-23: Evaluate
filter output tcp dport ssh
^^^^^^^^^
tcp
update transport layer protocol context:
link layer : none
network layer : ip
transport layer : tcp <-
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/nftables.h | 1 +
src/main.c | 6 +++++-
src/proto.c | 24 ++++++++++++++++++++++++
3 files changed, 30 insertions(+), 1 deletion(-)
diff --git a/include/nftables.h b/include/nftables.h
index 12f3c49..801000e 100644
--- a/include/nftables.h
+++ b/include/nftables.h
@@ -17,6 +17,7 @@ enum debug_level {
DEBUG_PARSER = 0x2,
DEBUG_EVALUATION = 0x4,
DEBUG_NETLINK = 0x8,
+ DEBUG_PROTO_CTX = 0x10,
};
#define INCLUDE_PATHS_MAX 16
diff --git a/src/main.c b/src/main.c
index 0c97120..859ddaa 100644
--- a/src/main.c
+++ b/src/main.c
@@ -111,7 +111,7 @@ static void show_help(const char *name)
" -a/--handle Output rule handle.\n"
" -I/--includepath <directory> Add <directory> to the paths searched for include files.\n"
#ifdef DEBUG
-" --debug <level [,level...]> Specify debugging level (scanner, parser, eval, netlink, all)\n"
+" --debug <level [,level...]> Specify debugging level (scanner, parser, eval, netlink, proto-ctx, all)\n"
#endif
"\n",
name);
@@ -139,6 +139,10 @@ static const struct {
.level = DEBUG_NETLINK,
},
{
+ .name = "proto-ctx",
+ .level = DEBUG_PROTO_CTX,
+ },
+ {
.name = "all",
.level = ~0,
},
diff --git a/src/proto.c b/src/proto.c
index f611c97..c3fb7bf 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -128,6 +128,26 @@ const struct hook_proto_desc hook_proto_desc[] = {
[NFPROTO_ARP] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_arp),
};
+static void proto_ctx_debug(const struct proto_ctx *ctx, enum proto_bases base)
+{
+#ifdef DEBUG
+ unsigned int i;
+
+ if (!(debug_level & DEBUG_PROTO_CTX))
+ return;
+
+ 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",
+ proto_base_names[i],
+ ctx->protocol[i].desc ? ctx->protocol[i].desc->name :
+ "none",
+ i == base ? " <-" : "");
+ }
+ pr_debug("\n");
+#endif
+}
+
/**
* proto_ctx_init - initialize protocol context for a given hook family
*
@@ -141,6 +161,8 @@ void proto_ctx_init(struct proto_ctx *ctx, unsigned int family)
memset(ctx, 0, sizeof(*ctx));
ctx->family = family;
ctx->protocol[h->base].desc = h->desc;
+
+ proto_ctx_debug(ctx, h->base);
}
/**
@@ -157,6 +179,8 @@ void proto_ctx_update(struct proto_ctx *ctx, enum proto_bases base,
{
ctx->protocol[base].location = *loc;
ctx->protocol[base].desc = desc;
+
+ proto_ctx_debug(ctx, base);
}
#define HDR_TEMPLATE(__name, __dtype, __type, __member) \
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 06/12] ct expr: protocol context updates and dynamic typing
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (4 preceding siblings ...)
2014-01-08 13:08 ` [PATCH 05/12] proto: add debugging for protocol context updates Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 07/12] include: resync nftables.h with kernel Patrick McHardy
` (5 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Include the protocols defined through relational ct expressions in the
protocol context and use the protocol context to dynamically determine
the types of network and transport layer ct expression types.
Before:
$ nft filter output ct proto-dst ssh
<cmdline>:1:28-30: Error: Can't parse symbolic invalid expressions
filter output ct proto-dst ssh
^^^
$ nft filter output ip protocol tcp ct proto-dst ssh
<cmdline>:1:44-46: Error: Can't parse symbolic invalid expressions
filter output ip protocol tcp ct proto-dst ssh
^^^
$ nft filter output ct protocol tcp ct proto-dst ssh
<cmdline>:1:44-46: Error: Can't parse symbolic invalid expressions
filter output ct protocol tcp ct proto-dst ssh
^^^
After:
$ nft filter output ct proto-dst ssh
<cmdline>:1:28-30: Error: Can't parse symbolic invalid expressions
filter output ct proto-dst ssh
^^^
$ nft filter output ip protocol tcp ct proto-dst ssh
$ nft filter output ct protocol tcp ct proto-dst ssh
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/ct.h | 1 +
src/ct.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/evaluate.c | 16 +++++++++++++++-
3 files changed, 74 insertions(+), 1 deletion(-)
diff --git a/include/ct.h b/include/ct.h
index 67718c8..64366ab 100644
--- a/include/ct.h
+++ b/include/ct.h
@@ -25,5 +25,6 @@ struct ct_template {
extern struct expr *ct_expr_alloc(const struct location *loc,
enum nft_ct_keys key);
+extern void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr);
#endif /* NFTABLES_CT_H */
diff --git a/src/ct.c b/src/ct.c
index e5ca593..b8f7632 100644
--- a/src/ct.c
+++ b/src/ct.c
@@ -23,6 +23,7 @@
#include <expression.h>
#include <datatype.h>
#include <ct.h>
+#include <gmputil.h>
#include <utils.h>
static const struct symbol_table ct_state_tbl = {
@@ -139,11 +140,32 @@ static void ct_expr_clone(struct expr *new, const struct expr *expr)
new->ct.key = expr->ct.key;
}
+static void ct_expr_pctx_update(struct proto_ctx *ctx, const struct expr *expr)
+{
+ const struct expr *left = expr->left, *right = expr->right;
+ const struct proto_desc *base, *desc;
+
+ assert(expr->op == OP_EQ);
+
+ switch (left->ct.key) {
+ case NFT_CT_PROTOCOL:
+ base = ctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
+ desc = proto_find_upper(base, mpz_get_uint32(right->value));
+
+ proto_ctx_update(ctx, PROTO_BASE_TRANSPORT_HDR,
+ &expr->location, desc);
+ break;
+ default:
+ break;
+ }
+}
+
static const struct expr_ops ct_expr_ops = {
.type = EXPR_CT,
.name = "ct",
.print = ct_expr_print,
.clone = ct_expr_clone,
+ .pctx_update = ct_expr_pctx_update,
};
struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key)
@@ -154,9 +176,45 @@ struct expr *ct_expr_alloc(const struct location *loc, enum nft_ct_keys key)
expr = expr_alloc(loc, &ct_expr_ops, tmpl->dtype,
tmpl->byteorder, tmpl->len);
expr->ct.key = key;
+
+ switch (key) {
+ case NFT_CT_PROTOCOL:
+ expr->flags = EXPR_F_PROTOCOL;
+ break;
+ default:
+ break;
+ }
+
return expr;
}
+void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr)
+{
+ const struct proto_desc *desc;
+
+ switch (expr->ct.key) {
+ case NFT_CT_SRC:
+ case NFT_CT_DST:
+ desc = ctx->protocol[PROTO_BASE_NETWORK_HDR].desc;
+ if (desc == &proto_ip)
+ expr->dtype = &ipaddr_type;
+ else if (desc == &proto_ip6)
+ expr->dtype = &ip6addr_type;
+
+ expr->len = expr->dtype->size;
+ break;
+ case NFT_CT_PROTO_SRC:
+ case NFT_CT_PROTO_DST:
+ desc = ctx->protocol[PROTO_BASE_TRANSPORT_HDR].desc;
+ if (desc == NULL)
+ break;
+ expr->dtype = &inet_service_type;
+ break;
+ default:
+ break;
+ }
+}
+
static void __init ct_init(void)
{
datatype_register(&ct_state_type);
diff --git a/src/evaluate.c b/src/evaluate.c
index 3fe9da4..257c67e 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -290,6 +290,19 @@ static int expr_evaluate_payload(struct eval_ctx *ctx, struct expr **expr)
}
/*
+ * CT expression: update the protocol dependant types bases on the protocol
+ * context.
+ */
+static int expr_evaluate_ct(struct eval_ctx *ctx, struct expr **expr)
+{
+ struct expr *ct = *expr;
+
+ ct_expr_update_type(&ctx->pctx, ct);
+
+ return expr_evaluate_primary(ctx, expr);
+}
+
+/*
* Prefix expression: the argument must be a constant value of integer base
* type; the prefix length must be less than or equal to the type width.
*/
@@ -1042,10 +1055,11 @@ static int expr_evaluate(struct eval_ctx *ctx, struct expr **expr)
case EXPR_VERDICT:
case EXPR_EXTHDR:
case EXPR_META:
- case EXPR_CT:
return expr_evaluate_primary(ctx, expr);
case EXPR_PAYLOAD:
return expr_evaluate_payload(ctx, expr);
+ case EXPR_CT:
+ return expr_evaluate_ct(ctx, expr);
case EXPR_PREFIX:
return expr_evaluate_prefix(ctx, expr);
case EXPR_RANGE:
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 07/12] include: resync nftables.h with kernel
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (5 preceding siblings ...)
2014-01-08 13:08 ` [PATCH 06/12] ct expr: protocol context updates and dynamic typing Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:08 ` [PATCH 08/12] nftables: add support for the "inet" family Patrick McHardy
` (4 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/linux/netfilter.h | 22 +++++--
include/linux/netfilter/nf_tables.h | 116 ++++++++++++++++++++++++++++++------
2 files changed, 115 insertions(+), 23 deletions(-)
diff --git a/include/linux/netfilter.h b/include/linux/netfilter.h
index 2eb00b6..be0bc18 100644
--- a/include/linux/netfilter.h
+++ b/include/linux/netfilter.h
@@ -3,6 +3,8 @@
#include <linux/types.h>
+#include <linux/sysctl.h>
+
/* Responses from hook functions. */
#define NF_DROP 0
@@ -14,14 +16,20 @@
#define NF_MAX_VERDICT NF_STOP
/* we overload the higher bits for encoding auxiliary data such as the queue
- * number. Not nice, but better than additional function arguments. */
-#define NF_VERDICT_MASK 0x0000ffff
-#define NF_VERDICT_BITS 16
+ * number or errno values. Not nice, but better than additional function
+ * arguments. */
+#define NF_VERDICT_MASK 0x000000ff
+
+/* extra verdict flags have mask 0x0000ff00 */
+#define NF_VERDICT_FLAG_QUEUE_BYPASS 0x00008000
+/* queue number (NF_QUEUE) or errno (NF_DROP) */
#define NF_VERDICT_QMASK 0xffff0000
#define NF_VERDICT_QBITS 16
-#define NF_QUEUE_NR(x) ((((x) << NF_VERDICT_BITS) & NF_VERDICT_QMASK) | NF_QUEUE)
+#define NF_QUEUE_NR(x) ((((x) << 16) & NF_VERDICT_QMASK) | NF_QUEUE)
+
+#define NF_DROP_ERR(x) (((-x) << 16) | NF_DROP)
/* only for userspace compatibility */
/* Generic cache responses from hook functions.
@@ -29,6 +37,9 @@
#define NFC_UNKNOWN 0x4000
#define NFC_ALTERED 0x8000
+/* NF_VERDICT_BITS should be 8 now, but userspace might break if this changes */
+#define NF_VERDICT_BITS 16
+
enum nf_inet_hooks {
NF_INET_PRE_ROUTING,
NF_INET_LOCAL_IN,
@@ -40,6 +51,7 @@ enum nf_inet_hooks {
enum {
NFPROTO_UNSPEC = 0,
+ NFPROTO_INET = 1,
NFPROTO_IPV4 = 2,
NFPROTO_ARP = 3,
NFPROTO_BRIDGE = 7,
@@ -56,4 +68,4 @@ union nf_inet_addr {
struct in6_addr in6;
};
-#endif /*__LINUX_NETFILTER_H*/
+#endif /* __LINUX_NETFILTER_H */
diff --git a/include/linux/netfilter/nf_tables.h b/include/linux/netfilter/nf_tables.h
index 1d5a925..448593c 100644
--- a/include/linux/netfilter/nf_tables.h
+++ b/include/linux/netfilter/nf_tables.h
@@ -32,6 +32,25 @@ enum nft_verdicts {
NFT_RETURN = -5,
};
+/**
+ * enum nf_tables_msg_types - nf_tables netlink message types
+ *
+ * @NFT_MSG_NEWTABLE: create a new table (enum nft_table_attributes)
+ * @NFT_MSG_GETTABLE: get a table (enum nft_table_attributes)
+ * @NFT_MSG_DELTABLE: delete a table (enum nft_table_attributes)
+ * @NFT_MSG_NEWCHAIN: create a new chain (enum nft_chain_attributes)
+ * @NFT_MSG_GETCHAIN: get a chain (enum nft_chain_attributes)
+ * @NFT_MSG_DELCHAIN: delete a chain (enum nft_chain_attributes)
+ * @NFT_MSG_NEWRULE: create a new rule (enum nft_rule_attributes)
+ * @NFT_MSG_GETRULE: get a rule (enum nft_rule_attributes)
+ * @NFT_MSG_DELRULE: delete a rule (enum nft_rule_attributes)
+ * @NFT_MSG_NEWSET: create a new set (enum nft_set_attributes)
+ * @NFT_MSG_GETSET: get a set (enum nft_set_attributes)
+ * @NFT_MSG_DELSET: delete a set (enum nft_set_attributes)
+ * @NFT_MSG_NEWSETELEM: create a new set element (enum nft_set_elem_attributes)
+ * @NFT_MSG_GETSETELEM: get a set element (enum nft_set_elem_attributes)
+ * @NFT_MSG_DELSETELEM: delete a set element (enum nft_set_elem_attributes)
+ */
enum nf_tables_msg_types {
NFT_MSG_NEWTABLE,
NFT_MSG_GETTABLE,
@@ -48,8 +67,6 @@ enum nf_tables_msg_types {
NFT_MSG_NEWSETELEM,
NFT_MSG_GETSETELEM,
NFT_MSG_DELSETELEM,
- NFT_MSG_COMMIT,
- NFT_MSG_ABORT,
NFT_MSG_MAX,
};
@@ -92,11 +109,14 @@ enum nft_table_flags {
* enum nft_table_attributes - nf_tables table netlink attributes
*
* @NFTA_TABLE_NAME: name of the table (NLA_STRING)
+ * @NFTA_TABLE_FLAGS: bitmask of enum nft_table_flags (NLA_U32)
+ * @NFTA_TABLE_USE: number of chains in this table (NLA_U32)
*/
enum nft_table_attributes {
NFTA_TABLE_UNSPEC,
NFTA_TABLE_NAME,
NFTA_TABLE_FLAGS,
+ NFTA_TABLE_USE,
__NFTA_TABLE_MAX
};
#define NFTA_TABLE_MAX (__NFTA_TABLE_MAX - 1)
@@ -105,8 +125,13 @@ enum nft_table_attributes {
* enum nft_chain_attributes - nf_tables chain netlink attributes
*
* @NFTA_CHAIN_TABLE: name of the table containing the chain (NLA_STRING)
+ * @NFTA_CHAIN_HANDLE: numeric handle of the chain (NLA_U64)
* @NFTA_CHAIN_NAME: name of the chain (NLA_STRING)
* @NFTA_CHAIN_HOOK: hook specification for basechains (NLA_NESTED: nft_hook_attributes)
+ * @NFTA_CHAIN_POLICY: numeric policy of the chain (NLA_U32)
+ * @NFTA_CHAIN_USE: number of references to this chain (NLA_U32)
+ * @NFTA_CHAIN_TYPE: type name of the string (NLA_NUL_STRING)
+ * @NFTA_CHAIN_COUNTERS: counter specification of the chain (NLA_NESTED: nft_counter_attributes)
*/
enum nft_chain_attributes {
NFTA_CHAIN_UNSPEC,
@@ -122,18 +147,15 @@ enum nft_chain_attributes {
};
#define NFTA_CHAIN_MAX (__NFTA_CHAIN_MAX - 1)
-enum {
- NFT_RULE_F_COMMIT = (1 << 0),
- NFT_RULE_F_MASK = NFT_RULE_F_COMMIT,
-};
-
/**
* enum nft_rule_attributes - nf_tables rule netlink attributes
*
* @NFTA_RULE_TABLE: name of the table containing the rule (NLA_STRING)
* @NFTA_RULE_CHAIN: name of the chain containing the rule (NLA_STRING)
- * @NFTA_RULE_HANDLE: numeric handle of the rule (NLA_U16)
+ * @NFTA_RULE_HANDLE: numeric handle of the rule (NLA_U64)
* @NFTA_RULE_EXPRESSIONS: list of expressions (NLA_NESTED: nft_expr_attributes)
+ * @NFTA_RULE_COMPAT: compatibility specifications of the rule (NLA_NESTED: nft_rule_compat_attributes)
+ * @NFTA_RULE_POSITION: numeric handle of the previous rule (NLA_U64)
*/
enum nft_rule_attributes {
NFTA_RULE_UNSPEC,
@@ -141,17 +163,28 @@ enum nft_rule_attributes {
NFTA_RULE_CHAIN,
NFTA_RULE_HANDLE,
NFTA_RULE_EXPRESSIONS,
- NFTA_RULE_FLAGS,
NFTA_RULE_COMPAT,
+ NFTA_RULE_POSITION,
__NFTA_RULE_MAX
};
#define NFTA_RULE_MAX (__NFTA_RULE_MAX - 1)
+/**
+ * enum nft_rule_compat_flags - nf_tables rule compat flags
+ *
+ * @NFT_RULE_COMPAT_F_INV: invert the check result
+ */
enum nft_rule_compat_flags {
NFT_RULE_COMPAT_F_INV = (1 << 1),
NFT_RULE_COMPAT_F_MASK = NFT_RULE_COMPAT_F_INV,
};
+/**
+ * enum nft_rule_compat_attributes - nf_tables rule compat attributes
+ *
+ * @NFTA_RULE_COMPAT_PROTO: numerice value of handled protocol (NLA_U32)
+ * @NFTA_RULE_COMPAT_FLAGS: bitmask of enum nft_rule_compat_flags (NLA_U32)
+ */
enum nft_rule_compat_attributes {
NFTA_RULE_COMPAT_UNSPEC,
NFTA_RULE_COMPAT_PROTO,
@@ -349,11 +382,26 @@ enum nft_bitwise_attributes {
};
#define NFTA_BITWISE_MAX (__NFTA_BITWISE_MAX - 1)
+/**
+ * enum nft_byteorder_ops - nf_tables byteorder operators
+ *
+ * @NFT_BYTEORDER_NTOH: network to host operator
+ * @NFT_BYTEORDER_HTON: host to network opertaor
+ */
enum nft_byteorder_ops {
NFT_BYTEORDER_NTOH,
NFT_BYTEORDER_HTON,
};
+/**
+ * enum nft_byteorder_attributes - nf_tables byteorder expression netlink attributes
+ *
+ * @NFTA_BYTEORDER_SREG: source register (NLA_U32: nft_registers)
+ * @NFTA_BYTEORDER_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_BYTEORDER_OP: operator (NLA_U32: enum nft_byteorder_ops)
+ * @NFTA_BYTEORDER_LEN: length of the data (NLA_U32)
+ * @NFTA_BYTEORDER_SIZE: data size in bytes (NLA_U32: 2 or 4)
+ */
enum nft_byteorder_attributes {
NFTA_BYTEORDER_UNSPEC,
NFTA_BYTEORDER_SREG,
@@ -365,6 +413,16 @@ enum nft_byteorder_attributes {
};
#define NFTA_BYTEORDER_MAX (__NFTA_BYTEORDER_MAX - 1)
+/**
+ * enum nft_cmp_ops - nf_tables relational operator
+ *
+ * @NFT_CMP_EQ: equal
+ * @NFT_CMP_NEQ: not equal
+ * @NFT_CMP_LT: less than
+ * @NFT_CMP_LTE: less than or equal to
+ * @NFT_CMP_GT: greater than
+ * @NFT_CMP_GTE: greater than or equal to
+ */
enum nft_cmp_ops {
NFT_CMP_EQ,
NFT_CMP_NEQ,
@@ -390,6 +448,13 @@ enum nft_cmp_attributes {
};
#define NFTA_CMP_MAX (__NFTA_CMP_MAX - 1)
+/**
+ * enum nft_lookup_attributes - nf_tables set lookup expression netlink attributes
+ *
+ * @NFTA_LOOKUP_SET: name of the set where to look for (NLA_STRING)
+ * @NFTA_LOOKUP_SREG: source register of the data to look for (NLA_U32: nft_registers)
+ * @NFTA_LOOKUP_DREG: destination register (NLA_U32: nft_registers)
+ */
enum nft_lookup_attributes {
NFTA_LOOKUP_UNSPEC,
NFTA_LOOKUP_SET,
@@ -430,6 +495,14 @@ enum nft_payload_attributes {
};
#define NFTA_PAYLOAD_MAX (__NFTA_PAYLOAD_MAX - 1)
+/**
+ * enum nft_exthdr_attributes - nf_tables IPv6 extension header expression netlink attributes
+ *
+ * @NFTA_EXTHDR_DREG: destination register (NLA_U32: nft_registers)
+ * @NFTA_EXTHDR_TYPE: extension header type (NLA_U8)
+ * @NFTA_EXTHDR_OFFSET: extension header offset (NLA_U32)
+ * @NFTA_EXTHDR_LEN: extension header length (NLA_U32)
+ */
enum nft_exthdr_attributes {
NFTA_EXTHDR_UNSPEC,
NFTA_EXTHDR_DREG,
@@ -458,6 +531,8 @@ enum nft_exthdr_attributes {
* @NFT_META_NFTRACE: packet nftrace bit
* @NFT_META_RTCLASSID: realm value of packet's route (skb->dst->tclassid)
* @NFT_META_SECMARK: packet secmark (skb->secmark)
+ * @NFT_META_NFPROTO: netfilter protocol
+ * @NFT_META_L4PROTO: layer 4 protocol number
*/
enum nft_meta_keys {
NFT_META_LEN,
@@ -475,6 +550,8 @@ enum nft_meta_keys {
NFT_META_NFTRACE,
NFT_META_RTCLASSID,
NFT_META_SECMARK,
+ NFT_META_NFPROTO,
+ NFT_META_L4PROTO,
};
/**
@@ -482,11 +559,13 @@ enum nft_meta_keys {
*
* @NFTA_META_DREG: destination register (NLA_U32)
* @NFTA_META_KEY: meta data item to load (NLA_U32: nft_meta_keys)
+ * @NFTA_META_SREG: source register (NLA_U32)
*/
enum nft_meta_attributes {
NFTA_META_UNSPEC,
NFTA_META_DREG,
NFTA_META_KEY,
+ NFTA_META_SREG,
__NFTA_META_MAX
};
#define NFTA_META_MAX (__NFTA_META_MAX - 1)
@@ -544,12 +623,12 @@ enum nft_ct_attributes {
* enum nft_limit_attributes - nf_tables limit expression netlink attributes
*
* @NFTA_LIMIT_RATE: refill rate (NLA_U64)
- * @NFTA_LIMIT_DEPTH: bucket depth (NLA_U64)
+ * @NFTA_LIMIT_UNIT: refill unit (NLA_U64)
*/
enum nft_limit_attributes {
NFTA_LIMIT_UNSPEC,
NFTA_LIMIT_RATE,
- NFTA_LIMIT_DEPTH,
+ NFTA_LIMIT_UNIT,
__NFTA_LIMIT_MAX
};
#define NFTA_LIMIT_MAX (__NFTA_LIMIT_MAX - 1)
@@ -589,9 +668,9 @@ enum nft_log_attributes {
/**
* enum nft_queue_attributes - nf_tables queue expression netlink attributes
*
- * @NFTA_QUEUE_NUM: netlink group to send messages to (NLA_U32)
- * @NFTA_QUEUE_TOTAL: prefix to prepend to log messages (NLA_STRING)
- * @NFTA_QUEUE_FLAGS: length of payload to include in netlink message (NLA_U32)
+ * @NFTA_QUEUE_NUM: netlink queue to send messages to (NLA_U16)
+ * @NFTA_QUEUE_TOTAL: number of queues to load balance packets on (NLA_U16)
+ * @NFTA_QUEUE_FLAGS: various flags (NLA_U16)
*/
enum nft_queue_attributes {
NFTA_QUEUE_UNSPEC,
@@ -646,10 +725,11 @@ enum nft_nat_types {
* enum nft_nat_attributes - nf_tables nat expression netlink attributes
*
* @NFTA_NAT_TYPE: NAT type (NLA_U32: nft_nat_types)
- * @NFTA_NAT_ADDR_MIN: source register of address range start (NLA_U32: nft_registers)
- * @NFTA_NAT_ADDR_MAX: source register of address range end (NLA_U32: nft_registers)
- * @NFTA_NAT_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
- * @NFTA_NAT_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
+ * @NFTA_NAT_FAMILY: NAT family (NLA_U32)
+ * @NFTA_NAT_REG_ADDR_MIN: source register of address range start (NLA_U32: nft_registers)
+ * @NFTA_NAT_REG_ADDR_MAX: source register of address range end (NLA_U32: nft_registers)
+ * @NFTA_NAT_REG_PROTO_MIN: source register of proto range start (NLA_U32: nft_registers)
+ * @NFTA_NAT_REG_PROTO_MAX: source register of proto range end (NLA_U32: nft_registers)
*/
enum nft_nat_attributes {
NFTA_NAT_UNSPEC,
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 08/12] nftables: add support for the "inet" family
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (6 preceding siblings ...)
2014-01-08 13:08 ` [PATCH 07/12] include: resync nftables.h with kernel Patrick McHardy
@ 2014-01-08 13:08 ` Patrick McHardy
2014-01-08 13:09 ` [PATCH 09/12] netlink_delinearize: remove implied meta expressions Patrick McHardy
` (3 subsequent siblings)
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:08 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add support for the mixed IPv4/IPv6 "inet" family. This mainly consist
of adding the "inet" <-> NFPROTO_INET mapping in the parser and netlink
support functions.
Additionally add the definitions for the inet filter table.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
src/evaluate.c | 1 +
src/parser.y | 3 +++
src/rule.c | 3 +++
src/scanner.l | 2 ++
4 files changed, 9 insertions(+)
diff --git a/src/evaluate.c b/src/evaluate.c
index 257c67e..4ca3294 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -1273,6 +1273,7 @@ static uint32_t str2hooknum(uint32_t family, const char *hook)
case NFPROTO_IPV4:
case NFPROTO_BRIDGE:
case NFPROTO_IPV6:
+ case NFPROTO_INET:
/* These families have overlapping values for each hook */
if (!strcmp(hook, "prerouting"))
return NF_INET_PRE_ROUTING;
diff --git a/src/parser.y b/src/parser.y
index 7778d50..1907333 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -166,6 +166,8 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token MAP "map"
%token HANDLE "handle"
+%token INET "inet"
+
%token ADD "add"
%token INSERT "insert"
%token DELETE "delete"
@@ -827,6 +829,7 @@ string : STRING
family_spec : /* empty */ { $$ = NFPROTO_IPV4; }
| IP { $$ = NFPROTO_IPV4; }
| IP6 { $$ = NFPROTO_IPV6; }
+ | INET { $$ = NFPROTO_INET; }
| ARP { $$ = NFPROTO_ARP; }
| BRIDGE { $$ = NFPROTO_BRIDGE; }
;
diff --git a/src/rule.c b/src/rule.c
index ec8b6a4..a16c2de 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -276,6 +276,8 @@ static const char *family2str(unsigned int family)
return "ip";
case NFPROTO_IPV6:
return "ip6";
+ case NFPROTO_INET:
+ return "inet";
case NFPROTO_ARP:
return "arp";
case NFPROTO_BRIDGE:
@@ -292,6 +294,7 @@ static const char *hooknum2str(unsigned int family, unsigned int hooknum)
case NFPROTO_IPV4:
case NFPROTO_BRIDGE:
case NFPROTO_IPV6:
+ case NFPROTO_INET:
switch (hooknum) {
case NF_INET_PRE_ROUTING:
return "prerouting";
diff --git a/src/scanner.l b/src/scanner.l
index 8c4f25d..f075f82 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -235,6 +235,8 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"goto" { return GOTO; }
"return" { return RETURN; }
+"inet" { return INET; }
+
"add" { return ADD; }
"insert" { return INSERT; }
"delete" { return DELETE; }
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 09/12] netlink_delinearize: remove implied meta expressions
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (7 preceding siblings ...)
2014-01-08 13:08 ` [PATCH 08/12] nftables: add support for the "inet" family Patrick McHardy
@ 2014-01-08 13:09 ` Patrick McHardy
2014-01-09 21:48 ` Arturo Borrero Gonzalez
2014-01-08 13:09 ` [PATCH 10/12] proto: add support for meta templates Patrick McHardy
` (2 subsequent siblings)
11 siblings, 1 reply; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:09 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/expression.h | 1 +
src/netlink_delinearize.c | 29 +++++++++++++++++++++++------
2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/include/expression.h b/include/expression.h
index 59b27c0..a9aa328 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -242,6 +242,7 @@ struct expr {
struct {
/* EXPR_META */
enum nft_meta_keys key;
+ enum proto_bases base;
} meta;
struct {
/* EXPR_CT */
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index c02f133..5a6cbfa 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -588,10 +588,19 @@ static void payload_dependency_kill(struct rule_pp_ctx *ctx, struct expr *expr)
ctx->pdep != NULL) {
list_del(&ctx->pdep->list);
stmt_free(ctx->pdep);
+ ctx->pbase = PROTO_BASE_INVALID;
ctx->pdep = NULL;
}
}
+static void payload_dependency_store(struct rule_pp_ctx *ctx,
+ struct stmt *stmt,
+ enum proto_bases base)
+{
+ ctx->pbase = base;
+ ctx->pdep = stmt;
+}
+
static void payload_match_postprocess(struct rule_pp_ctx *ctx,
struct stmt *stmt, struct expr *expr)
{
@@ -622,10 +631,10 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
* payload expression.
*/
if (ctx->pbase == PROTO_BASE_INVALID &&
- left->flags & EXPR_F_PROTOCOL) {
- ctx->pbase = left->payload.base;
- ctx->pdep = nstmt;
- } else
+ left->flags & EXPR_F_PROTOCOL)
+ payload_dependency_store(ctx, nstmt,
+ left->payload.base);
+ else
payload_dependency_kill(ctx, nexpr->left);
}
list_del(&stmt->list);
@@ -635,16 +644,24 @@ static void payload_match_postprocess(struct rule_pp_ctx *ctx,
payload_expr_complete(left, &ctx->pctx);
expr_set_type(expr->right, expr->left->dtype,
expr->left->byteorder);
+ payload_dependency_kill(ctx, expr->left);
break;
}
}
-static void meta_match_postprocess(struct proto_ctx *ctx,
+static void meta_match_postprocess(struct rule_pp_ctx *ctx,
+ struct stmt *stmt,
const struct expr *expr)
{
+ struct expr *left = expr->left;
+
switch (expr->op) {
case OP_EQ:
expr->left->ops->pctx_update(ctx, expr);
+
+ if (ctx->pbase == PROTO_BASE_INVALID &&
+ left->flags & EXPR_F_PROTOCOL)
+ payload_dependency_store(ctx, stmt, left->meta.base);
break;
default:
break;
@@ -765,7 +782,7 @@ static void expr_postprocess(struct rule_pp_ctx *ctx,
switch (expr->left->ops->type) {
case EXPR_META:
- meta_match_postprocess(&ctx->pctx, expr);
+ meta_match_postprocess(ctx, stmt, expr);
break;
case EXPR_BINOP:
relational_binop_postprocess(expr);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 10/12] proto: add support for meta templates
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (8 preceding siblings ...)
2014-01-08 13:09 ` [PATCH 09/12] netlink_delinearize: remove implied meta expressions Patrick McHardy
@ 2014-01-08 13:09 ` Patrick McHardy
2014-01-08 13:09 ` [PATCH 11/12] meta: add nfproto support Patrick McHardy
2014-01-08 13:09 ` [PATCH 12/12] meta: add l4proto support Patrick McHardy
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:09 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
The following two patches will add two new meta expression types that are
used as dependencies in the inet table. To reuse the existing dependency
generation code, add a slightly hackish way to specify meta expressions
as payload dependencies.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/proto.h | 11 +++++++++++
src/payload.c | 6 +++++-
2 files changed, 16 insertions(+), 1 deletion(-)
diff --git a/include/proto.h b/include/proto.h
index de58d4c..6a28036 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -2,6 +2,7 @@
#define NFTABLES_PROTO_H
#include <nftables.h>
+#include <linux/netfilter/nf_tables.h>
/**
* enum proto_bases - protocol bases
@@ -30,12 +31,14 @@ extern const char *proto_base_tokens[];
* @dtype: data type of the header field
* @offset: offset of the header field from base
* @len: length of header field
+ * @meta_key: special case: meta expression key
*/
struct proto_hdr_template {
const char *token;
const struct datatype *dtype;
uint16_t offset;
uint16_t len;
+ enum nft_meta_keys meta_key;
};
#define PROTO_HDR_TEMPLATE(__token, __dtype, __offset, __len) \
@@ -46,6 +49,14 @@ struct proto_hdr_template {
.len = (__len), \
}
+#define PROTO_META_TEMPLATE(__token, __dtype, __key, __len) \
+ { \
+ .token = (__token), \
+ .dtype = (__dtype), \
+ .meta_key = (__key), \
+ .len = (__len), \
+ }
+
#define PROTO_UPPER_MAX 16
#define PROTO_HDRS_MAX 20
diff --git a/src/payload.c b/src/payload.c
index 0ef3c79..04a3455 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -187,7 +187,11 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
desc->name, expr->payload.desc->name);
tmpl = &desc->templates[desc->protocol_key];
- left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
+ if (tmpl->meta_key)
+ left = meta_expr_alloc(&expr->location, tmpl->meta_key);
+ else
+ left = payload_expr_alloc(&expr->location, desc, desc->protocol_key);
+
right = constant_expr_alloc(&expr->location, tmpl->dtype,
BYTEORDER_HOST_ENDIAN,
tmpl->len, &protocol);
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 11/12] meta: add nfproto support
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (9 preceding siblings ...)
2014-01-08 13:09 ` [PATCH 10/12] proto: add support for meta templates Patrick McHardy
@ 2014-01-08 13:09 ` Patrick McHardy
2014-01-08 13:09 ` [PATCH 12/12] meta: add l4proto support Patrick McHardy
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:09 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add support for the meta nfproto type, which refers to the AF from the
netfilter hook ops. This is needed to get the actual family of a packet
in the dummy NFPROTO_INET family.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/datatype.h | 3 +++
include/proto.h | 2 ++
src/datatype.c | 18 ++++++++++++++++++
src/meta.c | 35 ++++++++++++++++++++++++++---------
src/parser.y | 2 ++
src/payload.c | 2 +-
src/proto.c | 18 ++++++++++++++++++
src/scanner.l | 1 +
8 files changed, 71 insertions(+), 10 deletions(-)
diff --git a/include/datatype.h b/include/datatype.h
index 239d5ea..9f8b44a 100644
--- a/include/datatype.h
+++ b/include/datatype.h
@@ -6,6 +6,7 @@
*
* @TYPE_INVALID: uninitialized
* @TYPE_VERDICT: nftables verdict
+ * @TYPE_NFPROTO: netfilter protocol (integer subtype)
* @TYPE_BITMASK: bitmask
* @TYPE_INTEGER: integer
* @TYPE_STRING: string
@@ -37,6 +38,7 @@
enum datatypes {
TYPE_INVALID,
TYPE_VERDICT,
+ TYPE_NFPROTO,
TYPE_BITMASK,
TYPE_INTEGER,
TYPE_STRING,
@@ -168,6 +170,7 @@ extern void rt_symbol_table_free(struct symbol_table *tbl);
extern const struct datatype invalid_type;
extern const struct datatype verdict_type;
+extern const struct datatype nfproto_type;
extern const struct datatype bitmask_type;
extern const struct datatype integer_type;
extern const struct datatype string_type;
diff --git a/include/proto.h b/include/proto.h
index 6a28036..772f9ed 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -290,6 +290,8 @@ extern const struct proto_desc proto_icmp6;
extern const struct proto_desc proto_ip;
extern const struct proto_desc proto_ip6;
+extern const struct proto_desc proto_inet;
+
extern const struct proto_desc proto_arp;
extern const struct proto_desc proto_vlan;
diff --git a/src/datatype.c b/src/datatype.c
index 2e5788d..fdcec8d 100644
--- a/src/datatype.c
+++ b/src/datatype.c
@@ -26,6 +26,7 @@
static const struct datatype *datatypes[TYPE_MAX + 1] = {
[TYPE_INVALID] = &invalid_type,
[TYPE_VERDICT] = &verdict_type,
+ [TYPE_NFPROTO] = &nfproto_type,
[TYPE_BITMASK] = &bitmask_type,
[TYPE_INTEGER] = &integer_type,
[TYPE_STRING] = &string_type,
@@ -204,6 +205,23 @@ const struct datatype verdict_type = {
.print = verdict_type_print,
};
+static const struct symbol_table nfproto_tbl = {
+ .symbols = {
+ SYMBOL("ipv4", NFPROTO_IPV4),
+ SYMBOL("ipv6", NFPROTO_IPV6),
+ SYMBOL_LIST_END
+ },
+};
+
+const struct datatype nfproto_type = {
+ .type = TYPE_NFPROTO,
+ .name = "nfproto",
+ .desc = "netfilter protocol",
+ .size = 1 * BITS_PER_BYTE,
+ .basetype = &integer_type,
+ .sym_tbl = &nfproto_tbl,
+};
+
const struct datatype bitmask_type = {
.type = TYPE_BITMASK,
.name = "bitmask",
diff --git a/src/meta.c b/src/meta.c
index e0ae950..1286569 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -301,6 +301,8 @@ static const struct meta_template meta_templates[] = {
4 * 8, BYTEORDER_HOST_ENDIAN),
[NFT_META_PROTOCOL] = META_TEMPLATE("protocol", ðertype_type,
2 * 8, BYTEORDER_BIG_ENDIAN),
+ [NFT_META_NFPROTO] = META_TEMPLATE("nfproto", &nfproto_type,
+ 1 * 8, BYTEORDER_HOST_ENDIAN),
[NFT_META_PRIORITY] = META_TEMPLATE("priority", &tchandle_type,
4 * 8, BYTEORDER_HOST_ENDIAN),
[NFT_META_MARK] = META_TEMPLATE("mark", &mark_type,
@@ -356,18 +358,29 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
const struct expr *left = expr->left, *right = expr->right;
const struct proto_desc *desc;
- if (left->meta.key != NFT_META_IIFTYPE)
- return;
-
assert(expr->op == OP_EQ);
- if (h->base < PROTO_BASE_NETWORK_HDR)
- return;
- desc = proto_dev_desc(mpz_get_uint16(right->value));
- if (desc == NULL)
- desc = &proto_unknown;
+ switch (left->meta.key) {
+ case NFT_META_IIFTYPE:
+ if (h->base < PROTO_BASE_NETWORK_HDR)
+ return;
+
+ desc = proto_dev_desc(mpz_get_uint16(right->value));
+ if (desc == NULL)
+ desc = &proto_unknown;
+
+ proto_ctx_update(ctx, PROTO_BASE_LL_HDR, &expr->location, desc);
+ break;
+ case NFT_META_NFPROTO:
+ desc = proto_find_upper(h->desc, mpz_get_uint8(right->value));
+ if (desc == NULL)
+ desc = &proto_unknown;
- proto_ctx_update(ctx, PROTO_BASE_LL_HDR, &expr->location, desc);
+ proto_ctx_update(ctx, PROTO_BASE_NETWORK_HDR, &expr->location, desc);
+ break;
+ default:
+ break;
+ }
}
static const struct expr_ops meta_expr_ops = {
@@ -391,6 +404,10 @@ struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
case NFT_META_IIFTYPE:
expr->flags |= EXPR_F_PROTOCOL;
break;
+ case NFT_META_NFPROTO:
+ expr->flags |= EXPR_F_PROTOCOL;
+ expr->meta.base = PROTO_BASE_LL_HDR;
+ break;
default:
break;
}
diff --git a/src/parser.y b/src/parser.y
index 1907333..aed00c7 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -281,6 +281,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token MH "mh"
%token META "meta"
+%token NFPROTO "nfproto"
%token MARK "mark"
%token IIF "iif"
%token IIFNAME "iifname"
@@ -1376,6 +1377,7 @@ meta_expr : META meta_key
;
meta_key : LENGTH { $$ = NFT_META_LEN; }
+ | NFPROTO { $$ = NFT_META_NFPROTO; }
| PROTOCOL { $$ = NFT_META_PROTOCOL; }
| PRIORITY { $$ = NFT_META_PRIORITY; }
| MARK { $$ = NFT_META_MARK; }
diff --git a/src/payload.c b/src/payload.c
index 04a3455..ac441d4 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -197,7 +197,7 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
tmpl->len, &protocol);
dep = relational_expr_alloc(&expr->location, OP_EQ, left, right);
- payload_expr_pctx_update(&ctx->pctx, dep);
+ left->ops->pctx_update(&ctx->pctx, dep);
*res = dep;
return 0;
}
diff --git a/src/proto.c b/src/proto.c
index c3fb7bf..81fe6cf 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -123,6 +123,7 @@ const struct proto_desc *proto_dev_desc(uint16_t type)
const struct hook_proto_desc hook_proto_desc[] = {
[NFPROTO_BRIDGE] = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR, &proto_eth),
+ [NFPROTO_INET] = HOOK_PROTO_DESC(PROTO_BASE_LL_HDR, &proto_inet),
[NFPROTO_IPV4] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip),
[NFPROTO_IPV6] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_ip6),
[NFPROTO_ARP] = HOOK_PROTO_DESC(PROTO_BASE_NETWORK_HDR, &proto_arp),
@@ -608,6 +609,23 @@ const struct proto_desc proto_ip6 = {
};
/*
+ * Dummy protocol for mixed IPv4/IPv6 tables. The protocol is set at the link
+ * layer header, the upper layer protocols are IPv4 and IPv6.
+ */
+
+const struct proto_desc proto_inet = {
+ .name = "inet",
+ .base = PROTO_BASE_LL_HDR,
+ .protocols = {
+ PROTO_LINK(NFPROTO_IPV4, &proto_ip),
+ PROTO_LINK(NFPROTO_IPV6, &proto_ip6),
+ },
+ .templates = {
+ [0] = PROTO_META_TEMPLATE("nfproto", &nfproto_type, NFT_META_NFPROTO, 8),
+ },
+};
+
+/*
* ARP
*/
diff --git a/src/scanner.l b/src/scanner.l
index f075f82..9541eb0 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -371,6 +371,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"mh" { return MH; }
"meta" { return META; }
+"nfproto" { return NFPROTO; }
"mark" { return MARK; }
"iif" { return IIF; }
"iifname" { return IIFNAME; }
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* [PATCH 12/12] meta: add l4proto support
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
` (10 preceding siblings ...)
2014-01-08 13:09 ` [PATCH 11/12] meta: add nfproto support Patrick McHardy
@ 2014-01-08 13:09 ` Patrick McHardy
11 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-08 13:09 UTC (permalink / raw)
To: pablo; +Cc: netfilter-devel
Add support for the meta l4proto type. This is used in the inet table to
match on the transport layer protocol without requiring the network layer
protocol to be known, allowing to use transport header matches that apply
to both IPv4 and IPv6.
Signed-off-by: Patrick McHardy <kaber@trash.net>
---
include/proto.h | 1 +
src/meta.c | 14 ++++++++++++++
src/parser.y | 2 ++
src/payload.c | 6 ++++++
src/proto.c | 25 +++++++++++++++++++++++++
src/scanner.l | 1 +
6 files changed, 49 insertions(+)
diff --git a/include/proto.h b/include/proto.h
index 772f9ed..bd3701e 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -291,6 +291,7 @@ extern const struct proto_desc proto_ip;
extern const struct proto_desc proto_ip6;
extern const struct proto_desc proto_inet;
+extern const struct proto_desc proto_inet_service;
extern const struct proto_desc proto_arp;
diff --git a/src/meta.c b/src/meta.c
index 1286569..d7b024b 100644
--- a/src/meta.c
+++ b/src/meta.c
@@ -303,6 +303,8 @@ static const struct meta_template meta_templates[] = {
2 * 8, BYTEORDER_BIG_ENDIAN),
[NFT_META_NFPROTO] = META_TEMPLATE("nfproto", &nfproto_type,
1 * 8, BYTEORDER_HOST_ENDIAN),
+ [NFT_META_L4PROTO] = META_TEMPLATE("l4proto", &inet_protocol_type,
+ 1 * 8, BYTEORDER_HOST_ENDIAN),
[NFT_META_PRIORITY] = META_TEMPLATE("priority", &tchandle_type,
4 * 8, BYTEORDER_HOST_ENDIAN),
[NFT_META_MARK] = META_TEMPLATE("mark", &mark_type,
@@ -378,6 +380,14 @@ static void meta_expr_pctx_update(struct proto_ctx *ctx,
proto_ctx_update(ctx, PROTO_BASE_NETWORK_HDR, &expr->location, desc);
break;
+ case NFT_META_L4PROTO:
+ desc = proto_find_upper(&proto_inet_service,
+ mpz_get_uint8(right->value));
+ if (desc == NULL)
+ desc = &proto_unknown;
+
+ proto_ctx_update(ctx, PROTO_BASE_TRANSPORT_HDR, &expr->location, desc);
+ break;
default:
break;
}
@@ -408,6 +418,10 @@ struct expr *meta_expr_alloc(const struct location *loc, enum nft_meta_keys key)
expr->flags |= EXPR_F_PROTOCOL;
expr->meta.base = PROTO_BASE_LL_HDR;
break;
+ case NFT_META_L4PROTO:
+ expr->flags |= EXPR_F_PROTOCOL;
+ expr->meta.base = PROTO_BASE_NETWORK_HDR;
+ break;
default:
break;
}
diff --git a/src/parser.y b/src/parser.y
index aed00c7..7c18875 100644
--- a/src/parser.y
+++ b/src/parser.y
@@ -282,6 +282,7 @@ static void location_update(struct location *loc, struct location *rhs, int n)
%token META "meta"
%token NFPROTO "nfproto"
+%token L4PROTO "l4proto"
%token MARK "mark"
%token IIF "iif"
%token IIFNAME "iifname"
@@ -1378,6 +1379,7 @@ meta_expr : META meta_key
meta_key : LENGTH { $$ = NFT_META_LEN; }
| NFPROTO { $$ = NFT_META_NFPROTO; }
+ | L4PROTO { $$ = NFT_META_L4PROTO; }
| PROTOCOL { $$ = NFT_META_PROTOCOL; }
| PRIORITY { $$ = NFT_META_PRIORITY; }
| MARK { $$ = NFT_META_MARK; }
diff --git a/src/payload.c b/src/payload.c
index ac441d4..a312e07 100644
--- a/src/payload.c
+++ b/src/payload.c
@@ -174,6 +174,12 @@ int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
}
desc = ctx->pctx.protocol[expr->payload.base - 1].desc;
+ /* Special case for mixed IPv4/IPv6 tables: use meta L4 proto */
+ if (desc == NULL &&
+ ctx->pctx.family == NFPROTO_INET &&
+ expr->payload.base == PROTO_BASE_TRANSPORT_HDR)
+ desc = &proto_inet_service;
+
if (desc == NULL)
return expr_error(ctx, expr,
"ambiguous payload specification: "
diff --git a/src/proto.c b/src/proto.c
index 81fe6cf..56fb793 100644
--- a/src/proto.c
+++ b/src/proto.c
@@ -626,6 +626,31 @@ const struct proto_desc proto_inet = {
};
/*
+ * Dummy protocol for cases where the network layer protocol isn't known
+ * (IPv4 or IPv6), The higher layer protocols are the protocols common to
+ * both.
+ */
+
+const struct proto_desc proto_inet_service = {
+ .name = "inet-service",
+ .base = PROTO_BASE_TRANSPORT_HDR,
+ .protocol_key = 0,
+ .protocols = {
+ PROTO_LINK(IPPROTO_ESP, &proto_esp),
+ PROTO_LINK(IPPROTO_AH, &proto_ah),
+ PROTO_LINK(IPPROTO_COMP, &proto_comp),
+ PROTO_LINK(IPPROTO_UDP, &proto_udp),
+ PROTO_LINK(IPPROTO_UDPLITE, &proto_udplite),
+ PROTO_LINK(IPPROTO_TCP, &proto_tcp),
+ PROTO_LINK(IPPROTO_DCCP, &proto_dccp),
+ PROTO_LINK(IPPROTO_SCTP, &proto_sctp),
+ },
+ .templates = {
+ [0] = PROTO_META_TEMPLATE("l4proto", &inet_protocol_type, NFT_META_L4PROTO, 8),
+ },
+};
+
+/*
* ARP
*/
diff --git a/src/scanner.l b/src/scanner.l
index 9541eb0..0b8abac 100644
--- a/src/scanner.l
+++ b/src/scanner.l
@@ -372,6 +372,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr})
"meta" { return META; }
"nfproto" { return NFPROTO; }
+"l4proto" { return L4PROTO; }
"mark" { return MARK; }
"iif" { return IIF; }
"iifname" { return IIFNAME; }
--
1.8.4.2
^ permalink raw reply related [flat|nested] 16+ messages in thread
* Re: [PATCH 09/12] netlink_delinearize: remove implied meta expressions
2014-01-08 13:09 ` [PATCH 09/12] netlink_delinearize: remove implied meta expressions Patrick McHardy
@ 2014-01-09 21:48 ` Arturo Borrero Gonzalez
2014-01-09 22:01 ` Patrick McHardy
0 siblings, 1 reply; 16+ messages in thread
From: Arturo Borrero Gonzalez @ 2014-01-09 21:48 UTC (permalink / raw)
To: Patrick McHardy; +Cc: Pablo Neira Ayuso, Netfilter Development Mailing list
On 8 January 2014 14:09, Patrick McHardy <kaber@trash.net> wrote:
>
> -static void meta_match_postprocess(struct proto_ctx *ctx,
> +static void meta_match_postprocess(struct rule_pp_ctx *ctx,
> + struct stmt *stmt,
> const struct expr *expr)
Hi Patrick,
I noticed something. When compiling here, I get:
$ make clean && make -j8
[...]
src/netlink_delinearize.c: In function ‘meta_match_postprocess’:
src/netlink_delinearize.c:660:3: warning: passing argument 1 of
‘expr-><U 390>.<Ua8e8>.left->ops->pctx_update’ from incompatible
pointer type [enabled by default]
src/netlink_delinearize.c:660:3: note: expected ‘struct proto_ctx *’
but argument is of type ‘struct rule_pp_ctx *’
[...]
The last commit I have in my local tree is:
* 01cd6fa (HEAD, origin/next-3.14, next-3.14) Merge remote-tracking
branch 'origin/master' into next-3.14
regards
--
Arturo Borrero González
--
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 [flat|nested] 16+ messages in thread
* Re: [PATCH 09/12] netlink_delinearize: remove implied meta expressions
2014-01-09 21:48 ` Arturo Borrero Gonzalez
@ 2014-01-09 22:01 ` Patrick McHardy
0 siblings, 0 replies; 16+ messages in thread
From: Patrick McHardy @ 2014-01-09 22:01 UTC (permalink / raw)
To: Arturo Borrero Gonzalez
Cc: Pablo Neira Ayuso, Netfilter Development Mailing list
On Thu, Jan 09, 2014 at 10:48:41PM +0100, Arturo Borrero Gonzalez wrote:
> On 8 January 2014 14:09, Patrick McHardy <kaber@trash.net> wrote:
> >
> > -static void meta_match_postprocess(struct proto_ctx *ctx,
> > +static void meta_match_postprocess(struct rule_pp_ctx *ctx,
> > + struct stmt *stmt,
> > const struct expr *expr)
>
> Hi Patrick,
>
> I noticed something. When compiling here, I get:
>
> $ make clean && make -j8
> [...]
> src/netlink_delinearize.c: In function ‘meta_match_postprocess’:
> src/netlink_delinearize.c:660:3: warning: passing argument 1 of
> ‘expr-><U 390>.<Ua8e8>.left->ops->pctx_update’ from incompatible
> pointer type [enabled by default]
> src/netlink_delinearize.c:660:3: note: expected ‘struct proto_ctx *’
> but argument is of type ‘struct rule_pp_ctx *’
> [...]
>
> The last commit I have in my local tree is:
>
> * 01cd6fa (HEAD, origin/next-3.14, next-3.14) Merge remote-tracking
> branch 'origin/master' into next-3.14
Thanks, for some reason gcc didn't warn me about this. I just pushed
this patch to fix this:
commit 488196551e5e34af3df5d92358f3efa5a08f5730
Author: Patrick McHardy <kaber@trash.net>
Date: Thu Jan 9 21:59:29 2014 +0000
netlink_delinearize: fix compiler warning
src/netlink_delinearize.c: In function ‘meta_match_postprocess’:
src/netlink_delinearize.c:660:3: warning: passing argument 1 of ‘expr->left->ops->pctx_update’ from incompatible pointer type [enabled by default]
src/netlink_delinearize.c:660:3: note: expected ‘struct proto_ctx *’ but argument is of type ‘struct rule_pp_ctx *’
Signed-off-by: Patrick McHardy <kaber@trash.net>
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 5a6cbfa..8f6ee38 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -657,7 +657,7 @@ static void meta_match_postprocess(struct rule_pp_ctx *ctx,
switch (expr->op) {
case OP_EQ:
- expr->left->ops->pctx_update(ctx, expr);
+ expr->left->ops->pctx_update(&ctx->pctx, expr);
if (ctx->pbase == PROTO_BASE_INVALID &&
left->flags & EXPR_F_PROTOCOL)
--
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] 16+ messages in thread
end of thread, other threads:[~2014-01-09 22:01 UTC | newest]
Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-01-08 13:08 [PATCH 00/12] nftables: generic protocol contexts, "inet" family Patrick McHardy
2014-01-08 13:08 ` [PATCH 01/12] expr: replace PAYLOAD_PROTOCOL_EXPR by generic flag Patrick McHardy
2014-01-08 13:08 ` [PATCH 02/12] nftables: generic procotol contexts Patrick McHardy
2014-01-08 13:08 ` [PATCH 03/12] expr: add protocol context update callback Patrick McHardy
2014-01-08 13:08 ` [PATCH 04/12] proto: add helper function to update protocol context Patrick McHardy
2014-01-08 13:08 ` [PATCH 05/12] proto: add debugging for protocol context updates Patrick McHardy
2014-01-08 13:08 ` [PATCH 06/12] ct expr: protocol context updates and dynamic typing Patrick McHardy
2014-01-08 13:08 ` [PATCH 07/12] include: resync nftables.h with kernel Patrick McHardy
2014-01-08 13:08 ` [PATCH 08/12] nftables: add support for the "inet" family Patrick McHardy
2014-01-08 13:09 ` [PATCH 09/12] netlink_delinearize: remove implied meta expressions Patrick McHardy
2014-01-09 21:48 ` Arturo Borrero Gonzalez
2014-01-09 22:01 ` Patrick McHardy
2014-01-08 13:09 ` [PATCH 10/12] proto: add support for meta templates Patrick McHardy
2014-01-08 13:09 ` [PATCH 11/12] meta: add nfproto support Patrick McHardy
2014-01-08 13:09 ` [PATCH 12/12] meta: add l4proto support Patrick McHardy
-- strict thread matches above, loose matches on Subject: below --
2014-01-06 17:27 [RFC PATCH 00/12] nftables: generic protocol contexts, "inet" family support Patrick McHardy
2014-01-06 17:27 ` [PATCH 08/12] nftables: add support for the "inet" family 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).