summaryrefslogtreecommitdiffstats
path: root/iptables/nft-bridge.h
diff options
context:
space:
mode:
authorPhil Sutter <phil@nwl.cc>2019-08-21 00:42:13 +0200
committerPhil Sutter <phil@nwl.cc>2019-11-25 23:31:14 +0100
commit26753888720d8e7eb422ae4311348347f5a05cb4 (patch)
treedd3b4041e08e0eaac8d08fdac1045a4f103c7303 /iptables/nft-bridge.h
parent6d19208caf8325649b9c7888fa8b3db796807c20 (diff)
nft: bridge: Rudimental among extension support
Support among match as far as possible given the limitations of nftables sets, namely limited to homogeneous MAC address only or MAC and IP address only matches. Signed-off-by: Phil Sutter <phil@nwl.cc> Acked-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'iptables/nft-bridge.h')
-rw-r--r--iptables/nft-bridge.h56
1 files changed, 56 insertions, 0 deletions
diff --git a/iptables/nft-bridge.h b/iptables/nft-bridge.h
index d90066f1..eb1b3928 100644
--- a/iptables/nft-bridge.h
+++ b/iptables/nft-bridge.h
@@ -122,4 +122,60 @@ void ebt_add_watcher(struct xtables_target *watcher,
struct iptables_command_state *cs);
int ebt_command_default(struct iptables_command_state *cs);
+struct nft_among_pair {
+ struct ether_addr ether;
+ struct in_addr in __attribute__((aligned (4)));
+};
+
+struct nft_among_data {
+ struct {
+ size_t cnt;
+ bool inv;
+ bool ip;
+ } src, dst;
+ /* first source, then dest pairs */
+ struct nft_among_pair pairs[0];
+};
+
+/* initialize fields, return offset into pairs array to write pairs to */
+static inline size_t
+nft_among_prepare_data(struct nft_among_data *data, bool dst,
+ size_t cnt, bool inv, bool ip)
+{
+ size_t poff;
+
+ if (dst) {
+ data->dst.cnt = cnt;
+ data->dst.inv = inv;
+ data->dst.ip = ip;
+ poff = data->src.cnt;
+ } else {
+ data->src.cnt = cnt;
+ data->src.inv = inv;
+ data->src.ip = ip;
+ poff = 0;
+ memmove(data->pairs + cnt, data->pairs,
+ data->dst.cnt * sizeof(*data->pairs));
+ }
+ return poff;
+}
+
+static inline void
+nft_among_insert_pair(struct nft_among_pair *pairs,
+ size_t *pcount, const struct nft_among_pair *new)
+{
+ int i;
+
+ /* nftables automatically sorts set elements from smallest to largest,
+ * insert sorted so extension comparison works */
+
+ for (i = 0; i < *pcount; i++) {
+ if (memcmp(new, &pairs[i], sizeof(*new)) < 0)
+ break;
+ }
+ memmove(&pairs[i + 1], &pairs[i], sizeof(*pairs) * (*pcount - i));
+ memcpy(&pairs[i], new, sizeof(*new));
+ (*pcount)++;
+}
+
#endif