configure: Avoid addition assignment operators
[iptables-mirror.git] / iptables / nft-cmd.c
blob58d5aa11e90d2ceee45c2500fde180d258883327
1 /*
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>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <xtables.h>
15 #include "nft.h"
16 #include "nft-cmd.h"
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 = {
25 .command = command,
27 struct nftnl_rule *rule;
28 struct nft_cmd *cmd;
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);
35 if (chain)
36 cmd->chain = xtables_strdup(chain);
37 cmd->rulenum = rulenum;
38 cmd->verbose = verbose;
40 if (state) {
41 rule = nft_rule_new(h, &ctx, chain, table, state);
42 if (!rule) {
43 nft_cmd_free(cmd);
44 return NULL;
47 cmd->obj.rule = rule;
49 if (!state->target && strlen(state->jumpto) > 0)
50 cmd->jumpto = xtables_strdup(state->jumpto);
53 list_add_tail(&cmd->head, &h->cmd_list);
55 return cmd;
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:
70 if (cmd->obj.rule)
71 nftnl_rule_free(cmd->obj.rule);
72 break;
73 default:
74 break;
77 list_del(&cmd->head);
78 free(cmd);
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);
86 if (!t)
87 return;
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);
95 else
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,
101 bool verbose)
103 struct nft_cmd *cmd;
105 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_APPEND, table, chain, state, -1,
106 verbose);
107 if (!cmd)
108 return 0;
110 nft_cmd_rule_bridge(h, cmd);
112 return 1;
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)
119 struct nft_cmd *cmd;
121 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_INSERT, table, chain, state,
122 rulenum, verbose);
123 if (!cmd)
124 return 0;
126 nft_cmd_rule_bridge(h, cmd);
128 if (cmd->rulenum > 0)
129 nft_cache_level_set(h, NFT_CL_RULES, cmd);
130 else
131 nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
133 return 1;
136 int nft_cmd_rule_delete(struct nft_handle *h, const char *chain,
137 const char *table, struct iptables_command_state *state,
138 bool verbose)
140 struct nft_cmd *cmd;
142 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_DELETE, table, chain, state,
143 -1, verbose);
144 if (!cmd)
145 return 0;
147 nft_cache_level_set(h, NFT_CL_RULES, cmd);
149 return 1;
152 int nft_cmd_rule_delete_num(struct nft_handle *h, const char *chain,
153 const char *table, int rulenum, bool verbose)
155 struct nft_cmd *cmd;
157 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_DELETE, table, chain, NULL,
158 rulenum, verbose);
159 if (!cmd)
160 return 0;
162 nft_cache_level_set(h, NFT_CL_RULES, cmd);
164 return 1;
167 int nft_cmd_rule_flush(struct nft_handle *h, const char *chain,
168 const char *table, bool verbose)
170 struct nft_cmd *cmd;
172 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_FLUSH, table, chain, NULL, -1,
173 verbose);
174 if (!cmd)
175 return 0;
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);
181 else
182 nft_cache_level_set(h, NFT_CL_TABLES, cmd);
184 return 1;
187 int nft_cmd_chain_zero_counters(struct nft_handle *h, const char *chain,
188 const char *table, bool verbose)
190 struct nft_cmd *cmd;
192 cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_ZERO, table, chain, NULL, -1,
193 verbose);
194 if (!cmd)
195 return 0;
197 nft_cache_level_set(h, NFT_CL_RULES, cmd);
199 return 1;
202 int nft_cmd_chain_user_add(struct nft_handle *h, const char *chain,
203 const char *table)
205 struct nft_cmd *cmd;
207 cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_USER_ADD, table, chain, NULL, -1,
208 false);
209 if (!cmd)
210 return 0;
212 nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
214 return 1;
217 int nft_cmd_chain_del(struct nft_handle *h, const char *chain,
218 const char *table, bool verbose)
220 struct nft_cmd *cmd;
222 cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_DEL, table, chain, NULL, -1,
223 verbose);
224 if (!cmd)
225 return 0;
227 /* This triggers nft_bridge_chain_postprocess() when fetching the
228 * rule cache.
230 if (h->family == NFPROTO_BRIDGE || !chain)
231 nft_cache_level_set(h, NFT_CL_RULES, cmd);
232 else
233 nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
235 return 1;
238 int nft_cmd_chain_user_rename(struct nft_handle *h,const char *chain,
239 const char *table, const char *newname)
241 struct nft_cmd *cmd;
243 cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_RENAME, table, chain, NULL, -1,
244 false);
245 if (!cmd)
246 return 0;
248 cmd->rename = xtables_strdup(newname);
250 nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
252 return 1;
255 int nft_cmd_rule_list(struct nft_handle *h, const char *chain,
256 const char *table, int rulenum, unsigned int format)
258 struct nft_cmd *cmd;
260 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_LIST, table, chain, NULL, rulenum,
261 false);
262 if (!cmd)
263 return 0;
265 cmd->format = format;
267 nft_cache_level_set(h, NFT_CL_RULES, cmd);
269 return 1;
272 int nft_cmd_rule_replace(struct nft_handle *h, const char *chain,
273 const char *table, void *data, int rulenum,
274 bool verbose)
276 struct nft_cmd *cmd;
278 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_REPLACE, table, chain, data,
279 rulenum, verbose);
280 if (!cmd)
281 return 0;
283 nft_cache_level_set(h, NFT_CL_RULES, cmd);
285 return 1;
288 int nft_cmd_rule_check(struct nft_handle *h, const char *chain,
289 const char *table, void *data, bool verbose)
291 struct nft_cmd *cmd;
293 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_CHECK, table, chain, data, -1,
294 verbose);
295 if (!cmd)
296 return 0;
298 nft_cache_level_set(h, NFT_CL_RULES, cmd);
300 return 1;
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)
307 struct nft_cmd *cmd;
309 cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_UPDATE, table, chain, NULL, -1,
310 false);
311 if (!cmd)
312 return 0;
314 cmd->policy = xtables_strdup(policy);
315 if (counters)
316 cmd->counters = *counters;
318 nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
320 return 1;
323 int nft_cmd_table_flush(struct nft_handle *h, const char *table, bool verbose)
325 struct nft_cmd *cmd;
327 if (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,
333 false);
334 if (!cmd)
335 return 0;
337 nft_cache_level_set(h, NFT_CL_TABLES, cmd);
339 return 1;
342 int nft_cmd_chain_restore(struct nft_handle *h, const char *chain,
343 const char *table)
345 struct nft_cmd *cmd;
347 cmd = nft_cmd_new(h, NFT_COMPAT_CHAIN_RESTORE, table, chain, NULL, -1,
348 false);
349 if (!cmd)
350 return 0;
352 nft_cache_level_set(h, NFT_CL_CHAINS, cmd);
354 return 1;
357 int nft_cmd_rule_zero_counters(struct nft_handle *h, const char *chain,
358 const char *table, int rulenum)
360 struct nft_cmd *cmd;
362 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_ZERO, table, chain, NULL, rulenum,
363 false);
364 if (!cmd)
365 return 0;
367 nft_cache_level_set(h, NFT_CL_RULES, cmd);
369 return 1;
372 int nft_cmd_rule_list_save(struct nft_handle *h, const char *chain,
373 const char *table, int rulenum, int counters)
375 struct nft_cmd *cmd;
377 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_SAVE, table, chain, NULL, rulenum,
378 false);
379 if (!cmd)
380 return 0;
382 cmd->counters_save = counters;
384 nft_cache_level_set(h, NFT_CL_RULES, cmd);
386 return 1;
389 int ebt_cmd_user_chain_policy(struct nft_handle *h, const char *table,
390 const char *chain, const char *policy)
392 struct nft_cmd *cmd;
394 cmd = nft_cmd_new(h, NFT_COMPAT_BRIDGE_USER_CHAIN_UPDATE, table, chain,
395 NULL, -1, false);
396 if (!cmd)
397 return 0;
399 cmd->policy = xtables_strdup(policy);
401 nft_cache_level_set(h, NFT_CL_RULES, cmd);
403 return 1;
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)
411 struct nft_cmd *cmd;
413 cmd = nft_cmd_new(h, NFT_COMPAT_RULE_CHANGE_COUNTERS, table, chain,
414 rule_nr == -1 ? cs : NULL, rule_nr, verbose);
415 if (!cmd)
416 return 0;
418 cmd->counter_op = counter_op;
419 cmd->counters = cs->counters;
421 nft_cache_level_set(h, NFT_CL_RULES, cmd);
423 return 1;