Skip to content

Commit 0f6d813

Browse files
authored
Merge pull request #177 from freifunk-gluon/ffac-private-wan-dhcp
ffac-private-wan-dhcp: add initial version of uci package and web config
2 parents 1dcca7b + 4abedca commit 0f6d813

13 files changed

Lines changed: 384 additions & 0 deletions

File tree

ffac-private-wan-dhcp/LICENSE

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
BSD 2-Clause License
2+
3+
Copyright (c) 2024, Marius Wehrmann
4+
5+
Redistribution and use in source and binary forms, with or without
6+
modification, are permitted provided that the following conditions are met:
7+
8+
1. Redistributions of source code must retain the above copyright notice, this
9+
list of conditions and the following disclaimer.
10+
11+
2. Redistributions in binary form must reproduce the above copyright notice,
12+
this list of conditions and the following disclaimer in the documentation
13+
and/or other materials provided with the distribution.
14+
15+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

ffac-private-wan-dhcp/Makefile

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
# SPDX-FileCopyrightText: 2024 Marius Wehrmann
2+
# SPDX-License-Identifier: BSD-2-Clause
3+
include $(TOPDIR)/rules.mk
4+
5+
PKG_NAME:=ffac-private-wan-dhcp
6+
PKG_VERSION:=1.0
7+
PKG_RELEASE:=1
8+
9+
PKG_LICENSE:=BSD-2-Clause
10+
11+
include $(TOPDIR)/../package/gluon.mk
12+
13+
define Package/$(PKG_NAME)
14+
TITLE:=bypass FF-Offloading for Direct Network Access for LTE/DSL via Private WAN-Socket
15+
DEPENDS:=+uradvd
16+
endef
17+
18+
define Package/$(PKG_NAME)/description
19+
The functionality of this package allows devices connected to a private WAN WiFi to utilize the LTE WAN
20+
connection directly, without the typical redirection or offloading to local network resources. This is
21+
achieved by dynamically managing network routing and gateway settings to ensure that all traffic is
22+
directed through the LTE connection, providing an uninterrupted and low-latency internet experience.
23+
endef
24+
25+
$(eval $(call BuildPackageGluon,$(PKG_NAME)))

ffac-private-wan-dhcp/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
# ffac-private-wan-dhcp
2+
3+
This package adds dynamic uci configurations when a cellular or wan interface is made available.
4+
It can be used to activate and configure a DHCP server on devices which terminate an uplink connection.
5+
6+
On cellular devices, activating the private wlan creates an interface in which no gateway is set by default.
7+
For this situation, a dhcp server on br-wan is configured through this package.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
config settings 'settings'
2+
option enabled '0'
3+
option ipaddr '192.168.222.1'
4+
option netmask '255.255.255.0'
5+
option dns_server '9.9.9.9'
6+
list uradvd_dns_server '2620:fe::fe'
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
ENABLED=$(uci get private-wan-dhcp.settings.enabled)
2+
3+
[ "${ENABLED}" != "1" ] && exit 0
4+
5+
if [ "$INTERFACE" = 'cellular_4' ] || [ "$INTERFACE" = 'cellular' ]; then
6+
if [ "${ACTION}" == "ifup" ]; then
7+
/lib/gluon/private-wan-dhcp-nat/update.lua up
8+
elif [ "${ACTION}" == "ifdown" ]; then
9+
/lib/gluon/private-wan-dhcp-nat/update.lua down
10+
fi
11+
fi
Lines changed: 198 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,198 @@
1+
#!/usr/bin/lua
2+
3+
local uci = require('simple-uci').cursor()
4+
5+
-- Funktion zum Ausführen von Shell-Befehlen und Erfassen der Ausgabe
6+
local function shell(cmd)
7+
local f = io.popen(cmd)
8+
local result = f:read("*a")
9+
f:close()
10+
return result
11+
end
12+
13+
-- Funktion um uradvd config zu prüfen
14+
15+
-- Funktion um zu prüfen, ob eine Regel bereits existiert
16+
local function uradvd_config_exists(name)
17+
local exists = false
18+
uci:foreach('uradvd', 'interface', function(iface)
19+
if iface.ifname == name then
20+
exists = true
21+
return false
22+
end
23+
end)
24+
return exists
25+
end
26+
27+
-- Funktion um uradvd config zu löschen
28+
local function delete_uradvd_section(name)
29+
uci:delete_all('uradvd', 'interface', function(iface)
30+
return iface.ifname == name
31+
end)
32+
end
33+
34+
-- Funktion um zu prüfen, ob eine Regel bereits existiert
35+
local function rule_exists(name)
36+
local exists = false
37+
uci:foreach('firewall', 'rule', function(section)
38+
if section.name == name then
39+
exists = true
40+
return false
41+
end
42+
end)
43+
return exists
44+
end
45+
46+
-- Funktion um Regel zu löschen
47+
local function delete_rule(name)
48+
uci:delete_all('firewall', 'rule', function(section)
49+
return section.name == name
50+
end)
51+
end
52+
53+
-- Funktion um zu prüfen, ob ein Forwarding bereits existiert
54+
local function forwarding_exists(src, dest)
55+
local exists = false
56+
uci:foreach('firewall', 'forwarding', function(section)
57+
if section.src == src and section.dest == dest then
58+
exists = true
59+
return false
60+
end
61+
end)
62+
return exists
63+
end
64+
65+
-- Funktion um ein forwarding zu löschen
66+
local function delete_forwarding(src, dest)
67+
-- Funktion um Regel zu löschen
68+
uci:delete_all('firewall', 'forwarding', function(section)
69+
return section.src == src and section.dest == dest
70+
end)
71+
end
72+
73+
if #arg < 1 then
74+
io.stderr:write('Usage: update.lua up|down\n')
75+
os.exit(1)
76+
end
77+
78+
local function add_dhcp_config()
79+
-- IPv4 für DHCP vergeben auf WAN-Interface
80+
local ipaddr = uci:get('private-wan-dhcp','settings','ipaddr')
81+
local netmask = uci:get('private-wan-dhcp','settings','netmask')
82+
uci:set('network', 'wan', 'proto', 'static')
83+
uci:set('network', 'wan', 'ipaddr', ipaddr)
84+
uci:set('network', 'wan', 'netmask', netmask)
85+
-- IPv6 /64 netzwerk auf cellular anfragen
86+
uci:set('network', 'cellular', 'ip6assign', '64')
87+
88+
uci:save('network')
89+
90+
os.execute("/etc/init.d/network reload")
91+
92+
-- Forwarding über das wwan-Interface erlauben
93+
uci:set('firewall', '@zone[1]', 'forward', 'ACCEPT')
94+
95+
-- DHCP in Firewall auf WAN erlauben
96+
if not rule_exists('Allow-DHCP-WAN') then
97+
uci:add('firewall', 'rule')
98+
uci:set('firewall', '@rule[-1]', 'name', 'Allow-DHCP-WAN')
99+
uci:set('firewall', '@rule[-1]', 'src', 'wan')
100+
uci:set('firewall', '@rule[-1]', 'proto', 'udp')
101+
uci:set('firewall', '@rule[-1]', 'src_port', '67 68')
102+
uci:set('firewall', '@rule[-1]', 'dest_port', '67 68')
103+
uci:set('firewall', '@rule[-1]', 'target', 'ACCEPT')
104+
end
105+
106+
-- DNS in Firewall auf WAN erlauben
107+
if not rule_exists('Allow-DNS-WAN') then
108+
uci:add('firewall', 'rule')
109+
uci:set('firewall', '@rule[-1]', 'name', 'Allow-DNS-WAN')
110+
uci:set('firewall', '@rule[-1]', 'src', 'wan')
111+
uci:set('firewall', '@rule[-1]', 'proto', 'tcp udp')
112+
uci:set('firewall', '@rule[-1]', 'dest_port', '53')
113+
uci:set('firewall', '@rule[-1]', 'target', 'ACCEPT')
114+
end
115+
116+
-- NAT von wan auf wwan einrichten
117+
if not forwarding_exists('wan', 'wwan') then
118+
uci:add('firewall', 'forwarding')
119+
uci:set('firewall', '@forwarding[-1]', 'src', 'wan')
120+
uci:set('firewall', '@forwarding[-1]', 'dest', 'wwan')
121+
end
122+
123+
uci:save('firewall')
124+
125+
os.execute("/etc/init.d/firewall reload")
126+
127+
-- DHCP-Server einstellen für wan
128+
uci:delete('dhcp', 'wan', 'ignore')
129+
uci:set('dhcp', 'wan', 'start', '100')
130+
uci:set('dhcp', 'wan', 'limit', '150')
131+
uci:set('dhcp', 'wan', 'leasetime', '12h')
132+
uci:set('dhcp', 'wan', 'force', '1')
133+
local dns_server = uci:get('private-wan-dhcp','settings','dns_server')
134+
uci:set_list('dhcp', 'wan', 'dhcp_option', { '6,'..dns_server })
135+
uci:save('dhcp')
136+
os.execute("/etc/init.d/dnsmasq reload")
137+
138+
-- Aktuelles IPv6-Präfix von wwan0 abrufen, doppelte Einträge entfernen
139+
local ipv6_prefix_cmd = "ip -6 addr show dev wwan0 | "
140+
.. "grep 'global' | "
141+
.. "grep -v 'temporary' | "
142+
.. "awk '{print $2}' | "
143+
.. "cut -f1,2,3,4 -d':' | "
144+
.. "sed 's/$/::\\/64/' | "
145+
.. "sort | "
146+
.. "uniq"
147+
local ipv6_prefix = shell(ipv6_prefix_cmd):match("%S+")
148+
149+
-- Schauen ob Prefix gefunden, falls nein kein IPv6
150+
if ipv6_prefix then
151+
print("ipv6 prefix is", ipv6_prefix)
152+
-- Prüfen, ob eine vorhandene Konfiguration für das Interface 'br-wan' existiert
153+
if uradvd_config_exists('br-wan') then
154+
delete_uradvd_section('br-wan')
155+
end
156+
157+
local br_wan_section = uci:add('uradvd', 'interface')
158+
-- Konfiguration für 'br-wan' aktualisieren
159+
uci:set('uradvd', br_wan_section, 'enabled', '1')
160+
uci:set('uradvd', br_wan_section, 'ifname', 'br-wan')
161+
uci:set('uradvd', br_wan_section, 'default_lifetime', '1800')
162+
uci:set_list('uradvd', br_wan_section, 'prefix_on_link', {ipv6_prefix})
163+
local uradvd_dns_server = uci:get_list('private-wan-dhcp','settings','uradvd_dns_server')
164+
uci:set_list('uradvd', br_wan_section, 'dns', uradvd_dns_server)
165+
uci:save('uradvd')
166+
167+
-- uradvd reload
168+
os.execute("/etc/init.d/uradvd reload")
169+
end
170+
end
171+
172+
local function remove_dhcp_config()
173+
delete_rule('Allow-DHCP-WAN')
174+
delete_rule('Allow-DNS-WAN')
175+
delete_forwarding('wan', 'wwan')
176+
uci:save('firewall')
177+
uci:set('dhcp', 'wan', 'ignore')
178+
uci:save('dhcp')
179+
180+
uci:set('network', 'wan', 'proto', 'dhcp')
181+
uci:delete('network', 'wan', 'ipaddr')
182+
uci:delete('network', 'wan', 'netmask')
183+
uci:save('network')
184+
os.execute("/etc/init.d/network reload")
185+
os.execute("/etc/init.d/firewall reload")
186+
os.execute("/etc/init.d/dnsmasq reload")
187+
188+
delete_uradvd_section('br-wan')
189+
uci:save('uradvd')
190+
191+
os.execute("/etc/init.d/uradvd reload")
192+
end
193+
194+
if arg[1] == "up" then
195+
add_dhcp_config()
196+
elseif arg[1] == "down" then
197+
remove_dhcp_config()
198+
end

ffac-web-private-wan-dhcp/Makefile

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
include $(TOPDIR)/rules.mk
2+
3+
PKG_NAME:=ffac-web-private-wan-dhcp
4+
PKG_VERSION:=1
5+
PKG_RELEASE:=1
6+
7+
include $(TOPDIR)/../package/gluon.mk
8+
9+
define Package/$(PKG_NAME)
10+
TITLE:=gluon-web module to enable and disable ffac-private-wan-dhcp
11+
DEPENDS:=+gluon-web-admin +ffac-private-wan-dhcp
12+
endef
13+
14+
$(eval $(call BuildPackageGluon,$(PKG_NAME)))
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
# ffac-web-private-wan-dhcp
2+
3+
This package adds configuration options to the config mode to configure ffac-private-wan-dhcp.
4+
It can be used to activate a DHCP server on devices which terminate an uplink connection.
5+
6+
It allows to set the following:
7+
8+
* enabled
9+
* ipaddr of the advertised WAN network
10+
* netmask of the advertised WAN network
11+
* dns server for IPv4 (advertised with dnsmasq)
12+
* dns server for IPv6 (advertised with uradvd)
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: PACKAGE VERSION\n"
4+
"PO-Revision-Date: 2024-07-22 12:00+0100\n"
5+
"Last-Translator: <fmaurer@disroot.org>\n"
6+
"Language-Team: German\n"
7+
"Language: de\n"
8+
"MIME-Version: 1.0\n"
9+
"Content-Type: text/plain; charset=UTF-8\n"
10+
"Content-Transfer-Encoding: 8bit\n"
11+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
12+
13+
msgid "Enabled"
14+
msgstr "Aktiviert"
15+
16+
msgid "Private WAN DHCP"
17+
msgstr "Private WAN DHCP"
18+
19+
msgid "ffac-web-private-wan-dhcp:description"
20+
msgstr ""
21+
"Aktiviert eine private WAN-Zone with DHCP und NAT. Das ist für Anschlüsse, die das nicht nativ mitbringen interessant (Mobilfunk oder DSL)"
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
msgid ""
2+
msgstr ""
3+
"Project-Id-Version: PACKAGE VERSION\n"
4+
"PO-Revision-Date: 2024-07-22 12:00+0100\n"
5+
"Last-Translator: <fmaurer@disroot.org>\n"
6+
"Language-Team: English\n"
7+
"Language: de\n"
8+
"MIME-Version: 1.0\n"
9+
"Content-Type: text/plain; charset=UTF-8\n"
10+
"Content-Transfer-Encoding: 8bit\n"
11+
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
12+
13+
msgid "Enabled"
14+
msgstr "Enabled"
15+
16+
msgid "Private WAN DHCP"
17+
msgstr "Private WAN DHCP"
18+
19+
msgid "ffac-web-private-wan-dhcp:description"
20+
msgstr ""
21+
"Activates the private WAN with DHCP and NAT. This is relevant for cellular or dsl uplinks"

0 commit comments

Comments
 (0)