From a5dadd72bef79d92c14271fb8718a13f0e7f3814 Mon Sep 17 00:00:00 2001 From: Patrick McHardy Date: Fri, 14 Dec 2012 17:39:22 +0100 Subject: chains: add chain rename support Signed-off-by: Patrick McHardy --- include/netlink.h | 2 ++ include/rule.h | 4 ++++ src/evaluate.c | 1 + src/netlink.c | 23 ++++++++++++++++++++++- src/parser.y | 15 ++++++++++++--- src/rule.c | 30 +++++++++++++++++++++++++++++- src/scanner.l | 1 + 7 files changed, 71 insertions(+), 5 deletions(-) diff --git a/include/netlink.h b/include/netlink.h index 22ef489c..8edd1a39 100644 --- a/include/netlink.h +++ b/include/netlink.h @@ -57,6 +57,8 @@ extern int netlink_get_rule(struct netlink_ctx *ctx, const struct handle *h); extern int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h, const struct chain *chain); +extern int netlink_rename_chain(struct netlink_ctx *ctx, const struct handle *h, + const char *name); extern int netlink_delete_chain(struct netlink_ctx *ctx, const struct handle *h); extern int netlink_list_chains(struct netlink_ctx *ctx, const struct handle *h); extern int netlink_get_chain(struct netlink_ctx *ctx, const struct handle *h); diff --git a/include/rule.h b/include/rule.h index 4a458d31..e468e8e8 100644 --- a/include/rule.h +++ b/include/rule.h @@ -190,6 +190,7 @@ extern void set_print(const struct set *set); * @CMD_DELETE: delete object * @CMD_LIST: list container * @CMD_FLUSH: flush container + * @CMD_RENAME: rename object */ enum cmd_ops { CMD_INVALID, @@ -197,6 +198,7 @@ enum cmd_ops { CMD_DELETE, CMD_LIST, CMD_FLUSH, + CMD_RENAME, }; /** @@ -229,6 +231,7 @@ enum cmd_obj { * @obj: object type to perform operation on * @handle: handle for operations working without full objects * @union: object + * @arg: argument data */ struct cmd { struct list_head list; @@ -244,6 +247,7 @@ struct cmd { struct chain *chain; struct table *table; }; + const void *arg; }; extern struct cmd *cmd_alloc(enum cmd_ops op, enum cmd_obj obj, diff --git a/src/evaluate.c b/src/evaluate.c index 906c1002..28681d0d 100644 --- a/src/evaluate.c +++ b/src/evaluate.c @@ -1311,6 +1311,7 @@ static int cmd_evaluate(struct eval_ctx *ctx, struct cmd *cmd) return cmd_evaluate_delete(ctx, cmd); case CMD_LIST: case CMD_FLUSH: + case CMD_RENAME: return 0; default: BUG("invalid command operation %u\n", cmd->op); diff --git a/src/netlink.c b/src/netlink.c index 7e4f4906..53ef2ba9 100644 --- a/src/netlink.c +++ b/src/netlink.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Patrick McHardy + * Copyright (c) 2008-2012 Patrick McHardy * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -100,6 +100,8 @@ struct nfnl_nft_chain *alloc_nft_chain(const struct handle *h) memory_allocation_error(); nfnl_nft_chain_set_family(nlc, h->family); nfnl_nft_chain_set_table(nlc, h->table, strlen(h->table) + 1); + if (h->handle != 0) + nfnl_nft_chain_set_handle(nlc, h->handle); if (h->chain != NULL) nfnl_nft_chain_set_name(nlc, h->chain, strlen(h->chain) + 1); return nlc; @@ -437,6 +439,24 @@ int netlink_add_chain(struct netlink_ctx *ctx, const struct handle *h, return err; } +int netlink_rename_chain(struct netlink_ctx *ctx, const struct handle *h, + const char *name) +{ + struct nfnl_nft_chain *nlc; + int err; + + nlc = alloc_nft_chain(h); + nfnl_nft_chain_set_name(nlc, name, strlen(name) + 1); + netlink_dump_object(OBJ_CAST(nlc)); + err = nfnl_nft_chain_add(nf_sock, nlc, 0); + nfnl_nft_chain_put(nlc); + + if (err < 0) + netlink_io_error(ctx, NULL, "Could not rename chain: %s", + nl_geterror(err)); + return err; +} + int netlink_delete_chain(struct netlink_ctx *ctx, const struct handle *h) { struct nfnl_nft_chain *nlc; @@ -470,6 +490,7 @@ static void list_chain_cb(struct nl_object *obj, void *arg) chain = chain_alloc(nfnl_nft_chain_get_name(nlc)); chain->handle.family = nfnl_nft_chain_get_family(nlc); chain->handle.table = xstrdup(nfnl_nft_chain_get_table(nlc)); + chain->handle.handle = nfnl_nft_chain_get_handle(nlc); chain->hooknum = nfnl_nft_chain_get_hooknum(nlc); chain->priority = nfnl_nft_chain_get_priority(nlc); list_add_tail(&chain->list, &ctx->list); diff --git a/src/parser.y b/src/parser.y index b0d56e52..2b0700db 100644 --- a/src/parser.y +++ b/src/parser.y @@ -1,5 +1,5 @@ /* - * Copyright (c) 2007-2008 Patrick McHardy + * Copyright (c) 2007-2012 Patrick McHardy * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -169,6 +169,7 @@ static void location_update(struct location *loc, struct location *rhs, int n) %token DELETE "delete" %token LIST "list" %token FLUSH "flush" +%token RENAME "rename" %token DESCRIBE "describe" %token ACCEPT "accept" @@ -327,8 +328,8 @@ static void location_update(struct location *loc, struct location *rhs, int n) %type line %destructor { cmd_free($$); } line -%type base_cmd add_cmd delete_cmd list_cmd flush_cmd -%destructor { cmd_free($$); } base_cmd add_cmd delete_cmd list_cmd flush_cmd +%type base_cmd add_cmd delete_cmd list_cmd flush_cmd rename_cmd +%destructor { cmd_free($$); } base_cmd add_cmd delete_cmd list_cmd flush_cmd rename_cmd %type table_spec chain_spec chain_identifier ruleid_spec %destructor { handle_free(&$$); } table_spec chain_spec chain_identifier ruleid_spec @@ -511,6 +512,7 @@ base_cmd : /* empty */ add_cmd { $$ = $1; } | DELETE delete_cmd { $$ = $2; } | LIST list_cmd { $$ = $2; } | FLUSH flush_cmd { $$ = $2; } + | RENAME rename_cmd { $$ = $2; } | DESCRIBE primary_expr { expr_describe($2); @@ -623,6 +625,13 @@ flush_cmd : TABLE table_spec } ; +rename_cmd : CHAIN chain_spec identifier + { + $$ = cmd_alloc(CMD_RENAME, CMD_OBJ_CHAIN, &$2, NULL); + $$->arg = $3; + } + ; + table_block_alloc : /* empty */ { $$ = table_alloc(); diff --git a/src/rule.c b/src/rule.c index 61e16e75..f671117d 100644 --- a/src/rule.c +++ b/src/rule.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2008 Patrick McHardy + * Copyright (c) 2008-2012 Patrick McHardy * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as @@ -332,6 +332,7 @@ void cmd_free(struct cmd *cmd) BUG("invalid command object type %u\n", cmd->obj); } } + xfree(cmd->arg); xfree(cmd); } @@ -524,6 +525,31 @@ static int do_command_flush(struct netlink_ctx *ctx, struct cmd *cmd) return 0; } +static int do_command_rename(struct netlink_ctx *ctx, struct cmd *cmd) +{ + struct table *table; + struct chain *chain; + int err; + + table = table_alloc(); + handle_merge(&table->handle, &cmd->handle); + table_add_hash(table); + + switch (cmd->obj) { + case CMD_OBJ_CHAIN: + err = netlink_get_chain(ctx, &cmd->handle); + if (err < 0) + return err; + list_splice_tail_init(&ctx->list, &table->chains); + chain = chain_lookup(table, &cmd->handle); + + return netlink_rename_chain(ctx, &chain->handle, cmd->arg); + default: + BUG("invalid command object type %u\n", cmd->obj); + } + return 0; +} + int do_command(struct netlink_ctx *ctx, struct cmd *cmd) { switch (cmd->op) { @@ -535,6 +561,8 @@ int do_command(struct netlink_ctx *ctx, struct cmd *cmd) return do_command_list(ctx, cmd); case CMD_FLUSH: return do_command_flush(ctx, cmd); + case CMD_RENAME: + return do_command_rename(ctx, cmd); default: BUG("invalid command object type %u\n", cmd->obj); } diff --git a/src/scanner.l b/src/scanner.l index de2373da..47397691 100644 --- a/src/scanner.l +++ b/src/scanner.l @@ -245,6 +245,7 @@ addrstring ({macaddr}|{ip4addr}|{ip6addr}) "delete" { return DELETE; } "list" { return LIST; } "flush" { return FLUSH; } +"rename" { return RENAME; } "counter" { return COUNTER; } -- cgit v1.2.3