Skip to content

Commit 0d83717

Browse files
committed
ffac-private-wan-dhcp: route private WAN clients' IPv6 over the LTE uplink
On uplink up, update.lua now also creates an IPv6 policy-routing rule (network.lte_clients, a rule6) that sends traffic from the LTE /64 into the LTE routing table (lookup 1, priority 9999), using the prefix already derived from wwan0; removed on down. Without it the clients received an IPv6 address but had no connectivity, because their traffic fell back to the main table whose default route points at the Freifunk mesh. NAT-free, since the cellular uplink is point-to-point and the whole /64 is routed to the device (RFC 7278). ffac-web-private-wan-dhcp: fix the IPv6 DNS field reusing the dns_server option id (now uradvd_dns_server). Assisted-by: Claude Opus 4.8 <noreply@anthropic.com>
1 parent c6a991b commit 0d83717

5 files changed

Lines changed: 62 additions & 11 deletions

File tree

ffac-private-wan-dhcp/Makefile

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
include $(TOPDIR)/rules.mk
44

55
PKG_NAME:=ffac-private-wan-dhcp
6-
PKG_VERSION:=1.0
6+
PKG_VERSION:=1.1
77
PKG_RELEASE:=1
88

99
PKG_LICENSE:=BSD-2-Clause
@@ -16,10 +16,14 @@ define Package/$(PKG_NAME)
1616
endef
1717

1818
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
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
2222
directed through the LTE connection, providing an uninterrupted and low-latency internet experience.
23+
24+
Includes IPv6 support: the LTE /64 is advertised to private WAN clients via uradvd and an IPv6
25+
policy-routing rule (rule6) sends their traffic through the LTE routing table instead of the
26+
Freifunk default route. The rule is (re)created with the current prefix on every uplink ifup.
2327
endef
2428

2529
$(eval $(call BuildPackageGluon,$(PKG_NAME)))

ffac-private-wan-dhcp/README.md

Lines changed: 29 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,32 @@
11
# ffac-private-wan-dhcp
22

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.
3+
Allows devices connected to a private WAN WiFi (terminating an LTE/DSL uplink) to
4+
use that uplink directly instead of being offloaded into the Freifunk mesh.
55

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.
6+
On `ifup` of the cellular uplink (`cellular` / `cellular_4`) it:
7+
8+
* switches the `wan` interface to a static IPv4 net and runs a DHCP server on it
9+
(range, lease, DNS configurable via `/etc/config/private-wan-dhcp`),
10+
* sets up firewall rules + NAT (`wan``wwan`) so IPv4 clients reach the internet,
11+
* requests a `/64` on the cellular interface, derives the current global IPv6 /64
12+
from `wwan0` and advertises it to the private WAN clients via **uradvd** on `br-wan`,
13+
* **adds an IPv6 policy-routing rule** (`network.lte_clients`, a `rule6`) that sends
14+
traffic from that /64 into the LTE routing table (lookup `1`, priority `9999`).
15+
Without it the clients' IPv6 traffic falls back to the `main` table, whose
16+
default route points at Freifunk — so they would get an address but no internet.
17+
18+
The IPv6 rule is recreated with the *current* prefix on every uplink `ifup`, so it
19+
survives provider prefix changes automatically. On `ifdown` all of the above
20+
(including the rule) is reverted.
21+
22+
## Config options (`/etc/config/private-wan-dhcp`)
23+
24+
* `enabled` — master switch (`0`/`1`)
25+
* `ipaddr` / `netmask` — advertised private WAN IPv4 network
26+
* `dns_server` — IPv4 DNS advertised via dnsmasq
27+
* `uradvd_dns_server` — IPv6 DNS advertised via uradvd (list)
28+
29+
> Why NAT-free routing works for IPv6: the cellular uplink (`wwan0`) is a
30+
> point-to-point link and the mobile network routes the whole /64 to the device
31+
> (3GPP / RFC 7278). The /64 can therefore be handed to clients and routed
32+
> directly — no NAT66 or NDP proxy required.

ffac-private-wan-dhcp/luasrc/lib/gluon/private-wan-dhcp-nat/update.lua

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,21 @@ local function add_dhcp_config()
166166

167167
-- uradvd reload
168168
os.execute("/etc/init.d/uradvd reload")
169+
170+
-- IPv6-Policy-Routing: Traffic der br-wan-Clients aus dem LTE-/64 ueber
171+
-- Tabelle 1 (LTE-Default via wwan0) leiten. Ohne diese Regel faellt der
172+
-- Client-Traffic auf Tabelle 'main' zurueck -> dort zeigt die v6-Default-
173+
-- Route auf Freifunk (br-client), und die Clients kommen nicht ueber LTE raus.
174+
-- Die Section wird mit dem AKTUELLEN Praefix neu gesetzt; da dieses Skript
175+
-- bei jedem 'ifup' der LTE-Schnittstelle laeuft, ist die Regel praefix-sicher.
176+
uci:delete('network', 'lte_clients')
177+
uci:section('network', 'rule6', 'lte_clients', {
178+
src = ipv6_prefix,
179+
lookup = '1',
180+
priority = '9999',
181+
})
182+
uci:save('network')
183+
os.execute("/etc/init.d/network reload")
169184
end
170185
end
171186

@@ -177,6 +192,9 @@ local function remove_dhcp_config()
177192
uci:set('dhcp', 'wan', 'ignore')
178193
uci:save('dhcp')
179194

195+
-- IPv6-Policy-Routing-Regel wieder entfernen
196+
uci:delete('network', 'lte_clients')
197+
180198
uci:set('network', 'wan', 'proto', 'dhcp')
181199
uci:delete('network', 'wan', 'ipaddr')
182200
uci:delete('network', 'wan', 'netmask')
@@ -185,6 +203,9 @@ local function remove_dhcp_config()
185203
os.execute("/etc/init.d/firewall reload")
186204
os.execute("/etc/init.d/dnsmasq reload")
187205

206+
-- evtl. noch live haengende Regel (Prio 9999) sicher abraeumen
207+
os.execute("while ip -6 rule del priority 9999 2>/dev/null; do :; done")
208+
188209
delete_uradvd_section('br-wan')
189210
uci:save('uradvd')
190211

ffac-web-private-wan-dhcp/Makefile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ include $(TOPDIR)/rules.mk
22

33
PKG_NAME:=ffac-web-private-wan-dhcp
44
PKG_VERSION:=1
5-
PKG_RELEASE:=1
5+
PKG_RELEASE:=2
66

77
include $(TOPDIR)/../package/gluon.mk
88

ffac-web-private-wan-dhcp/luasrc/lib/gluon/config-mode/model/admin/ffac_private_wan_dhcp.lua

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,9 @@ netmask.default = uci:get('private-wan-dhcp', 'settings', 'netmask', '255.255.25
1616
local dns_server = s:option(Value, "dns_server", translate("Static DNS servers") .. ' ' ..translate("IPv4"))
1717
dns_server.default = uci:get('private-wan-dhcp', 'settings', 'dns_server', '9.9.9.9')
1818

19-
local uradvd_dns_server = s:option(Value, "dns_server", translate("Static DNS servers") .. ' ' .. translate("IPv6"))
20-
uradvd_dns_server.default = uci:get('private-wan-dhcp', 'settings', 'uradvd_dns_server', '9.9.9.9')
19+
local uradvd_dns_server = s:option(Value, "uradvd_dns_server",
20+
translate("Static DNS servers") .. ' ' .. translate("IPv6"))
21+
uradvd_dns_server.default = uci:get('private-wan-dhcp', 'settings', 'uradvd_dns_server', '2620:fe::fe')
2122

2223
function f:write()
2324
uci:set('private-wan-dhcp', 'settings', 'enabled', enabled.data)

0 commit comments

Comments
 (0)