Skip to content

Commit 4a766d4

Browse files
committed
netfilter: nf_flow_table_offload: add flow_action_entry_next() and use it
This function retrieves a spare action entry from the array of actions. Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 6408c40 commit 4a766d4

File tree

1 file changed

+38
-38
lines changed

1 file changed

+38
-38
lines changed

net/netfilter/nf_flow_table_offload.c

Lines changed: 38 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -112,13 +112,22 @@ static void flow_offload_mangle(struct flow_action_entry *entry,
112112
memcpy(&entry->mangle.val, value, sizeof(u32));
113113
}
114114

115+
static inline struct flow_action_entry *
116+
flow_action_entry_next(struct nf_flow_rule *flow_rule)
117+
{
118+
int i = flow_rule->rule->action.num_entries++;
119+
120+
return &flow_rule->rule->action.entries[i];
121+
}
122+
115123
static int flow_offload_eth_src(struct net *net,
116124
const struct flow_offload *flow,
117125
enum flow_offload_tuple_dir dir,
118-
struct flow_action_entry *entry0,
119-
struct flow_action_entry *entry1)
126+
struct nf_flow_rule *flow_rule)
120127
{
121128
const struct flow_offload_tuple *tuple = &flow->tuplehash[!dir].tuple;
129+
struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule);
130+
struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule);
122131
struct net_device *dev;
123132
u32 mask, val;
124133
u16 val16;
@@ -145,10 +154,11 @@ static int flow_offload_eth_src(struct net *net,
145154
static int flow_offload_eth_dst(struct net *net,
146155
const struct flow_offload *flow,
147156
enum flow_offload_tuple_dir dir,
148-
struct flow_action_entry *entry0,
149-
struct flow_action_entry *entry1)
157+
struct nf_flow_rule *flow_rule)
150158
{
151159
const struct flow_offload_tuple *tuple = &flow->tuplehash[dir].tuple;
160+
struct flow_action_entry *entry0 = flow_action_entry_next(flow_rule);
161+
struct flow_action_entry *entry1 = flow_action_entry_next(flow_rule);
152162
struct neighbour *n;
153163
u32 mask, val;
154164
u16 val16;
@@ -175,8 +185,9 @@ static int flow_offload_eth_dst(struct net *net,
175185
static void flow_offload_ipv4_snat(struct net *net,
176186
const struct flow_offload *flow,
177187
enum flow_offload_tuple_dir dir,
178-
struct flow_action_entry *entry)
188+
struct nf_flow_rule *flow_rule)
179189
{
190+
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
180191
u32 mask = ~htonl(0xffffffff);
181192
__be32 addr;
182193
u32 offset;
@@ -201,8 +212,9 @@ static void flow_offload_ipv4_snat(struct net *net,
201212
static void flow_offload_ipv4_dnat(struct net *net,
202213
const struct flow_offload *flow,
203214
enum flow_offload_tuple_dir dir,
204-
struct flow_action_entry *entry)
215+
struct nf_flow_rule *flow_rule)
205216
{
217+
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
206218
u32 mask = ~htonl(0xffffffff);
207219
__be32 addr;
208220
u32 offset;
@@ -246,8 +258,9 @@ static int flow_offload_l4proto(const struct flow_offload *flow)
246258
static void flow_offload_port_snat(struct net *net,
247259
const struct flow_offload *flow,
248260
enum flow_offload_tuple_dir dir,
249-
struct flow_action_entry *entry)
261+
struct nf_flow_rule *flow_rule)
250262
{
263+
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
251264
u32 mask = ~htonl(0xffff0000);
252265
__be16 port;
253266
u32 offset;
@@ -272,8 +285,9 @@ static void flow_offload_port_snat(struct net *net,
272285
static void flow_offload_port_dnat(struct net *net,
273286
const struct flow_offload *flow,
274287
enum flow_offload_tuple_dir dir,
275-
struct flow_action_entry *entry)
288+
struct nf_flow_rule *flow_rule)
276289
{
290+
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
277291
u32 mask = ~htonl(0xffff);
278292
__be16 port;
279293
u32 offset;
@@ -297,9 +311,10 @@ static void flow_offload_port_dnat(struct net *net,
297311

298312
static void flow_offload_ipv4_checksum(struct net *net,
299313
const struct flow_offload *flow,
300-
struct flow_action_entry *entry)
314+
struct nf_flow_rule *flow_rule)
301315
{
302316
u8 protonum = flow->tuplehash[FLOW_OFFLOAD_DIR_ORIGINAL].tuple.l4proto;
317+
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
303318

304319
entry->id = FLOW_ACTION_CSUM;
305320
entry->csum_flags = TCA_CSUM_UPDATE_FLAG_IPV4HDR;
@@ -316,8 +331,9 @@ static void flow_offload_ipv4_checksum(struct net *net,
316331

317332
static void flow_offload_redirect(const struct flow_offload *flow,
318333
enum flow_offload_tuple_dir dir,
319-
struct flow_action_entry *entry)
334+
struct nf_flow_rule *flow_rule)
320335
{
336+
struct flow_action_entry *entry = flow_action_entry_next(flow_rule);
321337
struct rtable *rt;
322338

323339
rt = (struct rtable *)flow->tuplehash[dir].tuple.dst_cache;
@@ -330,39 +346,25 @@ int nf_flow_rule_route(struct net *net, const struct flow_offload *flow,
330346
enum flow_offload_tuple_dir dir,
331347
struct nf_flow_rule *flow_rule)
332348
{
333-
int i;
334-
335-
if (flow_offload_eth_src(net, flow, dir,
336-
&flow_rule->rule->action.entries[0],
337-
&flow_rule->rule->action.entries[1]) < 0)
349+
if (flow_offload_eth_src(net, flow, dir, flow_rule) < 0 ||
350+
flow_offload_eth_dst(net, flow, dir, flow_rule) < 0)
338351
return -1;
339352

340-
if (flow_offload_eth_dst(net, flow, dir,
341-
&flow_rule->rule->action.entries[2],
342-
&flow_rule->rule->action.entries[3]) < 0)
343-
return -1;
344-
345-
i = 4;
346353
if (flow->flags & FLOW_OFFLOAD_SNAT) {
347-
flow_offload_ipv4_snat(net, flow, dir,
348-
&flow_rule->rule->action.entries[i++]);
349-
flow_offload_port_snat(net, flow, dir,
350-
&flow_rule->rule->action.entries[i++]);
354+
flow_offload_ipv4_snat(net, flow, dir, flow_rule);
355+
flow_offload_port_snat(net, flow, dir, flow_rule);
351356
}
352357
if (flow->flags & FLOW_OFFLOAD_DNAT) {
353-
flow_offload_ipv4_dnat(net, flow, dir,
354-
&flow_rule->rule->action.entries[i++]);
355-
flow_offload_port_dnat(net, flow, dir,
356-
&flow_rule->rule->action.entries[i++]);
358+
flow_offload_ipv4_dnat(net, flow, dir, flow_rule);
359+
flow_offload_port_dnat(net, flow, dir, flow_rule);
357360
}
358361
if (flow->flags & FLOW_OFFLOAD_SNAT ||
359362
flow->flags & FLOW_OFFLOAD_DNAT)
360-
flow_offload_ipv4_checksum(net, flow,
361-
&flow_rule->rule->action.entries[i++]);
363+
flow_offload_ipv4_checksum(net, flow, flow_rule);
362364

363-
flow_offload_redirect(flow, dir, &flow_rule->rule->action.entries[i++]);
365+
flow_offload_redirect(flow, dir, flow_rule);
364366

365-
return i;
367+
return 0;
366368
}
367369
EXPORT_SYMBOL_GPL(nf_flow_rule_route);
368370

@@ -375,7 +377,7 @@ nf_flow_offload_rule_alloc(struct net *net,
375377
const struct flow_offload *flow = offload->flow;
376378
const struct flow_offload_tuple *tuple;
377379
struct nf_flow_rule *flow_rule;
378-
int err = -ENOMEM, num_actions;
380+
int err = -ENOMEM;
379381

380382
flow_rule = kzalloc(sizeof(*flow_rule), GFP_KERNEL);
381383
if (!flow_rule)
@@ -394,12 +396,10 @@ nf_flow_offload_rule_alloc(struct net *net,
394396
if (err < 0)
395397
goto err_flow_match;
396398

397-
num_actions = flowtable->type->action(net, flow, dir, flow_rule);
398-
if (num_actions < 0)
399+
flow_rule->rule->action.num_entries = 0;
400+
if (flowtable->type->action(net, flow, dir, flow_rule) < 0)
399401
goto err_flow_match;
400402

401-
flow_rule->rule->action.num_entries = num_actions;
402-
403403
return flow_rule;
404404

405405
err_flow_match:

0 commit comments

Comments
 (0)