Message ID | 20220913211601.30750-1-riemensberger@cadami.net |
---|---|
State | New |
Headers | show |
Series | bridge: Support nf_call_{ip,ip6,arp}tables attributes | expand |
Hi Maximilian Le mar. 13 sept. 2022, 17:23, Maximilian Riemensberger <riemensberger@cadami.net> a écrit : > > The bridge driver allows passing bridged frames to netfilter. Add > bridge config options nf_call_iptables, nf_call_ip6tables, > nf_call_arptables to opt in. You should have a look at using nftables instead, no need for those coarse grain options and way more flexible / powerful. https://wiki.nftables.org/wiki-nftables/index.php/Bridge_filtering Here an example switching from iptables + br_netfilter to nftables + table bridge: https://github.com/nccgroup/phantap/commit/b066ce2c2bb21038958a117b3b67413e9a0ea0a3 https://github.com/openwrt/packages/commit/66b7c19992688b924d2ecbbbc20781b32a82452f Etienne
Hi Etienne, On 9/14/22 02:24, Etienne Champetier wrote: >> The bridge driver allows passing bridged frames to netfilter. Add >> bridge config options nf_call_iptables, nf_call_ip6tables, >> nf_call_arptables to opt in. > > You should have a look at using nftables instead, > no need for those coarse grain options and way more flexible / powerful. > https://wiki.nftables.org/wiki-nftables/index.php/Bridge_filtering > > Here an example switching from iptables + br_netfilter to nftables + > table bridge: > https://github.com/nccgroup/phantap/commit/b066ce2c2bb21038958a117b3b67413e9a0ea0a3 > https://github.com/openwrt/packages/commit/66b7c19992688b924d2ecbbbc20781b32a82452f Thanks for the hints. Unfortunately, we use openNDS for splash portals, which is relying heavily on legacy iptables etc. So we are well served by those bridge settings. Exposing them as config parameters makes it much easier to configure them correctly per bridge within the lifecycle of an interface. We used to just globally enable the corresponding sysctls, but that's even cruder and has performance downsides if not all bridges need the filtering. Side note: How can I ensure with nftables that the cost of going to the firewall (ebtables/iptables replacement) is only incurred on some bridges? Or does nftables figure that out on it's own? With nf_call_iptables, I can set it on a per bridge basis. Best Max > > Etienne
Hi Etienne, On 9/14/22 02:24, Etienne Champetier wrote: >> The bridge driver allows passing bridged frames to netfilter. Add >> bridge config options nf_call_iptables, nf_call_ip6tables, >> nf_call_arptables to opt in. > > You should have a look at using nftables instead, > no need for those coarse grain options and way more flexible / powerful. > https://wiki.nftables.org/wiki-nftables/index.php/Bridge_filtering > > Here an example switching from iptables + br_netfilter to nftables + > table bridge: > https://github.com/nccgroup/phantap/commit/b066ce2c2bb21038958a117b3b67413e9a0ea0a3 > https://github.com/openwrt/packages/commit/66b7c19992688b924d2ecbbbc20781b32a82452f Thanks for the hints. Unfortunately, we use openNDS for splash portals, which is relying heavily on legacy iptables etc. So we are well served by those bridge settings. Exposing them as config parameters makes it much easier to configure them correctly per bridge within the lifecycle of an interface. We used to just globally enable the corresponding sysctls, but that's even cruder and has performance downsides if not all bridges need the filtering. Side note: How can I ensure with nftables that the cost of going to the firewall (ebtables/iptables replacement) is only incurred on some bridges? Or does nftables figure that out on it's own? With nf_call_iptables, I can set it on a per bridge basis. Best Max > > Etienne
diff --git a/bridge.c b/bridge.c index 7e61b9d..153e41f 100644 --- a/bridge.c +++ b/bridge.c @@ -43,6 +43,9 @@ enum { BRIDGE_ATTR_HAS_VLANS, BRIDGE_ATTR_STP_KERNEL, BRIDGE_ATTR_STP_PROTO, + BRIDGE_ATTR_NF_CALL_IPTABLES, + BRIDGE_ATTR_NF_CALL_IP6TABLES, + BRIDGE_ATTR_NF_CALL_ARPTABLES, __BRIDGE_ATTR_MAX }; @@ -66,6 +69,9 @@ static const struct blobmsg_policy bridge_attrs[__BRIDGE_ATTR_MAX] = { [BRIDGE_ATTR_HAS_VLANS] = { "__has_vlans", BLOBMSG_TYPE_BOOL }, /* internal */ [BRIDGE_ATTR_STP_KERNEL] = { "stp_kernel", BLOBMSG_TYPE_BOOL }, [BRIDGE_ATTR_STP_PROTO] = { "stp_proto", BLOBMSG_TYPE_STRING }, + [BRIDGE_ATTR_NF_CALL_IPTABLES] = { "nf_call_iptables", BLOBMSG_TYPE_BOOL }, + [BRIDGE_ATTR_NF_CALL_IP6TABLES] = { "nf_call_ip6tables", BLOBMSG_TYPE_BOOL }, + [BRIDGE_ATTR_NF_CALL_ARPTABLES] = { "nf_call_arptables", BLOBMSG_TYPE_BOOL }, }; static const struct uci_blob_param_info bridge_attr_info[__BRIDGE_ATTR_MAX] = { @@ -1114,6 +1120,15 @@ bridge_apply_settings(struct bridge_state *bst, struct blob_attr **tb) if ((cur = tb[BRIDGE_ATTR_VLAN_FILTERING])) cfg->vlan_filtering = blobmsg_get_bool(cur); + + if ((cur = tb[BRIDGE_ATTR_NF_CALL_IPTABLES])) + cfg->nf_call_iptables = blobmsg_get_bool(cur); + + if ((cur = tb[BRIDGE_ATTR_NF_CALL_IP6TABLES])) + cfg->nf_call_ip6tables = blobmsg_get_bool(cur); + + if ((cur = tb[BRIDGE_ATTR_NF_CALL_ARPTABLES])) + cfg->nf_call_arptables = blobmsg_get_bool(cur); } static enum dev_change_type diff --git a/system-dummy.c b/system-dummy.c index b13bc87..811404d 100644 --- a/system-dummy.c +++ b/system-dummy.c @@ -32,8 +32,10 @@ int system_init(void) int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg) { - D(SYSTEM, "brctl addbr %s vlan_filtering=%d\n", - bridge->ifname, cfg->vlan_filtering); + D(SYSTEM, + "brctl addbr %s vlan_filtering=%d nf_call_iptables=%d nf_call_ip6tables=%d nf_call_arptables=%d\n", + bridge->ifname, cfg->vlan_filtering, cfg->nf_call_iptables, + cfg->nf_call_ip6tables, cfg->nf_call_arptables); return 0; } diff --git a/system-linux.c b/system-linux.c index 0f13a99..71e9ec6 100644 --- a/system-linux.c +++ b/system-linux.c @@ -1342,6 +1342,9 @@ int system_bridge_addbr(struct device *bridge, struct bridge_config *cfg) } nla_put_u8(msg, IFLA_BR_VLAN_FILTERING, !!cfg->vlan_filtering); + nla_put_u8(msg, IFLA_BR_NF_CALL_IPTABLES, !!cfg->nf_call_iptables); + nla_put_u8(msg, IFLA_BR_NF_CALL_IP6TABLES, !!cfg->nf_call_ip6tables); + nla_put_u8(msg, IFLA_BR_NF_CALL_ARPTABLES, !!cfg->nf_call_arptables); nla_put_u16(msg, IFLA_BR_PRIORITY, cfg->priority); nla_put_u32(msg, IFLA_BR_HELLO_TIME, sec_to_jiffies(cfg->hello_time)); nla_put_u32(msg, IFLA_BR_MAX_AGE, sec_to_jiffies(cfg->max_age)); diff --git a/system.h b/system.h index 0f08c26..c551b13 100644 --- a/system.h +++ b/system.h @@ -208,6 +208,10 @@ struct bridge_config { int hash_max; bool vlan_filtering; + + bool nf_call_iptables; + bool nf_call_ip6tables; + bool nf_call_arptables; }; enum macvlan_opt {
The bridge driver allows passing bridged frames to netfilter. Add bridge config options nf_call_iptables, nf_call_ip6tables, nf_call_arptables to opt in. Signed-off-by: Maximilian Riemensberger <riemensberger@cadami.net> --- bridge.c | 15 +++++++++++++++ system-dummy.c | 6 ++++-- system-linux.c | 3 +++ system.h | 4 ++++ 4 files changed, 26 insertions(+), 2 deletions(-)