#! /bin/sh # SPDX-License-Identifier: GPL-2.0 CheckForwarding () { local sbase fwd sbase=/proc/sys/net/ipv4/conf fwd=0 if [ -d $sbase ]; then for dir in $sbase/*/forwarding; do fwd=$(( fwd + $(cat "$dir") )) done else fwd=2 fi return $fwd } RestartRDISC () { killall -HUP rdisc || rdisc -fs } ABCMaskLen () { local class; class=${1%%.*} if [ "$1" = "" -o $class -eq 0 -o $class -ge 224 ]; then return 0 elif [ $class -ge 224 ]; then return 0 elif [ $class -ge 192 ]; then return 24 elif [ $class -ge 128 ]; then return 16 else return 8; fi } label="label $1" ldev="$1" dev=${1%:*} if [ "$dev" = "" -o "$1" = "help" ]; then echo "Usage: ifcfg DEV [[add|del [ADDR[/LEN]] [PEER] | stop]" 1>&2 echo " add - add new address" 1>&2 echo " del - delete address" 1>&2 echo " stop - completely disable IP" 1>&2 exit 1 fi shift CheckForwarding fwd=$? if [ $fwd -ne 0 ]; then echo "Forwarding is ON or its state is unknown ($fwd). OK, No RDISC." 1>&2 fi deleting=0 case "$1" in add) shift ;; stop) if [ "$ldev" != "$dev" ]; then echo "Cannot stop alias $ldev" 1>&2 exit 1; fi ip -4 addr flush dev $dev $label || exit 1 if [ $fwd -eq 0 ]; then RestartRDISC; fi exit 0 ;; del*) deleting=1; shift ;; *) esac ipaddr= pfxlen= if [ "$1" != "" ]; then ipaddr=${1%/*} if [ "$1" != "$ipaddr" ]; then pfxlen=${1#*/} fi if [ "$ipaddr" = "" ]; then echo "$1 is bad IP address." 1>&2 exit 1 fi fi shift peer=$1 if [ "$peer" != "" ]; then if [ "$pfxlen" != "" -a "$pfxlen" != "32" ]; then echo "Peer address with non-trivial netmask." 1>&2 exit 1 fi pfx="$ipaddr peer $peer" else if [ "$ipaddr" = "" ]; then echo "Missing IP address argument." 1>&2 exit 1 fi if [ "$pfxlen" = "" ]; then ABCMaskLen $ipaddr pfxlen=$? fi pfx="$ipaddr/$pfxlen" fi if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then label= fi if [ $deleting -ne 0 ]; then ip addr del $pfx dev $dev $label || exit 1 if [ $fwd -eq 0 ]; then RestartRDISC; fi exit 0 fi if ! ip link set up dev $dev ; then echo "Error: cannot enable interface $dev." 1>&2 exit 1 fi if [ "$ipaddr" = "" ]; then exit 0; fi if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then echo "Error: some host already uses address $ipaddr on $dev." 1>&2 exit 1 fi if ! ip address add $pfx brd + dev $dev $label; then echo "Error: failed to add $pfx on $dev." 1>&2 exit 1 fi arping -q -A -c 1 -I $dev $ipaddr noarp=$? ( sleep 2 ; arping -q -U -c 1 -I $dev $ipaddr ) >/dev/null 2>&1 /dev/null 2>&1 ip route add unreachable 255.255.255.255 >/dev/null 2>&1 if [ "`ip link ls $dev | grep -c MULTICAST`" -ge 1 ]; then ip route add 224.0.0.0/4 dev $dev scope global >/dev/null 2>&1 fi if [ $fwd -eq 0 ]; then if [ $noarp -eq 0 ]; then ip ro append default dev $dev metric 30000 scope global elif [ "$peer" != "" ]; then if ping -q -c 2 -w 4 $peer ; then ip ro append default via $peer dev $dev metric 30001 fi fi RestartRDISC fi exit 0