From: Florian Westphal <fw@strlen.de>
To: netfilter-devel <netfilter-devel@vger.kernel.org>
Cc: Florian Westphal <fw@strlen.de>
Subject: [RFC ebtables-nft] unify ether type and meta protocol decoding
Date: Wed, 30 Nov 2022 12:37:18 +0100 [thread overview]
Message-ID: <20221130113718.85576-1-fw@strlen.de> (raw)
Handle "ether protocol" and "meta protcol" the same.
Problem is that this breaks the test case *again*:
I: [EXECUTING] iptables/tests/shell/testcases/ebtables/0006-flush_0
--A FORWARD --among-dst fe:ed:ba:be:13:37=10.0.0.1 -j ACCEPT
--A OUTPUT --among-src c0:ff:ee:90:0:0=192.168.0.1 -j DROP
+-A FORWARD -p IPv4 --among-dst fe:ed:ba:be:13:37=10.0.0.1 -j ACCEPT
+-A OUTPUT -p IPv4 --among-src c0:ff:ee:90:0:0=192.168.0.1 -j DROP
... because ebtables-nft will now render meta protocol as "-p IPv4".
ebtables-legacy does not have any special handling for this.
Solving this would need more internal annotations during decode, so
we can suppress/ignore "meta protocol" once a "among-type" set is
encountered.
Any (other) suggestions?
Signed-off-by: Florian Westphal <fw@strlen.de>
---
iptables/nft-bridge.c | 74 +++++++++++++++++++++++++++++++++++--------
1 file changed, 61 insertions(+), 13 deletions(-)
diff --git a/iptables/nft-bridge.c b/iptables/nft-bridge.c
index 50e90b22cf2f..4488ff172c2e 100644
--- a/iptables/nft-bridge.c
+++ b/iptables/nft-bridge.c
@@ -188,6 +188,64 @@ static int nft_bridge_add(struct nft_handle *h,
return _add_action(r, cs);
}
+static bool nft_bridge_parse_ethproto(struct nft_xt_ctx *ctx,
+ struct nftnl_expr *e,
+ struct iptables_command_state *cs)
+{
+ struct ebt_entry *fw = &cs->eb;
+ bool already_seen;
+ uint16_t ethproto;
+ uint8_t op;
+
+ already_seen = (fw->bitmask & EBT_NOPROTO) == 0;
+
+ __get_cmp_data(e, ðproto, sizeof(ethproto), &op);
+
+ switch (op) {
+ case NFT_CMP_EQ:
+ if (already_seen && fw->invflags & EBT_IPROTO) {
+ ctx->errmsg = "ethproto eq test contradicts previous";
+ return false;
+ }
+ break;
+ case NFT_CMP_NEQ:
+ if (already_seen && (fw->invflags & EBT_IPROTO) == 0) {
+ ctx->errmsg = "ethproto ne test contradicts previous";
+ return false;
+ }
+ fw->invflags |= EBT_IPROTO;
+ break;
+ case NFT_CMP_GTE:
+ if (already_seen && (fw->invflags & EBT_IPROTO) == 0) {
+ ctx->errmsg = "ethproto gte test contradicts previous";
+ return false;
+ }
+ fw->invflags |= EBT_IPROTO;
+ /* fallthrough */
+ case NFT_CMP_LT:
+ /* -p Length mode */
+ if (ethproto == htons(0x0600))
+ fw->bitmask |= EBT_802_3;
+ break;
+ default:
+ ctx->errmsg = "ethproto only supports eq/ne test";
+ return false;
+ }
+
+ if (already_seen) {
+ if (fw->ethproto != ethproto) {
+ ctx->errmsg = "ethproto ne test contradicts previous";
+ return false;
+ }
+ } else if ((fw->bitmask & EBT_802_3) == 0) {
+ fw->ethproto = ethproto;
+ }
+
+ fw->bitmask &= ~EBT_NOPROTO;
+
+ return true;
+}
+
static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
const struct nft_xt_ctx_reg *reg,
struct nftnl_expr *e,
@@ -199,6 +257,7 @@ static void nft_bridge_parse_meta(struct nft_xt_ctx *ctx,
switch (reg->meta_dreg.key) {
case NFT_META_PROTOCOL:
+ nft_bridge_parse_ethproto(ctx, e, cs);
return;
}
@@ -241,8 +300,6 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
{
struct ebt_entry *fw = &cs->eb;
unsigned char addr[ETH_ALEN];
- unsigned short int ethproto;
- uint8_t op;
bool inv;
int i;
@@ -275,17 +332,8 @@ static void nft_bridge_parse_payload(struct nft_xt_ctx *ctx,
fw->bitmask |= EBT_ISOURCE;
break;
case offsetof(struct ethhdr, h_proto):
- __get_cmp_data(e, ðproto, sizeof(ethproto), &op);
- if (ethproto == htons(0x0600)) {
- fw->bitmask |= EBT_802_3;
- inv = (op == NFT_CMP_GTE);
- } else {
- fw->ethproto = ethproto;
- inv = (op == NFT_CMP_NEQ);
- }
- if (inv)
- fw->invflags |= EBT_IPROTO;
- fw->bitmask &= ~EBT_NOPROTO;
+ if (!nft_bridge_parse_ethproto(ctx, e, cs))
+ return;
break;
}
}
--
2.38.1
next reply other threads:[~2022-11-30 11:37 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2022-11-30 11:37 Florian Westphal [this message]
2022-11-30 14:47 ` [RFC ebtables-nft] unify ether type and meta protocol decoding Phil Sutter
2022-12-01 10:16 ` Florian Westphal
2022-12-01 11:40 ` Phil Sutter
2022-12-20 20:44 ` [iptables RFC] ebtables: among: Embed meta protocol match into set lookup Phil Sutter
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20221130113718.85576-1-fw@strlen.de \
--to=fw@strlen.de \
--cc=netfilter-devel@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).