2 * (C) 2012 by Pablo Neira Ayuso <pablo@netfilter.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published
6 * by the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This code has been sponsored by Sophos Astaro <http://www.sophos.com>
17 #include <libnftnl/set.h>
19 struct nft_cmd
*nft_cmd_new(struct nft_handle
*h
, int command
,
20 const char *table
, const char *chain
,
21 struct iptables_command_state
*state
,
22 int rulenum
, bool verbose
)
24 struct nft_rule_ctx ctx
= {
27 struct nftnl_rule
*rule
;
30 cmd
= xtables_calloc(1, sizeof(struct nft_cmd
));
31 INIT_LIST_HEAD(&cmd
->head
);
32 cmd
->error
.lineno
= h
->error
.lineno
;
33 cmd
->command
= command
;
34 cmd
->table
= xtables_strdup(table
);
36 cmd
->chain
= xtables_strdup(chain
);
37 cmd
->rulenum
= rulenum
;
38 cmd
->verbose
= verbose
;
41 rule
= nft_rule_new(h
, &ctx
, chain
, table
, state
);
49 if (!state
->target
&& strlen(state
->jumpto
) > 0)
50 cmd
->jumpto
= xtables_strdup(state
->jumpto
);
53 list_add_tail(&cmd
->head
, &h
->cmd_list
);
58 void nft_cmd_free(struct nft_cmd
*cmd
)
60 free((void *)cmd
->table
);
61 free((void *)cmd
->chain
);
62 free((void *)cmd
->policy
);
63 free((void *)cmd
->rename
);
64 free((void *)cmd
->jumpto
);
66 switch (cmd
->command
) {
67 case NFT_COMPAT_RULE_CHECK
:
68 case NFT_COMPAT_RULE_DELETE
:
69 case NFT_COMPAT_RULE_CHANGE_COUNTERS
:
71 nftnl_rule_free(cmd
->obj
.rule
);
81 static void nft_cmd_rule_bridge(struct nft_handle
*h
, const struct nft_cmd
*cmd
)
83 const struct builtin_table
*t
;
85 t
= nft_table_builtin_find(h
, cmd
->table
);
89 /* Since ebtables user-defined chain policies are implemented as last
90 * rule in nftables, rule cache is required here to treat them right.
92 if (h
->family
== NFPROTO_BRIDGE
&&
93 !nft_chain_builtin_find(t
, cmd
->chain
))
94 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
96 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
99 int nft_cmd_rule_append(struct nft_handle
*h
, const char *chain
,
100 const char *table
, struct iptables_command_state
*state
,
105 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_APPEND
, table
, chain
, state
, -1,
110 nft_cmd_rule_bridge(h
, cmd
);
115 int nft_cmd_rule_insert(struct nft_handle
*h
, const char *chain
,
116 const char *table
, struct iptables_command_state
*state
,
117 int rulenum
, bool verbose
)
121 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_INSERT
, table
, chain
, state
,
126 nft_cmd_rule_bridge(h
, cmd
);
128 if (cmd
->rulenum
> 0)
129 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
131 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
136 int nft_cmd_rule_delete(struct nft_handle
*h
, const char *chain
,
137 const char *table
, struct iptables_command_state
*state
,
142 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_DELETE
, table
, chain
, state
,
147 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
152 int nft_cmd_rule_delete_num(struct nft_handle
*h
, const char *chain
,
153 const char *table
, int rulenum
, bool verbose
)
157 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_DELETE
, table
, chain
, NULL
,
162 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
167 int nft_cmd_rule_flush(struct nft_handle
*h
, const char *chain
,
168 const char *table
, bool verbose
)
172 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_FLUSH
, table
, chain
, NULL
, -1,
177 if (h
->family
== NFPROTO_BRIDGE
)
178 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
179 else if (chain
|| verbose
)
180 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
182 nft_cache_level_set(h
, NFT_CL_TABLES
, cmd
);
187 int nft_cmd_chain_zero_counters(struct nft_handle
*h
, const char *chain
,
188 const char *table
, bool verbose
)
192 cmd
= nft_cmd_new(h
, NFT_COMPAT_CHAIN_ZERO
, table
, chain
, NULL
, -1,
197 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
202 int nft_cmd_chain_user_add(struct nft_handle
*h
, const char *chain
,
207 cmd
= nft_cmd_new(h
, NFT_COMPAT_CHAIN_USER_ADD
, table
, chain
, NULL
, -1,
212 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
217 int nft_cmd_chain_del(struct nft_handle
*h
, const char *chain
,
218 const char *table
, bool verbose
)
222 cmd
= nft_cmd_new(h
, NFT_COMPAT_CHAIN_DEL
, table
, chain
, NULL
, -1,
227 /* This triggers nft_bridge_chain_postprocess() when fetching the
230 if (h
->family
== NFPROTO_BRIDGE
|| !chain
)
231 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
233 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
238 int nft_cmd_chain_user_rename(struct nft_handle
*h
,const char *chain
,
239 const char *table
, const char *newname
)
243 cmd
= nft_cmd_new(h
, NFT_COMPAT_CHAIN_RENAME
, table
, chain
, NULL
, -1,
248 cmd
->rename
= xtables_strdup(newname
);
250 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
255 int nft_cmd_rule_list(struct nft_handle
*h
, const char *chain
,
256 const char *table
, int rulenum
, unsigned int format
)
260 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_LIST
, table
, chain
, NULL
, rulenum
,
265 cmd
->format
= format
;
267 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
272 int nft_cmd_rule_replace(struct nft_handle
*h
, const char *chain
,
273 const char *table
, void *data
, int rulenum
,
278 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_REPLACE
, table
, chain
, data
,
283 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
288 int nft_cmd_rule_check(struct nft_handle
*h
, const char *chain
,
289 const char *table
, void *data
, bool verbose
)
293 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_CHECK
, table
, chain
, data
, -1,
298 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
303 int nft_cmd_chain_set(struct nft_handle
*h
, const char *table
,
304 const char *chain
, const char *policy
,
305 const struct xt_counters
*counters
)
309 cmd
= nft_cmd_new(h
, NFT_COMPAT_CHAIN_UPDATE
, table
, chain
, NULL
, -1,
314 cmd
->policy
= xtables_strdup(policy
);
316 cmd
->counters
= *counters
;
318 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
323 int nft_cmd_table_flush(struct nft_handle
*h
, const char *table
, bool verbose
)
328 return nft_cmd_rule_flush(h
, NULL
, table
, verbose
) &&
329 nft_cmd_chain_del(h
, NULL
, table
, verbose
);
332 cmd
= nft_cmd_new(h
, NFT_COMPAT_TABLE_FLUSH
, table
, NULL
, NULL
, -1,
337 nft_cache_level_set(h
, NFT_CL_TABLES
, cmd
);
342 int nft_cmd_chain_restore(struct nft_handle
*h
, const char *chain
,
347 cmd
= nft_cmd_new(h
, NFT_COMPAT_CHAIN_RESTORE
, table
, chain
, NULL
, -1,
352 nft_cache_level_set(h
, NFT_CL_CHAINS
, cmd
);
357 int nft_cmd_rule_zero_counters(struct nft_handle
*h
, const char *chain
,
358 const char *table
, int rulenum
)
362 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_ZERO
, table
, chain
, NULL
, rulenum
,
367 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
372 int nft_cmd_rule_list_save(struct nft_handle
*h
, const char *chain
,
373 const char *table
, int rulenum
, int counters
)
377 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_SAVE
, table
, chain
, NULL
, rulenum
,
382 cmd
->counters_save
= counters
;
384 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
389 int ebt_cmd_user_chain_policy(struct nft_handle
*h
, const char *table
,
390 const char *chain
, const char *policy
)
394 cmd
= nft_cmd_new(h
, NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE
, table
, chain
,
399 cmd
->policy
= xtables_strdup(policy
);
401 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);
406 int nft_cmd_rule_change_counters(struct nft_handle
*h
,
407 const char *chain
, const char *table
,
408 struct iptables_command_state
*cs
,
409 int rule_nr
, uint8_t counter_op
, bool verbose
)
413 cmd
= nft_cmd_new(h
, NFT_COMPAT_RULE_CHANGE_COUNTERS
, table
, chain
,
414 rule_nr
== -1 ? cs
: NULL
, rule_nr
, verbose
);
418 cmd
->counter_op
= counter_op
;
419 cmd
->counters
= cs
->counters
;
421 nft_cache_level_set(h
, NFT_CL_RULES
, cmd
);