miniupnpd: Fixes #39. Based on discussion with jow, use external interface if specifi...
authorMarkus Stenberg <markus.stenberg@iki.fi>
Mon, 23 Jun 2014 10:05:43 +0000 (13:05 +0300)
committerMarkus Stenberg <markus.stenberg@iki.fi>
Mon, 23 Jun 2014 10:05:43 +0000 (13:05 +0300)
miniupnpd/files/firewall.include
miniupnpd/files/miniupnpd.hotplug

index 5294c45db44113941aadfa9a9af33e0ede91da5f..9a42e0613f4ce11a11bca468fc5247af306c463f 100644 (file)
@@ -1,14 +1,6 @@
 #!/bin/sh
 # miniupnpd integration for firewall3
 
-# Note: Correct way to do this would be probably to use
-# /lib/functions/network.sh, and use network_find_wan{,6}, and then
-# network_get_device, then determine their zones using fw3 -q network
-# etc. However, network_find_wan* return only one device, and
-# frequently incorrect one if multiple ISPs are in use. So this
-# current ugly solution works, although perhaps makes holes where it
-# shouldn't (if so, do override it in e.g. firewall.user)
-
 IP6TABLES=/usr/sbin/ip6tables
 
 iptables -t filter -N MINIUPNPD 2>/dev/null
@@ -16,11 +8,42 @@ iptables -t nat -N MINIUPNPD 2>/dev/null
 
 [ -x $IP6TABLES ] && $IP6TABLES -t filter -N MINIUPNPD 2>/dev/null
 
-# IPv4 - due to NAT, need to add both to nat and filter table
-iptables -t filter -I delegate_forward 2 -j MINIUPNPD
-iptables -t nat -I delegate_prerouting 2 -j MINIUPNPD
+. /lib/functions/network.sh
+
+ADDED=0
+
+add_extzone_rules() {
+    local ext_zone=$1
 
-# IPv6 if available - filter only
-[ -x $IP6TABLES ] && {
-    $IP6TABLES -t filter -I delegate_forward 2 -j MINIUPNPD
+    [ -z "$ext_zone" ] && return
+
+    # IPv4 - due to NAT, need to add both to nat and filter table
+    iptables -t filter -I zone_${ext_zone}_forward -j MINIUPNPD
+    iptables -t nat -I zone_${ext_zone}_prerouting -j MINIUPNPD
+
+    # IPv6 if available - filter only
+    [ -x $IP6TABLES ] && {
+        $IP6TABLES -t filter -I zone_${ext_zone}_forward -j MINIUPNPD
+    }
+    ADDED=$(($ADDED + 1))
 }
+
+# By default, user configuration is king.
+
+for ext_iface in $(uci -q get upnpd.config.external_iface); do
+    add_extzone_rules $(fw3 -q network "$ext_iface")
+done
+
+[ ! $ADDED = 0 ] && exit 0
+
+# If it's not available, resort to network_find_wan{,6} and
+# assume external interfaces all have same firewall zone.
+
+network_find_wan wan_iface
+network_find_wan6 wan6_iface
+
+for ext_iface in $wan_iface $wan6_iface; do
+    # fw3 -q network fails on sub-interfaces => map to device first
+    network_get_device ext_device $ext_iface
+    add_extzone_rules $(fw3 -q device "$ext_device")
+done
index 7ff363a4ff8360a85e4d9261599f660886feffe3..a98a50cc441c5e66df70d46201f3e120d8377b63 100644 (file)
@@ -9,8 +9,11 @@ fi
 
 # If miniupnpd is not running:
 # - check on _any_ event (even updates may contribute to network_find_wan*)
+
 # If miniupnpd _is_ running:
-# - check only on ifup
+# - check only on ifup (otherwise lease updates etc would cause
+#   miniupnpd state loss)
+
 
 [ ! "$ACTION" = "ifup" ] && service_check /usr/sbin/miniupnpd && exit 0
 
@@ -23,6 +26,6 @@ network_find_wan ext_iface
 network_find_wan6 ext_iface6
 
 for iface in $ext_iface $ext_iface6 $(uci_get upnpd config internal_iface; uci_get upnpd config external_iface); do
-    [ "$INTERFACE" = "$iface" ] && /etc/init.d/miniupnpd restart
-    exit 0
+    network_get_device device $iface
+    [ "$DEVICE" = "$device" ] && /etc/init.d/miniupnpd restart && exit 0
 done