diff --git a/package/gluon-client-isolation/Makefile b/package/gluon-client-isolation/Makefile new file mode 100644 index 00000000..e64822ba --- /dev/null +++ b/package/gluon-client-isolation/Makefile @@ -0,0 +1,40 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=gluon-client-isolation + +include ../gluon.mk + +define Package/gluon-client-isolation + TITLE:=Support for client isolation over batman-adv + DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv +endef + +define Package/gluon-client-isolation/description + This package provides client isolation in a batman-adv + bridged layer 2 network. + + To use it, mesh.isolate must be set in the site or + domain configuration. + + When it is set to wireless, wireless clients are isolated from + other wireless clients, wireless to wired, wired to wireless + and wire to wired traffic is not affected in this mode. + + When it is set to all, wired traffic is also isolated. + + To isolate the clients connected to the same wireless interface, + it sets the isolate option in the wireless configuration for + the client and owe wifi interfaces. + + To extend the isolation the ap_isolation and isolation_mark + options are set for the gluon_bat0 network interface. + + A new filter chain ISOLATED is added to ebtables, through which + all traffic of br-client is routed. + Depending the value of mesh.isolate, the traffic is marked when + it arrives from the interfaces to isolate and batman-adv + restores the mark for isolated traffic from other nodes. + The marked traffic will not be forwarded to isolated interfaces. +endef + +$(eval $(call BuildPackageGluon,gluon-client-isolation)) diff --git a/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/100-isolated-chain b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/100-isolated-chain new file mode 100644 index 00000000..37147cd0 --- /dev/null +++ b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/100-isolated-chain @@ -0,0 +1 @@ +chain('ISOLATED', 'ACCEPT') diff --git a/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/110-mark-isolated-rules b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/110-mark-isolated-rules new file mode 100644 index 00000000..b77dd9b6 --- /dev/null +++ b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/110-mark-isolated-rules @@ -0,0 +1,12 @@ +local isolate = require('gluon.site').mesh.isolate("none") + +if isolate == "all" then + for _,dev in ipairs({ 'eth0', 'eth1', 'client0', 'client1', 'owe0', 'owe1' }) do + rule('ISOLATED -i ' .. dev .. ' -j mark --mark-or 0x10 --mark-target CONTINUE') + end +end +if isolate == "wireless" then + for _,dev in ipairs({ 'client0', 'client1', 'owe0', 'owe1' }) do + rule('ISOLATED -i ' .. dev .. ' -j mark --mark-or 0x10 --mark-target CONTINUE') + end +end diff --git a/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/120-drop-marked-isolated-rules b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/120-drop-marked-isolated-rules new file mode 100644 index 00000000..1e5a65cc --- /dev/null +++ b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/120-drop-marked-isolated-rules @@ -0,0 +1,12 @@ +local isolate = require('gluon.site').mesh.isolate("none") + +if isolate == "all" then + for _,dev in ipairs({ 'eth0', 'eth1', 'client0', 'client1', 'owe0', 'owe1' }) do + rule('ISOLATED -o ' .. dev .. ' --mark 0x10/0x10 -j DROP') + end +end +if isolate == "wireless" then + for _,dev in ipairs({ 'client0', 'client1', 'owe0', 'owe1' }) do + rule('ISOLATED -o ' .. dev .. ' --mark 0x10/0x10 -j DROP') + end +end diff --git a/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/400-isolated-rules b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/400-isolated-rules new file mode 100644 index 00000000..1fa1aebb --- /dev/null +++ b/package/gluon-client-isolation/luasrc/lib/gluon/ebtables/400-isolated-rules @@ -0,0 +1 @@ +rule('FORWARD --logical-in br-client -j ISOLATED') diff --git a/package/gluon-client-isolation/luasrc/lib/gluon/upgrade/340-client-isolation b/package/gluon-client-isolation/luasrc/lib/gluon/upgrade/340-client-isolation new file mode 100755 index 00000000..aecbe700 --- /dev/null +++ b/package/gluon-client-isolation/luasrc/lib/gluon/upgrade/340-client-isolation @@ -0,0 +1,38 @@ +#!/usr/bin/lua + +local site = require 'gluon.site' +local wireless = require 'gluon.wireless' + +local isolate = site.mesh.isolate("none") + +local uci = require('simple-uci').cursor() + +wireless.foreach_radio(uci, function(radio) + local radio_name = radio['.name'] + vif = 'client_' .. radio_name + if uci:get('wireless', vif) then + uci:delete('wireless', vif, 'isolate') + if isolate == "all" or isolate == "wireless" then + uci:set('wireless', vif, 'isolate', '1') + end + end + vif = 'owe_' .. radio_name + if uci:get('wireless', vif) then + uci:delete('wireless', vif, 'isolate') + if isolate == "all" or isolate == "wireless" then + uci:set('wireless', vif, 'isolate', '1') + end + end +end) + +uci:save('wireless') + +uci:delete('network', 'gluon_bat0', 'ap_isolation') +uci:delete('network', 'gluon_bat0', 'isolation_mark') + +if isolate == "all" or isolate == "wireless" then + uci:set('network', 'gluon_bat0', 'ap_isolation', '1') + uci:set('network', 'gluon_bat0', 'isolation_mark', '0x10/0x10') +end + +uci:save('network')