ref: c690c0b9f3074708f33c4d982e26b67de1dfcb95
dir: /rc/bin/ethermultilink/
#!/bin/rc # ethermultilink outpus bridge(3) commands to switch # between multiple ethernet (or wifi) interfaces # depending on their link status. # the first argument is the primary interface, # which is permanently added to the bridge # while the following arguments are for secondary # interfaces in increasing priority order. # only the highest priority active interface is bound. rfork e fn usage { echo 'Usage: ' $0 'primaryether secondaryether1 [secondaryether2 ....] > /net/bridgeX/ctl' >[1=2] exit 'usage' } fn missing { echo 'missing: ' $1 >[1=2] exit 'missing' } ~ $#* 0 1 && usage # make sure arguments are ethernets for(i){ test -r $i/stats || missing $i/stats } # first interface is the primary primary=$1 shift ea=`{cat $primary/addr} || missing $primary/addr net=`{echo $primary | sed 's!/*[^/]*$!!g'} test -r $net/arp || missing $net/arp # insert the primary to bridge echo bind ether primary 0 $primary || exit # now select secondary from the list depending on link status @{ type=none old=/dev/null while(){ # interfaces are in increasing priority order for(i){ if(! ~ $i $primary && grep -s 'link: 1' $i/stats) secondary=$i } if(! ~ $secondary $old){ echo $primary is switching from $old to $secondary >[1=2] if(! ~ $type none){ echo unbind $type secondary 0 } # if the secondary has the same ea as the primary, # we need to bind it in non-bridge mode type=ether if(~ $ea `{cat $secondary/addr}) type=ethermac echo bind $type secondary 0 $secondary # make switches aware of the new path echo flush > $net/arp } old=$secondary sleep 1 } } </dev/null & exit ''