summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
Diffstat (limited to 'include')
-rw-r--r--include/ct.h1
-rw-r--r--include/datatype.h3
-rw-r--r--include/expression.h18
-rw-r--r--include/exthdr.h6
-rw-r--r--include/linux/netfilter.h22
-rw-r--r--include/linux/netfilter/nf_tables.h130
-rw-r--r--include/nftables.h1
-rw-r--r--include/payload.h288
-rw-r--r--include/proto.h304
-rw-r--r--include/rule.h2
-rw-r--r--include/statement.h11
11 files changed, 474 insertions, 312 deletions
diff --git a/include/ct.h b/include/ct.h
index 67718c84..64366ab7 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/include/datatype.h b/include/datatype.h
index 239d5ea5..9f8b44ae 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/expression.h b/include/expression.h
index f0eb7993..a9aa328e 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);
};
/**
@@ -135,12 +139,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>
@@ -223,20 +229,20 @@ 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;
- unsigned int flags;
} payload;
struct {
/* EXPR_EXTHDR */
const struct exthdr_desc *desc;
- const struct payload_template *tmpl;
+ const struct proto_hdr_template *tmpl;
} exthdr;
struct {
/* EXPR_META */
enum nft_meta_keys key;
+ enum proto_bases base;
} meta;
struct {
/* EXPR_CT */
diff --git a/include/exthdr.h b/include/exthdr.h
index 62e69bd2..87c42857 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/linux/netfilter.h b/include/linux/netfilter.h
index 2eb00b6c..be0bc182 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 a236cc31..448593c0 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)
@@ -587,6 +666,26 @@ enum nft_log_attributes {
#define NFTA_LOG_MAX (__NFTA_LOG_MAX - 1)
/**
+ * enum nft_queue_attributes - nf_tables queue expression netlink attributes
+ *
+ * @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,
+ NFTA_QUEUE_NUM,
+ NFTA_QUEUE_TOTAL,
+ NFTA_QUEUE_FLAGS,
+ __NFTA_QUEUE_MAX
+};
+#define NFTA_QUEUE_MAX (__NFTA_QUEUE_MAX - 1)
+
+#define NFT_QUEUE_FLAG_BYPASS 0x01 /* for compatibility with v2 */
+#define NFT_QUEUE_FLAG_CPU_FANOUT 0x02 /* use current CPU (no hashing) */
+#define NFT_QUEUE_FLAG_MASK 0x03
+
+/**
* enum nft_reject_types - nf_tables reject expression reject types
*
* @NFT_REJECT_ICMP_UNREACH: reject using ICMP unreachable
@@ -626,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,
diff --git a/include/nftables.h b/include/nftables.h
index 12f3c492..801000e1 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/include/payload.h b/include/payload.h
index c9cc84f3..d47e5645 100644
--- a/include/payload.h
+++ b/include/payload.h
@@ -2,138 +2,14 @@
#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)
-
-/**
- * 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
- * @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);
-
struct eval_ctx;
extern int payload_gen_dependency(struct eval_ctx *ctx, const struct expr *expr,
struct expr **res);
@@ -143,162 +19,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 00000000..bd3701e3
--- /dev/null
+++ b/include/proto.h
@@ -0,0 +1,304 @@
+#ifndef NFTABLES_PROTO_H
+#define NFTABLES_PROTO_H
+
+#include <nftables.h>
+#include <linux/netfilter/nf_tables.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
+ * @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) \
+ { \
+ .token = (__token), \
+ .dtype = (__dtype), \
+ .offset = (__offset), \
+ .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
+
+/**
+ * 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 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,
+ 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_inet;
+extern const struct proto_desc proto_inet_service;
+
+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 6ad8af3b..2a7b7980 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/include/statement.h b/include/statement.h
index 6ecbb18d..14a66df6 100644
--- a/include/statement.h
+++ b/include/statement.h
@@ -59,6 +59,14 @@ struct nat_stmt {
extern struct stmt *nat_stmt_alloc(const struct location *loc);
+struct queue_stmt {
+ uint16_t queuenum;
+ uint16_t queues_total;
+ uint16_t flags;
+};
+
+extern struct stmt *queue_stmt_alloc(const struct location *loc);
+
/**
* enum stmt_types - statement types
*
@@ -71,6 +79,7 @@ extern struct stmt *nat_stmt_alloc(const struct location *loc);
* @STMT_LOG: log statement
* @STMT_REJECT: REJECT statement
* @STMT_NAT: NAT statement
+ * @STMT_QUEUE: QUEUE statement
*/
enum stmt_types {
STMT_INVALID,
@@ -82,6 +91,7 @@ enum stmt_types {
STMT_LOG,
STMT_REJECT,
STMT_NAT,
+ STMT_QUEUE,
};
/**
@@ -127,6 +137,7 @@ struct stmt {
struct limit_stmt limit;
struct reject_stmt reject;
struct nat_stmt nat;
+ struct queue_stmt queue;
};
};