summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--include/rule.h2
-rw-r--r--src/evaluate.c1
-rw-r--r--src/parser_bison.y4
-rw-r--r--src/rule.c38
4 files changed, 42 insertions, 3 deletions
diff --git a/include/rule.h b/include/rule.h
index f137a4c8..30b4597d 100644
--- a/include/rule.h
+++ b/include/rule.h
@@ -270,6 +270,7 @@ enum cmd_ops {
* @CMD_OBJ_SETS: multiple sets
* @CMD_OBJ_RULE: rule
* @CMD_OBJ_CHAIN: chain
+ * @CMD_OBJ_CHAINS: multiple chains
* @CMD_OBJ_TABLE: table
* @CMD_OBJ_RULESET: ruleset
* @CMD_OBJ_EXPR: expression
@@ -283,6 +284,7 @@ enum cmd_obj {
CMD_OBJ_SETS,
CMD_OBJ_RULE,
CMD_OBJ_CHAIN,
+ CMD_OBJ_CHAINS,
CMD_OBJ_TABLE,
CMD_OBJ_RULESET,
CMD_OBJ_EXPR,
diff --git a/src/evaluate.c b/src/evaluate.c
index e8eafc64..97625864 100644
--- a/src/evaluate.c
+++ b/src/evaluate.c
@@ -2105,6 +2105,7 @@ static int cmd_evaluate_list(struct eval_ctx *ctx, struct cmd *cmd)
return cmd_error(ctx, "Could not process rule: Chain '%s' does not exist",
cmd->handle.chain);
return 0;
+ case CMD_OBJ_CHAINS:
case CMD_OBJ_SETS:
case CMD_OBJ_RULESET:
return 0;
diff --git a/src/parser_bison.y b/src/parser_bison.y
index 3c371ba3..86e2dc95 100644
--- a/src/parser_bison.y
+++ b/src/parser_bison.y
@@ -780,6 +780,10 @@ list_cmd : TABLE table_spec
{
$$ = cmd_alloc(CMD_LIST, CMD_OBJ_CHAIN, &$2, &@$, NULL);
}
+ | CHAINS ruleset_spec
+ {
+ $$ = cmd_alloc(CMD_LIST, CMD_OBJ_CHAINS, &$2, &@$, NULL);
+ }
| SETS tables_spec
{
$$ = cmd_alloc(CMD_LIST, CMD_OBJ_SETS, &$2, &@$, NULL);
diff --git a/src/rule.c b/src/rule.c
index fa3d4c11..344e3967 100644
--- a/src/rule.c
+++ b/src/rule.c
@@ -604,10 +604,8 @@ static const char *chain_policy2str(uint32_t policy)
return "unknown";
}
-static void chain_print(const struct chain *chain)
+static void chain_print_declaration(const struct chain *chain)
{
- struct rule *rule;
-
printf("\tchain %s {\n", chain->handle.chain);
if (chain->flags & CHAIN_F_BASECHAIN) {
if (chain->dev != NULL) {
@@ -623,6 +621,14 @@ static void chain_print(const struct chain *chain)
chain->priority, chain_policy2str(chain->policy));
}
}
+}
+
+static void chain_print(const struct chain *chain)
+{
+ struct rule *rule;
+
+ chain_print_declaration(chain);
+
list_for_each_entry(rule, &chain->rules, list) {
printf("\t\t");
rule_print(rule);
@@ -1037,6 +1043,30 @@ static int do_list_tables(struct netlink_ctx *ctx, struct cmd *cmd)
return 0;
}
+static int do_list_chains(struct netlink_ctx *ctx, struct cmd *cmd)
+{
+ struct table *table;
+ struct chain *chain;
+
+ list_for_each_entry(table, &table_list, list) {
+ if (cmd->handle.family != NFPROTO_UNSPEC &&
+ cmd->handle.family != table->handle.family)
+ continue;
+
+ printf("table %s %s {\n",
+ family2str(table->handle.family),
+ table->handle.table);
+
+ list_for_each_entry(chain, &table->chains, list) {
+ chain_print_declaration(chain);
+ printf("\t}\n");
+ }
+ printf("}\n");
+ }
+
+ return 0;
+}
+
static int do_list_set(struct netlink_ctx *ctx, struct cmd *cmd,
struct table *table)
{
@@ -1064,6 +1094,8 @@ static int do_command_list(struct netlink_ctx *ctx, struct cmd *cmd)
return do_list_table(ctx, cmd, table);
case CMD_OBJ_CHAIN:
return do_list_table(ctx, cmd, table);
+ case CMD_OBJ_CHAINS:
+ return do_list_chains(ctx, cmd);
case CMD_OBJ_SETS:
return do_list_sets(ctx, cmd);
case CMD_OBJ_SET: