diff mbox

[v3] set simple network setup via the system configuration submenu

Message ID 1414071600-28318-1-git-send-email-jeremy.rosen@openwide.fr
State Superseded
Headers show

Commit Message

Jeremy Rosen Oct. 23, 2014, 1:40 p.m. UTC
This patch allows the setup of simple /etc/network/interfaces (or
/etc/systemd/network/80-buildroot.network if networkd is enabled) via the
configuration menus instead of using an overlay

* supports disabling the interface
* supports manual ipv4 configuration
* supports dhcp configuration

Signed-off-by: Jérémy Rosen <jeremy.rosen@openwide.fr>

---

This patch is here to avoid having to do an overlay for the most common
cases (ipv4 with fixed IP or DHCP)

This is reduced to the bare minimum to cover the most common case. Anything
more complex can be done by using overlays instead.

I have not added the option to (de)activate persistant naming when networkd
is enabled because it logically belongs to the networkd package and not to
the simple network configuration
---
v3 :
* rename the script to a more generic name
* reorganized script to separate param verification from generation
* quoted params properly to protect against faulty params
* removed /etc/network/interfaces from skeleton
* reorganized options in configuration menu
* added networkd configuration support

v2 :
* moved to TARGET_FINALIZE
* removed support for lo. It should always be on.
* reworked default parameters
---
 support/scripts/generate-network-config.sh | 136 +++++++++++++++++++++++++++++
 system/Config.in                           |  60 +++++++++++++
 system/skeleton/etc/network/interfaces     |   4 -
 system/system.mk                           |   5 ++
 4 files changed, 201 insertions(+), 4 deletions(-)
 create mode 100755 support/scripts/generate-network-config.sh
 delete mode 100644 system/skeleton/etc/network/interfaces

Comments

André Erdmann Oct. 24, 2014, 2:37 p.m. UTC | #1
Hi,


2014/10/24 Jeremy Rosen <jeremy.rosen@openwide.fr>:
> diff --git a/support/scripts/generate-network-config.sh b/support/scripts/generate-network-config.sh
> new file mode 100755
> index 0000000..c09d165
> --- /dev/null
> +++ b/support/scripts/generate-network-config.sh
> @@ -0,0 +1,136 @@
> +#!/bin/sh
> +
> +#extract our parameters from the config file
> +# see comment in support/scripts/mkusers at to why we can't simply source
> +for PARAM in \
> +	BR2_PACKAGE_SYSTEMD_NETWORKD \
> +	BR2_SIMPLE_NETWORK_NONE \
> +	BR2_SIMPLE_NETWORK_IPV4_DHCP \
> +	BR2_SIMPLE_NETWORK_IPV4_MANUAL \
> +	; do
> +TMP=$(sed -r -e "/^$PARAM=(.*)$/!d;" -e 's//\1/;' $BR2_CONFIG)
> +export $PARAM=$TMP
> +done
> +
> +for PARAM in \
> +	BR2_SIMPLE_NETWORK_NAME \
> +	BR2_SIMPLE_NETWORK_IPV4_ADDRESS \
> +	BR2_SIMPLE_NETWORK_IPV4_NETMASK \
> +	BR2_SIMPLE_NETWORK_IPV4_BROADCAST \
> +	BR2_SIMPLE_NETWORK_IPV4_GATEWAY \
> +	; do
> +TMP=$(sed -r -e "/^$PARAM=\"(.*)\"$/!d;" -e 's//\1/;' $BR2_CONFIG)
> +export $PARAM="$TMP"
> +done
> +
> +check_configuration ()
> +{
> +	if [ -z "$BR2_SIMPLE_NETWORK_NONE" ] ; then
> +		if [ -z "$BR2_SIMPLE_NETWORK_NAME" ] ; then
> +			echo ERROR no name specified for first network interface
> +			exit 1
> +		fi
> +		if [ "$BR2_SIMPLE_NETWORK_IPV4_MANUAL" ] ; then
> +			if [ -z "$BR2_SIMPLE_NETWORK_IPV4_ADDRESS" ] ; then
> +				echo ERROR BR2_SIMPLE_NETWORK_IPV4_ADDRESS not set 1>&2
> +				exit 1
> +			fi
> +			if [ -z "$BR2_SIMPLE_NETWORK_IPV4_NETMASK" ] ; then
> +				echo ERROR BR2_SIMPLE_NETWORK_IPV4_NETMASK not set 1>&2
> +				exit 1
> +			fi

Not strictly necessary(*), but it's safer to back up the old field separator and
restore it later on:

OLDIFS="$IFS"; IFS=.


(*) otherwise, the script could misbehave if TARGET_DIR contains dot "." chars:

  TARGET_DIR="/tmp/br.foo/..."
  echo > $TARGET_DIR/x   =expands-to=>   echo > /tmp/br foo/.../x

> +			IFS=.
> +			for dec in $BR2_SIMPLE_NETWORK_IPV4_NETMASK ; do
> +				case $dec in
> +					255 | 254 | 252 |248 | 240 |224 | 192 | 128 | 0 );;
> +					*) echo "Error: $BR2_SIMPLE_NETWORK_IPV4_NETMASK is not a correct NETMASK" 1>&2; exit 1 ;;
> +				esac
> +			done

IFS="$OLDIFS"

> +		fi
> +	fi
> +}
> +
> +do_generate_interfaces ()
> +{

==START
> +	if [ "$BR2_PACKAGE_SYSTEMD_NETWORKD" ] ; then
> +		echo
> +		return
> +	fi
==END

Can be dropped, because you already check BR2_PACKAGE_SYSTEMD_NETWORKD
before calling do_generate_interfaces().

> +	echo "# interface file auto-generated by buildroot"
> +	echo
> +	echo "auto lo"
> +	echo "iface lo inet loopback"
> +	echo
> +
> +	if [ -z "$BR2_SIMPLE_NETWORK_NONE" ] ; then
> +		echo "auto $BR2_SIMPLE_NETWORK_NAME"
> +		if [ "$BR2_SIMPLE_NETWORK_IPV4_DHCP" ] ; then
> +			echo "iface $BR2_SIMPLE_NETWORK_NAME inet dhcp"
> +		elif [ "$BR2_SIMPLE_NETWORK_IPV4_MANUAL" ] ; then
> +			echo "iface $BR2_SIMPLE_NETWORK_NAME inet static"
> +			echo "	address $BR2_SIMPLE_NETWORK_IPV4_ADDRESS"
> +			echo "	netmask $BR2_SIMPLE_NETWORK_IPV4_NETMASK"
> +
> +			if [ "$BR2_SIMPLE_NETWORK_IPV4_BROADCAST" ] ; then
> +				echo "	broadcast $BR2_SIMPLE_NETWORK_IPV4_BROADCAST"
> +			fi
> +			if [ "$BR2_SIMPLE_NETWORK_IPV4_GATEWAY" ] ; then
> +				echo "	gateway $BR2_SIMPLE_NETWORK_IPV4_GATEWAY"
> +			fi
> +		fi
> +	fi
> +}
> +
> +do_generate_network_service ()
> +{
> +	if [ "$BR2_SIMPLE_NETWORK_NONE" ] ; then
> +		return
> +	fi
> +	echo "[Match]"
> +	echo "Name=$BR2_SIMPLE_NETWORK_NAME"
> +	echo

==START
> +	if [ $BR2_SIMPLE_NETWORK_IPV4_DHCP ] ; then
> +		echo "[Network]"
> +		echo "DHCP=v4"
> +	elif [ $BR2_SIMPLE_NETWORK_IPV4_MANUAL ] ; then
> +		nbits=0
> +		IFS=.
> +		for dec in $BR2_SIMPLE_NETWORK_IPV4_NETMASK ; do
> +			case $dec in
> +				255) let nbits+=8;;
> +				254) let nbits+=7;;
> +				252) let nbits+=6;;
> +				248) let nbits+=5;;
> +				240) let nbits+=4;;
> +				224) let nbits+=3;;
> +				192) let nbits+=2;;
> +				128) let nbits+=1;;
> +				0);;
> +			esac
> +		done
> +
> +		if [ "$BR2_SIMPLE_NETWORK_IPV4_ADDRESS" != "0.0.0.0" ] ; then
> +			if [ "$BR2_SIMPLE_NETWORK_IPV4_GATEWAY" ] ; then
> +				echo "[Network]"
> +				echo "Gateway=$BR2_SIMPLE_NETWORK_IPV4_GATEWAY"
> +				echo "Description=buildroot-configured interface"
> +				echo
> +			fi
> +			echo "[Address]"
> +			echo "Address=$BR2_SIMPLE_NETWORK_IPV4_ADDRESS/$nbits"
> +			if [ "$BR2_SIMPLE_NETWORK_IPV4_BROADCAST" ] ; then
> +				echo "Broadcast=$BR2_SIMPLE_NETWORK_IPV4_BROADCAST"
> +			fi
> +		fi
> +	fi
==END

What happens here is that "Description=" is only printed if a gateway is configured,
plus you can optimize the control flow a bit:


echo "[Network]"
echo "Description=buildroot-configured interface"

if [ $BR2_SIMPLE_NETWORK_IPV4_DHCP ] ; then
	echo "DHCP=v4"
elif \
	[ $BR2_SIMPLE_NETWORK_IPV4_MANUAL ] && \
	[ "$BR2_SIMPLE_NETWORK_IPV4_ADDRESS" != "0.0.0.0" ]
then
	OLDIFS="$IFS"; IFS=.            ## save IFS
	for ... case ... esac ... done  ## nbits
	IFS="$OLDIFS"                   ## restore IFS

	if [ "$BR2_SIMPLE_NETWORK_IPV4_GATEWAY" ]; then
		echo "Gateway=$BR2_SIMPLE_NETWORK_IPV4_GATEWAY"
	fi
	echo
	echo "[Address]"
	echo "Address=$BR2_SIMPLE_NETWORK_IPV4_ADDRESS/$nbits"
	if [ "$BR2_SIMPLE_NETWORK_IPV4_BROADCAST" ] ; then
		echo "Broadcast=$BR2_SIMPLE_NETWORK_IPV4_BROADCAST"
	fi
fi


> +}
> +
> +check_configuration
> +mkdir -p $TARGET_DIR/etc/network/

Need an "mkdir -p $TARGET_DIR/etc/systemd/network" here.
However, this would also create it for non-systemd systems, which is useless,
so rather remove the systemd file if it exists:

rm -f -- $TARGET_DIR/etc/systemd/network/80-buildroot.network


> +if [ "$BR2_PACKAGE_SYSTEMD_NETWORKD" ] ; then

and create the directory here:

	mkdir -p $TARGET_DIR/etc/systemd/network

> +	echo > $TARGET_DIR/etc/network/interfaces
> +	do_generate_network_service > $TARGET_DIR/etc/systemd/network/80-buildroot.network
> +else
> +	do_generate_interfaces > $TARGET_DIR/etc/network/interfaces

and drop this echo:

> +	echo > $TARGET_DIR/etc/systemd/network/80-buildroot.network

> +fi
> diff --git a/system/Config.in b/system/Config.in
> index 2465f79..3683edf 100644
> --- a/system/Config.in
[snip]
diff mbox

Patch

diff --git a/support/scripts/generate-network-config.sh b/support/scripts/generate-network-config.sh
new file mode 100755
index 0000000..c09d165
--- /dev/null
+++ b/support/scripts/generate-network-config.sh
@@ -0,0 +1,136 @@ 
+#!/bin/sh
+
+#extract our parameters from the config file
+# see comment in support/scripts/mkusers at to why we can't simply source
+for PARAM in \
+	BR2_PACKAGE_SYSTEMD_NETWORKD \
+	BR2_SIMPLE_NETWORK_NONE \
+	BR2_SIMPLE_NETWORK_IPV4_DHCP \
+	BR2_SIMPLE_NETWORK_IPV4_MANUAL \
+	; do
+TMP=$(sed -r -e "/^$PARAM=(.*)$/!d;" -e 's//\1/;' $BR2_CONFIG)
+export $PARAM=$TMP
+done
+
+for PARAM in \
+	BR2_SIMPLE_NETWORK_NAME \
+	BR2_SIMPLE_NETWORK_IPV4_ADDRESS \
+	BR2_SIMPLE_NETWORK_IPV4_NETMASK \
+	BR2_SIMPLE_NETWORK_IPV4_BROADCAST \
+	BR2_SIMPLE_NETWORK_IPV4_GATEWAY \
+	; do
+TMP=$(sed -r -e "/^$PARAM=\"(.*)\"$/!d;" -e 's//\1/;' $BR2_CONFIG)
+export $PARAM="$TMP"
+done
+
+check_configuration ()
+{
+	if [ -z "$BR2_SIMPLE_NETWORK_NONE" ] ; then
+		if [ -z "$BR2_SIMPLE_NETWORK_NAME" ] ; then
+			echo ERROR no name specified for first network interface
+			exit 1
+		fi
+		if [ "$BR2_SIMPLE_NETWORK_IPV4_MANUAL" ] ; then
+			if [ -z "$BR2_SIMPLE_NETWORK_IPV4_ADDRESS" ] ; then
+				echo ERROR BR2_SIMPLE_NETWORK_IPV4_ADDRESS not set 1>&2
+				exit 1
+			fi
+			if [ -z "$BR2_SIMPLE_NETWORK_IPV4_NETMASK" ] ; then
+				echo ERROR BR2_SIMPLE_NETWORK_IPV4_NETMASK not set 1>&2
+				exit 1
+			fi
+			IFS=.
+			for dec in $BR2_SIMPLE_NETWORK_IPV4_NETMASK ; do
+				case $dec in
+					255 | 254 | 252 |248 | 240 |224 | 192 | 128 | 0 );;
+					*) echo "Error: $BR2_SIMPLE_NETWORK_IPV4_NETMASK is not a correct NETMASK" 1>&2; exit 1 ;;
+				esac
+			done
+		fi
+	fi
+}
+
+do_generate_interfaces ()
+{
+	if [ "$BR2_PACKAGE_SYSTEMD_NETWORKD" ] ; then
+		echo
+		return
+	fi
+	echo "# interface file auto-generated by buildroot"
+	echo
+	echo "auto lo"
+	echo "iface lo inet loopback"
+	echo
+
+	if [ -z "$BR2_SIMPLE_NETWORK_NONE" ] ; then
+		echo "auto $BR2_SIMPLE_NETWORK_NAME"
+		if [ "$BR2_SIMPLE_NETWORK_IPV4_DHCP" ] ; then
+			echo "iface $BR2_SIMPLE_NETWORK_NAME inet dhcp"
+		elif [ "$BR2_SIMPLE_NETWORK_IPV4_MANUAL" ] ; then
+			echo "iface $BR2_SIMPLE_NETWORK_NAME inet static"
+			echo "	address $BR2_SIMPLE_NETWORK_IPV4_ADDRESS"
+			echo "	netmask $BR2_SIMPLE_NETWORK_IPV4_NETMASK"
+
+			if [ "$BR2_SIMPLE_NETWORK_IPV4_BROADCAST" ] ; then
+				echo "	broadcast $BR2_SIMPLE_NETWORK_IPV4_BROADCAST"
+			fi
+			if [ "$BR2_SIMPLE_NETWORK_IPV4_GATEWAY" ] ; then
+				echo "	gateway $BR2_SIMPLE_NETWORK_IPV4_GATEWAY"
+			fi
+		fi
+	fi
+}
+
+do_generate_network_service ()
+{
+	if [ "$BR2_SIMPLE_NETWORK_NONE" ] ; then
+		return
+	fi
+	echo "[Match]"
+	echo "Name=$BR2_SIMPLE_NETWORK_NAME"
+	echo
+	if [ $BR2_SIMPLE_NETWORK_IPV4_DHCP ] ; then
+		echo "[Network]"
+		echo "DHCP=v4"
+	elif [ $BR2_SIMPLE_NETWORK_IPV4_MANUAL ] ; then
+		nbits=0
+		IFS=.
+		for dec in $BR2_SIMPLE_NETWORK_IPV4_NETMASK ; do
+			case $dec in
+				255) let nbits+=8;;
+				254) let nbits+=7;;
+				252) let nbits+=6;;
+				248) let nbits+=5;;
+				240) let nbits+=4;;
+				224) let nbits+=3;;
+				192) let nbits+=2;;
+				128) let nbits+=1;;
+				0);;
+			esac
+		done
+
+		if [ "$BR2_SIMPLE_NETWORK_IPV4_ADDRESS" != "0.0.0.0" ] ; then
+			if [ "$BR2_SIMPLE_NETWORK_IPV4_GATEWAY" ] ; then
+				echo "[Network]"
+				echo "Gateway=$BR2_SIMPLE_NETWORK_IPV4_GATEWAY"
+				echo "Description=buildroot-configured interface"
+				echo
+			fi
+			echo "[Address]"
+			echo "Address=$BR2_SIMPLE_NETWORK_IPV4_ADDRESS/$nbits"
+			if [ "$BR2_SIMPLE_NETWORK_IPV4_BROADCAST" ] ; then
+				echo "Broadcast=$BR2_SIMPLE_NETWORK_IPV4_BROADCAST"
+			fi
+		fi
+	fi
+}
+
+check_configuration
+mkdir -p $TARGET_DIR/etc/network/
+if [ "$BR2_PACKAGE_SYSTEMD_NETWORKD" ] ; then
+	echo > $TARGET_DIR/etc/network/interfaces
+	do_generate_network_service > $TARGET_DIR/etc/systemd/network/80-buildroot.network
+else
+	do_generate_interfaces > $TARGET_DIR/etc/network/interfaces
+	echo > $TARGET_DIR/etc/systemd/network/80-buildroot.network
+fi
diff --git a/system/Config.in b/system/Config.in
index 2465f79..3683edf 100644
--- a/system/Config.in
+++ b/system/Config.in
@@ -324,6 +324,66 @@  config BR2_TARGET_GENERIC_REMOUNT_ROOTFS_RW
 
 endif # BR2_ROOTFS_SKELETON_DEFAULT
 
+choice
+	prompt 'Simple network configuration'
+	default BR2_SIMPLE_NETWORK_NONE
+	help
+	  buildroot will create a simple network configuration for a network
+	  interface. This will generate the corresponding lines in
+	  /etc/network/interfaces which is used by ifupdown.
+
+	  The simple network configuration only supports a single network
+	  interface using a static or DHCP-allocated IPv4 address. If you
+	  need something more complicate, create your own configuration file
+	  in the BR2_ROOTFS_OVERLAY.
+
+config BR2_SIMPLE_NETWORK_NONE
+	bool "No configured network interface"
+	help
+	  Do not configure the network interface, only configure the
+	  loopback device
+
+config BR2_SIMPLE_NETWORK_IPV4_DHCP
+	bool "IPv4 with DHCP"
+	help
+	  Use DHCP to configure this interface using the IPv4 protocol
+
+config BR2_SIMPLE_NETWORK_IPV4_MANUAL
+	bool "IPv4 with static IP address"
+	help
+	  Configure IPv4 by specifying each parameter separately
+
+endchoice
+
+if !BR2_SIMPLE_NETWORK_NONE
+
+config BR2_SIMPLE_NETWORK_NAME
+	string "name of the physical network interface"
+	default "eth0"
+	help
+	  The name used to recognise the network interface as reported
+	  by the kernel
+
+if BR2_SIMPLE_NETWORK_IPV4_MANUAL
+config BR2_SIMPLE_NETWORK_IPV4_ADDRESS
+	string "IP Address of the network interface"
+	default "0.0.0.0"
+
+config BR2_SIMPLE_NETWORK_IPV4_NETMASK
+	string "Netmask of the network interface"
+	default "255.255.255.255"
+
+config BR2_SIMPLE_NETWORK_IPV4_BROADCAST
+	string "Broadcast Address of the network interface"
+
+config BR2_SIMPLE_NETWORK_IPV4_GATEWAY
+	string "Address of the gateway for the network interface"
+
+endif # BR2_SIMPLE_NETWORK_IPV4_MANUAL
+
+endif # !BR2_SIMPLE_NETWORK_NONE
+
+
 config BR2_TARGET_TZ_INFO
 	bool "Install timezone info"
 	# No timezone for musl; only for uClibc or (e)glibc.
diff --git a/system/skeleton/etc/network/interfaces b/system/skeleton/etc/network/interfaces
deleted file mode 100644
index 218b82c..0000000
--- a/system/skeleton/etc/network/interfaces
+++ /dev/null
@@ -1,4 +0,0 @@ 
-# Configure Loopback
-auto lo
-iface lo inet loopback
-
diff --git a/system/system.mk b/system/system.mk
index 5802e2d..8385c31 100644
--- a/system/system.mk
+++ b/system/system.mk
@@ -38,6 +38,11 @@  ifneq ($(TARGET_GENERIC_ROOT_PASSWD),)
 TARGETS += host-mkpasswd
 endif
 
+define SIMPLE_NETWORK
+	$(TOPDIR)/support/scripts/generate-network-config.sh $(TARGET_DIR)
+endef
+TARGET_FINALIZE_HOOKS += SIMPLE_NETWORK
+
 ifeq ($(BR2_ROOTFS_SKELETON_DEFAULT),y)
 
 define SYSTEM_ROOT_PASSWD