This commit is contained in:
Maciej Krüger 2023-05-10 07:46:31 -07:00 committed by GitHub
commit 087105d439
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
117 changed files with 599 additions and 438 deletions

2
.github/labeler.yml vendored
View File

@ -28,7 +28,7 @@
- package/gluon-mesh-vpn-fastd/** - package/gluon-mesh-vpn-fastd/**
"3. topic: firewall": "3. topic: firewall":
- package/**/*-firewall - package/**/*-firewall
- package/gluon-ebtables-*/** - package/gluon-nftables-*/**
"3. topic: hardware": "3. topic: hardware":
- package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac - package/gluon-core/luasrc/lib/gluon/upgrade/010-primary-mac
- package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua - package/gluon-core/luasrc/usr/lib/lua/gluon/platform.lua

View File

@ -81,10 +81,17 @@ files["package/**/luasrc/lib/gluon/**/controller/*"] = {
}, },
} }
files["package/**/luasrc/lib/gluon/ebtables/*"] = { files["package/**/luasrc/lib/gluon/nftables/*"] = {
read_globals = { read_globals = {
"chain", "path",
"include",
"rule", "rule",
"bridge_rule",
"bridge_chain",
"bridge_table",
"bridge_include_rule",
"bridge_include_table",
}, },
max_line_length = false, max_line_length = false,
} }

View File

@ -7,9 +7,6 @@
GLUON_FEATURES := \ GLUON_FEATURES := \
autoupdater \ autoupdater \
ebtables-filter-multicast \
ebtables-filter-ra-dhcp \
ebtables-limit-arp \
mesh-olsrd \ mesh-olsrd \
mesh-vpn-fastd \ mesh-vpn-fastd \
respondd \ respondd \

View File

@ -29,10 +29,10 @@ the workflow using these scripts:
contrib/run_qemu.sh output/images/factory/[...]-x86-64.img contrib/run_qemu.sh output/images/factory/[...]-x86-64.img
# apply changes to the desired package # apply changes to the desired package
vi package/gluon-ebtables/files/etc/init.d/gluon-ebtables vi package/gluon-nftables/files/etc/init.d/gluon-nftables
# rebuild and push the package to the qemu instance # rebuild and push the package to the qemu instance
contrib/push_pkg.sh package/gluon-ebtables/ contrib/push_pkg.sh package/gluon-nftables/
# test your changes # test your changes
... ...
@ -41,7 +41,7 @@ the workflow using these scripts:
... ...
# rebuild and push the package to the qemu instance # rebuild and push the package to the qemu instance
contrib/push_pkg.sh package/gluon-ebtables/ contrib/push_pkg.sh package/gluon-nftables/
# test your changes # test your changes
... ...
@ -83,7 +83,7 @@ Note that:
* If you add new packages, you must run ``make update config GLUON_TARGET=...``. * If you add new packages, you must run ``make update config GLUON_TARGET=...``.
* You can change the gluon target of the target machine via ``make config GLUON_TARGET=...``. * You can change the gluon target of the target machine via ``make config GLUON_TARGET=...``.
* If you want to update the ``site.conf`` of the target machine, use ``push_pkg.sh package/gluon-site/``. * If you want to update the ``site.conf`` of the target machine, use ``push_pkg.sh package/gluon-site/``.
* Sometimes when things break, you can heal them by compiling a package with its dependencies: ``cd openwrt; make package/gluon-ebtables/clean; make package/gluon-ebtables/compile; cd ..``. * Sometimes when things break, you can heal them by compiling a package with its dependencies: ``cd openwrt; make package/gluon-nftables/clean; make package/gluon-nftables/compile; cd ..``.
* You can exit qemu by pressing ``CTRL + a`` and ``c`` afterwards. * You can exit qemu by pressing ``CTRL + a`` and ``c`` afterwards.
Gluon package makefiles Gluon package makefiles

View File

@ -62,10 +62,10 @@ Several Freifunk communities in Germany use Gluon as the foundation of their Fre
package/gluon-client-bridge package/gluon-client-bridge
package/gluon-config-mode-domain-select package/gluon-config-mode-domain-select
package/gluon-ebtables-filter-multicast package/gluon-nftables-filter-multicast
package/gluon-ebtables-filter-ra-dhcp package/gluon-nftables-filter-ra-dhcp
package/gluon-ebtables-limit-arp package/gluon-nftables-limit-arp
package/gluon-ebtables-source-filter package/gluon-nftables-source-filter
package/gluon-hoodselector package/gluon-hoodselector
package/gluon-logging package/gluon-logging
package/gluon-mesh-batman-adv package/gluon-mesh-batman-adv

View File

@ -7,9 +7,9 @@
GLUON_FEATURES := \ GLUON_FEATURES := \
autoupdater \ autoupdater \
ebtables-filter-multicast \ nftables-filter-multicast \
ebtables-filter-ra-dhcp \ nftables-filter-ra-dhcp \
ebtables-limit-arp \ nftables-limit-arp \
mesh-batman-adv-15 \ mesh-batman-adv-15 \
mesh-vpn-fastd \ mesh-vpn-fastd \
respondd \ respondd \

View File

@ -13,7 +13,7 @@ domain and will see each other "as if they were connected to one giant switch".
This comes with a set of advantages (like quick and economical client device roaming, This comes with a set of advantages (like quick and economical client device roaming,
layer 3 protocol agnosticism, broadcast/multicast). But also impediments, especially layer 3 protocol agnosticism, broadcast/multicast). But also impediments, especially
layer 2 multicast overhead - which Gluon tries to mitigate to achieve a certain degree layer 2 multicast overhead - which Gluon tries to mitigate to achieve a certain degree
of scalability. See :doc:`gluon-ebtables-filter-multicast` and of scalability. See :doc:`gluon-nftables-filter-multicast` and
:ref:`batman-adv-multicast-architecture` for details. :ref:`batman-adv-multicast-architecture` for details.
B.A.T.M.A.N. Advanced project homepage: B.A.T.M.A.N. Advanced project homepage:
@ -53,9 +53,9 @@ While generally broadcast capability is a nice feature of a layer 2
mesh protocol, it quickly reaches its limit. mesh protocol, it quickly reaches its limit.
For meshes with about **50 nodes / 100 clients, or more** it is therefore highly For meshes with about **50 nodes / 100 clients, or more** it is therefore highly
recommended to add the :doc:`gluon-ebtables-filter-multicast` recommended to add the :doc:`gluon-nftables-filter-multicast`
package. Also, with the *mesh-batman-adv-15* feature, package. Also, with the *mesh-batman-adv-15* feature,
:doc:`gluon-ebtables-limit-arp` is selected by default. :doc:`gluon-nftables-limit-arp` is selected by default.
Furthermore, by default IGMP and MLD messages are filtered. See Furthermore, by default IGMP and MLD messages are filtered. See
:ref:`site.conf mesh section <user-site-mesh>` and :ref:`site.conf mesh section <user-site-mesh>` and

View File

@ -1,7 +1,7 @@
gluon-ebtables-filter-multicast gluon-nftables-filter-multicast
=============================== ===============================
The *gluon-ebtables-filter-multicast* package filters out various kinds of The *gluon-nftables-filter-multicast* package filters out various kinds of
non-essential multicast traffic, as this traffic often constitutes a non-essential multicast traffic, as this traffic often constitutes a
disproportionate burden on the mesh network. Unfortunately, this breaks many useful services disproportionate burden on the mesh network. Unfortunately, this breaks many useful services
(Avahi, Bonjour chat, ...), but this seems unavoidable, as the current Avahi implementation is (Avahi, Bonjour chat, ...), but this seems unavoidable, as the current Avahi implementation is

View File

@ -1,7 +1,7 @@
gluon-ebtables-filter-ra-dhcp gluon-nftables-filter-ra-dhcp
============================= =============================
The *gluon-ebtables-filter-ra-dhcp* package tries to prevent common The *gluon-nftables-filter-ra-dhcp* package tries to prevent common
misconfigurations (i.e. connecting the client interface of a Gluon misconfigurations (i.e. connecting the client interface of a Gluon
node to a private network) from causing issues for either of the node to a private network) from causing issues for either of the
networks. networks.

View File

@ -1,14 +1,14 @@
gluon-ebtables-limit-arp gluon-nftables-limit-arp
======================== ========================
The *gluon-ebtables-limit-arp* package adds filters to limit the The *gluon-nftables-limit-arp* package adds filters to limit the
amount of ARP requests client devices are allowed to send into the amount of ARP requests client devices are allowed to send into the
mesh. mesh.
The limits per client device, identified by its MAC address, are The limits per client device, identified by its MAC address, are
6 packets per minute and 1 per second per node in total. 6 packets per minute and 1 per second per node in total.
A burst of up to 50 ARP requests is allowed until the rate-limiting A burst of up to 50 ARP requests is allowed until the rate-limiting
takes effect (see ``--limit-burst`` in ``ebtables(8)``). takes effect (see ``--limit-burst`` in ``nftables(8)``).
Furthermore, ARP requests for a target IP already present in the Furthermore, ARP requests for a target IP already present in the
batman-adv DAT cache are excluded from rate-limiting, in regard batman-adv DAT cache are excluded from rate-limiting, in regard
@ -26,4 +26,4 @@ feature is *mesh-batman-adv-15*.
It can be unselected via:: It can be unselected via::
GLUON_SITE_PACKAGES := \ GLUON_SITE_PACKAGES := \
-gluon-ebtables-limit-arp -gluon-nftables-limit-arp

View File

@ -1,7 +1,7 @@
gluon-ebtables-source-filter gluon-nftables-source-filter
============================ ============================
The *gluon-ebtables-source-filter* package adds an additional layer-2 filter The *gluon-nftables-source-filter* package adds an additional layer-2 filter
ruleset to prevent unreasonable traffic entering the network via the nodes. ruleset to prevent unreasonable traffic entering the network via the nodes.
Unreasonable means traffic entering the mesh via a node which source IP does Unreasonable means traffic entering the mesh via a node which source IP does
not belong to the configured IP space. not belong to the configured IP space.

View File

@ -35,7 +35,7 @@ connected to the client interface via cable or WLAN instead of via the mesh
fake TQ of 512, so that they are always preferred. fake TQ of 512, so that they are always preferred.
Be aware of problems if you plan to use local routers together with the Be aware of problems if you plan to use local routers together with the
:doc:`gluon-ebtables-filter-ra-dhcp` package. These router advertisements are :doc:`gluon-nftables-filter-ra-dhcp` package. These router advertisements are
filtered anyway and reach neither the node nor any other client. Therefore the filtered anyway and reach neither the node nor any other client. Therefore the
use of local routers is not possible as long as the package use of local routers is not possible as long as the package
``gluon-radv-filterd`` is used. ``gluon-radv-filterd`` is used.

View File

@ -105,7 +105,7 @@ New features
The new package *gluon-ebtables-source-filter* can be used to prevent traffic The new package *gluon-ebtables-source-filter* can be used to prevent traffic
using unexpected IP addresses or packet types from entering the mesh. using unexpected IP addresses or packet types from entering the mesh.
See also: :doc:`../package/gluon-ebtables-source-filter` See also: :doc:`../package/gluon-nftables-source-filter`
Bugfixes Bugfixes
~~~~~~~~ ~~~~~~~~

View File

@ -120,7 +120,7 @@ trying it out, please contact us on our mailing list or in our IRC channel.
gluon-ebtables-limit-arp enabled by default gluon-ebtables-limit-arp enabled by default
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The :doc:`../package/gluon-ebtables-limit-arp` package, introduced in Gluon The :doc:`../package/gluon-nftables-limit-arp` package, introduced in Gluon
2018.1, is now included by default. In case of issues, it can be removed by 2018.1, is now included by default. In case of issues, it can be removed by
adding ``-gluon-ebtables-limit-arp`` to *GLUON_SITE_PACKAGES*. adding ``-gluon-ebtables-limit-arp`` to *GLUON_SITE_PACKAGES*.

View File

@ -7,9 +7,9 @@
GLUON_FEATURES := \ GLUON_FEATURES := \
autoupdater \ autoupdater \
ebtables-filter-multicast \ nftables-filter-multicast \
ebtables-filter-ra-dhcp \ nftables-filter-ra-dhcp \
ebtables-limit-arp \ nftables-limit-arp \
mesh-batman-adv-15 \ mesh-batman-adv-15 \
mesh-vpn-fastd \ mesh-vpn-fastd \
respondd \ respondd \

View File

@ -38,7 +38,7 @@ when(_'web-advanced' and _'autoupdater', {
when(_'mesh-batman-adv-15', { when(_'mesh-batman-adv-15', {
'gluon-ebtables-limit-arp', 'gluon-nftables-limit-arp',
'gluon-radvd', 'gluon-radvd',
}) })

View File

@ -11,7 +11,7 @@ define Package/gluon-core
TITLE:=Base files of Gluon TITLE:=Base files of Gluon
DEPENDS:= \ DEPENDS:= \
+gluon-site +libgluonutil +libiwinfo-lua +lua-platform-info +lua-simple-uci +lua-hash +lua-jsonc \ +gluon-site +libgluonutil +libiwinfo-lua +lua-platform-info +lua-simple-uci +lua-hash +lua-jsonc \
+luabitop +luaposix +vxlan +odhcp6c +firewall +pretty-hostname +luabitop +luaposix +vxlan +odhcp6c +firewall4 +pretty-hostname
endef endef
define Package/gluon-core/description define Package/gluon-core/description

View File

@ -1,20 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-ebtables-filter-multicast
include ../gluon.mk
define Package/gluon-ebtables-filter-multicast
TITLE:=Ebtables filters for multicast packets
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv
endef
define Package/gluon-ebtables-filter-multicast/description
Gluon community wifi mesh firmware framework: Ebtables filters for multicast packets
These filters drop non-essential multicast traffic before it enters the mesh.
Allowed protocols are: DHCP, DHCPv6, ARP, ICMP, ICMPv6, BitTorrent local peer discovery, BABEL and OSPF
endef
$(eval $(call BuildPackageGluon,gluon-ebtables-filter-multicast))

View File

@ -1,7 +0,0 @@
-- Bridge loop avoidance
rule 'MULTICAST_OUT -p ARP --arp-opcode Reply --arp-gratuitous --arp-mac-dst ff:43:05:00:00:00/ff:ff:ff:fc:00:00 -j RETURN'
rule 'MULTICAST_OUT -p ARP --arp-opcode Reply --arp-gratuitous --arp-mac-dst ff:43:05:05:00:00/ff:ff:ff:ff:00:00 -j RETURN'
rule 'MULTICAST_OUT -p ARP --arp-opcode Reply --arp-ip-src 0.0.0.0 -j DROP'
rule 'MULTICAST_OUT -p ARP --arp-opcode Request --arp-ip-dst 0.0.0.0 -j DROP'
rule 'MULTICAST_OUT -p ARP -j RETURN'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol udp --ip6-destination-port 6696 -j RETURN'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv4 --ip-destination 239.192.152.143 --ip-protocol udp --ip-destination-port 6771 -j RETURN'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv4 --ip-protocol udp --ip-destination-port 67 -j RETURN'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol udp --ip6-destination-port 547 -j RETURN'

View File

@ -1,3 +0,0 @@
rule 'MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type echo-request -j RETURN'
rule 'MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 139 -j RETURN' -- ICMP Node Information Query
rule 'MULTICAST_OUT_ICMPV6 -j ACCEPT'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv4 --ip-protocol igmp -j RETURN'

View File

@ -1,2 +0,0 @@
rule 'MULTICAST_OUT -p IPv4 --ip-protocol ospf -j RETURN'
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol ospf -j RETURN'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol udp --ip6-destination-port 1001 --ip6-dst ff05::2:1001 -j RETURN'

View File

@ -1 +0,0 @@
rule 'MULTICAST_OUT -p IPv6 --ip6-protocol udp --ip6-destination ff02::9 --ip6-destination-port 521 -j RETURN'

View File

@ -1,3 +0,0 @@
rule ('MULTICAST_OUT -p IPv6 --ip6-dst ff02::1/128 -j DROP')
rule ('MULTICAST_OUT -p IPv6 --ip6-dst ff00::/8 -j mark --set-mark 0x4 --mark-target RETURN')
rule ('MULTICAST_OUT -j DROP')

View File

@ -1,19 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-ebtables-filter-ra-dhcp
include ../gluon.mk
define Package/gluon-ebtables-filter-ra-dhcp
TITLE:=Ebtables filters for Router Advertisement and DHCP packets
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv
endef
define Package/gluon-ebtables-filter-ra-dhcp/description
Gluon community wifi mesh firmware framework: Ebtables filters for Router Advertisement and DHCP packets
These filters ensure that RA and DHCP packets are only forwarded from the mesh into the
client network, and not vice-versa.
endef
$(eval $(call BuildPackageGluon,gluon-ebtables-filter-ra-dhcp))

View File

@ -1,11 +0,0 @@
local uci = require('simple-uci').cursor()
local gw_mode = uci:get('network', 'gluon_bat0', 'gw_mode')
if gw_mode ~= 'server' then
rule 'FORWARD -p IPv4 --ip-protocol udp --ip-destination-port 67 -j OUT_ONLY'
rule 'OUTPUT -p IPv4 --ip-protocol udp --ip-destination-port 67 -j OUT_ONLY'
rule 'FORWARD -p IPv4 --ip-protocol udp --ip-destination-port 68 -j IN_ONLY'
rule 'INPUT -p IPv4 --ip-protocol udp --ip-destination-port 68 -j IN_ONLY'
end

View File

@ -1,5 +0,0 @@
rule 'FORWARD -p IPv6 --ip6-protocol udp --ip6-destination-port 547 -j OUT_ONLY'
rule 'OUTPUT -p IPv6 --ip6-protocol udp --ip6-destination-port 547 -j OUT_ONLY'
rule 'FORWARD -p IPv6 --ip6-protocol udp --ip6-destination-port 546 -j IN_ONLY'
rule 'INPUT -p IPv6 --ip6-protocol udp --ip6-destination-port 546 -j IN_ONLY'

View File

@ -1,5 +0,0 @@
rule 'FORWARD -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-solicitation -j OUT_ONLY'
rule 'OUTPUT -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-solicitation -j OUT_ONLY'
rule 'FORWARD -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-advertisement -j IN_ONLY'
rule 'INPUT -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-advertisement -j IN_ONLY'

View File

@ -1,3 +0,0 @@
chain('ARP_LIMIT', 'DROP')
chain('ARP_LIMIT_DATCHECK', 'RETURN')
chain('ARP_LIMIT_TLCHECK', 'RETURN')

View File

@ -1,6 +0,0 @@
rule('ARP_LIMIT -j ARP_LIMIT_DATCHECK')
rule('ARP_LIMIT --mark 0x2/0x2 -j RETURN')
rule('ARP_LIMIT -j ARP_LIMIT_TLCHECK')
rule('ARP_LIMIT --limit 1/sec --limit-burst 50 -j RETURN')
rule('FORWARD -p ARP --logical-out br-client -o bat0 --arp-op Request -j ARP_LIMIT')

View File

@ -1,17 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-ebtables-source-filter
include ../gluon.mk
define Package/gluon-ebtables-source-filter
TITLE:=Ebtables rules to filter unreasonable L2 traffic.
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv
endef
define Package/gluon-ebtables-source-filter/description
This package adds an additional layer-2 filter-ruleset to prevent unreasonable
traffic entering the network via the nodes.
endef
$(eval $(call BuildPackageGluon,gluon-ebtables-source-filter))

View File

@ -1 +0,0 @@
chain('LOCAL_FORWARD', 'DROP')

View File

@ -1,6 +0,0 @@
local prefix4 = require('gluon.site').prefix4()
if prefix4 then
rule('LOCAL_FORWARD -p ARP --arp-ip-src ' .. prefix4 .. ' --arp-ip-dst ' .. prefix4 .. ' -j RETURN')
rule('LOCAL_FORWARD -p ARP --arp-ip-src 0.0.0.0 --arp-ip-dst ' .. prefix4 .. ' -j RETURN')
end

View File

@ -1,6 +0,0 @@
local prefix4 = require('gluon.site').prefix4()
if prefix4 then
rule('LOCAL_FORWARD -p IPv4 --ip-protocol udp --ip-destination-port 67 -j RETURN')
rule('LOCAL_FORWARD -p IPv4 --ip-src ' .. prefix4 .. ' -j RETURN')
end

View File

@ -1,9 +0,0 @@
local site = require 'gluon.site'
rule('LOCAL_FORWARD -p IPv6 --ip6-src fe80::/64 -j RETURN')
rule('LOCAL_FORWARD -p IPv6 --ip6-src ::/128 --ip6-proto ipv6-icmp -j RETURN')
rule('LOCAL_FORWARD -p IPv6 --ip6-src ' .. site.prefix6() .. ' -j RETURN')
for _, prefix in ipairs(site.extra_prefixes6({})) do
rule('LOCAL_FORWARD -p IPv6 --ip6-src ' .. prefix .. ' -j RETURN')
end

View File

@ -1 +0,0 @@
rule('FORWARD --logical-in br-client -i ! bat0 -j LOCAL_FORWARD')

View File

@ -1,17 +0,0 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-ebtables
include ../gluon.mk
define Package/gluon-ebtables
TITLE:=Ebtables support
DEPENDS:=+gluon-core +ebtables-tiny \
+kmod-ebtables +kmod-ebtables-ipv4 +kmod-ebtables-ipv6
endef
define Package/gluon-ebtables/description
Gluon community wifi mesh firmware framework: ebtables support
endef
$(eval $(call BuildPackageGluon,gluon-ebtables))

View File

@ -1,80 +0,0 @@
#!/bin/sh /etc/rc.common
# Copyright (C) 2013 Project Gluon
#
# Firewall script for inserting and removing ebtables rules.
#
# Example format, for filtering any IPv4 multicast packets to the SSDP UDP port:
# rule FORWARD --logical-out br-client -d Multicast -p IPv4 --ip-protocol udp --ip-destination-port 5355 -j DROP
#
# Removing all rules:
# $ /etc/init.d/gluon-ebtables stop
# Inserting all rules:
# $ /etc/init.d/gluon-ebtables start
# Inserting a specific rule file:
# $ /etc/init.d/gluon-ebtables start /lib/gluon/ebtables/100-mcast-chain
# Removing a specific rule file:
# $ /etc/init.d/gluon-ebtables stop /lib/gluon/ebtables/100-mcast-chain
START=19
STOP=91
exec_file() {
local file="$1"
/usr/bin/lua -e "
function rule(command, table)
table = table or 'filter'
os.execute($EBTABLES_RULE)
end
function chain(name, policy, table)
table = table or 'filter'
os.execute($EBTABLES_CHAIN)
end
" "$file"
}
exec_all() {
local sort_arg="$1"
local old_ifs="$IFS"
IFS='
'
for file in `find /lib/gluon/ebtables -type f | sort $sort_arg`; do
exec_file "$file"
done
IFS="$old_ifs"
}
start() {
(
export EBTABLES_RULE='"ebtables-tiny -t " .. table .. " -A " .. command'
export EBTABLES_CHAIN='"ebtables-tiny -t " .. table .. " -N " .. name .. " -P " .. policy'
# Contains /var/lib/ebtables/lock for '--concurrent'
[ ! -d "/var/lib/ebtables" ] && \
mkdir -p /var/lib/ebtables
if [ -z "$1" ]; then
exec_all ''
else
exec_file "$1"
fi
)
}
stop() {
(
export EBTABLES_RULE='"ebtables-tiny -t " .. table .. " -D " .. command'
export EBTABLES_CHAIN='"ebtables-tiny -t " .. table .. " -X " .. name'
if [ -z "$1" ]; then
exec_all '-r'
else
exec_file "$1"
fi
)
}

View File

@ -1,2 +0,0 @@
#!/bin/sh
/etc/init.d/gluon-ebtables stop

View File

@ -1,2 +0,0 @@
#!/bin/sh
/etc/init.d/gluon-ebtables start

View File

@ -1,9 +0,0 @@
chain('IN_ONLY', 'RETURN')
chain('OUT_ONLY', 'RETURN')
-- nat chain runs early, so we can drop IGMP/MLD
chain('MULTICAST_IN', 'RETURN', 'nat')
chain('MULTICAST_IN_ICMPV6', 'RETURN', 'nat')
chain('MULTICAST_OUT', 'RETURN')
chain('MULTICAST_OUT_ICMPV6', 'RETURN')

View File

@ -1,7 +0,0 @@
rule 'IN_ONLY --logical-in br-client -i bat0 -j RETURN'
rule 'IN_ONLY --logical-in br-client -i local-port -j RETURN'
rule 'IN_ONLY --logical-in br-client -j DROP'
rule 'OUT_ONLY --logical-out br-client -o bat0 -j RETURN'
rule 'OUT_ONLY --logical-out br-client -o local-port -j RETURN'
rule 'OUT_ONLY --logical-out br-client -j DROP'

View File

@ -1,20 +0,0 @@
local site = require 'gluon.site'
rule('MULTICAST_IN -p IPv4 --ip-protocol igmp --ip-igmp-type membership-query -j DROP', 'nat')
rule('MULTICAST_OUT -p IPv4 --ip-protocol igmp --ip-igmp-type membership-query -j DROP')
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP') -- MLD Query
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 130 -j DROP', 'nat') -- MLD Query
if site.mesh.filter_membership_reports(true) then
rule('MULTICAST_IN -p IPv4 --ip-protocol igmp -j DROP', 'nat')
rule('MULTICAST_OUT -p IPv4 --ip-protocol igmp -j DROP')
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP') -- MLDv1 Report
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP') -- MLDv1 Done
rule('MULTICAST_OUT_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP') -- MLDv2 Report
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 131 -j DROP', 'nat') -- MLDv1 Report
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 132 -j DROP', 'nat') -- MLDv1 Done
rule('MULTICAST_IN_ICMPV6 -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type 143 -j DROP', 'nat') -- MLDv2 Report
end

View File

@ -1,3 +0,0 @@
*mangle
-A FORWARD -o mesh-vpn+ -p tcp -m tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu
COMMIT

View File

@ -1,10 +0,0 @@
#!/usr/bin/lua
local uci = require('simple-uci').cursor()
uci:section('firewall', 'include', 'vpn_clamp_mss', {
family = 'ipv6',
type = 'restore',
path = '/lib/gluon/mesh-vpn/iptables-mss.rules'
})
uci:save('firewall')

View File

@ -9,7 +9,7 @@ include ../gluon.mk
define Package/gluon-mesh-babel define Package/gluon-mesh-babel
TITLE:=Babel mesh TITLE:=Babel mesh
DEPENDS:=+gluon-core +babeld +gluon-mesh-layer3-common +libiwinfo +libgluonutil +firewall +libjson-c +libnl-tiny +libubus +libubox +libblobmsg-json +libbabelhelper +luabitop DEPENDS:=+gluon-core +babeld +gluon-mesh-layer3-common +libiwinfo +libgluonutil +firewall4 +libjson-c +libnl-tiny +libubus +libubox +libblobmsg-json +libbabelhelper +luabitop
PROVIDES:=gluon-mesh-provider PROVIDES:=gluon-mesh-provider
endef endef

View File

@ -12,8 +12,9 @@ define Package/gluon-mesh-batman-adv-15
+gluon-core \ +gluon-core \
+libgluonutil \ +libgluonutil \
+gluon-client-bridge \ +gluon-client-bridge \
+gluon-ebtables \ +gluon-nftables \
+firewall \ +gluon-nftables-multicast \
+firewall4 \
+libiwinfo \ +libiwinfo \
+kmod-dummy \ +kmod-dummy \
+libnl-tiny \ +libnl-tiny \

View File

@ -1,41 +0,0 @@
local client_bridge = require 'gluon.client_bridge'
local site = require 'gluon.site'
local next_node = site.next_node({})
local macaddr = client_bridge.next_node_macaddr()
rule('FORWARD --logical-out br-client -i bat0 -o local-port -j DROP')
rule('FORWARD --logical-out br-client -i local-port -o bat0 -j DROP')
rule('PREROUTING --logical-in br-client -i bat0 -s ' .. macaddr .. ' -j DROP', 'nat')
rule('PREROUTING --logical-in br-client -i bat0 -d ' .. macaddr .. ' -j DROP', 'nat')
rule('FORWARD --logical-out br-client -o bat0 -d ' .. macaddr .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -d ' .. macaddr .. ' -j DROP')
rule('FORWARD --logical-out br-client -o bat0 -s ' .. macaddr .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -s ' .. macaddr .. ' -j DROP')
if next_node.ip4 then
rule('FORWARD --logical-out br-client -o bat0 -p ARP --arp-ip-src ' .. next_node.ip4 .. ' -j DROP')
rule('FORWARD --logical-out br-client -o bat0 -p ARP --arp-ip-dst ' .. next_node.ip4 .. ' -j DROP')
rule('FORWARD --logical-out br-client -i bat0 -p ARP --arp-ip-src ' .. next_node.ip4 .. ' -j DROP')
rule('FORWARD --logical-out br-client -i bat0 -p ARP --arp-ip-dst ' .. next_node.ip4 .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -p ARP --arp-ip-src ' .. next_node.ip4 .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -p ARP --arp-ip-dst ' .. next_node.ip4 .. ' -j DROP')
rule('INPUT -i bat0 -p ARP --arp-ip-src ' .. next_node.ip4 .. ' -j DROP')
rule('INPUT -i bat0 -p ARP --arp-ip-dst ' .. next_node.ip4 .. ' -j DROP')
rule('FORWARD --logical-out br-client -o bat0 -p IPv4 --ip-destination ' .. next_node.ip4 .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -p IPv4 --ip-destination ' .. next_node.ip4 .. ' -j DROP')
rule('FORWARD --logical-out br-client -o bat0 -p IPv4 --ip-source ' .. next_node.ip4 .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -p IPv4 --ip-source ' .. next_node.ip4 .. ' -j DROP')
end
if next_node.ip6 then
rule('FORWARD --logical-out br-client -o bat0 -p IPv6 --ip6-destination ' .. next_node.ip6 .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -p IPv6 --ip6-destination ' .. next_node.ip6 .. ' -j DROP')
rule('FORWARD --logical-out br-client -o bat0 -p IPv6 --ip6-source ' .. next_node.ip6 .. ' -j DROP')
rule('OUTPUT --logical-out br-client -o bat0 -p IPv6 --ip6-source ' .. next_node.ip6 .. ' -j DROP')
end

View File

@ -1,2 +0,0 @@
rule 'INPUT -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-solicitation -i bat0 -j DROP'
rule 'OUTPUT -p IPv6 --ip6-protocol ipv6-icmp --ip6-icmp-type router-advertisement -o bat0 -j DROP'

View File

@ -0,0 +1,41 @@
local client_bridge = require 'gluon.client_bridge'
local site = require 'gluon.site'
local next_node = site.next_node({})
local macaddr = client_bridge.next_node_macaddr()
bridge_rule('FORWARD', 'obrname "br-client" iifname "bat0" oifname "bat0" drop')
bridge_rule('FORWARD', 'obrname "br-client" iifname "local-port" oifname "bat0" drop')
bridge_rule('PREROUTING', 'ibrname "br-client" iifname "bat0" ether saddr ' .. macaddr .. ' drop', 'nat')
bridge_rule('PREROUTING', 'ibrname "br-client" iifname "bat0" ether daddr ' .. macaddr .. ' drop', 'nat')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" ether daddr ' .. macaddr .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" ether daddr ' .. macaddr .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" ether saddr ' .. macaddr .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" ether saddr ' .. macaddr .. ' drop')
if next_node.ip4 then
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" arp saddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" arp daddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" iifname "bat0" arp saddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" arp daddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" arp saddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" arp daddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('INPUT', 'iifname "bat0" arp saddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('INPUT', 'iifname "bat0" arp daddr ip ' .. next_node.ip4 .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" ip daddr ' .. next_node.ip4 .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" ip daddr ' .. next_node.ip4 .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" ip saddr ' .. next_node.ip4 .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" ip saddr ' .. next_node.ip4 .. ' drop')
end
if next_node.ip6 then
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" ip6 daddr ' .. next_node.ip6 .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" ip6 daddr ' .. next_node.ip6 .. ' drop')
bridge_rule('FORWARD', 'obrname "br-client" oifname "bat0" ip6 saddr ' .. next_node.ip6 .. ' drop')
bridge_rule('OUTPUT', 'obrname "br-client" oifname "bat0" ip6 saddr ' .. next_node.ip6 .. ' drop')
end

View File

@ -0,0 +1,2 @@
bridge_rule('INPUT', 'iifname "bat0" icmpv6 type nd-router-solicit drop')
bridge_rule('OUTPUT', 'oifname "bat0" icmpv6 type nd-router-advert drop')

View File

@ -6,7 +6,7 @@ include ../gluon.mk
define Package/gluon-mesh-layer3-common define Package/gluon-mesh-layer3-common
TITLE:=Layer3 common files TITLE:=Layer3 common files
DEPENDS:=+gluon-core +gluon-mmfd +firewall DEPENDS:=+gluon-core +gluon-mmfd +firewall4
endef endef
$(eval $(call BuildPackageGluon,gluon-mesh-layer3-common)) $(eval $(call BuildPackageGluon,gluon-mesh-layer3-common))

View File

@ -6,7 +6,7 @@ include ../gluon.mk
define Package/gluon-mesh-vpn-core define Package/gluon-mesh-vpn-core
TITLE:=Basic support for connecting meshes via VPN tunnels TITLE:=Basic support for connecting meshes via VPN tunnels
DEPENDS:=+gluon-core +gluon-wan-dnsmasq +iptables-zz-legacy +iptables-mod-extra +simple-tc DEPENDS:=+gluon-core +gluon-nftables +gluon-wan-dnsmasq +simple-tc
USERID:=:gluon-mesh-vpn=800 USERID:=:gluon-mesh-vpn=800
endef endef

View File

@ -1,3 +0,0 @@
*nat
-I OUTPUT -m owner --gid-owner gluon-mesh-vpn -o lo -d 127.0.0.1 -p udp --dport 53 -j DNAT --to-destination :54
COMMIT

View File

@ -0,0 +1 @@
meta skgid gluon-mesh-vpn oifname "lo" ip daddr 127.0.0.1 udp dport 53 redirect to 54

View File

@ -0,0 +1,4 @@
include('mesh_vpn_dns', {
position = 'chain-pre',
chain = 'dstnat',
})

View File

@ -25,14 +25,6 @@ uci:save('network')
users.remove_user('gluon-fastd') users.remove_user('gluon-fastd')
users.remove_group('gluon-fastd') users.remove_group('gluon-fastd')
uci:section('firewall', 'include', 'mesh_vpn_dns', {
type = 'restore',
path = '/lib/gluon/mesh-vpn/iptables.rules',
family = 'ipv4',
})
uci:save('firewall')
-- VPN migration -- VPN migration
if not uci:get('gluon', 'mesh_vpn') then if not uci:get('gluon', 'mesh_vpn') then

View File

@ -1,12 +1,12 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-iptables-clamp-mss-to-pmtu PKG_NAME:=gluon-nftables-clamp-mss-to-pmtu
include ../gluon.mk include ../gluon.mk
define Package/$(PKG_NAME) define Package/$(PKG_NAME)
TITLE:=This will establish a firewall rule to clamp the mss to pmtu on the mesh-vpn interface when the connection is towards 64:ff9b::/96 TITLE:=This will establish a firewall rule to clamp the mss to pmtu on the mesh-vpn interface when the connection is towards 64:ff9b::/96
DEPENDS:= +ip6tables-zz-legacy DEPENDS:=+gluon-nftables
endef endef
define Package/$(PKG_NAME)/description define Package/$(PKG_NAME)/description

View File

@ -0,0 +1 @@
oifname "mesh-vpn*" tcp flags & (syn|rst) == syn counter tcp option maxseg size set rt mtu

View File

@ -0,0 +1,4 @@
include('mesh_vpn_clamp_mss_to_pmtu', {
position = 'chain-prepend',
chain = 'mangle_forward',
})

View File

@ -0,0 +1,20 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-nftables-filter-multicast
include ../gluon.mk
define Package/gluon-nftables-filter-multicast
TITLE:=nftables filters for multicast packets
DEPENDS:=+gluon-core +gluon-nftables +gluon-nftables-multicast +gluon-mesh-batman-adv
endef
define Package/gluon-nftables-filter-multicast/description
Gluon community wifi mesh firmware framework: nftables filters for multicast packets
These filters drop non-essential multicast traffic before it enters the mesh.
Allowed protocols are: DHCP, DHCPv6, ARP, ICMP, ICMPv6, BitTorrent local peer discovery, BABEL and OSPF
endef
$(eval $(call BuildPackageGluon,gluon-nftables-filter-multicast))

View File

@ -0,0 +1,7 @@
-- Bridge loop avoidance
-- bridge_rule('MULTICAST_OUT', 'arp operation reply arp saddr ip = arp daddr ip arp daddr ether ff:43:05:00:00:00/ff:ff:ff:fc:00:00 return')
-- bridge_rule('MULTICAST_OUT', 'arp operation reply arp saddr ip = arp daddr ip arp daddr ether ff:43:05:05:00:00/ff:ff:ff:ff:00:00 return')
bridge_rule('MULTICAST_OUT', 'arp operation reply arp saddr ip 0.0.0.0 drop')
bridge_rule('MULTICAST_OUT', 'arp operation request arp daddr ip 0.0.0.0 drop')
bridge_rule('MULTICAST_OUT', 'ether type arp return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip version 6 udp dport 6696 return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip daddr 239.192.152.143 udp dport 6771 return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip version 4 udp dport 67 return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip version 6 udp dport 547 return')

View File

@ -0,0 +1,3 @@
bridge_rule('MULTICAST_OUT_ICMPV6', 'icmpv6 type echo-request return')
bridge_rule('MULTICAST_OUT_ICMPV6', 'icmpv6 type 139 return')
bridge_rule('MULTICAST_OUT_ICMPV6', 'accept')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip protocol igmp return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip protocol ospf return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip6 daddr ff05::2:1001 udp dport 1001 return')

View File

@ -0,0 +1 @@
bridge_rule('MULTICAST_OUT', 'ip6 daddr ff02::9 udp dport 521 return')

View File

@ -0,0 +1,3 @@
bridge_rule('MULTICAST_OUT', 'ip6 daddr f02::1/128 drop')
bridge_rule('MULTICAST_OUT', 'ip6 daddr ff00::/8 mark 0x4 return')
bridge_rule('MULTICAST_OUT', 'drop')

View File

@ -0,0 +1,19 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-nftables-filter-ra-dhcp
include ../gluon.mk
define Package/gluon-nftables-filter-ra-dhcp
TITLE:=nftables filters for Router Advertisement and DHCP packets
DEPENDS:=+gluon-core +gluon-nftables +gluon-mesh-batman-adv
endef
define Package/gluon-nftables-filter-ra-dhcp/description
Gluon community wifi mesh firmware framework: nftables filters for Router Advertisement and DHCP packets
These filters ensure that RA and DHCP packets are only forwarded from the mesh into the
client network, and not vice-versa.
endef
$(eval $(call BuildPackageGluon,gluon-nftables-filter-ra-dhcp))

View File

@ -0,0 +1,11 @@
local uci = require('simple-uci').cursor()
local gw_mode = uci:get('network', 'gluon_bat0', 'gw_mode')
if gw_mode ~= 'server' then
bridge_rule('FORWARD', 'ip version 4 udp dport 67 jump out_only')
bridge_rule('OUTPUT', 'ip version 4 udp dport 67 jump out_only')
bridge_rule('FORWARD', 'ip version 4 udp dport 68 jump in_only')
bridge_rule('INPUT', 'ip version 4 udp dport 68 jump in_only')
end

View File

@ -0,0 +1,5 @@
bridge_rule('FORWARD', 'ip version 6 udp dport 547 jump out_only')
bridge_rule('OUTPUT', 'ip version 6 udp dport 547 jump out_only')
bridge_rule('FORWARD', 'ip version 6 udp dport 546 jump in_only')
bridge_rule('INPUT', 'ip version 6 udp dport 546 jump in_only')

View File

@ -0,0 +1,5 @@
bridge_rule('FORWARD', 'icmpv6 type nd-router-solicit jump out_only')
bridge_rule('OUTPUT', 'icmpv6 type nd-router-solicit jump out_only')
bridge_rule('FORWARD', 'icmpv6 type nd-router-advert jump in_only')
bridge_rule('INPUT', 'icmpv6 type nd-router-advert jump in_only')

View File

@ -1,16 +1,16 @@
include $(TOPDIR)/rules.mk include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-ebtables-limit-arp PKG_NAME:=gluon-nftables-limit-arp
include ../gluon.mk include ../gluon.mk
define Package/gluon-ebtables-limit-arp define Package/gluon-nftables-limit-arp
TITLE:=Ebtables limiter for ARP packets TITLE:=nftables limiter for ARP packets
DEPENDS:=+gluon-core +gluon-ebtables gluon-mesh-batman-adv DEPENDS:=+gluon-core +gluon-nftables +gluon-mesh-batman-adv
endef endef
define Package/gluon-ebtables-limit-arp/description define Package/gluon-nftables-limit-arp/description
Gluon community wifi mesh firmware framework: Ebtables rules to Gluon community wifi mesh firmware framework: nftables rules to
rate-limit ARP packets. rate-limit ARP packets.
This package adds filters to limit the amount of ARP Requests This package adds filters to limit the amount of ARP Requests
@ -19,7 +19,7 @@ define Package/gluon-ebtables-limit-arp/description
node in total. node in total.
A burst of up to 50 ARP Requests is allowed until the rate-limiting A burst of up to 50 ARP Requests is allowed until the rate-limiting
takes effect (see --limit-burst in the ebtables manpage). takes effect (see burst in the nft manpage).
Furthermore, ARP Requests with a target IP already present in the Furthermore, ARP Requests with a target IP already present in the
batman-adv DAT Cache are excluded from the rate-limiting, batman-adv DAT Cache are excluded from the rate-limiting,
@ -30,13 +30,15 @@ define Package/gluon-ebtables-limit-arp/description
However it should mitigate the problem of curious people or However it should mitigate the problem of curious people or
smart devices scanning the whole IP range. Which could create smart devices scanning the whole IP range. Which could create
a significant amount of overhead for all participants so far. a significant amount of overhead for all participants so far.
Note that this package currently only supports batman.
endef endef
define Package/gluon-ebtables-limit-arp/install define Package/gluon-nftables-limit-arp/install
$(Gluon/Build/Install) $(Gluon/Build/Install)
$(INSTALL_DIR) $(1)/usr/sbin/ $(INSTALL_DIR) $(1)/usr/sbin/
$(CP) $(PKG_BUILD_DIR)/gluon-arp-limiter $(1)/usr/sbin/gluon-arp-limiter $(CP) $(PKG_BUILD_DIR)/gluon-arp-limiter $(1)/usr/sbin/gluon-arp-limiter
endef endef
$(eval $(call BuildPackageGluon,gluon-ebtables-limit-arp)) $(eval $(call BuildPackageGluon,gluon-nftables-limit-arp))

View File

@ -0,0 +1,61 @@
set limitmac {
type ether_addr
}
set datips {
type ipv4_addr
}
# Rewrite arp packet target hardware address if target protocol address matches a given address.
# input meta iifname enp2s0 arp ptype 0x0800 arp htype 1 arp hlen 6 arp plen 4 @nh,192,32 0xc0a88f10 @nh,144,48 set 0x112233445566 accept
# chain('ARP_LIMIT', 'DROP')
chain arplimit {
# obrname "br-client" \
# oifname "bat0" \
# arp operation request \
# counter
# match everything which will land on bridge br-client
# protocol type: ipv4
# hardware type: ethernet
# hardware address length: 6 byte mac
# protocol address length: 4 byte ipv4
# arp request
# source address is mac to be limited
# target address is not in DAT
# we're over the limit
# count
# obrname "br-client" \
# oifname "bat0" \
arp ptype 0x0800 \
arp htype 1 \
arp hlen 6 \
arp plen 4 \
arp operation request \
arp saddr ether @limitmac \
arp daddr ip != @datips \
limit rate over 6/minute burst 50 packets \
counter \
drop
# obrname "br-client" \
# oifname "bat0" \
arp ptype 0x0800 \
arp htype 1 \
arp hlen 6 \
arp plen 4 \
arp operation request \
arp saddr ether != @limitmac \
arp daddr ip != @datips \
limit rate over 1/second burst 50 packets \
counter \
drop
}
# chain('ARP_LIMIT_DATCHECK', 'RETURN')
# %s ARP_LIMIT_DATCHECK -p ARP --arp-ip-dst %s -j mark --mark-or 0x2 --mark-target RETURN
# chain('ARP_LIMIT_TLCHECK', 'RETURN')
# %s ARP_LIMIT_TLCHECK --source %s --limit 6/min --limit-burst 50 -j RETURN"
# %s ARP_LIMIT_TLCHECK (add ? "2" : "") --source %s -j DROP

View File

@ -0,0 +1,6 @@
-- include('limit_arp', {
-- position = 'ruleset-pre'
-- })
bridge_include_table('pre', 'limit_arp_chain')
bridge_rule('FORWARD', 'oifname "bat0" obrname "br-client" arp operation request counter jump arplimit')

View File

@ -14,7 +14,7 @@
#define BATCTL_DC "/usr/sbin/batctl dc -H -n" #define BATCTL_DC "/usr/sbin/batctl dc -H -n"
#define BATCTL_TL "/usr/sbin/batctl tl -H -n" #define BATCTL_TL "/usr/sbin/batctl tl -H -n"
#define EBTABLES "/usr/sbin/ebtables-tiny" #define NFTABLES "/usr/sbin/nft"
#define BUILD_BUG_ON(check) ((void)sizeof(int[1-2*!!(check)])) #define BUILD_BUG_ON(check) ((void)sizeof(int[1-2*!!(check)]))
@ -39,13 +39,13 @@ static void ebt_ip_call(char *mod, struct in_addr ip)
int ret; int ret;
snprintf(str, sizeof(str), snprintf(str, sizeof(str),
EBTABLES " %s ARP_LIMIT_DATCHECK -p ARP --arp-ip-dst %s -j mark --mark-or 0x2 --mark-target RETURN", NFTABLES " %s element bridge gluon datips { %s }",
mod, inet_ntoa(ip)); mod, inet_ntoa(ip));
ret = system(str); ret = system(str);
if (ret) if (ret)
fprintf(stderr, fprintf(stderr,
"%i: Calling ebtables for DAT failed with status %i\n", "%i: Calling nft for DAT failed with status %i\n",
clock, ret); clock, ret);
} }
@ -53,7 +53,7 @@ static void ip_node_destructor(struct addr_list *node)
{ {
struct in_addr *ip = (struct in_addr *)node->addr; struct in_addr *ip = (struct in_addr *)node->addr;
ebt_ip_call("-D", *ip); ebt_ip_call("delete", *ip);
} }
static void ebt_mac_limit_call(char *mod, struct mac_addr *mac) static void ebt_mac_limit_call(char *mod, struct mac_addr *mac)
@ -62,40 +62,22 @@ static void ebt_mac_limit_call(char *mod, struct mac_addr *mac)
int ret; int ret;
snprintf(str, sizeof(str), snprintf(str, sizeof(str),
EBTABLES " %s ARP_LIMIT_TLCHECK --source %s --limit 6/min --limit-burst 50 -j RETURN", NFTABLES " %s element bridge gluon limitmac { %s }",
mod, mac_ntoa(mac)); mod, mac_ntoa(mac));
ret = system(str); ret = system(str);
if (ret) if (ret)
fprintf(stderr, fprintf(stderr,
"%i: Calling ebtables for TL failed with status %i\n", "%i: Calling nft for TL failed with status %i\n",
clock, ret);
}
static void ebt_mac_ret_call(char *mod, struct mac_addr *mac, int add)
{
char str[128];
int ret;
snprintf(str, sizeof(str),
EBTABLES " %s ARP_LIMIT_TLCHECK %s --source %s -j DROP",
mod, add ? "2" : "", mac_ntoa(mac));
ret = system(str);
if (ret)
fprintf(stderr,
"%i: Calling ebtables for TL failed with status %i\n",
clock, ret); clock, ret);
} }
static void ebt_mac_call(char *mod, struct mac_addr *mac) static void ebt_mac_call(char *mod, struct mac_addr *mac)
{ {
if (!strncmp(mod, "-D", strlen(mod))) { if (!strncmp(mod, "delete", strlen(mod))) {
ebt_mac_ret_call(mod, mac, 0);
ebt_mac_limit_call(mod, mac); ebt_mac_limit_call(mod, mac);
} else { } else {
ebt_mac_limit_call(mod, mac); ebt_mac_limit_call(mod, mac);
ebt_mac_ret_call(mod, mac, 1);
} }
} }
@ -103,7 +85,7 @@ static void mac_node_destructor(struct addr_list *node)
{ {
struct mac_addr *mac = (struct mac_addr *)node->addr; struct mac_addr *mac = (struct mac_addr *)node->addr;
ebt_mac_call("-D", mac); ebt_mac_call("delete", mac);
} }
static int dat_parse_line(const char *line, struct in_addr *ip) static int dat_parse_line(const char *line, struct in_addr *ip)
@ -141,7 +123,7 @@ static void ebt_add_ip(struct in_addr ip)
if (ret) if (ret)
return; return;
ebt_ip_call("-I", ip); ebt_ip_call("add", ip);
} }
static void ebt_add_mac(struct mac_addr *mac) static void ebt_add_mac(struct mac_addr *mac)
@ -152,7 +134,7 @@ static void ebt_add_mac(struct mac_addr *mac)
if (ret) if (ret)
return; return;
ebt_mac_call("-I", mac); ebt_mac_call("add", mac);
} }
static void ebt_dat_update(void) static void ebt_dat_update(void)
@ -168,7 +150,7 @@ static void ebt_dat_update(void)
fprintf(stderr, "%i: Error: Could not call batctl dc\n", clock); fprintf(stderr, "%i: Error: Could not call batctl dc\n", clock);
return; return;
} }
while (1) { while (1) {
pline = fgets(line, sizeof(line), fp); pline = fgets(line, sizeof(line), fp);
if (!pline) { if (!pline) {
@ -257,18 +239,18 @@ static void ebt_tl_update(void)
static void ebt_dat_flush(void) static void ebt_dat_flush(void)
{ {
int ret = system(EBTABLES " -F ARP_LIMIT_DATCHECK"); int ret = system(NFTABLES " flush set bridge gluon datips");
if (ret) if (ret)
fprintf(stderr, "Error flushing ARP_LIMIT_DATCHECK\n"); fprintf(stderr, "Error flushing arplimit datips set\n");
} }
static void ebt_tl_flush(void) static void ebt_tl_flush(void)
{ {
int ret = system(EBTABLES " -F ARP_LIMIT_TLCHECK"); int ret = system(NFTABLES " flush set bridge gluon limitmac");
if (ret) if (ret)
fprintf(stderr, "Error flushing ARP_LIMIT_TLCHECK\n"); fprintf(stderr, "Error flushing arplimit limitmac\n");
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

@ -0,0 +1,16 @@
include $(TOPDIR)/rules.mk
PKG_NAME:=gluon-nftables-multicast
include ../gluon.mk
define Package/gluon-nftables-multicast
TITLE:=nftables multicast filtering
DEPENDS:=+gluon-core +gluon-nftables
endef
define Package/gluon-nftables-multicast/description
Gluon community wifi mesh firmware framework: nftables multicast filtering
endef
$(eval $(call BuildPackageGluon,gluon-nftables-multicast))

View File

@ -0,0 +1,9 @@
bridge_chain('IN_ONLY')
bridge_chain('OUT_ONLY')
-- nat chain runs early, so we can drop IGMP/MLD
bridge_chain('MULTICAST_IN', nil, 'nat')
bridge_chain('MULTICAST_IN_ICMPV6', nil, 'nat')
bridge_chain('MULTICAST_OUT')
bridge_chain('MULTICAST_OUT_ICMPV6')

View File

@ -0,0 +1,5 @@
bridge_rule('IN_ONLY', 'ibrname "br-client" iifname { "bat0", "local-port" } return')
bridge_rule('IN_ONLY', 'drop')
bridge_rule('OUT_ONLY', 'obrname "br-client" oifname { "bat0", "local-port" } return')
bridge_rule('OUT_ONLY', 'drop')

Some files were not shown because too many files have changed in this diff Show More