<?sphp $this->text('pagetitle') ?>
 
Home of the Squeezebox™ & Transporter® network music players.

Fab4 Networking

From SqueezeboxWiki

Revision as of 15:43, 30 June 2010 by Soulkeeper (Talk | contribs)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to: navigation, search

Contents

Requirements

Minimal requirements

  • wired interface
  • wireless interface
  • DHCP
  • static ip address
  • auto-ip
  • WPA2, WPA, WEP
  • WPS
  • DNS
  • ARP
  • WOL (to wake up a SC)
  • bridging between wired and wireless

Additional requirements

  • WOL (to be woken up if running SC) [RT to check if possible]
  • AP functionality [Not possible with Marvell 8686]
  • WOWL (wake on wireless lan) [RT to check if possible]

How Jive works today

Note: Jive only uses a wireless interface (eth0).

Wireless interface (eth0) up/down

[I think the ssid is used in ifup]

These commands should be the main entry point for changing the network.

  • up: /sbin/ifup eth0
  • down: /sbin/ifdown -f eth0

wpa_supplicant (controlled by wpa_cli) takes care of most network tasks.

The wpa_supplicant is loaded with the wlan modules. ifup/ifdown send commands to wpa_supplicant to reconfigure the network. The wpa_action script is run on association state changes, and is responsible for starting dhcp, static ip, etc. (via ifup)

  • config file: /etc/wpa_supplicant.conf
  • cmd: /usr/sbin/wpa_supplicant -B -Dmarvell -ieth0 -c/etc/wpa_supplicant.conf
  • cmd: /usr/sbin/wpa_cli -B -a/etc/network/wpa_action

wpa_cli cmds

  • SCAN: scan for wireless APs
  • STATUS: get info about AP currently associated to
  • SCAN_RESULTS: get a list of APs found
  • ADD_NETWORK: add a new network to the list
  • SET_NETWORK: set ssid and other parameters for that network
  • SELECT_NETWORK: disables all not used networks and only enables one
  • LIST_NETWORKS: show list of all configured networks
  • REMOVE_NETWORK: remove a network from the list
  • REASSOCIATE: force association to the one enabled network
  • DISCONNECT: disconnect from network (and wait for reassociate cmd)
  • SAVE_CONFIG: write config to wpa_supplicant.conf file

Wireless region

  • config file: /etc/network/config
  • cmd: /sbin/iwpriv eth0 setregioncode _mapping_

Get connection data about wireless interface

  • cmd: /sbin/iwpriv eth0 getSNR 1 (beacon average)
  • cmd: /sbin/iwpriv eth0 getRSSI 1 (beacon average)
  • cmd: /sbin/iwpriv eth0 getNF 1 (beacon average)

Get wireless tranfer bit rate

  • cmd: /sbin/iwconfig eth0

Power safe mode

  • cmd: /sbin/iwconfig power on
  • cmd: /sbin/iwconfig power off

DHCP

This is performed by wpa_action script.

  • start: /etc/network/udhcpc_action
  • stop: kill -TERM 'cat /var/run/udhcpc.eth0.pid'

Configuration of wireless interface

This file is used by ifup/ifdown.

  • config file: /etc/network/interfaces

DNS

This file is written by udhcpc_action script when using DHCP. (And from Networking.lua for static ip.)

  • config file: /etc/resolv.conf

Proposal for Fab4

Note: Fab4 uses two network interfaces - wired (eth0) and wireless (wlan0)

Tools and scripts

  • ifup / ifdown
  • udhcpc (DHCP client)
  • wpa_supplicant / wpa_cli (tools to configure wireless interface)
  • /etc/network/if_mapping
  • /etc/network/wpa_action
  • wpsapp (WPS application supplied by Marvell (only works with Marvell driver / hardware))

Configuration files

  • /etc/network/interfaces (wired and wireless interfaces configuration)
  • /etc/resolv.conf (DNS configuration)
  • /etc/wpa_supplicant.conf (wireless configuration file)
  • /etc/network/config (wireless region configuration)

Tools and scripts for wired (eth0) and wireless (wlan0)

ifup / ifdown

Wired (eth0) or wireless (wlan0) interfaces are started / stopped via ifup / ifdown.

ifup eth0		# starts wired interface
ifdown eth0		# stops wired interface
ifup wlan0=<SSID>	# starts wireless interface (wlan driver must be loaded and wpa_supplicant running)
ifdown wlan0=<SSID>	# stops wireless interface

udhcpc

DHCP client needed once for each interface - automatically started and stopped together with ifup / ifdown.

Called from busybox like this:

udhcpc -R -p /var/run/udhcpc.eth0.pid -b --syslog --zeroconf
-s /etc/network/udhcpc_action -i eth0 -H SqueezeboxController

Configuration files for wired (eth0) and wireless (wlan0)

Configuration files needed for both, wired (eth0) and wireless (wlan0) interfaces

/etc/network/interfaces

  • Contains info for each interface (i.e. DHCP or static IP)
  • Written by: squeezeplay_jive/share/jive/net/Networking.lua
  • Read by: /sbin/ifup - /sbin/ifdown
  • All Interfaces marked auto are started when a ifup -a is issued, which happens at boot time

Sample file (DHCP, auto-starting wired interface)

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet dhcp
	script /etc/network/udhcpc_action

#auto wlan0=<SSID>
mapping wlan0
	script /etc/network/if_mapping
iface <SSID> inet dhcp
	script /etc/network/udhcpc_action

Sample file (static IP, auto-starting wired interface)

auto lo
iface lo inet loopback

auto eth0
iface eth0 inet static
	address 192.168.144.76
	netmask 255.255.255.0
	gateway 192.168.144.1

#auto wlan0=<SSID>
mapping wlan0
	script /etc/network/if_mapping
iface <SSID> inet static
	address 192.168.144.76
	netmask 255.255.255.0
	gateway 192.168.144.1

/etc/resolv.conf

  • Contains DNS information
  • Written by: /etc/network/udhcpc_action (dhcp) / Networking.lua (static)
  • Read by: squeezeplay/src/net/jive_dns.c
nameserver 192.168.144.1
nameserver 62.5.24.163

Tools and scripts for wireless (wlan0) only

The /etc/init.d/rcS script is executed at boot time and starts the wlan script which starts the wlan driver and wpa_supplicant.

wpa_supplicant

wpa_supplicant is running in the background and controlled via wpa_cli from Networking.lua

wpa_supplicant -B -D marvell -i wlan0 -c /etc/wpa_supplicant.conf

wpa_supplicant / wpa_cli can also be used to scan for WPS capable APs. Scan results include the WPS status. (7.4 r3873)

Sample output:

# wpa_cli scan_results
Selected interface 'wlan0'
bssid / frequency / signal level / flags / ssid
00:1b:2f:xx:xx:xx       2412    222     [WPA2-PSK-CCMP-preauth] No Support
00:18:4d:xx:xx:xx       2462    210     [WPA2-PSK-CCMP-preauth] No Device
00:21:29:xx:xx:xx       2437    211     [WPA2-PSK-CCMP][WPS]    No Internet

/etc/network/if_mapping

Replaces tabs and spaces in SSIDs with underscores (_)

#!/bin/sh

# replace all " \t" in the ssid.
# FIXME ssid's with \n are not supported.
SSID=`/usr/sbin/wpa_cli -iwlan0 status | grep ^ssid= | cut -f2- -d= | tr ' \t' _`
echo $SSID

/etc/network/wpa_action

Currently does nothing, but could be used to enter power save mode for the wlan driver when not connected etc. (used by wpa_cli when run as daemon)

wpsapp

wpsapp (by Marvell) can be used to find WPS capable APs and to get the wireless configuration via WPS (either by pressing a button on the client and the AP or by providing a 8 digit pin.) Upon successful retrieving of wireless configuration data from the AP wpsapp writes a wps.conf file which contains a network section that can be used by wpa_supplicant.

wpsapp needs to be started from within the /usr/sbin/wps/ directory to work, i.e.

cd /usr/sbin/wps/
./wpsapp

Standard mode as provided by Marvell

wpsapp wlan0           # Interactive mode

Additional modes added by Logitech

wpsapp wlan0 scanall   # List all APs found (WPS and non WPS)
wpsapp wlan0 scanwps   # List only WPS capable APs
wpsapp wlan0 scanpbc   # List only APs which have its push button pressed (waiting for client)
wpsapp wlan0 scanpin   # List only APs which have a pin entered (waiting for client)
wpsapp wlan0 pbc       # Starts the push button configuration process
wpsapp wlan0 getpin    # Generates the client pin to be entered on the AP
wpsapp wlan0 pin <pin> # Starts the pin configuration process

Successful push button config log:

# ./wpsapp wlan0 pbc
Driver build with Wireless Extension 22
WPS Application build with Wireless Extension 22
Role : WPS_ENROLLEE

Start Active Scan ...

Scan Result : 0 entry in Scan List

Scan Result : 1 entry in Scan List
-----------------------------------------------------------------------
  # |  Mode | Chan# | WPA | WPS |       BSSID       |     SSID
-----------------------------------------------------------------------
 00 | Infra |  006  |  N  |  Y* | 00:21:29:xx:xx:xx | No Internet

Connecting .....

Connected to following BSS (or IBSS) :
SSID = [No Internet], BSSID = [00:21:29:c7:7a:6a]

WPS Registration Protocol Starting .....
Press [q/Q] to abort this program.

WPS Registration Protocol Completed Successfully !

#

Configuration files for wireless (wlan0) only

Configuration files only needed for wireless (wlan0) interface

/etc/wpa_supplicant.conf

  • Contains wireless configurations for different APs
  • Written, Read by: squeezeplay_jive/share/jive/net/Networking.lua (via requests to wpa_cli)
  • Read by: /usr/sbin/wpa_supplicant
update_config=1
ctrl_interface=/var/run/wpa_supplicant

network={
	ssid="<SSID>"
	proto=RSN
	key_mgmt=WPA-PSK
	psk="98765432"
#	disabled=1
}

/etc/network/config

  • Contains wireless region
  • Written, Read by: squeezeplay_jive/share/jive/net/Networking.lua
  • Read by: /etc/init.d/wlan (start / stop wlan script)
REGION=US
REGIONCODE=16

Autostart current connection after power-up / reset

The wired interface is auto-started using DHCP after a factory reset / reboot. This connects Fab4 to the network if and ethernet cable is plugged in. Setup could check for that and skip the wired / wireless selection screen (or tell the user that it found a connection and offer to use it or allow to manually switch to wireless).

Autostart wired

  • Add auto eth0 in /etc/network/interfaces ('ifup -a' in '/etc/init.d/rcS' will start it)
  • Remove auto wlan0=<SSID> in /etc/network/interfaces
  • Add disabled=1 to each wireless setting in /etc/wpa_supplicant.conf

Autostart wireless

  • Remove auto eth0 in /etc/network/interfaces
  • Add auto wlan0=<SSID> in /etc/network/interfaces ('ifup -a' in '/etc/init.d/rcS' will start it)
  • Only remove disabled=1 from the one wireless setting to start in /etc/wpa_supplicant.conf

Proposed Changes to Lua/High-Level Networking code

this section is out of date, so culling to avoid confusion

Networking has replaced Wireless as of about r3740

run perldoc on jive.net.Networking for information about new methods in Networking

Enhanced solution - some thoughts

Wireless should be turned off if not used. (As a lot of people are concerned about whether wlan really is off if not used. It's also needed for battery driven products to save energy.) This can be done by loading / unloading the wlan driver using insmod / rmmod (or the /etc/init.d/wlan script).

Stopping the wlan driver is currently not working properly. [Richard to check]

Doing so (and also starting / stopping wpa_supplicant) makes things a bit more complicated though.

  • It takes a bit to load / unload the driver [Need to see if it is acceptable]
  • If wired and a user goes into 'Settings > ... > Networks' available wlans should be listed which makes it necessary to run wlan temporarily
  • The application will need to reopen the wpa_cli socket, etc.
  • While using Marvell's WPS code we need to shutdown wpa_supplicant temporarily (maybe disassociate is enough, need to check - checked (fm): using wpa_cli disassociate / reconnect seems to only work sometimes - shutting down wpa_supplicant always works) as it interferes with the Marvell executable which talks to the driver directly.

wpa_supplicant start / stop script idea

One thing to consider though: The wpa_supplicant.conf file is manipulated through the wpa_cli script which needs to be able to connect to a running wpa_supplicant. This means the interface would either need to be upped or wpa_supplicant needs to run all the time.

Can be placed into the four following directories as needed:

  • /etc/networking/if-pre-up
  • /etc/networking/if-up
  • /etc/networking/if-down
  • /etc/networking/if-post-down
#!/bin/sh                                                                                                                     
                                                                                                                              
# Quit if not called for wlan0                                                                                                
if [ "$IFACE" != wlan0 ]; then                                                                                                
        exit 0                                                                                                                
fi                                                                                                                            
                                                                                                                             
# Get phase from script path                                                                                                  
PHASE=`dirname $0 | sed 's/.*\/\(.*\).d$/\1/'`                                                                                
echo $PHASE                                                                                                                   
                                                                                                                              
case "$MODE" in                                                                                                               
        start)                                                                                                                
                case "$PHASE" in                                                                                              
                        if-pre-up)                                                                                            
                                echo "Start wpa_supplicant"                                                                   
                                /usr/bin/logger "Starting wpa_supplicant"                                                     
                                /usr/sbin/wpa_supplicant -B -Dmarvell -iwlan0 -c/etc/wpa_supplicant.conf
                                /usr/bin/logger "Started wpa_supplicant"                                                      
                                ;;                                                                                            
                        if-up)                                                                                                
                                # ATTENTION: wpa_action calls ifup which results in a loop                                    
                                #echo "Start wpa_cli"                                                                         
                                #/usr/bin/logger "Starting wpa_cli"                                                           
                                #/usr/sbin/wpa_cli -B -a/etc/network/wpa_action                                               
                                #/usr/bin/logger "Started wap_cli"                                                            
                                ;;                                                                                            
                esac                                                                                                          
                ;;                                                                                                            
        stop)                                                                                                                 
                case "$PHASE" in                                                                                              
                        if-down)                                                                                              
                                #echo "Stop wpa_cli"                                                                          
                                #/usr/bin/logger "Stop wpa_cli"                                                               
                                #killall wpa_cli                                                                              
                                #/usr/bin/logger "Stopped wpa_cli"                                                            
                                ;;                                                                                            
                        if-post-down)                                                                                         
                                echo "Stop wpa_supplicant"                                                                    
                                /usr/bin/logger "Stop wpa_supplicant"                                                         
                                killall wpa_supplicant                                                                        
                                /usr/bin/logger "Stopped wpa_supplicant"                                                      
                                ;;                                                                                            
                esac                                                                                                          
                ;;                                                                                                            
        *)                                                                                                                    
                echo "Unknown mode: \"$MODE\""                                                                                
                exit 1                                                                                                        
                ;;                                                                                                            
esac                                                                                                                          
                                                                                                                              
exit 0

Some WPS notes

wpa_supplicant versions (as of January 09)

  • Latest (stable) wpa_supplicant is 0.5.11 - we currently use 0.5.7 (with Marvell / Logitech changes)
  • Latest (developer) version is 0.6.7 - integrates WPS into wpa_supplicant (this would make the separate wpsapp obsolete.)


Bridging Notes

Links

Tools

  • bridge-utils - Tools to configure a bridge
  • ebtables - Tools to configure MAC NAT

Kernel configuration

CONFIG_BRIDGE=y
CONFIG_BRIDGE_NETFILTER=n
CONFIG_BRIDGE_NF_EBTABLES=y
CONFIG_BRIDGE_EBT_BROUTE=y
CONFIG_BRIDGE_EBT_T_FILTER=y
CONFIG_BRIDGE_EBT_T_NAT=y
CONFIG_BRIDGE_EBT_802_3=y
CONFIG_BRIDGE_EBT_AMONG=y
CONFIG_BRIDGE_EBT_ARP=y
CONFIG_BRIDGE_EBT_IP=y
CONFIG_BRIDGE_EBT_LIMIT=y
CONFIG_BRIDGE_EBT_MARK=y
CONFIG_BRIDGE_EBT_PKTTYPE=y
CONFIG_BRIDGE_EBT_STP=y
CONFIG_BRIDGE_EBT_VLAN=y
CONFIG_BRIDGE_EBT_ARPREPLY=y
CONFIG_BRIDGE_EBT_DNAT=y
CONFIG_BRIDGE_EBT_MARK_T=y
CONFIG_BRIDGE_EBT_REDIRECT=y
CONFIG_BRIDGE_EBT_SNAT=y

Note: Kernel compilation failed if CONFIG_BRIDGE_NETFILTER was set to 'y'.

Wired (eth0) - Wired (eth1)

Tested on a PC running Ubuntu 8.04 with two ethernet cards.

ifconfig eth0 down
ifconfig eth1 down

ifconfig eth0 0.0.0.0
ifconfig eth1 0.0.0.0

brctl addbr br0
brctl setfd br0 0

brctl addif br0 eth0
brctl addif br0 eth1

ifconfig br0 <ip>

echo "1" > /proc/sys/net/ipv4/ip_forward

route add default gw <ip> dev br0


What works so far

  • Bridge can ping AP and beyond through eth0
  • Bridge can ping PC through eth1
  • PC (eth1) can ping bridge and beyond
  • PC attached to the AP can ping bridge and PC connected to eth1

Issues

  • As soon as I issue an ebtables command the bridge PC crashes

Wired (eth0) - Wireless (wlan0)

Tested on Fab4 and a PC running Ubuntu 8.04.

ifconfig eth0 down
ifconfig wlan0 down

ifconfig eth0 0.0.0.0
ifconfig wlan0 0.0.0.0

brctl addbr br0
brctl setfd br0 0

brctl addif br0 eth0
brctl addif br0 wlan0

ifconfig br0 <ip>

echo "1" > /proc/sys/net/ipv4/ip_forward

route add default gw <ip> dev br0
ebtables -t nat -A POSTROUTING -o wlan0 -j snat --to-src <wlan0 mac>


What is working so far

  • When the bridge is setup pings go through on the wired interface.

Issues

  • Wireless connection (wpa_supplicant) is not stable. Oscillates between SCANNING and ASSOCIATING.
  • No pings go through over wireless connection (Fab4 - AP)
  • After setting up the bridge I often see the "NETDEV WATCHDOG: wlan0: transmit timed out" error.
  • On Fab4 often the kernel crashes when I issue the ebtables command
  • On the PC it always crashes the kernel when I issue an ebtables command