diff --git a/package/base-files-network/Makefile b/package/base-files-network/Makefile index 0a74196bc1..78c9981e6b 100644 --- a/package/base-files-network/Makefile +++ b/package/base-files-network/Makefile @@ -18,6 +18,7 @@ include $(INCLUDE_DIR)/package.mk define Package/base-files-network SECTION:=base CATEGORY:=Base system + DEPENDS:=@!USE_NETIFD TITLE:=Network scripts for the OpenWrt base system URL:=http://openwrt.org/ VERSION:=$(PKG_RELEASE) diff --git a/package/base-files/Makefile b/package/base-files/Makefile index 0f823beee1..b19f694a09 100644 --- a/package/base-files/Makefile +++ b/package/base-files/Makefile @@ -34,7 +34,7 @@ endif define Package/base-files SECTION:=base CATEGORY:=Base system - DEPENDS:=+base-files-network + DEPENDS:=+!USE_NETIFD:base-files-network +USE_NETIFD:netifd TITLE:=Base filesystem for OpenWrt URL:=http://openwrt.org/ VERSION:=$(PKG_RELEASE)-$(REVISION) @@ -66,6 +66,11 @@ define Package/base-files/description This package contains a base filesystem and system scripts for OpenWrt. endef +define Package/base-files/config + config USE_NETIFD + bool "Use netifd instead of the old network init scripts (experimental!)" + default n +endef define Package/gcc/Default SECTION:=libs diff --git a/package/netifd/Makefile b/package/netifd/Makefile new file mode 100644 index 0000000000..c25158c581 --- /dev/null +++ b/package/netifd/Makefile @@ -0,0 +1,40 @@ +include $(TOPDIR)/rules.mk + +PKG_NAME:=netifd +PKG_VERSION:=2011-10-21 +PKG_RELEASE=$(PKG_SOURCE_VERSION) + +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=git://nbd.name/luci2/netifd.git +PKG_SOURCE_SUBDIR:=$(PKG_NAME)-$(PKG_VERSION) +PKG_SOURCE_VERSION:=986c4a1434cc61d2de560690ecc0d532a157d40a +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-$(PKG_SOURCE_VERSION).tar.gz +PKG_MIRROR_MD5SUM:=627677df83aa7844f72caa8ad4f7eea9 +# CMAKE_INSTALL:=1 + +include $(INCLUDE_DIR)/package.mk +include $(INCLUDE_DIR)/cmake.mk + +define Package/netifd + SECTION:=base + CATEGORY:=Base system + DEPENDS:=+libubus +ubus +ubusd @USE_NETIFD + TITLE:=OpenWrt Network Interface Configuration Daemon +endef + +TARGET_CFLAGS += \ + -I$(STAGING_DIR)/usr/include \ + -I$(STAGING_DIR)/usr/include/libnl-tiny + +CMAKE_OPTIONS += \ + -DLIBNL_LIBS=-lnl-tiny \ + -DDEBUG=1 + +define Package/netifd/install + $(INSTALL_DIR) $(1)/sbin + $(INSTALL_BIN) $(PKG_BUILD_DIR)/netifd $(1)/sbin/ + $(CP) ./files/* $(1)/ + $(CP) $(PKG_BUILD_DIR)/dummy/netifd-proto.sh $(1)/lib/netifd/ +endef + +$(eval $(call BuildPackage,netifd)) diff --git a/package/netifd/files/etc/hotplug.d/iface/00-netstate b/package/netifd/files/etc/hotplug.d/iface/00-netstate new file mode 100644 index 0000000000..d5cf761669 --- /dev/null +++ b/package/netifd/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/netifd/files/etc/init.d/netifd b/package/netifd/files/etc/init.d/netifd new file mode 100755 index 0000000000..e1047e7a81 --- /dev/null +++ b/package/netifd/files/etc/init.d/netifd @@ -0,0 +1,18 @@ +#!/bin/sh /etc/rc.common +START=20 +PIDFILE=/var/run/netifd.pid + +start() { + stop + start-stop-daemon -S -b -m -p $PIDFILE -x /sbin/netifd +} + +reload() { + ubus call network reload +} + +stop() { + [ -e "$PIDFILE" ] || return + start-stop-daemon -K -p $PIDFILE -x /sbin/netifd + rm -f "$PIDFILE" +} diff --git a/package/netifd/files/etc/init.d/network b/package/netifd/files/etc/init.d/network new file mode 100755 index 0000000000..d7d87350ef --- /dev/null +++ b/package/netifd/files/etc/init.d/network @@ -0,0 +1,20 @@ +#!/bin/sh /etc/rc.common +START=40 +STOP=90 + +start() { + setup_switch() { return 0; } + + include /lib/network + setup_switch + + ubus call network reload +} + +restart() { + start +} + +stop() { + /sbin/ifdown -a +} diff --git a/package/netifd/files/lib/netifd/dhcp.script b/package/netifd/files/lib/netifd/dhcp.script new file mode 100755 index 0000000000..d13ce7ec74 --- /dev/null +++ b/package/netifd/files/lib/netifd/dhcp.script @@ -0,0 +1,59 @@ +#!/bin/sh +[ -z "$1" ] && echo "Error: should be run by udhcpc" && exit 1 + +. /etc/functions.sh +. /lib/netifd/netifd-proto.sh + +set_classless_routes() { + local max=128 + local type + while [ -n "$1" -a -n "$2" -a $max -gt 0 ]; do + proto_add_ipv4_route "${1%%/*}" "${1##*/}" "$2" + max=$(($max-1)) + shift 2 + done +} + +setup_interface () { + proto_init_update "*" 1 + proto_add_ipv4_address "$ip" "${subnet:-255.255.255.0}" + # TODO: apply $broadcast + + for i in $router; do + proto_add_ipv4_route 0.0.0.0 0 "$i" + done + + # CIDR STATIC ROUTES (rfc3442) + [ -n "$staticroutes" ] && set_classless_routes $staticroutes + [ -n "$msstaticroutes" ] && set_classless_routes $msstaticroutes + + for dns in $dns; do + proto_add_dns_server "$dns" + done + for domain in $domain; do + proto_add_dns_search "$domain" + done + proto_send_update "$INTERFACE" + + # TODO + # [ -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" +} + +deconfig_interface() { + proto_init_update "*" 0 + proto_send_update "$INTERFACE" +} + +case "$1" in + deconfig) + deconfig_interface + ;; + renew|bound) + setup_interface + ;; +esac + +exit 0 diff --git a/package/netifd/files/lib/netifd/ppp-down b/package/netifd/files/lib/netifd/ppp-down new file mode 100755 index 0000000000..40aae86d07 --- /dev/null +++ b/package/netifd/files/lib/netifd/ppp-down @@ -0,0 +1,6 @@ +#!/bin/sh +PPP_IPPARAM="$6" + +. /lib/netifd/netifd-proto.sh +proto_init_update "$IFNAME" 0 +proto_send_update "$PPP_IPPARAM" diff --git a/package/netifd/files/lib/netifd/ppp-up b/package/netifd/files/lib/netifd/ppp-up new file mode 100755 index 0000000000..67884a7014 --- /dev/null +++ b/package/netifd/files/lib/netifd/ppp-up @@ -0,0 +1,16 @@ +#!/bin/sh +PPP_IPPARAM="$6" + +. /lib/netifd/netifd-proto.sh +proto_init_update "$IFNAME" 1 1 +[ -n "$PPP_IPPARAM" ] && { + [ + [ -n "$IPLOCAL" ] && proto_add_ipv4_address "$IPREMOTE" 32 + [ -n "$IPREMOTE" ] && proto_add_ipv4_route 0.0.0.0 0 "$IPREMOTE" + [ -n "$LLLOCAL" ] && proto_add_ipv6_address "$LLLOCAL" 128 + [ -n "$LLREMOTE" ] && proto_add_ipv6_route "::0" 0 "$LLREMOTE" + [ -n "$DNS1" ] && proto_add_dns_server "$DNS1" + [ -n "$DNS2" -a "$DNS1" != "$DNS2" ] && proto_add_dns_server "$DNS2" +} +proto_send_update "$PPP_IPPARAM" + diff --git a/package/netifd/files/lib/netifd/proto/dhcp.sh b/package/netifd/files/lib/netifd/proto/dhcp.sh new file mode 100755 index 0000000000..a4b96baa3f --- /dev/null +++ b/package/netifd/files/lib/netifd/proto/dhcp.sh @@ -0,0 +1,56 @@ +#!/bin/sh + +. /etc/functions.sh +. ../netifd-proto.sh +init_proto "$@" + +dhcp_init_config() { + proto_config_add_string "ipaddr" + proto_config_add_string "netmask" + proto_config_add_string "hostname" + proto_config_add_string "clientid" + proto_config_add_string "vendorid" + proto_config_add_boolean "broadcast" + proto_config_add_string "reqopts" +} + +dhcp_setup() { + local config="$1" + local iface="$2" + + json_get_var ipaddr ipaddr + json_get_var hostname hostname + json_get_var clientid clientid + json_get_var vendorid vendorid + json_get_var broadcast broadcast + json_get_var reqopts reqopts + + local opt dhcpopts + for opt in $reqopts; do + append dhcpopts "-O opt" + done + + [ "$broadcast" = 1 ] && broadcast="-O broadcast" || broadcast= + + proto_export "INTERFACE=$config" + proto_run_command "$config" udhcpc \ + -p /var/run/udhcpc-$iface.pid \ + -s /lib/netifd/dhcp.script \ + -f -t 0 -i "$iface" \ + ${ipaddr:+-r $ipaddr} \ + ${hostname:+-H $hostname} \ + ${clientid:+-c $clientid} \ + ${vendorid:+-V $vendorid} \ + $broadcast $dhcpopts +} + +dhcp_teardown() { + proto_kill_command +} + +dhcp_init() { + return +} + +add_protocol dhcp + diff --git a/package/netifd/files/lib/netifd/proto/ppp.sh b/package/netifd/files/lib/netifd/proto/ppp.sh new file mode 100755 index 0000000000..d79a897992 --- /dev/null +++ b/package/netifd/files/lib/netifd/proto/ppp.sh @@ -0,0 +1,194 @@ +#!/bin/sh + +[ -x /usr/sbin/pppd ] || exit 0 + +[ -n "$INCLUDE_ONLY" ] || { + . /etc/functions.sh + . ../netifd-proto.sh + init_proto "$@" +} + +ppp_generic_init_config() { + proto_config_add_string "username" + proto_config_add_string "password" + proto_config_add_string "keepalive" + proto_config_add_int "demand" + proto_config_add_string "pppd_options" + proto_config_add_string "connect" + proto_config_add_string "disconnect" + proto_config_add_boolean "defaultroute" + proto_config_add_boolean "peerdns" + proto_config_add_boolean "ipv6" + proto_config_add_int "mtu" +} + +ppp_generic_setup() { + local config="$1"; shift + + json_get_var ipv6 ipv6 + [ "$ipv6" = 1 ] || ipv6="" + + json_get_var peerdns peerdns + [ "$peerdns" = 0 ] && peerdns="" || peerdns="1" + + json_get_var defaultroute defaultroute + if [ "$defaultroute" = 1 ]; then + defaultroute="defaultroute replacedefaultroute"; + else + defaultroute="nodefaultroute" + fi + + json_get_var demand demand + if [ "${demand:-0}" -gt 0 ]; then + demand="precompiled-active-filter /etc/ppp/filter demand idle $demand" + else + demand="persist" + fi + + [ -n "$mtu" ] || json_get_var mtu mtu + + json_get_var keepalive keepalive + local interval="${keepalive##*[, ]}" + [ "$interval" != "$keepalive" ] || interval=5 + + json_get_var username username + json_get_var password password + + json_get_var connect connect + json_get_var disconnect disconnect + json_get_var pppd_options pppd_options + + proto_run_command "$config" /usr/sbin/pppd \ + nodetach ipparam "$config" \ + ifname "${proto:-ppp}-$config" \ + ${keepalive:+lcp-echo-interval $interval lcp-echo-failure ${keepalive%%[, ]*}} \ + ${ipv6:++ipv6} $defaultroute \ + ${peerdns:+usepeerdns} \ + $demand maxfail 1 \ + ${username:+user "$username" password "$password"} \ + ${connect:+connect "$connect"} \ + ${disconnect:+disconnect "$disconnect"} \ + ip-up-script /lib/netifd/ppp-up \ + ipv6-up-script /lib/netifd/ppp-up \ + ip-down-script /lib/netifd/ppp-down \ + ipv6-down-script /lib/netifd/ppp-down \ + ${mtu:+mtu $mtu mru $mtu} \ + $pppd_options "$@" +} + +ppp_generic_teardown() { + local interface="$1" + + case "$ERROR" in + 11|19) + proto_notify_error "$interface" AUTH_FAILED + proto_block_restart "$interface" + ;; + esac + proto_kill_command "$interface" +} + +# PPP on serial device + +ppp_init_config() { + proto_config_add_string "device" + ppp_generic_init_config + no_device=1 +} + +ppp_setup() { + local config="$1" + + json_get_var device device + ppp_generic_setup "$config" "$device" +} + +ppp_teardown() { + ppp_generic_teardown "$@" +} + +ppp_init() { + return +} + +pppoe_init_config() { + ppp_generic_init_config + proto_config_add_string "ac" + proto_config_add_string "service" +} + +pppoe_setup() { + local config="$1" + local iface="$2" + + for module in slhc ppp_generic pppox pppoe; do + /sbin/insmod $module 2>&- >&- + done + + json_get_var mtu mtu + mtu="${mtu:-1492}" + + json_get_var ac ac + json_get_var service service + + ppp_generic_setup "$config" \ + plugin rp-pppoe.so \ + ${ac:+rp_pppoe_ac "$ac"} \ + ${service:+rp_pppoe_service "$service"} \ + "nic-$iface" +} + +pppoe_teardown() { + ppp_generic_teardown "$@" +} + +pppoe_init() { + return +} + +pppoa_init_config() { + ppp_generic_init_config + proto_config_add_int "atmdev" + proto_config_add_int "vci" + proto_config_add_int "vpi" + proto_config_add_string "encaps" +} + +pppoa_setup() { + local config="$1" + local iface="$2" + + for module in slhc ppp_generic pppox pppoatm; do + /sbin/insmod $module 2>&- >&- + done + + json_get_var atmdev atmdev + json_get_var vci vci + json_get_var vpi vpi + + json_get_var encaps encaps + case "$encaps" in + 1|vc) encaps="vc-encaps" ;; + *) encaps="llc-encaps" ;; + esac + + ppp_generic_setup "$config" \ + plugin pppoatm.so \ + ${atmdev:+$atmdev.}${vpi:-8}.${vci:-35} \ + ${encaps} +} + +pppoa_teardown() { + ppp_generic_teardown "$@" +} + +pppoa_init() { + return +} + +[ -n "$INCLUDE_ONLY" ] || { + add_protocol ppp + [ -f /usr/lib/pppd/*/rp-pppoe.so ] && add_protocol pppoe + [ -f /usr/lib/pppd/*/pppoatm.so ] && add_protocol pppoa +} + diff --git a/package/netifd/files/lib/network/config.sh b/package/netifd/files/lib/network/config.sh new file mode 100755 index 0000000000..778c964e7b --- /dev/null +++ b/package/netifd/files/lib/network/config.sh @@ -0,0 +1,50 @@ +#!/bin/sh +# Copyright (C) 2011 OpenWrt.org + +. /usr/share/libubox/jshn.sh + +find_config() { + return +} + +unbridge() { + return +} + +ubus_call() { + json_init + local _data="$(ubus call "$1" "$2")" + [ $? -ne 0 ] && return "$?" + json_load "$_data" + return 0 +} + + +fixup_interface() { + local config="$1" + local ifname + + config_get type "$config" type + config_get ifname "$config" ifname + [ "bridge" = "$type" ] && ifname="br-$config" + config_set "$config" device "$ifname" + ubus_call "network.interface.$config" status + json_get_var l3dev l3_device + [ -n "$l3dev" ] && ifname="$l3dev" + json_init + config_set "$config" ifname "$ifname" +} + +scan_interfaces() { + config_load network + config_foreach fixup_interface interface +} + +setup_interface() { + local iface="$1" + local config="$2" + + [ -n "$config" ] || return 0 + ubus call network.interface."$config" add_device "{ \"name\": \"$iface\" }" +} + diff --git a/package/netifd/files/sbin/ifdown b/package/netifd/files/sbin/ifdown new file mode 120000 index 0000000000..a0e5c176a3 --- /dev/null +++ b/package/netifd/files/sbin/ifdown @@ -0,0 +1 @@ +ifup \ No newline at end of file diff --git a/package/netifd/files/sbin/ifup b/package/netifd/files/sbin/ifup new file mode 100755 index 0000000000..1036943ab2 --- /dev/null +++ b/package/netifd/files/sbin/ifup @@ -0,0 +1,27 @@ +#!/bin/sh + +case "$0" in + *ifdown) modes=down;; + *ifup) modes="down up";; + *) echo "Invalid command: $0";; +esac + +if_call() { + local interface="$1" + for mode in $modes; do + ubus call $interface $mode + done +} + +[[ "$1" == "-a" ]] && { + for interface in `ubus -S list 'network.interface.*'`; do + if_call "$interface" + done + exit +} + +ubus -S list "network.interface.$1" > /dev/null || { + echo "Interface $1 not found" + exit +} +if_call "network.interface.$1"