[OpenWrt-Devel] [PATCH 3/3] ppp: Unnumbered support

Hans Dedecker dedeckeh at gmail.com
Wed Jun 10 04:39:03 EDT 2015


Adds PPP unnumbered support via the parameter unnumbered which points to a logical OpenWRT interface.
The PPP proto shell handler will "borrow" an IP address from the unnumbered interface (if multiple
IP addresses are present the longest prefix different from 32 will be "borrowed") for which a host
dependency will be created. Due to the host dependency the PPP unnumbered interface will only "borrow"
an IP address from an interface which is up.
The borrowed IP address will be shared as local IP address by the PPP daemon and no other local IP
will be accepted from the peer in the IPCP negotiation.

A typical use case is the usage of a public IP subnet on the Lan interface which will be shared
by the PPP interface as local IP address.

Signed-off-by: Hans Dedecker <dedeckeh at gmail.com>
---
 package/network/services/ppp/files/ppp.sh | 66 ++++++++++++++++++++++++++++++-
 1 file changed, 65 insertions(+), 1 deletion(-)

diff --git a/package/network/services/ppp/files/ppp.sh b/package/network/services/ppp/files/ppp.sh
index 1a72a1e..6770db3 100755
--- a/package/network/services/ppp/files/ppp.sh
+++ b/package/network/services/ppp/files/ppp.sh
@@ -4,10 +4,63 @@
 
 [ -n "$INCLUDE_ONLY" ] || {
 	. /lib/functions.sh
+	. /lib/functions/network.sh
 	. ../netifd-proto.sh
 	init_proto "$@"
 }
 
+ppp_mask2cidr()
+{
+	local x=${1##*255.}
+	# count the number of leading all ones
+	local allones=$(( (${#1} - ${#x}) * 2 ))
+	# conversion table based on blocks containing
+	# 4 characters to count the number of trailing bits
+	local tbl="0^^^128^192^224^240^248^252^254^"
+
+	# count the number of four character blocks
+	x=${tbl%%${x%%.*}*}
+	echo $(( $allones + (${#x}/4) ))
+}
+
+ppp_select_ipaddr()
+{
+	local interface="$1"
+	local addrs=$(uci_get "network.${interface}.ipaddr")
+	local netmask=$(uci_get "network.${interface}.netmask")
+	local res
+	local res_mask
+
+	if [ -n "$netmask" ]; then
+		[ "$netmask" != "${netmask##*.}" ] && netmask=$(ppp_mask2cidr $netmask)
+	else
+		netmask=32
+	fi
+
+	for entry in $addrs; do
+		local addr="${entry%%/*}"
+		local mask="${entry#*/}"
+
+		if [ "$addr" != "$mask" ]; then
+			[ "$mask" != "${mask##*.}" ] && mask=$(ppp_mask2cidr $mask)
+		else
+			mask="$netmask"
+		fi
+
+		if [ -n "$res_mask" -a "$mask" != 32 ]; then
+			[ "$mask" -gt "$res_mask" ] || [ "$res_mask" = 32 ] && {
+				res="$addr"
+				res_mask="$mask"
+			}
+		elif [ -z "$res_mask" ]; then
+			res="$addr"
+			res_mask="$mask"
+		fi
+	done
+
+	echo "$res"
+}
+
 ppp_exitcode_tostring()
 {
 	local errorcode=$1
@@ -53,12 +106,14 @@ ppp_generic_init_config() {
 	proto_config_add_boolean authfail
 	proto_config_add_int mtu
 	proto_config_add_string pppname
+	proto_config_add_string unnumbered
 }
 
 ppp_generic_setup() {
 	local config="$1"; shift
+	local localip
 
-	json_get_vars ipv6 demand keepalive keepalive_adaptive username password pppd_options pppname
+	json_get_vars ipv6 demand keepalive keepalive_adaptive username password pppd_options pppname unnumbered
 	if [ "$ipv6" = 0 ]; then
 		ipv6=""
 	elif [ -z "$ipv6" -o "$ipv6" = auto ]; then
@@ -73,6 +128,14 @@ ppp_generic_setup() {
 	fi
 	[ -n "$mtu" ] || json_get_var mtu mtu
 	[ -n "$pppname" ] || pppname="${proto:-ppp}-$config"
+	[ -n "$unnumbered" ] && {
+		localip=$(ppp_select_ipaddr $unnumbered)
+		[ -n "$localip" ] || {
+			proto_block_restart "$config"
+			return
+		}
+		( proto_add_host_dependency "$config" "$localip" "$unnumbered" )
+	}
 
 	local lcp_failure="${keepalive%%[, ]*}"
 	local lcp_interval="${keepalive##*[, ]}"
@@ -86,6 +149,7 @@ ppp_generic_setup() {
 	proto_run_command "$config" /usr/sbin/pppd \
 		nodetach ipparam "$config" \
 		ifname "$pppname" \
+		${localip:+$localip:} \
 		${lcp_failure:+lcp-echo-interval $lcp_interval lcp-echo-failure $lcp_failure $lcp_adaptive} \
 		${ipv6:++ipv6} \
 		nodefaultroute \
-- 
1.9.1
_______________________________________________
openwrt-devel mailing list
openwrt-devel at lists.openwrt.org
https://lists.openwrt.org/cgi-bin/mailman/listinfo/openwrt-devel



More information about the openwrt-devel mailing list