static const struct input_descriptor indesc_cli = {
.type = INDESC_CLI,
+ .name = "<cli>",
};
static struct parser_state *state;
{
const HIST_ENTRY *hist;
const char *c;
+ LIST_HEAD(msgs);
line = cli_append_multiline(line);
if (line == NULL)
if (hist == NULL || strcmp(hist->line, line))
add_history(line);
+ parser_init(state, &msgs);
scanner_push_buffer(scanner, &indesc_cli, line);
- nft_parse(scanner, state);
-
- erec_print_list(stdout, state->msgs);
+ nft_run(scanner, state, &msgs);
+ erec_print_list(stdout, &msgs);
xfree(line);
}
rl_forced_update_display();
}
-int cli_init(void *_scanner, struct parser_state *_state)
+int cli_init(struct parser_state *_state)
{
const char *home;
read_history(histfile);
history_set_pos(history_length);
- scanner = _scanner;
state = _state;
+ scanner = scanner_init(state);
while (!eof)
rl_callback_read_char();
.name = "<cmdline>",
};
+int nft_run(void *scanner, struct parser_state *state, struct list_head *msgs)
+{
+ struct eval_ctx ctx;
+ int ret;
+
+ ret = nft_parse(scanner, state);
+ if (ret != 0)
+ return -1;
+
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.msgs = msgs;
+ if (evaluate(&ctx, &state->cmds) < 0)
+ return -1;
+
+ {
+ struct netlink_ctx ctx;
+ struct cmd *cmd, *next;
+
+ list_for_each_entry_safe(cmd, next, &state->cmds, list) {
+ memset(&ctx, 0, sizeof(ctx));
+ ctx.msgs = msgs;
+ init_list_head(&ctx.list);
+ ret = do_command(&ctx, cmd);
+ list_del(&cmd->list);
+ cmd_free(cmd);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ return 0;
+}
+
int main(int argc, char * const *argv)
{
struct parser_state state;
- struct eval_ctx ctx;
void *scanner;
LIST_HEAD(msgs);
char *buf = NULL, *filename = NULL;
unsigned int len;
bool interactive = false;
int i, val;
- int ret;
while (1) {
val = getopt_long(argc, argv, OPTSTRING, options, NULL);
}
}
- parser_init(&state, &msgs);
- scanner = scanner_init(&state);
-
if (optind != argc) {
for (len = 0, i = optind; i < argc; i++)
len += strlen(argv[i]) + strlen(" ");
if (i + 1 < argc)
strcat(buf, " ");
}
-
+ parser_init(&state, &msgs);
+ scanner = scanner_init(&state);
scanner_push_buffer(scanner, &indesc_cmdline, buf);
} else if (filename != NULL) {
+ parser_init(&state, &msgs);
+ scanner = scanner_init(&state);
if (scanner_read_file(scanner, filename, &internal_location) < 0)
goto out;
} else if (interactive) {
- cli_init(scanner, &state);
+ cli_init(&state);
+ return 0;
} else {
fprintf(stderr, "%s: no command specified\n", argv[0]);
exit(NFT_EXIT_FAILURE);
}
- ret = nft_parse(scanner, &state);
- if (ret != 0)
- goto out;
-
- memset(&ctx, 0, sizeof(ctx));
- ctx.msgs = &msgs;
- if (evaluate(&ctx, &state.cmds) < 0)
- goto out;
-
- {
- struct netlink_ctx ctx;
- struct cmd *cmd, *next;
-
- list_for_each_entry_safe(cmd, next, &state.cmds, list) {
- memset(&ctx, 0, sizeof(ctx));
- ctx.msgs = &msgs;
- init_list_head(&ctx.list);
- if (do_command(&ctx, cmd) < 0)
- goto out;
- list_del(&cmd->list);
- cmd_free(cmd);
- }
- }
+ nft_run(scanner, &state, &msgs);
out:
scanner_destroy(scanner);
- scope_release(&state.top_scope);
erec_print_list(stdout, &msgs);
xfree(buf);
struct scope *scope_init(struct scope *scope, const struct scope *parent)
{
scope->parent = parent;
- init_list_head(&scope->symbols);
return scope;
}
chain = xzalloc(sizeof(*chain));
init_list_head(&chain->rules);
+ init_list_head(&chain->scope.symbols);
if (name != NULL)
chain->handle.chain = xstrdup(name);
return chain;
table = xzalloc(sizeof(*table));
init_list_head(&table->chains);
init_list_head(&table->sets);
+ init_list_head(&table->scope.symbols);
return table;
}
static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
{
- struct table *table;
- struct chain *chain;
+ struct table *table = NULL;
+ struct chain *chain, *nchain;
struct rule *rule, *nrule;
struct set *set, *nset;
- table = table_alloc();
- handle_merge(&table->handle, &cmd->handle);
- table_add_hash(table);
+ /* No need to allocate the table object when listing all tables */
+ if (cmd->handle.table != NULL) {
+ table = table_lookup(&cmd->handle);
+ if (table == NULL) {
+ table = table_alloc();
+ handle_merge(&table->handle, &cmd->handle);
+ table_add_hash(table);
+ }
+ }
switch (cmd->obj) {
case CMD_OBJ_TABLE:
}
table_print(table);
+
+ list_for_each_entry_safe(chain, nchain, &table->chains, list) {
+ list_del(&chain->list);
+ chain_free(chain);
+ }
+
return 0;
}