path: root/include
diff options
authorFlorian Westphal <>2015-07-05 20:27:28 +0200
committerFlorian Westphal <>2015-09-18 00:05:02 +0200
commit7ead4932f9ab00fdb8a2cc339b41ee2f5aee441e (patch)
tree93a488d6905ed9ec9c21646a139dcf373c7756a1 /include
parentc02107ef4e0fa49e5e57bfc8fb4e2b83654e8c68 (diff)
nft: allow stacking vlan header on top of ethernet
currently 'vlan id 42' or even 'vlan type ip' doesn't work since we expect ethernet header but get vlan. So if we want to add another protocol header to the same base, we attempt to figure out if the new header can fit on top of the existing one (i.e. proto_find_num gives a protocol number when asking to find link between the two). We also annotate protocol description for eth and vlan with the full header size and track the offset from the current base. Otherwise, 'vlan type ip' fetches the protocol field from mac header offset 0, which is some mac address. Instead, we must consider full size of ethernet header. Signed-off-by: Florian Westphal <>
Diffstat (limited to 'include')
1 files changed, 4 insertions, 0 deletions
diff --git a/include/proto.h b/include/proto.h
index 0e531b24..a43bf98b 100644
--- a/include/proto.h
+++ b/include/proto.h
@@ -69,6 +69,7 @@ struct proto_hdr_template {
* @name: protocol name
* @base: header base
* @protocol_key: key of template containing upper layer protocol description
+ * @length: total size of the header, in bits
* @protocols: link to upper layer protocol descriptions indexed by protocol value
* @templates: header templates
@@ -76,6 +77,7 @@ struct proto_desc {
const char *name;
enum proto_bases base;
unsigned int protocol_key;
+ unsigned int length;
struct {
unsigned int num;
const struct proto_desc *desc;
@@ -122,6 +124,7 @@ extern const struct proto_desc *proto_dev_desc(uint16_t type);
* @family: hook family
* @location: location of the relational expression defining the context
* @desc: protocol description for this layer
+ * @offset: offset from the base, for stacked headers (eg 8*14 for vlan on top of ether)
* The location of the context is the location of the relational expression
* defining it, either directly through a protocol match or indirectly
@@ -132,6 +135,7 @@ struct proto_ctx {
struct {
struct location location;
const struct proto_desc *desc;
+ unsigned int offset;
} protocol[PROTO_BASE_MAX + 1];