1#! /bin/sh 2# SPDX-License-Identifier: GPL-2.0 3 4CheckForwarding () { 5 local sbase fwd 6 sbase=/proc/sys/net/ipv4/conf 7 fwd=0 8 if [ -d $sbase ]; then 9 for dir in $sbase/*/forwarding; do 10 fwd=$(( fwd + $(cat "$dir") )) 11 done 12 else 13 fwd=2 14 fi 15 return $fwd 16} 17 18RestartRDISC () { 19 killall -HUP rdisc || rdisc -fs 20} 21 22ABCMaskLen () { 23 local class; 24 25 class=${1%%.*} 26 if [ "$1" = "" -o $class -eq 0 -o $class -ge 224 ]; then return 0 27 elif [ $class -ge 224 ]; then return 0 28 elif [ $class -ge 192 ]; then return 24 29 elif [ $class -ge 128 ]; then return 16 30 else return 8; fi 31} 32 33label="label $1" 34ldev="$1" 35dev=${1%:*} 36if [ "$dev" = "" -o "$1" = "help" ]; then 37 echo "Usage: ifcfg DEV [[add|del [ADDR[/LEN]] [PEER] | stop]" 1>&2 38 echo " add - add new address" 1>&2 39 echo " del - delete address" 1>&2 40 echo " stop - completely disable IP" 1>&2 41 exit 1 42fi 43shift 44 45CheckForwarding 46fwd=$? 47if [ $fwd -ne 0 ]; then 48 echo "Forwarding is ON or its state is unknown ($fwd). OK, No RDISC." 1>&2 49fi 50 51 52deleting=0 53case "$1" in 54add) shift ;; 55stop) 56 if [ "$ldev" != "$dev" ]; then 57 echo "Cannot stop alias $ldev" 1>&2 58 exit 1; 59 fi 60 ip -4 addr flush dev $dev $label || exit 1 61 if [ $fwd -eq 0 ]; then RestartRDISC; fi 62 exit 0 ;; 63del*) 64 deleting=1; shift ;; 65*) 66esac 67 68ipaddr= 69pfxlen= 70if [ "$1" != "" ]; then 71 ipaddr=${1%/*} 72 if [ "$1" != "$ipaddr" ]; then 73 pfxlen=${1#*/} 74 fi 75 if [ "$ipaddr" = "" ]; then 76 echo "$1 is bad IP address." 1>&2 77 exit 1 78 fi 79fi 80shift 81 82peer=$1 83if [ "$peer" != "" ]; then 84 if [ "$pfxlen" != "" -a "$pfxlen" != "32" ]; then 85 echo "Peer address with non-trivial netmask." 1>&2 86 exit 1 87 fi 88 pfx="$ipaddr peer $peer" 89else 90 if [ "$ipaddr" = "" ]; then 91 echo "Missing IP address argument." 1>&2 92 exit 1 93 fi 94 if [ "$pfxlen" = "" ]; then 95 ABCMaskLen $ipaddr 96 pfxlen=$? 97 fi 98 pfx="$ipaddr/$pfxlen" 99fi 100 101if [ "$ldev" = "$dev" -a "$ipaddr" != "" ]; then 102 label= 103fi 104 105if [ $deleting -ne 0 ]; then 106 ip addr del $pfx dev $dev $label || exit 1 107 if [ $fwd -eq 0 ]; then RestartRDISC; fi 108 exit 0 109fi 110 111 112if ! ip link set up dev $dev ; then 113 echo "Error: cannot enable interface $dev." 1>&2 114 exit 1 115fi 116if [ "$ipaddr" = "" ]; then exit 0; fi 117 118if ! arping -q -c 2 -w 3 -D -I $dev $ipaddr ; then 119 echo "Error: some host already uses address $ipaddr on $dev." 1>&2 120 exit 1 121fi 122 123if ! ip address add $pfx brd + dev $dev $label; then 124 echo "Error: failed to add $pfx on $dev." 1>&2 125 exit 1 126fi 127 128arping -q -A -c 1 -I $dev $ipaddr 129noarp=$? 130( sleep 2 ; 131 arping -q -U -c 1 -I $dev $ipaddr ) >/dev/null 2>&1 </dev/null & 132 133ip route add unreachable 224.0.0.0/24 >/dev/null 2>&1 134ip route add unreachable 255.255.255.255 >/dev/null 2>&1 135if [ "`ip link ls $dev | grep -c MULTICAST`" -ge 1 ]; then 136 ip route add 224.0.0.0/4 dev $dev scope global >/dev/null 2>&1 137fi 138 139if [ $fwd -eq 0 ]; then 140 if [ $noarp -eq 0 ]; then 141 ip ro append default dev $dev metric 30000 scope global 142 elif [ "$peer" != "" ]; then 143 if ping -q -c 2 -w 4 $peer ; then 144 ip ro append default via $peer dev $dev metric 30001 145 fi 146 fi 147 RestartRDISC 148fi 149 150exit 0 151