OpenWrt – Blame information for rev 4
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
4 | office | 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, ¬rack_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 |