summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/expression.h1
-rw-r--r--include/exthdr.h2
-rw-r--r--include/tcpopt.h3
-rw-r--r--src/exthdr.c11
-rw-r--r--src/netlink_delinearize.c5
-rw-r--r--src/netlink_linearize.c1
-rw-r--r--src/tcpopt.c5
7 files changed, 18 insertions, 10 deletions
diff --git a/include/expression.h b/include/expression.h
index 4f2948cc..423eae71 100644
--- a/include/expression.h
+++ b/include/expression.h
@@ -282,6 +282,7 @@ struct expr {
const struct proto_hdr_template *tmpl;
unsigned int offset;
enum nft_exthdr_op op;
+ unsigned int flags;
} exthdr;
struct {
/* EXPR_META */
diff --git a/include/exthdr.h b/include/exthdr.h
index cdcc2b95..c7f806eb 100644
--- a/include/exthdr.h
+++ b/include/exthdr.h
@@ -23,7 +23,7 @@ extern struct expr *exthdr_expr_alloc(const struct location *loc,
extern void exthdr_init_raw(struct expr *expr, uint8_t type,
unsigned int offset, unsigned int len,
- enum nft_exthdr_op op);
+ enum nft_exthdr_op op, uint32_t flags);
extern bool exthdr_find_template(struct expr *expr, const struct expr *mask,
unsigned int *shift);
diff --git a/include/tcpopt.h b/include/tcpopt.h
index f43a7eb7..412d02e7 100644
--- a/include/tcpopt.h
+++ b/include/tcpopt.h
@@ -8,7 +8,8 @@ extern struct expr *tcpopt_expr_alloc(const struct location *loc,
uint8_t type, uint8_t field);
extern void tcpopt_init_raw(struct expr *expr, uint8_t type,
- unsigned int offset, unsigned int len);
+ unsigned int offset, unsigned int len,
+ uint32_t flags);
extern bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
unsigned int *shift);
diff --git a/src/exthdr.c b/src/exthdr.c
index ddda1b87..21fe734f 100644
--- a/src/exthdr.c
+++ b/src/exthdr.c
@@ -46,7 +46,8 @@ static bool exthdr_expr_cmp(const struct expr *e1, const struct expr *e2)
{
return e1->exthdr.desc == e2->exthdr.desc &&
e1->exthdr.tmpl == e2->exthdr.tmpl &&
- e1->exthdr.op == e2->exthdr.op;
+ e1->exthdr.op == e2->exthdr.op &&
+ e1->exthdr.flags == e2->exthdr.flags;
}
static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
@@ -55,6 +56,7 @@ static void exthdr_expr_clone(struct expr *new, const struct expr *expr)
new->exthdr.tmpl = expr->exthdr.tmpl;
new->exthdr.offset = expr->exthdr.offset;
new->exthdr.op = expr->exthdr.op;
+ new->exthdr.flags = expr->exthdr.flags;
}
const struct expr_ops exthdr_expr_ops = {
@@ -97,16 +99,17 @@ 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,
- enum nft_exthdr_op op)
+ enum nft_exthdr_op op, uint32_t flags)
{
const struct proto_hdr_template *tmpl;
unsigned int i;
assert(expr->ops->type == EXPR_EXTHDR);
if (op == NFT_EXTHDR_OP_TCPOPT)
- return tcpopt_init_raw(expr, type, offset, len);
+ return tcpopt_init_raw(expr, type, offset, len, flags);
expr->len = len;
+ expr->exthdr.flags = flags;
expr->exthdr.offset = offset;
expr->exthdr.desc = exthdr_protocols[type];
assert(expr->exthdr.desc != NULL);
@@ -149,7 +152,7 @@ bool exthdr_find_template(struct expr *expr, const struct expr *mask, unsigned i
off += round_up(mask->len, BITS_PER_BYTE) - mask_len;
exthdr_init_raw(expr, expr->exthdr.desc->type,
- off, mask_len - mask_offset, NFT_EXTHDR_OP_IPV6);
+ off, mask_len - mask_offset, NFT_EXTHDR_OP_IPV6, 0);
/* still failed to find a template... Bug. */
if (expr->exthdr.tmpl == &exthdr_unknown_template)
diff --git a/src/netlink_delinearize.c b/src/netlink_delinearize.c
index 36e8fe3c..9ad1e2c6 100644
--- a/src/netlink_delinearize.c
+++ b/src/netlink_delinearize.c
@@ -498,9 +498,9 @@ static void netlink_parse_exthdr(struct netlink_parse_ctx *ctx,
const struct location *loc,
const struct nftnl_expr *nle)
{
+ uint32_t offset, len, flags;
enum nft_registers dreg;
enum nft_exthdr_op op;
- uint32_t offset, len;
uint8_t type;
struct expr *expr;
@@ -508,9 +508,10 @@ static void netlink_parse_exthdr(struct netlink_parse_ctx *ctx,
offset = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_OFFSET) * BITS_PER_BYTE;
len = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_LEN) * BITS_PER_BYTE;
op = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_OP);
+ flags = nftnl_expr_get_u32(nle, NFTNL_EXPR_EXTHDR_FLAGS);
expr = exthdr_expr_alloc(loc, NULL, 0);
- exthdr_init_raw(expr, type, offset, len, op);
+ exthdr_init_raw(expr, type, offset, len, op, flags);
dreg = netlink_parse_register(nle, NFTNL_EXPR_EXTHDR_DREG);
netlink_set_register(ctx, dreg, expr);
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c
index 293150e2..b2f27b7a 100644
--- a/src/netlink_linearize.c
+++ b/src/netlink_linearize.c
@@ -178,6 +178,7 @@ static void netlink_gen_exthdr(struct netlink_linearize_ctx *ctx,
nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_LEN,
div_round_up(expr->len, BITS_PER_BYTE));
nftnl_expr_set_u8(nle, NFTNL_EXPR_EXTHDR_OP, expr->exthdr.op);
+ nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_FLAGS, expr->exthdr.flags);
nftnl_rule_add_expr(ctx->nlr, nle);
}
diff --git a/src/tcpopt.c b/src/tcpopt.c
index f8612141..d34dfd45 100644
--- a/src/tcpopt.c
+++ b/src/tcpopt.c
@@ -192,7 +192,7 @@ struct expr *tcpopt_expr_alloc(const struct location *loc, uint8_t type,
}
void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int offset,
- unsigned int len)
+ unsigned int len, uint32_t flags)
{
const struct proto_hdr_template *tmpl;
unsigned int i, off;
@@ -200,6 +200,7 @@ void tcpopt_init_raw(struct expr *expr, uint8_t type, unsigned int offset,
assert(expr->ops->type == EXPR_EXTHDR);
expr->len = len;
+ expr->exthdr.flags = flags;
expr->exthdr.offset = offset;
assert(type < array_size(tcpopt_protocols));
@@ -229,7 +230,7 @@ bool tcpopt_find_template(struct expr *expr, const struct expr *mask,
return false;
tcpopt_init_raw(expr, expr->exthdr.desc->type, expr->exthdr.offset,
- expr->len);
+ expr->len, 0);
if (expr->exthdr.tmpl == &tcpopt_unknown_template)
return false;