diff options
Diffstat (limited to 'package/base-files-network/files')
8 files changed, 979 insertions, 0 deletions
| diff --git a/package/base-files-network/files/etc/hotplug.d/iface/00-netstate b/package/base-files-network/files/etc/hotplug.d/iface/00-netstate new file mode 100644 index 000000000..37b1e934e --- /dev/null +++ b/package/base-files-network/files/etc/hotplug.d/iface/00-netstate @@ -0,0 +1,5 @@ +[ ifup = "$ACTION" ] && { +	uci_toggle_state network "$INTERFACE" up 1  +	uci_toggle_state network "$INTERFACE" connect_time $(sed -ne 's![^0-9].*$!!p' /proc/uptime) +	[ -n "$DEVICE" ] && uci_toggle_state network "$INTERFACE" ifname "$DEVICE" +} diff --git a/package/base-files-network/files/etc/hotplug.d/iface/10-routes b/package/base-files-network/files/etc/hotplug.d/iface/10-routes new file mode 100644 index 000000000..d57a5b3c7 --- /dev/null +++ b/package/base-files-network/files/etc/hotplug.d/iface/10-routes @@ -0,0 +1,137 @@ +add_route() { +	local config="$1" + +	# is this route intended for the +	# $INTERFACE of this hotplug event +	config_get interface "$config" interface +	[ "$interface" != "$INTERFACE" ] && return 0 +	 +	# get the real interface name from network config +	config_get dev "$interface" ifname + +	config_get target "$config" target +	config_get netmask "$config" netmask +	config_get gateway "$config" gateway +	config_get metric "$config" metric +	config_get mtu "$config" mtu + +	# make sure there is a gateway and a target +	[ -n "$target" ] || { +		echo "Missing target in route section $config" +		return 1 +	} +	[ -n "$gateway" ] || { +		config_get gateway "$interface" gateway +	} + +	# handle "0.0.0.0" as "no gateway given" to allow +	# defining gateway-less routes while still keeping +	# the possibility to have static routes with a +	# proper gateway on interfaces with dynamic ips  +	[ "$gateway" = "0.0.0.0" ] && gateway="" + +	dest="${netmask:+-net "$target" netmask "$netmask"}" +	dest="${dest:--host "$target"}" +	 +	/sbin/route add $dest ${gateway:+gw "$gateway"} \ +		${dev:+dev "$dev"} ${metric:+ metric "$metric"} \ +		${mtu:+mss "$mtu"} +} + +add_route6() { +	local config="$1" + +	# is this route intended for the +	# $INTERFACE of this hotplug event +	config_get interface "$config" interface +	[ "$interface" != "$INTERFACE" ] && return 0 +	 +	# get the real interface name from network config +	config_get dev "$interface" ifname + +	config_get target "$config" target +	config_get gateway "$config" gateway +	config_get metric "$config" metric +	config_get mtu "$config" mtu + +	# make sure there is a gateway and a target +	[ -n "$target" ] || { +		echo "Missing target in route section $config" +		return 1 +	} +	[ -n "$gateway" ] || { +		config_get gateway "$interface" gateway +	} + +	/sbin/route -A inet6 add $target ${gateway:+gw "$gateway"} \ +		${dev:+dev "$dev"} ${metric:+ metric "$metric"} \ +		${mtu:+mss "$mtu"} +} + +# Skip fake devices (e.g. relayd) +grep -qs "^ *$DEVICE:" /proc/net/dev || exit 0 + +case "$ACTION" in +	ifup) +		include /lib/network +		scan_interfaces + +		# Setup aliases +		config_set "$INTERFACE" aliases "" +		config_set "$INTERFACE" alias_count 0 +		config_foreach setup_interface_alias alias "$INTERFACE" "$DEVICE" + +		# Save alias references in state vars +		local aliases +		config_get aliases "$INTERFACE" aliases +		[ -z "$aliases" ] || uci_toggle_state network "$INTERFACE" aliases "$aliases" + +		# Make ip6addr of parent iface the main address again +		local ip6addr +		config_get ip6addr "$INTERFACE" ip6addr +		[ -z "$ip6addr" ] || { +			ifconfig "$DEVICE" del "$ip6addr" +			ifconfig "$DEVICE" add "$ip6addr" +		} +		 +		# Setup sysctls +		local proto accept_ra send_rs +		 +		config_get proto "$INTERFACE" proto +		if [ "$proto" = dhcp ]; then +			accept_ra=1 +			send_rs=0 +		else +			accept_ra=0 +			send_rs=1 +		fi + +		config_get_bool accept_ra "$INTERFACE" accept_ra $accept_ra +		[ $accept_ra -eq 0 ] || { +			logger -t ifup "Allowing Router Advertisements on $INTERFACE ($DEVICE)" +			accept_ra=2 +		} +		do_sysctl "net.ipv6.conf.$DEVICE.accept_ra" $accept_ra + +		config_get_bool send_rs "$INTERFACE" send_rs $send_rs +		[ $send_rs -eq 0 ] || { +			logger -t ifup "Enabling Router Solicitations on $INTERFACE ($DEVICE)" +			send_rs=2 +		} +		do_sysctl "net.ipv6.conf.$DEVICE.forwarding" $send_rs + + +		# Setup routes +		config_foreach "add_route" route +		config_foreach "add_route6" route6 +	;; +	ifdown) +		# Bring down named aliases +		local device=$(uci_get_state network "$INTERFACE" device) +		local ifn +		for ifn in $(ifconfig | sed -ne "s/^\(\($DEVICE${device:+\|$device}\|br-$INTERFACE\):[^[:space:]]\+\).*/\1/p"); do +			ifconfig "$ifn" down +		done +	;; +esac + diff --git a/package/base-files-network/files/etc/hotplug.d/net/10-net b/package/base-files-network/files/etc/hotplug.d/net/10-net new file mode 100644 index 000000000..013ece39c --- /dev/null +++ b/package/base-files-network/files/etc/hotplug.d/net/10-net @@ -0,0 +1,72 @@ +# Copyright (C) 2006 OpenWrt.org + +include /lib/network + +addif() { +	# Ensure that ipv6 is loaded, autoloading happens later but ipv6 might be +	# required now for interface setup. +	[ -d /proc/sys/net/ipv6 ] || { +		grep -q '^ipv6' /etc/modules.d/* && insmod ipv6 +	} + +	# PPP devices are configured by pppd, no need to run setup_interface here +	case "$INTERFACE" in +		3g-*|ppp-*|pppoa-*|pppoe-*|pptp-*) return 0;; +	esac + +	scan_interfaces +	local cfg="$(find_config "$INTERFACE")" + +	case "$INTERFACE" in +		# Skip wireless parent interfaces +		ath[0-9]|wlan[0-9]) ;; +		*) +			# check the autoload setting +			config_get auto "$cfg" auto +			case "$auto" in +				1|on|enabled) setup_interface "$INTERFACE";; +			esac +		;; +	esac + +	# find all vlan configurations for this interface and set them up as well +	for ifc in $interfaces; do +		config_get iftype "$ifc" type +		config_get ifs "$ifc" device +		for dev in $ifs; do +			[ "${dev%%\.*}" = "$INTERFACE" -a "$dev" != "$INTERFACE" ] && { +				add_vlan "$dev" +			} +		done +	done +} + + +delif() { +	scan_interfaces + +	# find all vlan configurations for this interface and nuke 'em +	for ifc in $interfaces; do +		config_get iftype "$ifc" type +		config_get ifs "$ifc" device +		confdevs="$(uci_get network.$ifc.ifname)" +		for dev in $ifs; do +			[ "${dev%%\.*}" = "$INTERFACE" ] && { +				list_contains confdevs "$dev" || list_remove ifs "$dev" +			} +		done +		uci_set_state "network" "$ifc" device "$ifs" +	done +} + +case "$ACTION" in +	add|register) +		case "$PHYSDEVDRIVER" in +			natsemi) sleep 1;; +		esac +		addif +	;; +	remove|unregister) +		delif +	;; +esac diff --git a/package/base-files-network/files/etc/init.d/network b/package/base-files-network/files/etc/init.d/network new file mode 100755 index 000000000..fc512216f --- /dev/null +++ b/package/base-files-network/files/etc/init.d/network @@ -0,0 +1,52 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2006-2011 OpenWrt.org + +START=40 +STOP=90 + +boot() { +	setup_switch() { return 0; } + +	include /lib/network +	setup_switch + +	/sbin/wifi detect > /tmp/wireless.tmp +	[ -s /tmp/wireless.tmp ] && { +		cat /tmp/wireless.tmp >> /etc/config/wireless +	} +	rm -f /tmp/wireless.tmp +	grep -qs config /etc/config/wireless && { +		/sbin/wifi up +	} + +	scan_interfaces + +	local ifc +	for ifc in $interfaces; do +		local proto +		config_get proto "$ifc" proto + +		local auto +		config_get_bool auto "$ifc" auto 1 + +		type "coldplug_interface_$proto" >/dev/null && [ "$auto" = 1 ] && \ +			coldplug_interface_$proto "$ifc" +	done +} + +start() { +	setup_switch() { return 0; } +	 +	include /lib/network +	setup_switch +	ifup -a +	/sbin/wifi up +} + +stop() { +	ifdown -a +} + +restart() { +	start +} diff --git a/package/base-files-network/files/lib/network/config.sh b/package/base-files-network/files/lib/network/config.sh new file mode 100755 index 000000000..29d021af9 --- /dev/null +++ b/package/base-files-network/files/lib/network/config.sh @@ -0,0 +1,444 @@ +#!/bin/sh +# Copyright (C) 2006 OpenWrt.org + +# DEBUG="echo" + +do_sysctl() { +	[ -n "$2" ] && \ +		sysctl -n -e -w "$1=$2" >/dev/null || \ +		sysctl -n -e "$1" +} + +map_sysctls() { +	local cfg="$1" +	local ifn="$2" + +	local fam +	for fam in ipv4 ipv6; do +		if [ -d /proc/sys/net/$fam ]; then +			local key +			for key in /proc/sys/net/$fam/*/$ifn/*; do +				local val +				config_get val "$cfg" "${fam}_${key##*/}" +				[ -n "$val" ] && echo -n "$val" > "$key" +			done +		fi +	done +} + +find_config() { +	local iftype device iface ifaces ifn +	for ifn in $interfaces; do +		config_get iftype "$ifn" type +		config_get iface "$ifn" ifname +		case "$iftype" in +			bridge) config_get ifaces "$ifn" ifnames;; +		esac +		config_get device "$ifn" device +		for ifc in $device $iface $ifaces; do +			[ ."$ifc" = ."$1" ] && { +				echo "$ifn" +				return 0 +			} +		done +	done + +	return 1; +} + +scan_interfaces() { +	local cfgfile="${1:-network}" +	interfaces= +	config_cb() { +		case "$1" in +			interface) +				config_set "$2" auto 1 +			;; +		esac +		local iftype ifname device proto +		config_get iftype "$CONFIG_SECTION" TYPE +		case "$iftype" in +			interface) +				append interfaces "$CONFIG_SECTION" +				config_get proto "$CONFIG_SECTION" proto +				config_get iftype "$CONFIG_SECTION" type +				config_get ifname "$CONFIG_SECTION" ifname +				config_get device "$CONFIG_SECTION" device "$ifname" +				config_set "$CONFIG_SECTION" device "$device" +				case "$iftype" in +					bridge) +						config_set "$CONFIG_SECTION" ifnames "$device" +						config_set "$CONFIG_SECTION" ifname br-"$CONFIG_SECTION" +					;; +				esac +				( type "scan_$proto" ) >/dev/null 2>/dev/null && eval "scan_$proto '$CONFIG_SECTION'" +			;; +		esac +	} +	config_load "${cfgfile}" +} + +add_vlan() { +	local vif="${1%\.*}" + +	[ "$1" = "$vif" ] || ifconfig "$1" >/dev/null 2>/dev/null || { +		ifconfig "$vif" up 2>/dev/null >/dev/null || add_vlan "$vif" +		$DEBUG vconfig add "$vif" "${1##*\.}" +		return 0 +	} +	return 1 +} + +# add dns entries if they are not in resolv.conf yet +add_dns() { +	local cfg="$1"; shift + +	remove_dns "$cfg" + +	# We may be called by pppd's ip-up which has a nonstandard umask set. +	# Create an empty file here and force its permission to 0644, otherwise +	# dnsmasq will not be able to re-read the resolv.conf.auto . +	[ ! -f /tmp/resolv.conf.auto ] && { +		touch /tmp/resolv.conf.auto +		chmod 0644 /tmp/resolv.conf.auto +	} + +	local dns +	local add +	for dns in "$@"; do +		grep -qsE "^nameserver ${dns//./\\.}$" /tmp/resolv.conf.auto || { +			add="${add:+$add }$dns" +			echo "nameserver $dns" >> /tmp/resolv.conf.auto +		} +	done + +	[ -n "$cfg" ] && { +		uci_toggle_state network "$cfg" dns "$add" +		uci_toggle_state network "$cfg" resolv_dns "$add" +	} +} + +# remove dns entries of the given iface +remove_dns() { +	local cfg="$1" + +	[ -n "$cfg" ] && { +		[ -f /tmp/resolv.conf.auto ] && { +			local dns=$(uci_get_state network "$cfg" resolv_dns) +			for dns in $dns; do +				sed -i -e "/^nameserver ${dns//./\\.}$/d" /tmp/resolv.conf.auto +			done +		} + +		uci_revert_state network "$cfg" dns +		uci_revert_state network "$cfg" resolv_dns +	} +} + +# sort the device list, drop duplicates +sort_list() { +	local arg="$*" +	( +		for item in $arg; do +			echo "$item" +		done +	) | sort -u +} + +# Create the interface, if necessary. +# Return status 0 indicates that the setup_interface() call should continue +# Return status 1 means that everything is set up already. + +prepare_interface() { +	local iface="$1" +	local config="$2" +	local macaddr="$3" + +	# if we're called for the bridge interface itself, don't bother trying +	# to create any interfaces here. The scripts have already done that, otherwise +	# the bridge interface wouldn't exist. +	[ "br-$config" = "$iface" -o -e "$iface" ] && return 0; + +	ifconfig "$iface" 2>/dev/null >/dev/null && { +		local proto +		config_get proto "$config" proto + +		# make sure the interface is removed from any existing bridge and deconfigured, +		# (deconfigured only if the interface is not set to proto=none) +		unbridge "$iface" + +		local mtu macaddr txqueuelen +		config_get mtu "$config" mtu +		[ -n "$macaddr" ] || config_get macaddr "$config" macaddr +		config_get txqueuelen "$config" txqueuelen +		[ -n "$macaddr" ] && $DEBUG ifconfig "$iface" down +		$DEBUG ifconfig "$iface" ${macaddr:+hw ether "$macaddr"} ${mtu:+mtu $mtu} ${txqueuelen:+txqueuelen $txqueuelen} up + +		[ "$proto" = none ] || ifconfig "$iface" 0.0.0.0 + +		# Apply sysctl settings +		map_sysctls "$config" "$iface" +	} + +	# Setup VLAN interfaces +	add_vlan "$iface" && return 1 +	ifconfig "$iface" 2>/dev/null >/dev/null || return 0 + +	# Setup bridging +	local iftype +	config_get iftype "$config" type +	case "$iftype" in +		bridge) +			local macaddr +			config_get macaddr "$config" macaddr +			[ -x /usr/sbin/brctl ] && { +				ifconfig "br-$config" 2>/dev/null >/dev/null && { +					local newdevs devices +					config_get devices "$config" device +					for dev in $(sort_list "$devices" "$iface"); do +						append newdevs "$dev" +					done +					uci_toggle_state network "$config" device "$newdevs" +					$DEBUG ifconfig "$iface" 0.0.0.0 +					$DEBUG do_sysctl "net.ipv6.conf.$iface.disable_ipv6" 1 +					$DEBUG brctl addif "br-$config" "$iface" +					# Bridge existed already. No further processing necesary +				} || { +					local stp igmp_snooping +					config_get_bool stp "$config" stp 0 +					config_get_bool igmp_snooping "$config" igmp_snooping 1 +					$DEBUG brctl addbr "br-$config" +					$DEBUG brctl setfd "br-$config" 0 +					$DEBUG ifconfig "$iface" 0.0.0.0 +					$DEBUG do_sysctl "net.ipv6.conf.$iface.disable_ipv6" 1 +					$DEBUG brctl addif "br-$config" "$iface" +					$DEBUG brctl stp "br-$config" $stp +					[ -z "$macaddr" ] && macaddr="$(cat /sys/class/net/$iface/address)" +					echo $igmp_snooping > /sys/devices/virtual/net/br-$config/bridge/multicast_snooping 2>/dev/null +					$DEBUG ifconfig "br-$config" hw ether $macaddr up +					# Creating the bridge here will have triggered a hotplug event, which will +					# result in another setup_interface() call, so we simply stop processing +					# the current event at this point. +				} +				ifconfig "$iface" ${macaddr:+hw ether "${macaddr}"} up 2>/dev/null >/dev/null +				return 1 +			} +		;; +	esac +	return 0 +} + +set_interface_ifname() { +	local config="$1" +	local ifname="$2" + +	local device +	config_get device "$1" device +	uci_toggle_state network "$config" ifname "$ifname" +	uci_toggle_state network "$config" device "$device" +} + +setup_interface_none() { +	env -i ACTION="ifup" INTERFACE="$2" DEVICE="$1" PROTO=none /sbin/hotplug-call "iface" & +} + +setup_interface_static() { +	local iface="$1" +	local config="$2" + +	local ipaddr netmask ip6addr +	config_get ipaddr "$config" ipaddr +	config_get netmask "$config" netmask +	config_get ip6addr "$config" ip6addr +	[ -z "$ipaddr" -o -z "$netmask" ] && [ -z "$ip6addr" ] && return 1 + +	local gateway ip6gw dns bcast metric +	config_get gateway "$config" gateway +	config_get ip6gw "$config" ip6gw +	config_get dns "$config" dns +	config_get bcast "$config" broadcast +	config_get metric "$config" metric + +	case "$ip6addr" in +		*/*) ;; +		*:*) ip6addr="$ip6addr/64" ;; +	esac + +	[ -z "$ipaddr" ] || $DEBUG ifconfig "$iface" "$ipaddr" netmask "$netmask" broadcast "${bcast:-+}" +	[ -z "$ip6addr" ] || $DEBUG ifconfig "${iface%:*}" add "$ip6addr" +	[ -z "$gateway" ] || $DEBUG route add default gw "$gateway" ${metric:+metric $metric} dev "$iface" +	[ -z "$ip6gw" ] || $DEBUG route -A inet6 add default gw "$ip6gw" ${metric:+metric $metric} dev "${iface%:*}" +	[ -z "$dns" ] || add_dns "$config" $dns + +	config_get type "$config" TYPE +	[ "$type" = "alias" ] && return 0 + +	env -i ACTION="ifup" INTERFACE="$config" DEVICE="$iface" PROTO=static /sbin/hotplug-call "iface" & +} + +setup_interface_alias() { +	local config="$1" +	local parent="$2" +	local iface="$3" + +	local cfg +	config_get cfg "$config" interface +	[ "$parent" == "$cfg" ] || return 0 + +	# parent device and ifname +	local p_device p_type +	config_get p_device "$cfg" device +	config_get p_type   "$cfg" type + +	# select alias ifname +	local layer use_iface +	config_get layer "$config" layer 2 +	case "$layer:$p_type" in +		# layer 3: e.g. pppoe-wan or pptp-vpn +		3:*)      use_iface="$iface" ;; + +		# layer 2 and parent is bridge: e.g. br-wan +		2:bridge) use_iface="br-$cfg" ;; + +		# layer 1: e.g. eth0 or ath0 +		*)        use_iface="$p_device" ;; +	esac + +	# alias counter +	local ctr +	config_get ctr "$parent" alias_count 0 +	ctr="$(($ctr + 1))" +	config_set "$parent" alias_count "$ctr" + +	# alias list +	local list +	config_get list "$parent" aliases +	append list "$config" +	config_set "$parent" aliases "$list" + +	use_iface="$use_iface:$ctr" +	set_interface_ifname "$config" "$use_iface" + +	local proto +	config_get proto "$config" proto "static" +	case "${proto}" in +		static) +			setup_interface_static "$use_iface" "$config" +		;; +		*) +			echo "Unsupported type '$proto' for alias config '$config'" +			return 1 +		;; +	esac +} + +setup_interface() { +	local iface="$1" +	local config="$2" +	local proto="$3" +	local vifmac="$4" + +	[ -n "$config" ] || { +		config=$(find_config "$iface") +		[ "$?" = 0 ] || return 1 +	} + +	prepare_interface "$iface" "$config" "$vifmac" || return 0 + +	[ "$iface" = "br-$config" ] && { +		# need to bring up the bridge and wait a second for +		# it to switch to the 'forwarding' state, otherwise +		# it will lose its routes... +		ifconfig "$iface" up +		sleep 1 +	} + +	# Interface settings +	set_interface_ifname "$config" "$iface" + +	[ -n "$proto" ] || config_get proto "$config" proto +	case "$proto" in +		static) +			setup_interface_static "$iface" "$config" +		;; +		dhcp) +			# kill running udhcpc instance +			local pidfile="/var/run/dhcp-${iface}.pid" +			service_kill udhcpc "$pidfile" + +			local ipaddr netmask hostname proto1 clientid vendorid broadcast reqopts +			config_get ipaddr "$config" ipaddr +			config_get netmask "$config" netmask +			config_get hostname "$config" hostname +			config_get proto1 "$config" proto +			config_get clientid "$config" clientid +			config_get vendorid "$config" vendorid +			config_get_bool broadcast "$config" broadcast 0 +			config_get reqopts "$config" reqopts + +			[ -z "$ipaddr" ] || \ +				$DEBUG ifconfig "$iface" "$ipaddr" ${netmask:+netmask "$netmask"} + +			# additional request options +			local opt dhcpopts +			for opt in $reqopts; do +				append dhcpopts "-O $opt" +			done + +			# don't stay running in background if dhcp is not the main proto on the interface (e.g. when using pptp) +			[ "$proto1" != "$proto" ] && append dhcpopts "-n -q" || append dhcpopts "-O rootpath -R &" +			[ "$broadcast" = 1 ] && broadcast="-O broadcast" || broadcast= + +			$DEBUG eval udhcpc -t 0 -i "$iface" \ +				${ipaddr:+-r $ipaddr} \ +				${hostname:+-H $hostname} \ +				${clientid:+-c $clientid} \ +				${vendorid:+-V $vendorid} \ +				-b -p "$pidfile" $broadcast \ +				${dhcpopts} +		;; +		none) +			setup_interface_none "$iface" "$config" +		;; +		*) +			if ( eval "type setup_interface_$proto" ) >/dev/null 2>/dev/null; then +				eval "setup_interface_$proto '$iface' '$config' '$proto'" +			else +				echo "Interface type $proto not supported." +				return 1 +			fi +		;; +	esac +} + +stop_interface_dhcp() { +	local config="$1" + +	local ifname +	config_get ifname "$config" ifname + +	local lock="/var/lock/dhcp-${ifname}" +	[ -f "$lock" ] && lock -u "$lock" + +	remove_dns "$config" + +	local pidfile="/var/run/dhcp-${ifname}.pid" +	service_kill udhcpc "$pidfile" + +	uci -P /var/state revert "network.$config" +} + +unbridge() { +	local dev="$1" +	local brdev + +	[ -x /usr/sbin/brctl ] || return 0 +	brctl show 2>/dev/null | grep "$dev" >/dev/null && { +		# interface is still part of a bridge, correct that + +		for brdev in $(brctl show | awk '$2 ~ /^[0-9].*\./ { print $1 }'); do +			brctl delif "$brdev" "$dev" 2>/dev/null >/dev/null +			do_sysctl "net.ipv6.conf.$dev.disable_ipv6" 0 +		done +	} +} diff --git a/package/base-files-network/files/sbin/ifdown b/package/base-files-network/files/sbin/ifdown new file mode 100755 index 000000000..1455a9de7 --- /dev/null +++ b/package/base-files-network/files/sbin/ifdown @@ -0,0 +1,57 @@ +#!/bin/sh +# Copyright (C) 2006-2011 OpenWrt.org + +. /etc/functions.sh +[ $# = 0 ] && { echo "  $0 <group>"; exit; } + +case "$1" in +	"-a") +		[ -e "/tmp/resolv.conf.auto" ] && rm /tmp/resolv.conf.auto +		config_cb() { +			[ interface != "$1" -o -z "$2" ] || eval "$0 -w $2" +		} +		config_load network +		exit 0 +	;; +	"-w") shift ;; +esac + +include /lib/network +scan_interfaces + +cfg=$1 +debug "### ifdown $cfg ###" + +config_get proto "$cfg" proto +[ -z "$proto" ] && { echo "interface not found."; exit; } + +config_get iface "$cfg" device +[ "static" = "$proto" -o "none" = "$proto" ] && { +	env -i ACTION="ifdown" INTERFACE="$cfg" DEVICE="$iface" PROTO="$proto" /sbin/hotplug-call "iface" +} + +# call interface stop handler +( type "stop_interface_$proto" ) >/dev/null 2>/dev/null && eval "stop_interface_$proto '$cfg'" + +config_get ifname "$cfg" ifname +config_get device "$cfg" device + +[ ."$device" != ."$ifname" ] || device= +for dev in $ifname $device; do +	ifconfig "$dev" 0.0.0.0 down >/dev/null 2>/dev/null +done + +config_get iftype "$cfg" type +[ "bridge" = "$iftype" ] && brctl delbr "$ifname" >/dev/null 2>/dev/null + +# remove the interface's dns entries +remove_dns "$cfg" + +# remove the interface's network state +uci_revert_state network "$1" + +# revert aliases state as well +config_get aliases "$1" aliases +for config in $aliases; do +	uci_revert_state network "$config" +done diff --git a/package/base-files-network/files/sbin/ifup b/package/base-files-network/files/sbin/ifup new file mode 100755 index 000000000..5f8d80dc2 --- /dev/null +++ b/package/base-files-network/files/sbin/ifup @@ -0,0 +1,51 @@ +#!/bin/sh +# Copyright (C) 2006-2011 OpenWrt.org + +/sbin/ifdown "$@" + +. /etc/functions.sh +[ $# = 0 ] && { echo "  $0 <group>"; exit; } + +setup_wifi=1 + +case "$1" in +	"-a") +		[ -e "/tmp/resolv.conf.auto" ] && rm /tmp/resolv.conf.auto +		config_cb() { +			[ interface != "$1" -o -z "$2" ] || eval "$0 -w $2" +		} +		config_load network +		exit 0 +	;; +	"-w") setup_wifi=0; shift ;; +esac + +if [ $setup_wifi -gt 0 ] && grep -q config /etc/config/wireless; then +	find_related_radios() { +		local wdev wnet +		config_get wdev "$1" device +		config_get wnet "$1" network + +		if [ -n "$wdev" ] && [ "$wnet" = "$network" ]; then +			append radio_devs "$wdev" "$N" +		fi +	} + +	local radio_devs +	local network="$1" +	config_load wireless +	config_foreach find_related_radios wifi-iface + +	local dev +	for dev in $(echo "$radio_devs" | sort -u); do +		/sbin/wifi up "$dev" +	done +fi + +include /lib/network +scan_interfaces + +config_get ifname "$1" device +for dev in ${ifname:-$1}; do +	setup_interface "$dev" "$1" +done diff --git a/package/base-files-network/files/usr/share/udhcpc/default.script b/package/base-files-network/files/usr/share/udhcpc/default.script new file mode 100755 index 000000000..8dbff4747 --- /dev/null +++ b/package/base-files-network/files/usr/share/udhcpc/default.script @@ -0,0 +1,161 @@ +#!/bin/sh +[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1 + +. /etc/functions.sh +include /lib/network +RESOLV_CONF="/tmp/resolv.conf.auto" + +change_state () { +	[ -n "$ifc" ] || return +	uci_revert_state "$1" "$2" "$3" "$4" +	uci_set_state "$1" "$2" "$3" "$4" +} + +set_classless_routes() { +	local max=128 +	local type +	while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do +		[ ${1##*/} -eq 32 ] && type=host || type=net +		echo "udhcpc: adding route for $type $1 via $2" +		route add -$type "$1" gw "$2" dev "$interface" +		max=$(($max-1)) +		shift 2 +	done +} + +setup_interface () { +	local old_ip +	local old_broadcast +	local old_subnet +	local old_router +	local old_dns +	local user_dns +	local user_router +	local user_metric + +	[ -n "$ifc" ] && { +		old_ip="$(uci_get_state network "$ifc" ipaddr)" +		old_broadcast="$(uci_get_state network "$ifc" broadcast)" +		old_subnet="$(uci_get_state network "$ifc" netmask)" +	} + +	[ "$ip" != "$old_ip" ] \ +	|| [ "${broadcast:-+}" != "$old_broadcast" ] \ +	|| [ "${subnet:-255.255.255.0}" != "$old_subnet" ] && { +		echo "udhcpc: ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+}" +		ifconfig $interface $ip netmask ${subnet:-255.255.255.0} broadcast ${broadcast:-+} + +		change_state network "$ifc" ipaddr "$ip" +		change_state network "$ifc" broadcast "${broadcast:-+}" +		change_state network "$ifc" netmask "${subnet:-255.255.255.0}" +	} + + +	# Default Route +	[ -n "$ifc" ] && { +		change_state network "$ifc" lease_gateway "$router" +		old_router="$(uci_get_state network "$ifc" gateway)" +		user_router="$(uci_get network "$ifc" gateway)" +		user_metric="$(uci_get network "$ifc" metric)" +		[ -n "$user_router" ] && router="$user_router" +	} + +	[ -n "$router" ] && [ "$router" != "0.0.0.0" ] && [ "$router" != "255.255.255.255" ] && [ "$router" != "$old_router" ] && { +		echo "udhcpc: setting default routers: $router" + +		local valid_gw="" +		for i in $router ; do +			route add default gw $i ${user_metric:+metric $user_metric} dev $interface +			valid_gw="${valid_gw:+$valid_gw|}$i" +		done +		 +		eval $(route -n | awk ' +			/^0.0.0.0\W{9}('$valid_gw')\W/ {next} +			/^0.0.0.0/ {print "route del -net "$1" gw "$2";"} +		') + +		change_state network "$ifc" gateway "$router" +	} + +	# CIDR STATIC ROUTES (rfc3442) +	[ -n "$staticroutes" ] && set_classless_routes $staticroutes +	[ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes + +	# DNS +	old_dns=$(uci_get_state network "$ifc" dns) +	old_domain=$(uci_get_state network "$ifc" dnsdomain) +	user_dns=$(uci_get "network.$ifc.dns") +	[ -n "$user_dns" ] && dns="$user_dns" + +	[ -n "$dns" ] && [ "$dns" != "$old_dns" -o -n "$user_dns" ] && { +		echo "udhcpc: setting dns servers: $dns" +		add_dns "$ifc" $dns + +		[ -n "$domain" ] && [ "$domain" != "$old_domain" ] && { +			echo "udhcpc: setting dns domain: $domain" +			sed -i -e "${old_domain:+/^search $old_domain$/d; }/^search $domain$/d" "${RESOLV_CONF}" +			echo "search $domain" >> "${RESOLV_CONF}" +			change_state network "$ifc" dnsdomain "$domain" +		} +	} + +	[ -n "$ifc" ] || return + +	# UCI State +	change_state network "$ifc" lease_server "$serverid" +	change_state network "$ifc" lease_acquired "$(sed -ne 's![^0-9].*$!!p' /proc/uptime)" +	change_state network "$ifc" lease_lifetime "$lease" +	[ -n "$ntpsrv" ] && 	change_state network "$ifc" lease_ntpsrv "$ntpsrv" +	[ -n "$timesvr" ] && 	change_state network "$ifc" lease_timesrv "$timesvr" +	[ -n "$hostname" ] &&	change_state network "$ifc" lease_hostname "$hostname" +	[ -n "$timezone" ] && 	change_state network "$ifc" lease_timezone "$timezone" + + +	# Hotplug +	env -i ACTION="$1" INTERFACE="$ifc" DEVICE="$ifname" PROTO=dhcp /sbin/hotplug-call iface +} + + +scan_interfaces +applied= +for ifc in $interfaces __default; do +	if [ "$ifc" = __default ]; then +		ifc="" +		[ -n "$applied" ] && continue +	else +		config_get ifname "$ifc" ifname +		[ "$ifname" = "$interface" ] || continue + +		config_get proto "$ifc" proto +		[ "$proto" = "dhcp" ] || continue +		applied=true +	fi + +	case "$1" in +		deconfig) +			ifconfig "$interface" 0.0.0.0 +			[ -n "$ifc" ] && { +				env -i ACTION="ifdown" INTERFACE="$ifc" DEVICE="$ifname" PROTO=dhcp /sbin/hotplug-call iface +			 +				config_get device "$ifc" device +				config_get ifname "$ifc" ifname +				config_get aliases "$ifc" aliases +				uci_revert_state network "$ifc" +				[ -n "$device" ] && uci_set_state network "$ifc" device "$device" +				[ -n "$ifname" ] && uci_set_state network "$ifc" ifname "$ifname" +				[ -n "$aliases" ] && uci_set_state network "$ifc" aliases "$aliases" +			} +		;; +		renew) +			setup_interface update +		;; +		bound) +			setup_interface ifup +		;; +	esac +done + +# user rules +[ -f /etc/udhcpc.user ] && . /etc/udhcpc.user + +exit 0 | 
