LED Configuration With OpenWRT

I still had an unused obsolete PCEngines WRAP.1C board lying around. I had never tried OpenWRT on x86 (back in the early to mid 2000s, my WRAP ran LEAF Bering uClibc).

So I set up a SixXS IPv6 tunnel endpoint on the WRAP, and while reading the OpenWRT documentation, I stumbled over the mentioning of LEDs. Turns out that OpenWRT can trigger some boards’ LEDs on a number of events - which let me configure two special purpose LEDs instead of the two unused-by-default in the WRAP’s array of 3 GPIO LEDs.

  • The first LED shows me the basic system state: power is on and system is booting, system has booted, system has shut down.

  • The second LED shows me “Link Status” and TX/RX activity on the IPv6 tunnel endpoint. Just like the LEDs commonly found on Ethernet RJ45 jacks do, but for a software defined virtual network interface.

  • The third LED shows me whether someone else in the local network has their computer turned on. For me, this means that I know to avoid saturating the internet uplink while someone else might be trying to use the internet.

The LEDs on the WRAP

Exploring the LEDs
1
2
3
4
5
6
root@OpenWrt:~# opkg install kmod-leds-wrap
root@OpenWrt:~# ls -1 /sys/class/leds/
wrap::error
wrap::extra
wrap::power
root@OpenWrt:~#

Manually playing with the pseudo files in /sys/class/leds/*/ showed that we can actually control the LEDs through this interface.

OpenWRT is set up such that /etc/config/system can contain config led sections which are read and applied close to the end of the system boot.

System state LED

When the WRAP board is supplied with electricity, the power LED turns on and stays on.

However, I would rather the LED showed me more than just the presence of power:

  • When the system is being rebooted or halted, it would be nice to see when the system has actually finished shutting down.

  • When the system is booting, it would be nice to see when it has finished booting.

When the system is turned on, the WRAP firmware turns on the power LED and keeps it on. Then OpenWRT runs through all /etc/rc.d/S* scripts in order. When it arrives at S99led, the following configuration is activated, making the power LED flash for 0.1s every second.

Install packages
1
2
root@OpenWrt:~# opkg install kmod-ledtrig-heartbeat
root@OpenWrt:~#
/etc/config/system snippet
1
2
3
4
5
6
7
[...]

config led power_led
        option sysfs   'wrap::power'
        option trigger 'heartbeat'

[...]

For the shutdown, we need to put some code late into the sequence of /etc/rc.d/S* scripts being run.

/etc/init.d/powerled
1
2
3
4
5
6
7
8
9
#!/bin/sh /etc/rc.common

STOP=99

stop() {
        local led="/sys/class/leds/wrap::power"
        echo "none" > "$led/trigger"
        echo "0"    > "$led/brightness"
}
Install powerled as K99powerled
1
2
root@OpenWrt:~# /etc/init.d/powerled enable
root@OpenWrt:~#

That’s it.

Tunnel endpoint link status and activity LED

The following lights up the middle LED when the sixxs0 tunnel endpoint network interface becomes available and has a ‘link’, and flashes the LED dark whenever a data packet goes through the sixxs0 interface.

Install packages
1
2
root@OpenWrt:~# opkg install kmod-ledtrig-netdev
root@OpenWrt:~#
/etc/config/system snippet
1
2
3
4
5
6
7
8
9
[...]

config led sixxs_led
        option sysfs   'wrap::error'
        option dev     'sixxs0'
        option mode    'link rx tx'
        option trigger 'netdev'

[...]

If we had more than one LED to spare

If we had three whole LEDs to spare, we could spend one LED on the link status, the second one flashing on transmission and the third one flashing on reception of a data packet.

/etc/config/system snippet
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
[...]

config led link_led
        option sysfs   'wrap::extra'
        option dev     'sixxs0'
        option mode    'link'
        option trigger 'netdev'

config led rx_led
        option sysfs   'wrap::power'
        option dev     'sixxs0'
        option mode    'rx'
        option trigger 'netdev'

config led tx_led
        option sysfs   'wrap::error'
        option dev     'sixxs0
        option mode    'tx'
        option trigger 'netdev'

[...]

Or if we have two LEDs to spare, we could do

/etc/config/system
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[...]

config led link_led
        option sysfs   'wrap::error'
        option dev     'sixxs0'
        option mode    'link'
        option trigger 'netdev'

config led rxtx_led
        option sysfs   'wrap::extra'
        option dev     'sixxs0
        option mode    'rx tx'
        option trigger 'netdev'

[...]

“Someone else is using the internet” LED (YUP LED)

Update: I have put a much improved version of this setup at YUP LED With Send-echo-request.

In case someone else is busy with their PCs on my home network and I am downloading something, they will want to signal me to yield at least some of the uplink to them.

OpenWRT makes it easy to dedicate a LED to YUP (yield uplink, please) at the cost of running one or more continuous ping processes on the OpenWRT system and having the respective ICMP packets on the LAN.

Install packages
1
2
3
4
root@OpenWrt:~# opkg install kmod-ledtrig-netfilter
root@OpenWrt:~# opkt install kmod-ipt-led
root@OpenWrt:~# opkt install iptables-mod-led
root@OpenWrt:~#
/etc/config/system
1
2
3
4
5
6
7
[...]

config led otheruser_led
        option sysfs   'wrap::extra'
        option trigger 'netfilter-yup'

[...]
/etc/rc.local
1
2
3
4
5
6
7
8
[...]

# Check whether the other PCs with IP .23 and .42 are online.
# Restart the pings in case there is no route temporarily.
(while :; do ping -q 192.168.1.23; sleep 2; done &) &
(while :; do ping -q 192.168.1.42; sleep 2; done &) &

[...]
/etc/firewall.user
1
2
3
4
5
6
7
[...]

iptables -I INPUT -p icmp --icmp-type echo-reply \
         --source 192.168.0.0/16 \
         -j LED --led-trigger-id yup --led-delay 1000

[...]

This can even be changed to have a secondary function of showing that another host 192.168.1.23 is up while primary host 192.168.1.42 is down:

/etc/firewall.user
1
2
3
4
5
6
7
8
9
10
[...]

iptables -I INPUT -p icmp --icmp-type echo-reply \
         --source 192.168.1.23/32 \
         -j LED --led-trigger-id yup --led-delay 100
iptables -I INPUT -p icmp --icmp-type echo-reply \
         --source 192.168.1.42/32 \
         -j LED --led-trigger-id yup --led-delay 1000

[...]