diff options
-rw-r--r-- | iptables/ebtables-nft.8 | 42 | ||||
-rw-r--r-- | iptables/nft-bridge.c | 36 | ||||
-rw-r--r-- | iptables/nft-shared.c | 39 | ||||
-rw-r--r-- | iptables/nft-shared.h | 3 | ||||
-rw-r--r-- | iptables/nft.c | 13 | ||||
-rw-r--r-- | iptables/nft.h | 3 | ||||
-rwxr-xr-x | iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 | 4 |
7 files changed, 112 insertions, 28 deletions
diff --git a/iptables/ebtables-nft.8 b/iptables/ebtables-nft.8 index d75aae24..0304b508 100644 --- a/iptables/ebtables-nft.8 +++ b/iptables/ebtables-nft.8 @@ -55,7 +55,7 @@ It is analogous to the application, but less complicated, due to the fact that the Ethernet protocol is much simpler than the IP protocol. .SS CHAINS -There are two ebtables tables with built-in chains in the +There are three ebtables tables with built-in chains in the Linux kernel. These tables are used to divide functionality into different sets of rules. Each set of rules is called a chain. Each chain is an ordered list of rules that can match Ethernet frames. If a @@ -81,7 +81,10 @@ an 'extension' (see below) or a jump to a user-defined chain. .B ACCEPT means to let the frame through. .B DROP -means the frame has to be dropped. +means the frame has to be dropped. In the +.BR BROUTING " chain however, the " ACCEPT " and " DROP " target have different" +meanings (see the info provided for the +.BR -t " option)." .B CONTINUE means the next rule has to be checked. This can be handy, f.e., to know how many frames pass a certain point in the chain, to log those frames or to apply multiple @@ -93,17 +96,13 @@ For the extension targets please refer to the .B "TARGET EXTENSIONS" section of this man page. .SS TABLES -As stated earlier, there are two ebtables tables in the Linux -kernel. The table names are -.BR filter " and " nat . -Of these two tables, +As stated earlier, the table names are +.BR filter ", " nat " and " broute . +Of these tables, the filter table is the default table that the command operates on. -If you are working with the filter table, then you can drop the '-t filter' -argument to the ebtables command. However, you will need to provide -the -t argument for -.B nat -table. Moreover, the -t argument must be the -first argument on the ebtables command line, if used. +If you are working with a table other than filter, you will need to provide +the -t argument. Moreover, the -t argument must be the +first argument on the ebtables command line, if used. .TP .B "-t, --table" .br @@ -131,6 +130,23 @@ iptables world to ebtables it is easier to have the same names. Note that you can change the name .BR "" ( -E ) if you don't like the default. +.br +.br +.B broute +is used to make a brouter, it has one built-in chain: +.BR BROUTING . +The targets +.BR DROP " and " ACCEPT +have a special meaning in the broute table (these names are used for +compatibility reasons with ebtables-legacy). +.B DROP +actually means the frame has to be routed, while +.B ACCEPT +means the frame has to be bridged. The +.B BROUTING +chain is traversed very early. +Normally those frames +would be bridged, but you can decide otherwise here. .SH EBTABLES COMMAND LINE ARGUMENTS After the initial ebtables '-t table' command line argument, the remaining arguments can be divided into several groups. These groups @@ -1059,8 +1075,6 @@ arp message and the hardware address length in the arp header is 6 bytes. .BR "" "See " http://netfilter.org/mailinglists.html .SH BUGS The version of ebtables this man page ships with does not support the -.B broute -table. Also there is no support for .B string match. Further, support for atomic-options .RB ( --atomic-file ", " --atomic-init ", " --atomic-save ", " --atomic-commit ) diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c index b9983b20..22860d6b 100644 --- a/iptables/nft-bridge.c +++ b/iptables/nft-bridge.c @@ -95,8 +95,44 @@ static void add_logical_outiface(struct nft_handle *h, struct nftnl_rule *r, add_cmp_ptr(r, op, iface, iface_len + 1, reg); } +static int add_meta_broute(struct nftnl_rule *r) +{ + struct nftnl_expr *expr; + + expr = nftnl_expr_alloc("immediate"); + if (expr == NULL) + return -1; + + nftnl_expr_set_u32(expr, NFTNL_EXPR_IMM_DREG, NFT_REG32_01); + nftnl_expr_set_u8(expr, NFTNL_EXPR_IMM_DATA, 1); + nftnl_rule_add_expr(r, expr); + + expr = nftnl_expr_alloc("meta"); + if (expr == NULL) + return -1; + nftnl_expr_set_u32(expr, NFTNL_EXPR_META_KEY, NFT_META_BRI_BROUTE); + nftnl_expr_set_u32(expr, NFTNL_EXPR_META_SREG, NFT_REG32_01); + + nftnl_rule_add_expr(r, expr); + return 0; +} + static int _add_action(struct nftnl_rule *r, struct iptables_command_state *cs) { + const char *table = nftnl_rule_get_str(r, NFTNL_RULE_TABLE); + + if (cs->target && + table && strcmp(table, "broute") == 0) { + if (strcmp(cs->jumpto, XTC_LABEL_DROP) == 0) { + int ret = add_meta_broute(r); + + if (ret) + return ret; + + cs->jumpto = "ACCEPT"; + } + } + return add_action(r, cs, false); } diff --git a/iptables/nft-shared.c b/iptables/nft-shared.c index 1b22eb7a..c19d78e4 100644 --- a/iptables/nft-shared.c +++ b/iptables/nft-shared.c @@ -511,8 +511,24 @@ void get_cmp_data(struct nftnl_expr *e, void *data, size_t dlen, bool *inv) *inv = (op == NFT_CMP_NEQ); } -static void nft_meta_set_to_target(struct nft_xt_ctx *ctx, - struct nftnl_expr *e) +static bool nft_parse_meta_set_common(struct nft_xt_ctx* ctx, + struct nft_xt_ctx_reg *sreg) +{ + if ((sreg->type != NFT_XT_REG_IMMEDIATE)) { + ctx->errmsg = "meta sreg is not an immediate"; + return false; + } + + if (sreg->immediate.data[0] == 0) { + ctx->errmsg = "meta sreg immediate is 0"; + return false; + } + + return true; +} + +static void nft_parse_meta_set(struct nft_xt_ctx *ctx, + struct nftnl_expr *e) { struct xtables_target *target; struct nft_xt_ctx_reg *sreg; @@ -528,18 +544,17 @@ static void nft_meta_set_to_target(struct nft_xt_ctx *ctx, switch (nftnl_expr_get_u32(e, NFTNL_EXPR_META_KEY)) { case NFT_META_NFTRACE: - if ((sreg->type != NFT_XT_REG_IMMEDIATE)) { - ctx->errmsg = "meta nftrace but reg not immediate"; + if (!nft_parse_meta_set_common(ctx, sreg)) return; - } - - if (sreg->immediate.data[0] == 0) { - ctx->errmsg = "trace is cleared"; - return; - } targname = "TRACE"; break; + case NFT_META_BRI_BROUTE: + if (!nft_parse_meta_set_common(ctx, sreg)) + return; + + ctx->cs->jumpto = "DROP"; + return; default: ctx->errmsg = "meta sreg key not supported"; return; @@ -568,7 +583,7 @@ static void nft_parse_meta(struct nft_xt_ctx *ctx, struct nftnl_expr *e) struct nft_xt_ctx_reg *reg; if (nftnl_expr_is_set(e, NFTNL_EXPR_META_SREG)) { - nft_meta_set_to_target(ctx, e); + nft_parse_meta_set(ctx, e); return; } @@ -1145,6 +1160,8 @@ static void nft_parse_immediate(struct nft_xt_ctx *ctx, struct nftnl_expr *e) /* Standard target? */ switch(verdict) { case NF_ACCEPT: + if (cs->jumpto && strcmp(ctx->table, "broute") == 0) + break; cs->jumpto = "ACCEPT"; break; case NF_DROP: diff --git a/iptables/nft-shared.h b/iptables/nft-shared.h index b8bc1a6c..2c4c0d90 100644 --- a/iptables/nft-shared.h +++ b/iptables/nft-shared.h @@ -61,6 +61,9 @@ struct nft_xt_ctx_reg { struct { uint32_t key; } meta_dreg; + struct { + uint32_t key; + } meta_sreg; }; struct { diff --git a/iptables/nft.c b/iptables/nft.c index 5ef5335a..1cb104e7 100644 --- a/iptables/nft.c +++ b/iptables/nft.c @@ -643,6 +643,19 @@ static const struct builtin_table xtables_bridge[NFT_TABLE_MAX] = { }, }, }, + [NFT_TABLE_BROUTE] = { + .name = "broute", + .type = NFT_TABLE_BROUTE, + .chains = { + { + .name = "BROUTING", + .type = "filter", + .prio = NF_BR_PRI_FIRST, + .hook = NF_BR_PRE_ROUTING, + }, + }, + }, + }; static int nft_table_builtin_add(struct nft_handle *h, diff --git a/iptables/nft.h b/iptables/nft.h index 56005863..1d18982d 100644 --- a/iptables/nft.h +++ b/iptables/nft.h @@ -14,8 +14,9 @@ enum nft_table_type { NFT_TABLE_RAW, NFT_TABLE_FILTER, NFT_TABLE_NAT, + NFT_TABLE_BROUTE, }; -#define NFT_TABLE_MAX (NFT_TABLE_NAT + 1) +#define NFT_TABLE_MAX (NFT_TABLE_BROUTE + 1) struct builtin_chain { const char *name; diff --git a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 index 6f11bd12..bae0de7d 100755 --- a/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 +++ b/iptables/tests/shell/testcases/ebtables/0001-ebtables-basic_0 @@ -15,13 +15,13 @@ get_entries_count() { # (chain) set -x -for t in filter nat;do +for t in filter nat broute; do $XT_MULTI ebtables -t $t -L || exit 1 $XT_MULTI ebtables -t $t -X || exit 1 $XT_MULTI ebtables -t $t -F || exit 1 done -for t in broute foobar ;do +for t in foobar; do $XT_MULTI ebtables -t $t -L && $XT_MULTI ebtables -t $t -X && $XT_MULTI ebtables -t $t -F |