#!/bin/rc
# ipv6on [netdir ndbfile] - configure an interface for ipv6.
# use ipv6 address from ndb if present,
# else do stateless address autoconfiguration (SLAAC).
if (! ~ $#* 0 2 3) {
echo usage: $0 '[netdir ndbfile [obs-gw-v4-name]]' >[1=2]
exit usage
}
rfork e
fn ipq { # attr val rattr
ndb/ipquery $* | sed 's/^[a-z0-9]+=//'
}
if (~ $#* 0) {
netdir=/net
ndbf=/lib/ndb/local
}
if not {
netdir=$1
ndbf=$2
}
if (~ $netdir /net) {
xsfx=()
xdir=()
}
if not {
xsfx=(-x `{echo $netdir | sed 's;^/net;;'})
xdir=(-x $netdir)
}
fn nonnil { # variable
if (~ $#$1 0) {
echo ipv6on: no ip for $1 >[1=2]
exit no-ip
}
if (! ~ $#$1 1) {
echo ipv6on: multiple ips for $1 >[1=2]
exit multiple-ips
}
}
#
# configure v6 for link-local addresses (fe80::) & multicast (ff02::).
# accept router advertisements, which will contain a default route.
#
if (! ip/ipconfig -6 $xdir ether $netdir/ether?)
exit 'ipconfig -6 failed'
ip/ipconfig $xdir ether $netdir/ether? ra6 recvra 1
# lookup any v6 address for me in ndb, else use slaac
myeth=`{cat $netdir/ether?/addr}
mev6=`{ndb/query -f $ndbf ether $myeth ipv6}
if (~ $#mev6 0 || ~ $mev6 '')
mev6=`{ndb/query -f $ndbf sys $sysname ipv6}
if (~ $#mev6 0 || ~ $mev6 '') {
# slaac: could perhaps get prefix from above RA
ipnet=`{ipq ether $myeth ipnet}
if (~ $#ipnet 0 || ~ $ipnet '')
ipnet=`{ipq sys $sysname ipnet}
nonnil ipnet
v6pfx=`{ipq ipnet $ipnet ipv6pfx}
nonnil v6pfx
mev6=`{ip/linklocal $myeth | sed 's/^fe80:/'$v6pfx'/'}
}
nonnil mev6
#
# configure my global v6 addresses
#
v6mask=`{ipq ip $mev6 ipmask}
ip/ipconfig $xdir ether $netdir/ether? add $mev6 $v6mask
ip/ipconfig $xdir loopback /dev/null add $mev6 /128
|