86dfb1d94aaf9ee64aa2e3994770ecfb70641851
[openwrt/staging/luka.git] / package / network / utils / nftables / patches / 203-src-flow-offload-support.patch
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
4
5 This patch allows us to refer to existing flowtables:
6
7 # nft add rule x x flow offload @m
8
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.
12
13 Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
14 ---
15
16 --- a/include/ct.h
17 +++ b/include/ct.h
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);
20
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);
24
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,
31 struct expr *expr);
32
33 +struct flow_stmt {
34 + const char *table_name;
35 +};
36 +
37 +struct stmt *flow_stmt_alloc(const struct location *loc, const char *name);
38 +
39 struct objref_stmt {
40 uint32_t type;
41 struct expr *expr;
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
47 */
48 enum stmt_types {
49 STMT_INVALID,
50 @@ -256,6 +263,7 @@ enum stmt_types {
51 STMT_NOTRACK,
52 STMT_OBJREF,
53 STMT_EXTHDR,
54 + STMT_FLOW_OFFLOAD,
55 };
56
57 /**
58 @@ -316,6 +324,7 @@ struct stmt {
59 struct fwd_stmt fwd;
60 struct xt_stmt xt;
61 struct objref_stmt objref;
62 + struct flow_stmt flow;
63 };
64 };
65
66 --- a/src/ct.c
67 +++ b/src/ct.c
68 @@ -456,3 +456,26 @@ struct stmt *notrack_stmt_alloc(const st
69 {
70 return stmt_alloc(loc, &notrack_stmt_ops);
71 }
72 +
73 +static void flow_offload_stmt_print(const struct stmt *stmt,
74 + struct output_ctx *octx)
75 +{
76 + printf("flow offload @%s", stmt->flow.table_name);
77 +}
78 +
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,
83 +};
84 +
85 +struct stmt *flow_offload_stmt_alloc(const struct location *loc,
86 + const char *table_name)
87 +{
88 + struct stmt *stmt;
89 +
90 + stmt = stmt_alloc(loc, &flow_offload_stmt_ops);
91 + stmt->flow.table_name = table_name;
92 +
93 + return stmt;
94 +}
95 --- a/src/evaluate.c
96 +++ b/src/evaluate.c
97 @@ -2773,6 +2773,7 @@ int stmt_evaluate(struct eval_ctx *ctx,
98 case STMT_LIMIT:
99 case STMT_QUOTA:
100 case STMT_NOTRACK:
101 + case STMT_FLOW_OFFLOAD:
102 return 0;
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);
109 }
110
111 +static void netlink_parse_flow_offload(struct netlink_parse_ctx *ctx,
112 + const struct location *loc,
113 + const struct nftnl_expr *nle)
114 +{
115 + const char *table_name;
116 +
117 + table_name = xstrdup(nftnl_expr_get_str(nle, NFTNL_EXPR_FLOW_TABLE_NAME));
118 + ctx->stmt = flow_offload_stmt_alloc(loc, table_name);
119 +}
120 +
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 },
129 };
130
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);
136 }
137
138 +static void netlink_gen_flow_offload_stmt(struct netlink_linearize_ctx *ctx,
139 + const struct stmt *stmt)
140 +{
141 + struct nftnl_expr *nle;
142 +
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);
147 +}
148 +
149 static void netlink_gen_set_stmt(struct netlink_linearize_ctx *ctx,
150 const struct stmt *stmt)
151 {
152 @@ -1300,6 +1311,8 @@ static void netlink_gen_stmt(struct netl
153 break;
154 case STMT_NOTRACK:
155 return netlink_gen_notrack_stmt(ctx, stmt);
156 + case STMT_FLOW_OFFLOAD:
157 + return netlink_gen_flow_offload_stmt(ctx, stmt);
158 case STMT_OBJREF:
159 return netlink_gen_objref_stmt(ctx, stmt);
160 default:
161 --- a/src/parser_bison.y
162 +++ b/src/parser_bison.y
163 @@ -248,6 +248,7 @@ int nft_lex(void *, void *, void *);
164 %token SIZE "size"
165
166 %token FLOW "flow"
167 +%token OFFLOAD "offload"
168 %token METER "meter"
169 %token METERS "meters"
170
171 @@ -3384,6 +3385,10 @@ meta_stmt : META meta_key SET stmt_expr
172 {
173 $$ = notrack_stmt_alloc(&@$);
174 }
175 + | FLOW OFFLOAD AT string
176 + {
177 + $$ = flow_offload_stmt_alloc(&@$, $4);
178 + }
179 ;
180
181 offset_opt : /* empty */ { $$ = 0; }
182 --- a/src/scanner.l
183 +++ b/src/scanner.l
184 @@ -296,6 +296,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr
185 "memory" { return MEMORY; }
186
187 "flow" { return FLOW; }
188 +"offload" { return OFFLOAD; }
189 "meter" { return METER; }
190 "meters" { return METERS; }
191