1 From: Pablo Neira Ayuso <pablo@netfilter.org>
2 Date: Sun, 3 Dec 2017 21:27:03 +0100
3 Subject: [PATCH] src: flow offload support
5 This patch allows us to refer to existing flowtables:
7 # nft add rule x x flow offload @m
9 Packets matching this rule create an entry in the flow table 'm', hence,
10 follow up packets that get to the flowtable at ingress bypass the
11 classic forwarding path.
13 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
18 @@ -29,6 +29,8 @@ extern struct expr *ct_expr_alloc(const
19 extern void ct_expr_update_type(struct proto_ctx *ctx, struct expr *expr);
21 extern struct stmt *notrack_stmt_alloc(const struct location *loc);
22 +extern struct stmt *flow_offload_stmt_alloc(const struct location *loc,
23 + const char *table_name);
25 extern const struct datatype ct_dir_type;
26 extern const struct datatype ct_state_type;
27 --- a/include/statement.h
28 +++ b/include/statement.h
29 @@ -10,6 +10,12 @@ extern struct stmt *expr_stmt_alloc(cons
30 extern struct stmt *verdict_stmt_alloc(const struct location *loc,
34 + const char *table_name;
37 +struct stmt *flow_stmt_alloc(const struct location *loc, const char *name);
42 @@ -231,6 +237,7 @@ extern struct stmt *xt_stmt_alloc(const
43 * @STMT_NOTRACK: notrack statement
44 * @STMT_OBJREF: stateful object reference statement
45 * @STMT_EXTHDR: extension header statement
46 + * @STMT_FLOW_OFFLOAD: flow offload statement
50 @@ -256,6 +263,7 @@ enum stmt_types {
58 @@ -316,6 +324,7 @@ struct stmt {
61 struct objref_stmt objref;
62 + struct flow_stmt flow;
68 @@ -456,3 +456,26 @@ struct stmt *notrack_stmt_alloc(const st
70 return stmt_alloc(loc, ¬rack_stmt_ops);
73 +static void flow_offload_stmt_print(const struct stmt *stmt,
74 + struct output_ctx *octx)
76 + printf("flow offload @%s", stmt->flow.table_name);
79 +static const struct stmt_ops flow_offload_stmt_ops = {
80 + .type = STMT_FLOW_OFFLOAD,
81 + .name = "flow_offload",
82 + .print = flow_offload_stmt_print,
85 +struct stmt *flow_offload_stmt_alloc(const struct location *loc,
86 + const char *table_name)
90 + stmt = stmt_alloc(loc, &flow_offload_stmt_ops);
91 + stmt->flow.table_name = table_name;
97 @@ -2773,6 +2773,7 @@ int stmt_evaluate(struct eval_ctx *ctx,
101 + case STMT_FLOW_OFFLOAD:
103 case STMT_EXPRESSION:
104 return stmt_evaluate_expr(ctx, stmt);
105 --- a/src/netlink_delinearize.c
106 +++ b/src/netlink_delinearize.c
107 @@ -680,6 +680,16 @@ static void netlink_parse_notrack(struct
108 ctx->stmt = notrack_stmt_alloc(loc);
111 +static void netlink_parse_flow_offload(struct netlink_parse_ctx *ctx,
112 + const struct location *loc,
113 + const struct nftnl_expr *nle)
115 + const char *table_name;
117 + table_name = xstrdup(nftnl_expr_get_str(nle, NFTNL_EXPR_FLOW_TABLE_NAME));
118 + ctx->stmt = flow_offload_stmt_alloc(loc, table_name);
121 static void netlink_parse_ct_stmt(struct netlink_parse_ctx *ctx,
122 const struct location *loc,
123 const struct nftnl_expr *nle)
124 @@ -1255,6 +1265,7 @@ static const struct {
125 { .name = "hash", .parse = netlink_parse_hash },
126 { .name = "fib", .parse = netlink_parse_fib },
127 { .name = "tcpopt", .parse = netlink_parse_exthdr },
128 + { .name = "flow_offload", .parse = netlink_parse_flow_offload },
131 static int netlink_parse_expr(const struct nftnl_expr *nle,
132 --- a/src/netlink_linearize.c
133 +++ b/src/netlink_linearize.c
134 @@ -1201,6 +1201,17 @@ static void netlink_gen_notrack_stmt(str
135 nftnl_rule_add_expr(ctx->nlr, nle);
138 +static void netlink_gen_flow_offload_stmt(struct netlink_linearize_ctx *ctx,
139 + const struct stmt *stmt)
141 + struct nftnl_expr *nle;
143 + nle = alloc_nft_expr("flow_offload");
144 + nftnl_expr_set_str(nle, NFTNL_EXPR_FLOW_TABLE_NAME,
145 + stmt->flow.table_name);
146 + nftnl_rule_add_expr(ctx->nlr, nle);
149 static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
150 const struct stmt *stmt)
152 @@ -1300,6 +1311,8 @@ static void netlink_gen_stmt(struct netl
155 return netlink_gen_notrack_stmt(ctx, stmt);
156 + case STMT_FLOW_OFFLOAD:
157 + return netlink_gen_flow_offload_stmt(ctx, stmt);
159 return netlink_gen_objref_stmt(ctx, stmt);
161 --- a/src/parser_bison.y
162 +++ b/src/parser_bison.y
163 @@ -248,6 +248,7 @@ int nft_lex(void *, void *, void *);
167 +%token OFFLOAD "offload"
169 %token METERS "meters"
171 @@ -3384,6 +3385,10 @@ meta_stmt : META meta_key SET stmt_expr
173 $$ = notrack_stmt_alloc(&@$);
175 + | FLOW OFFLOAD AT string
177 + $$ = flow_offload_stmt_alloc(&@$, $4);
181 offset_opt : /* empty */ { $$ = 0; }
184 @@ -296,6 +296,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr
185 "memory" { return MEMORY; }
187 "flow" { return FLOW; }
188 +"offload" { return OFFLOAD; }
189 "meter" { return METER; }
190 "meters" { return METERS; }