summaryrefslogtreecommitdiffstats
path: root/src/lib/connections
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/connections')
-rw-r--r--src/lib/connections/README28
-rw-r--r--src/lib/connections/bond40
-rw-r--r--src/lib/connections/bridge47
-rw-r--r--src/lib/connections/ethernet279
-rw-r--r--src/lib/connections/pppoe77
-rw-r--r--src/lib/connections/tunnel34
-rw-r--r--src/lib/connections/tuntap28
-rw-r--r--src/lib/connections/vlan28
-rw-r--r--src/lib/connections/wireless116
9 files changed, 677 insertions, 0 deletions
diff --git a/src/lib/connections/README b/src/lib/connections/README
new file mode 100644
index 0000000..38ef11a
--- /dev/null
+++ b/src/lib/connections/README
@@ -0,0 +1,28 @@
+Support for connection types is implemented by connection files in
+
+ /usr/lib/network/connections/
+
+The file name determines the name of the connection type, so support
+for the aviancarrier connection type will be provided by the file:
+
+ /usr/lib/network/connections/aviancarrier
+
+Files that implement support for a connection type should NOT be
+executable. Such files should contain valid Bash code, among which two
+functions, namely <connection_type>_up and <connection_type>_down. For
+the aviancarrier file this would be:
+
+ aviancarrier_up
+ aviancarrier_down
+
+These functions are responsible for bringing the network up and down,
+respectively. When the functions are called, three bash files are
+already sourced, so all functions and variables in those files are
+available. The readily sourced files are:
+
+ /usr/lib/network/network
+ /usr/lib/network/globals
+ /etc/network.d/<profile>
+
+Here, <profile> is the profile file specifying the desired network
+configuration.
diff --git a/src/lib/connections/bond b/src/lib/connections/bond
new file mode 100644
index 0000000..bc5aa95
--- /dev/null
+++ b/src/lib/connections/bond
@@ -0,0 +1,40 @@
+#! /bin/bash
+. /usr/lib/network/network
+IFENSLAVE="/sbin/ifenslave"
+
+bond_up() {
+ load_profile "$1"
+
+ if [[ -e "/sys/class/net/$INTERFACE" ]]; then
+ report_fail "Interface $INTERFACE already exists."
+ exit 1
+ else
+ ip link add dev $INTERFACE type bond
+ fi
+ bring_interface up "$INTERFACE"
+
+ for slave in "${SLAVE_INTERFACES[@]}"; do
+ bring_interface up "$slave"
+ $IFENSLAVE $INTERFACE $slave
+ done
+
+ "$CONN_DIR/ethernet" up "$1"
+ return 0
+}
+
+bond_down() {
+ load_profile "$1"
+
+ for slave in "${SLAVE_INTERFACES[@]}"; do
+ $IFENSLAVE $INTERFACE -d $slave
+ done
+
+ "$CONN_DIR/ethernet" down "$1"
+ ip link delete "$INTERFACE"
+ return 0
+}
+
+bond_$1 "$2"
+exit $?
+
+# vim: set ts=4 et sw=4:
diff --git a/src/lib/connections/bridge b/src/lib/connections/bridge
new file mode 100644
index 0000000..6b3ab67
--- /dev/null
+++ b/src/lib/connections/bridge
@@ -0,0 +1,47 @@
+#! /bin/bash
+. /usr/lib/network/network
+BRCTL="/usr/sbin/brctl"
+
+bridge_up() {
+ local bridge_interface
+ load_profile "$1"
+
+ if [[ -e "/sys/class/net/$INTERFACE" ]]; then
+ if [[ ! -d "/sys/class/net/$INTERFACE/brif" ]]; then
+ report_fail "Interface $INTERFACE already exists and is not a bridge."
+ exit 1
+ fi
+ else
+ $BRCTL addbr "$INTERFACE"
+ fi
+
+ for bridge_client in $BRIDGE_INTERFACES; do
+ ip link set "$bridge_client" promisc on up
+ ip addr flush dev "$bridge_client"
+ $BRCTL addif "$INTERFACE" "$bridge_client"
+ done
+ # Set options
+ [[ "$FWD_DELAY" ]] && $BRCTL setfd "$INTERFACE" "$FWD_DELAY"
+ [[ "$MAX_AGE" ]] && $BRCTL setmaxage "$INTERFACE" "$MAX_AGE"
+
+ "$CONN_DIR/ethernet" up "$1"
+ return 0
+}
+
+bridge_down() {
+ local bridge_interface
+ load_profile "$1"
+
+ for bridge_client in $BRIDGE_INTERFACES; do
+ ip link set "$bridge_client" promisc off down
+ $BRCTL delif "$INTERFACE" "$bridge_client"
+ done
+
+ "$CONN_DIR/ethernet" down "$1"
+ $BRCTL delbr "$INTERFACE"
+ return 0
+}
+
+bridge_$1 "$2"
+exit $?
+# vim: set ts=4 et sw=4:
diff --git a/src/lib/connections/ethernet b/src/lib/connections/ethernet
new file mode 100644
index 0000000..487adf8
--- /dev/null
+++ b/src/lib/connections/ethernet
@@ -0,0 +1,279 @@
+#! /bin/bash
+# Source file for the 'ethernet' connection
+# ethernet_up $profile
+# ethernet_down $profile
+# ethernet_status
+
+. /usr/lib/network/network
+
+report_iproute()
+{
+ report_fail "$*"
+ bring_interface down "$INTERFACE"
+ exit 1
+}
+
+ethernet_up() {
+ load_profile "$1"
+ SYSCTL_INTERFACE="${INTERFACE/.//}"
+
+ if ! is_interface "$INTERFACE"; then
+ report_iproute "Interface $INTERFACE does not exist"
+ fi
+
+ # Disable IPv6 before bringing the interface up to prevent SLAAC
+ if [[ "$IP6" == "no" ]]; then
+ sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.disable_ipv6=1"
+ fi
+
+ report_debug ethernet_up bring_interface up "$INTERFACE"
+ bring_interface up "$INTERFACE"
+
+ if ! checkyesno "${SKIPNOCARRIER:-no}"; then
+ # Some cards are plain slow to come up. Don't fail immediately.
+ if ! timeout_wait "${CARRIER_TIMEOUT:-5}" '(( $(< "/sys/class/net/$INTERFACE/carrier") ))'; then
+ report_iproute "No connection"
+ fi
+ fi
+
+
+ if checkyesno "${AUTH8021X:-no}"; then
+ . "$SUBR_DIR/8021x"
+ [[ -z "$WPA_CONF" ]] && WPA_CONF="/etc/wpa_supplicant.conf"
+ [[ -z "$WPA_DRIVER" ]] && WPA_DRIVER="wired"
+
+ report_debug ethernet_up start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"
+ if ! start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"; then
+ report_fail "wpa_supplicant did not start, possible configuration error"
+ return 1
+ fi
+
+ if ! wpa_check "$INTERFACE" "$TIMEOUT" "ASSOCIATED"; then
+ bring_interface down "$INTERFACE"
+ report_fail "WPA Authentication/Association Failed"
+ return 1
+ fi
+ fi
+
+ if [[ -z "$IP" && -z "$IP6" ]]; then
+ report_iproute "At least one of IP or IP6 should be specified"
+ return 1
+ fi
+
+ case "$IP" in
+ dhcp)
+ if checkyesno "${DHCLIENT:-no}"; then
+ rm -r "/run/dhclient-${INTERFACE}.pid" >/dev/null 2>&1
+ report_debug ethernet_up dhclient -q -e TIMEOUT="${DHCP_TIMEOUT:-10}" -pf "/run/dhclient-$INTERFACE.pid" "$INTERFACE"
+ if ! dhclient -q -e TIMEOUT="${DHCP_TIMEOUT:-10}" -pf "/run/dhclient-${INTERFACE}.pid" ${DHCLIENT_OPTIONS} "$INTERFACE"; then
+ report_fail "DHCP IP lease attempt failed."
+ stop_80211x
+ return 1
+ fi
+ else
+ # Clear remaining pid files.
+ rm -f "/run/dhcpcd-$INTERFACE".{pid,cache} >/dev/null 2>&1
+ # If using own dns, tell dhcpcd to NOT replace resolv.conf
+ [[ -n "$DNS" ]] && DHCP_OPTIONS="-C resolv.conf $DHCP_OPTIONS"
+ # Start dhcpcd
+ report_debug ethernet_up dhcpcd -qL -t "${DHCP_TIMEOUT:-10}" $DHCPCD_INTERNAL_OPTIONS $DHCP_OPTIONS "$INTERFACE"
+ dhcpcd -qL -t "${DHCP_TIMEOUT:-10}" $DHCPCD_INTERNAL_OPTIONS $DHCP_OPTIONS "$INTERFACE" 2>&1 | report_debug "$(cat)"
+ if [[ "$PIPESTATUS" -ne 0 ]]; then
+ report_fail "DHCP IP lease attempt failed."
+ stop_80211x
+ return 1
+ fi
+ fi
+ ;;
+ static)
+ if [[ -n "$ADDR" ]]; then
+ [[ -z $NETMASK ]] && NETMASK=24
+ report_debug ethernet_up ip addr add "$ADDR/$NETMASK" brd + dev "$INTERFACE"
+ if ! ip addr add "$ADDR/$NETMASK" brd + dev "$INTERFACE"; then
+ report_iproute "Could not configure interface"
+ fi
+ fi
+ if [[ -n "$GATEWAY" ]]; then
+ report_debug ethernet_up ip route add default via "$GATEWAY" dev "$INTERFACE"
+ if ! ip route add default via "$GATEWAY" dev "$INTERFACE"; then
+ report_iproute "Adding gateway $GATEWAY failed"
+ fi
+ fi
+ ;;
+ ""|no)
+ ;;
+ *)
+ report_iproute "IP must be either 'dhcp', 'static' or 'no'"
+ ;;
+ esac
+
+ if [[ -n "$IP" && -n "$ROUTES" ]]; then
+ for route in "${ROUTES[@]}"; do
+ report_debug ethernet_up ip route add $route dev "$INTERFACE"
+ if ! ip route add $route dev "$INTERFACE"; then
+ report_iproute "Adding route '$route' failed"
+ fi
+ done
+ fi
+
+ # Load ipv6 module if necessary (FS#25530)
+ case "$IP6" in
+ dhcp*|stateless|static)
+ [[ -d "/proc/sys/net/ipv6" ]] || modprobe ipv6
+ ;;
+ no)
+ [[ -d "/proc/sys/net/ipv6" ]] && sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.accept_ra=0"
+ ;;
+ "") # undefined IP6 does not prevent RA's from being received -> nop
+ ;;
+ *)
+ report_iproute "IP6 must be 'dhcp', 'dhcp-noaddr', 'stateless', 'static' or 'no'"
+ ;;
+ esac
+
+ case "$IP6" in
+ dhcp*)
+ if ! type dhclient &>/dev/null; then
+ report_fail "You need to install dhclient to use DHCPv6."
+ stop_80211x
+ return 1
+ fi
+ sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.accept_ra=1"
+ if [[ "$IP6" == "dhcp-noaddr" ]]; then
+ DHCLIENT6_OPTIONS="-S ${DHCLIENT6_OPTIONS}"
+ fi
+ _DHCLIENT_PIDFILE="/run/dhclient6-${INTERFACE}.pid"
+ rm -r ${_DHCLIENT_PIDFILE} &>/dev/null
+ report_debug ethernet_up dhclient -6 -q -e TIMEOUT="${DHCP_TIMEOUT:-10}" -pf ${_DHCLIENT_PIDFILE} "$INTERFACE"
+ if ! dhclient -6 -q -e TIMEOUT="${DHCP_TIMEOUT:-10}" -pf ${_DHCLIENT_PIDFILE} ${DHCLIENT6_OPTIONS} "$INTERFACE"; then
+ report_fail "DHCPv6 IP lease attempt failed."
+ stop_80211x
+ return 1
+ fi
+ ;;
+ stateless)
+ sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.accept_ra=1"
+ ;;
+ static)
+ sysctl -q -w "net.ipv6.conf.$SYSCTL_INTERFACE.accept_ra=0"
+ if [[ -n "$ADDR6" ]]; then
+ for addr in "${ADDR6[@]}"; do
+ report_debug ethernet_up ip -6 addr add $addr dev "$INTERFACE"
+ if ! ip -6 addr add $addr dev "$INTERFACE"; then
+ report_iproute "Could not add address '$addr' to interface"
+ fi
+ done
+ fi
+ ;;
+ esac
+
+ if [[ -n "$IP6" ]]; then
+ # Wait for DAD to finish (FS#28887)
+ report_debug ethernet_up ip -6 addr show dev "$INTERFACE" tentative
+ if ! timeout_wait "${DAD_TIMEOUT:-3}" '[[ -z "$(ip -6 addr show dev "$INTERFACE" tentative)" ]]'; then
+ report_iproute "Duplicate Address Detection is taking too long"
+ fi
+
+ # Add static IPv6 routes
+ if [[ -n "$ROUTES6" ]]; then
+ for route in "${ROUTES6[@]}"; do
+ report_debug ethernet_up ip -6 route add $route dev "$INTERFACE"
+ if ! ip -6 route add $route dev "$INTERFACE"; then
+ report_iproute "Adding route '$route' failed"
+ fi
+ done
+ fi
+
+ # Set a custom gateway after waiting for DAD to finish
+ if [[ "$IP6" == "static" && -n "$GATEWAY6" ]]; then
+ report_debug ethernet_up ip -6 route replace default via "$GATEWAY6" dev "$INTERFACE"
+ if ! ip -6 route replace default via "$GATEWAY6" dev "$INTERFACE"; then
+ report_iproute "Adding gateway $GATEWAY6 failed"
+ fi
+ fi
+ fi
+
+ if [[ -n "$IPCFG" ]]; then
+ for line in "${IPCFG[@]}"; do
+ report_debug ethernet_up ip "$line"
+ if ! ip $line; then
+ report_iproute "Could not configure interface ($line)."
+ fi
+ done
+ fi
+
+ # Set hostname
+ if [[ -n "$HOSTNAME" ]]; then
+ report_debug ethernet_up hostname "$HOSTNAME"
+ if ! echo "$HOSTNAME" >/proc/sys/kernel/hostname; then
+ report_iproute "Cannot set hostname to $HOSTNAME"
+ fi
+ fi
+
+ # Generate a new resolv.conf
+ if [[ -n "$DNS" ]]; then
+ : >/etc/resolv.conf
+ [[ -n "$DOMAIN" ]] && echo "domain $DOMAIN" >>/etc/resolv.conf
+ [[ -n "$SEARCH" ]] && echo "search $SEARCH" >>/etc/resolv.conf
+ for dns in "${DNS[@]}"; do
+ echo "nameserver $dns" >>/etc/resolv.conf
+ done
+ for dnsoption in "${DNS_OPTIONS[@]}"; do
+ echo "options $dnsoption" >>/etc/resolv.conf
+ done
+ fi
+
+ return 0
+}
+
+ethernet_down() {
+ load_profile "$1"
+
+ if [[ "$IP" == "dhcp" ]]; then
+ if checkyesno "${DHCLIENT:-no}"; then
+ if [[ -f "/run/dhclient-$INTERFACE.pid" ]]; then
+ report_debug ethernet_down dhclient -q -x "$INTERFACE" -pf "/run/dhclient-$INTERFACE.pid"
+ dhclient -q -x "$INTERFACE" -pf "/run/dhclient-$INTERFACE.pid" &>/dev/null
+ #dhclient -q -r "$INTERFACE" &>/dev/null
+ fi
+ else
+ if [[ -f "/run/dhcpcd-$INTERFACE.pid" ]]; then
+ report_debug ethernet_down dhcpcd -qk "$INTERFACE"
+ dhcpcd -qk "$INTERFACE" &>/dev/null
+ fi
+ fi
+ fi
+ if [[ "$IP6" == dhcp* ]]; then
+ if [[ -f "/run/dhclient6-$INTERFACE.pid" ]]; then
+ report_debug ethernet_down dhclient -6 -q -x "$INTERFACE" -pf "/run/dhclient6-$INTERFACE.pid"
+ dhclient -6 -q -x "$INTERFACE" -pf "/run/dhclient6-$INTERFACE.pid" &>/dev/null
+ report_debug ethernet_down /bin/kill $(< /run/dhclient6-$INTERFACE.pid)
+ /bin/kill $(< /run/dhclient6-$INTERFACE.pid) &>/dev/null
+ fi
+ fi
+
+ stop_80211x
+
+ if [[ "$CONNECTION" == "wireless" ]]; then
+ report_debug ethernet_down bring_interface flush "$INTERFACE"
+ bring_interface flush "$INTERFACE"
+ else
+ report_debug ethernet_down bring_interface down "$INTERFACE"
+ bring_interface down "$INTERFACE"
+ fi
+ return 0
+}
+
+# Stop wpa_supplicant if neccessary
+stop_80211x() {
+ if checkyesno "${AUTH8021X:-no}"; then
+ . "$SUBR_DIR/8021x"
+ [[ -z "$WPA_CONF" ]] && WPA_CONF="/etc/wpa_supplicant.conf"
+ report_debug ethernet_down stop_wpa "$INTERFACE"
+ stop_wpa "$INTERFACE"
+ fi
+}
+
+ethernet_$1 "$2"
+exit $?
+# vim: set ts=4 et sw=4:
diff --git a/src/lib/connections/pppoe b/src/lib/connections/pppoe
new file mode 100644
index 0000000..17fe42d
--- /dev/null
+++ b/src/lib/connections/pppoe
@@ -0,0 +1,77 @@
+#! /bin/bash
+. /usr/lib/network/network
+
+_quotestring() {
+ echo "\"${1/\"/\\\"}\""
+}
+
+pppoe_up() {
+ local cfg
+ load_profile "$1"
+
+ mkdir -p "$STATE_DIR/pppoe.${INTERFACE}.$1/"
+ chmod 700 "$STATE_DIR/pppoe.${INTERFACE}.$1/"
+ cfg="$STATE_DIR/pppoe.${INTERFACE}.$1/options"
+ : > "${cfg}"
+ chmod 600 "${cfg}"
+
+ echo "plugin rp-pppoe.so" >> "${cfg}"
+ echo "nic-${INTERFACE}" >> "${cfg}"
+ echo "noauth" >> "${cfg}"
+ if checkyesno ${DEFAULTROUTE:-1}; then
+ echo "defaultroute" >> "${cfg}"
+ else
+ echo "nodefaultroute" >> "${cfg}"
+ fi
+ if checkyesno ${USEPEERDNS:-1}; then
+ echo "usepeerdns" >> "${cfg}"
+ fi
+ echo "linkname $(_quotestring "$1")" >> "${cfg}"
+ echo "maxfail 5" >> "${cfg}"
+ echo "updetach" >> "${cfg}"
+ if [[ ${CONNECTION_MODE} == demand ]]; then
+ echo "demand" >> "${cfg}"
+ echo "idle ${IDLE_TIMEOUT}" >> "${cfg}"
+ else
+ echo "persist" >> "${cfg}"
+ fi
+ echo "user $(_quotestring "${USER}")" >> "${cfg}"
+ echo "password $(_quotestring "${PASSWORD}")" >> "${cfg}"
+ [[ -n ${LCP_ECHO_INTERVAL} ]] && echo "lcp-echo-interval ${LCP_ECHO_INTERVAL}" >> "${cfg}"
+ [[ -n ${LCP_ECHO_FAILURE} ]] && echo "lcp-echo-failure ${LCP_ECHO_FAILURE}" >> "${cfg}"
+ [[ -n ${PPPOE_SERVICE} ]] && echo "rp_pppoe_service $(_quotestring "${PPPOE_SERVICE}")" >> "${cfg}"
+ [[ -n ${PPPOE_AC} ]] && echo "rp_pppoe_ac $(_quotestring "${PPPOE_AC}")" >> "${cfg}"
+ [[ -n ${PPPOE_SESSION} ]] && echo "rp_pppoe_sess $(_quotestring "${PPPOE_SESSION}")" >> "${cfg}"
+ [[ -n ${PPPOE_MAC} ]] && echo "pppoe-mac $(_quotestring "${PPPOE_MAC}")" >> "${cfg}"
+ [[ ${PPPOE_IP6} == yes ]] && echo "+ipv6" >> "${cfg}"
+
+ /sbin/ip link set dev "${INTERFACE}" up
+ /usr/sbin/pppd file "${cfg}"
+
+ if [[ $? -ne 0 ]]; then
+ rm "${cfg}"
+ rmdir "$STATE_DIR/pppoe.${INTERFACE}.$1/"
+ report_fail "Couldn't make pppd connection."
+ return 1
+ fi
+}
+
+pppoe_down() {
+ load_profile "$1"
+ local cfg
+ cfg="$STATE_DIR/pppoe.${INTERFACE}.$1/options"
+ PIDFILE="/var/run/ppp-$1.pid"
+
+ if [[ -e $PIDFILE ]]; then
+ read PID < "$PIDFILE"
+ [[ "$PID" ]] && kill "$PID"
+ fi
+
+ rm "${cfg}"
+ rmdir "$STATE_DIR/pppoe.${INTERFACE}.$1/"
+}
+
+pppoe_$1 "$2"
+exit $?
+
+# vim: ft=sh ts=4 et sw=4:
diff --git a/src/lib/connections/tunnel b/src/lib/connections/tunnel
new file mode 100644
index 0000000..6cefc5c
--- /dev/null
+++ b/src/lib/connections/tunnel
@@ -0,0 +1,34 @@
+#! /bin/bash
+. /usr/lib/network/network
+
+tunnel_up() {
+ load_profile "$1"
+
+ if [[ -e "/sys/class/net/$INTERFACE" ]]; then
+ report_fail "Interface $INTERFACE already exists."
+ exit 1
+ else
+ ip tunnel add "$INTERFACE" mode "$MODE" remote "$REMOTE"
+ fi
+
+ if [[ -n "$LOCAL" ]]; then
+ ip tunnel change "$INTERFACE" local "$LOCAL"
+ fi
+
+ "$CONN_DIR/ethernet" up "$1"
+ return 0
+}
+
+tunnel_down() {
+ load_profile "$1"
+
+ "$CONN_DIR/ethernet" down "$1"
+ ip tunnel del "$INTERFACE"
+
+ return 0
+}
+
+tunnel_$1 "$2"
+exit $?
+
+# vim: set ts=4 et sw=4:
diff --git a/src/lib/connections/tuntap b/src/lib/connections/tuntap
new file mode 100644
index 0000000..6985c8c
--- /dev/null
+++ b/src/lib/connections/tuntap
@@ -0,0 +1,28 @@
+#! /bin/bash
+. /usr/lib/network/network
+
+tuntap_up() {
+ load_profile "$1"
+
+ if [[ -e /sys/class/net/$INTERFACE ]]; then
+ report_fail "Interface $INTERFACE already exists."
+ exit 1
+ else
+ ip tuntap add dev "$INTERFACE" mode "$MODE" \
+ user "$USER" group "$GROUP"
+ fi
+ IP=${IP-no} "$CONN_DIR/ethernet" up "$1"
+ return 0
+}
+
+tuntap_down() {
+ load_profile "$1"
+
+ "$CONN_DIR/ethernet" down "$1"
+ ip tuntap del dev "$INTERFACE" mode "$MODE"
+ return 0
+}
+
+tuntap_$1 "$2"
+exit $?
+# vim: set ts=4 et sw=4 tw=0:
diff --git a/src/lib/connections/vlan b/src/lib/connections/vlan
new file mode 100644
index 0000000..75c7fa9
--- /dev/null
+++ b/src/lib/connections/vlan
@@ -0,0 +1,28 @@
+#! /bin/bash
+. /usr/lib/network/network
+
+vlan_up() {
+ load_profile "$1"
+
+ if [[ -e "/sys/class/net/$INTERFACE" ]]; then
+ report_fail "Interface $INTERFACE already exists."
+ exit 1
+ else
+ bring_interface up "$VLAN_PHYS_DEV"
+ ip link add link "$VLAN_PHYS_DEV" name "$INTERFACE" type vlan id "$VLAN_ID"
+ fi
+ "$CONN_DIR/ethernet" up "$1"
+ return 0
+}
+
+vlan_down() {
+ load_profile "$1"
+
+ "$CONN_DIR/ethernet" down "$1"
+ ip link delete "$INTERFACE"
+ return 0
+}
+
+vlan_$1 "$2"
+exit $?
+# vim: set ts=4 et sw=4:
diff --git a/src/lib/connections/wireless b/src/lib/connections/wireless
new file mode 100644
index 0000000..135bec7
--- /dev/null
+++ b/src/lib/connections/wireless
@@ -0,0 +1,116 @@
+#! /bin/bash
+. /usr/lib/network/network
+. "$SUBR_DIR/8021x"
+. "$SUBR_DIR/rfkill"
+
+wireless_up() {
+ PROFILE="$1"
+ load_profile "$PROFILE"
+
+ # Default settings
+ SECURITY=${SECURITY:-none}
+ WPA_DRIVER=${WPA_DRIVER:-nl80211,wext}
+
+ enable_rf $INTERFACE $RFKILL $RFKILL_NAME || return 1
+
+ # Check if interface exists
+ is_interface "$INTERFACE" || { report_fail "interface $INTERFACE does not exist"; return 1; }
+
+ # Kill any lingering wpa_supplicants.
+ stop_wpa "$INTERFACE" &> /dev/null
+
+ # Start wpa_supplicant
+ if [[ "$SECURITY" = "wpa-config" ]]; then
+ WPA_CONF="${WPA_CONF:-/etc/wpa_supplicant.conf}"
+ else
+ WPA_CONF=$(make_wpa_config_file $INTERFACE)
+ fi
+ report_debug wireless_up start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"
+ if ! start_wpa "$INTERFACE" "$WPA_CONF" "$WPA_DRIVER" "$WPA_OPTS"; then
+ report_fail "wpa_supplicant did not start, possible configuration error"
+ return 1
+ fi
+
+ # Scan for network's existence first
+ if checkyesno "${SCAN:-no}"; then
+ report_debug wireless_up scanning
+ local OLDESSID="$ESSID"
+ if [[ -n "$AP" ]]; then
+ BSSID=$(wpa_find_ap "$INTERFACE" "$AP")
+ else
+ ESSID=$(wpa_find_essid "$INTERFACE" "$ESSID")
+ fi
+ if [[ $? -gt 0 ]]; then
+ report_fail "Wireless network \"$OLDESSID\" not present."
+ report_debug wireless_up stop_wpa "$INTERFACE"
+ stop_wpa "$INTERFACE"
+ return 1
+ fi
+ fi
+
+ # Build configuration file
+ case "$SECURITY" in
+ wpa-config)
+ ;;
+ none|wep|wpa|wpa-configsection)
+ printf "%s\n" "network={" "$(make_wpa_config)" "}" >> "$WPA_CONF"
+ report_debug wireless_up "Configuration generated at $WPA_CONF"
+ report_debug wireless_up wpa_reconfigure "$INTERFACE"
+ if ! wpa_reconfigure "$INTERFACE"; then
+ report_fail "WPA configuration failed!"
+ stop_wpa "$INTERFACE"
+ return 1
+ fi
+ ;;
+ *)
+ report_fail "Invalid SECURITY setting: $SECURITY"
+ ;;
+ esac
+
+ # Bring interface up after starting wpa_supplicant
+ # This is important since cards such as iwl3945 do not support
+ # mode switching when they are already up.
+ report_debug wireless_up ifup
+ bring_interface up "$INTERFACE" || return 1
+
+ report_debug wireless_up wpa_check
+ if ! wpa_check "$INTERFACE" "$TIMEOUT"; then
+ report_fail "WPA Authentication/Association Failed"
+ return 1
+ fi
+
+ if ! "$CONN_DIR/ethernet" up "$PROFILE"; then
+ wireless_down "$PROFILE" YES
+ return 1
+ fi
+}
+
+# wireless_down PROFILE [ LEAVE ifconfig up? default no ]
+wireless_down() {
+ local PROFILE="$1"
+ load_profile "$PROFILE"
+
+ "$CONN_DIR/ethernet" down "$PROFILE"
+
+ # The config file can contain a non-standard control socket path
+ if [[ "$SECURITY" = "wpa-config" ]]; then
+ WPA_CONF="${WPA_CONF:-/etc/wpa_supplicant.conf}"
+ fi
+ report_debug wireless_down stop_wpa "$INTERFACE"
+ stop_wpa "$INTERFACE"
+ rm -rf "$STATE_DIR/wpa.$INTERFACE"
+
+ bring_interface down "$INTERFACE"
+
+ # Handle wireless kill switches
+ # Any reason why a hardware switch should be considered on interface down?
+ if [[ "$RFKILL" == "soft" ]]; then
+ set_rf_state "$INTERFACE" disabled $RFKILL_NAME || return 1
+ fi
+}
+
+wireless_$1 "$2" "$3"
+exit $?
+
+# vim: ft=sh ts=4 et sw=4 tw=0:
+