diff options
Diffstat (limited to 'src/netlink_linearize.c')
-rw-r--r-- | src/netlink_linearize.c | 29 |
1 files changed, 29 insertions, 0 deletions
diff --git a/src/netlink_linearize.c b/src/netlink_linearize.c index 3d684569..c5a47dec 100644 --- a/src/netlink_linearize.c +++ b/src/netlink_linearize.c @@ -816,6 +816,33 @@ static bool payload_needs_l4csum_update_pseudohdr(const struct expr *expr, return false; } +static void netlink_gen_exthdr_stmt(struct netlink_linearize_ctx *ctx, + const struct stmt *stmt) +{ + struct nftnl_expr *nle; + const struct expr *expr; + enum nft_registers sreg; + unsigned int offset; + + sreg = get_register(ctx, stmt->exthdr.val); + netlink_gen_expr(ctx, stmt->exthdr.val, sreg); + release_register(ctx, stmt->exthdr.val); + + expr = stmt->exthdr.expr; + + offset = expr->exthdr.tmpl->offset + expr->exthdr.offset; + + nle = alloc_nft_expr("exthdr"); + netlink_put_register(nle, NFTNL_EXPR_EXTHDR_SREG, sreg); + nftnl_expr_set_u8(nle, NFTNL_EXPR_EXTHDR_TYPE, + expr->exthdr.desc->type); + nftnl_expr_set_u32(nle, NFTNL_EXPR_EXTHDR_OFFSET, offset / BITS_PER_BYTE); + 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_rule_add_expr(ctx->nlr, nle); +} + static void netlink_gen_payload_stmt(struct netlink_linearize_ctx *ctx, const struct stmt *stmt) { @@ -1239,6 +1266,8 @@ static void netlink_gen_stmt(struct netlink_linearize_ctx *ctx, return netlink_gen_verdict_stmt(ctx, stmt); case STMT_FLOW: return netlink_gen_flow_stmt(ctx, stmt); + case STMT_EXTHDR: + return netlink_gen_exthdr_stmt(ctx, stmt); case STMT_PAYLOAD: return netlink_gen_payload_stmt(ctx, stmt); case STMT_META: |