summaryrefslogblamecommitdiffstats
path: root/source/ap/lxc/scripts/rc.inet1.lxc
blob: 58213a7c054a3b3a58cbb595f49b440c62f11e1d (plain) (tree)
























                                                                           
                                                              




                               






                                            
















                                                                               
                                              







                                                              






                                                                                     





                                               


                                                                       






                       

















                                                                                                                    


                                                                         





                                                    
      
                                        



                                             
                                          
                                                                         
                                

                                                                             
                                        
      

                                          











                                                                     







                                                                                           





                                                                              




                                                                                                    






                                                                                                               









                                                                                                     
        

                                                                   







                                                                               
                                                                               




                                                                                           
                                                                                         






                                                                                    

                                                   
                                                                       
                                          


                                                                                       

                                                                                      


                                










                                                                                                             
                                                         
                                                                      
                                    



                                                                                                          
            









                                                                                 


          
                                              

       
                                                   










                                                                 




                                                                                           

                                                                   
                                                                             

             

                                                                           
















                                                                       



                                                                                     





                                                    


                                                                    





                                

                              







                               
                              

              
                








            
                                                                  

       
                                                                     

      
                                          


       
                                               

       




                                                                                              


                  

                                                                                               


                                                                         
                                             




                    




                                                          
#! /bin/sh
# /etc/rc.d/rc.inet1
# This script is used to bring up the various network interfaces.
#
# @(#)/etc/rc.d/rc.inet1 10.2  Sun Jul 24 12:45:56 PDT 2005  (pjv)

# Set $container variable since this is a modified version of rc.inet1 with
# changes for running in an lxc container.  A check to see if this variable
# is set will be used to skip parts of the script that we don't want to run
# in a container.  Thanks to Matteo Bernardini <ponce@slackbuilds.org> and
# Chris Willing for the initial work making this script lxc compatible.
container="lxc"

############################
# READ NETWORK CONFIG FILE #
############################

# Get the configuration information from /etc/rc.d/rc.inet1.conf:
. /etc/rc.d/rc.inet1.conf

###########
# LOGGING #
###########

# If possible, log events in /var/log/messages:
if [ -f /var/run/syslogd.pid ] && [ -x /usr/bin/logger ]; then
  LOGGER=/usr/bin/logger
else # output to stdout/stderr:
  LOGGER=/bin/cat
fi

# Handy wrapper for verbose logging
debug_log() {
  if [ "$DEBUG_ETH_UP" = "yes" ]; then
    echo "/etc/rc.d/rc.inet1:  $*" | $LOGGER
  fi
}

############################
# DETERMINE INTERFACE LIST #
############################

# Compose a list of interfaces from /etc/rc.d/rc.inet1.conf (with a maximum
# of 6 interfaces, but you can easily enlarge the interface limit
# - send me a picture of such a box :-).
# If a value for IFNAME[n] is not set, we assume it is an eth'n' interface.
# This way, the new script is compatible with older rc.inet1.conf files.
# The IFNAME array will be used to determine which interfaces to bring up/down.
MAXNICS=${MAXNICS:-6}
i=0
while [ $i -lt $MAXNICS ];
do
  IFNAME[$i]=${IFNAME[$i]:=eth${i}}
  i=$(($i+1))
done
debug_log "List of interfaces: '${IFNAME[*]}'"

######################
# LOOPBACK FUNCTIONS #
######################

# Function to bring up the loopback interface.  If loopback is
# already up, do nothing.
lo_up() {
  if [ -e /sys/class/net/lo ]; then
    if ! /sbin/ip link show dev lo | grep -wq -e "state UP" -e "state UNKNOWN" ; then
      echo "/etc/rc.d/rc.inet1:  /sbin/ip address add 127.0.0.1/8 dev lo" | $LOGGER
      /sbin/ip address add 127.0.0.1/8 dev lo
      /sbin/ip link set dev lo up
      echo "/etc/rc.d/rc.inet1:  /sbin/ip route add 127.0.0.0/8 dev lo" | $LOGGER
      /sbin/ip route add 127.0.0.0/8 dev lo 
    fi
  fi
}

# Function to take down the loopback interface:
lo_down() {
  if [ -e /sys/class/net/lo ]; then
    echo "/etc/rc.d/rc.inet1:  /sbin/ip link set dev lo down" | $LOGGER
    /sbin/ip link set dev lo down
  fi
}

#######################
# INTERFACE FUNCTIONS #
#######################

# Function to create virtual interfaces
virtif_create() {
  # argument is 'i' - the position of this interface in the VIRTIFNAME array.
  # this loop goes from i=0 to i=number_of_configured_virtual_interfaces_minus_one
  # which means it doesn't do anything if there are none.
  for i in $(seq 0 $((${#VIRTIFNAME[@]} - 1))); do
    /sbin/ip tuntap add dev ${VIRTIFNAME[$i]} mode ${VIRTIFTYPE[$i]} user ${VIRTIFUSER[$i]} group ${VIRTIFGROUP[$i]}
  done
}

# Function to destory virtual interfaces
virtif_destroy() {
  # argument is 'i' - the position of this interface in the VIRTIFNAME array.
  for i in $(seq 0 $((${#VIRTIFNAME[@]} - 1))); do
    /sbin/ip tuntap del dev ${VIRTIFNAME[$i]} mode ${VIRTIFTYPE[$i]}
  done
}

# Function to assemble a bridge interface.
br_open() {
  # argument is 'i' - the position of this interface in the IFNAME array.
  /sbin/ip link add name ${IFNAME[$1]} type bridge
  for BRIF in ${BRNICS[$1]}; do
    /sbin/ip link set dev $BRIF down
    /sbin/ip address add 0.0.0.0 dev $BRIF
    /sbin/ip link set dev $BRIF master ${IFNAME[$1]}
    /sbin/ip link set dev $BRIF up
  done
  /sbin/ip link set dev ${IFNAME[$1]} up
}

# Function to disassemble a bridge interface.
br_close() {
  /sbin/ip link set dev ${IFNAME[$1]} down
  # argument is 'i' - the position of this interface in the IFNAME array.
  #for BRIF in ${BRNICS[$1]}; do
  for BRIF in $(ls --indicator-style=none /sys/class/net/${IFNAME[$1]}/brif/)
  do
    /sbin/ip link set dev $BRIF nomaster
  done
  /sbin/ip link set dev ${IFNAME[$1]} down
  /sbin/ip link del ${IFNAME[$1]}
}

# Function to bring up a network interface.  If the interface is
# already up or does not yet exist (perhaps because the kernel driver
# is not loaded yet), do nothing.
if_up() {
  # Determine position 'i' of this interface in the IFNAME array:
  i=0
  while [ $i -lt $MAXNICS ]; do
    [ "${IFNAME[$i]}" = "${1}" ] && break
    i=$(($i+1))
  done
  # If "i" is greater or equal to "MAXNICS" at this point, it means we didn't
  # find an entry in IFNAME array corresponding to "$1", which likely means
  # there are more interfaces configured than MAXNICS. Let's err on the
  # side of caution and do nothing instead of possibly doing the wrong thing.
  if [ $i -ge $MAXNICS ]; then
    echo "/etc/rc.d/rc.inet1:  skipping ${1}, you might need to increase MAXNICS" | $LOGGER
    return
  fi

  if [ -z "$container" ]; then
    # If the interface is a bridge, then create it first:
    [ -n "${BRNICS[$i]}" ] && br_open $i
    # If the interface isn't in the kernel yet (but there's an alias for it in
    # modules.conf), then it should be loaded first:
    if [ -z "${IPADDR[$i]}" ] && [ "${USE_DHCP[$i]}" != "yes" ]; then # skip unconfigured interfaces
      debug_log "skipping ${1} early, interface is not configured in /etc/rc.d/rc.inet1.conf"
      return 0
    fi
    if [ ! -e /sys/class/net/${1%%:*} ]; then # no interface yet
      if /sbin/modprobe -c | grep -v "^#" | grep -w "alias ${1}" | grep -vw "alias ${1} off" > /dev/null ; then
        echo "/etc/rc.d/rc.inet1:  /sbin/modprobe ${1}" | $LOGGER
        /sbin/modprobe ${1}
      fi
    fi
  fi # end check container

  if [ -e /sys/class/net/${1%%:*} ]; then # interface exists
    if ! /sbin/ip address show dev ${1} 2>/dev/null | grep -wq inet || \
      ! /sbin/ip link show dev ${1} | grep -wq "state UP" ; then # interface not up or not configured
      if [ -n "${HWADDR[$i]}" ]; then # Set hardware address _before_ the interface goes up:
        echo "/etc/rc.d/rc.inet1:  /sbin/ip link set dev ${1} address ${HWADDR[$i]}" | $LOGGER
        /sbin/ip link set dev ${1} address ${HWADDR[$i]}
      fi
      if [ -n "${MTU[$i]}" ]; then # Set MTU to something else than 1500
        echo "/etc/rc.d/rc.inet1:  /sbin/ip link set dev ${1} mtu ${MTU[$i]}" | $LOGGER
        /sbin/ip link set dev ${1} mtu ${MTU[$i]}
      fi
      if /sbin/ip link show dev ${1} | grep -wq "state DOWN" ; then
        /sbin/ip link set dev ${1} up  # Bring up interface
      fi
      if [ -x /etc/rc.d/rc.wireless ]; then
        . /etc/rc.d/rc.wireless ${1} start # Initialize any wireless parameters
      fi
      if [ "${USE_DHCP[$i]}" = "yes" ]; then # use DHCP to bring interface up
        # Clear DHCP_OPTIONS before adding new options to it:
        unset DHCP_OPTIONS
        # Set DHCP_OPTIONS for this interface:
        [ -n "${DHCP_HOSTNAME[$i]}" ] && DHCP_OPTIONS="-h ${DHCP_HOSTNAME[$i]}"
        [ "${DHCP_KEEPRESOLV[$i]}" = "yes" ] && DHCP_OPTIONS="$DHCP_OPTIONS -C resolv.conf"
        [ "${DHCP_KEEPNTP[$i]}" = "yes" ] && DHCP_OPTIONS="$DHCP_OPTIONS -C ntp.conf"
        [ "${DHCP_KEEPGW[$i]}" = "yes" ] && DHCP_OPTIONS="$DHCP_OPTIONS -G"
        [ "${DHCP_DEBUG[$i]}" = "yes" ] && DHCP_OPTIONS="$DHCP_OPTIONS -d"
        [ "${DHCP_NOIPV4LL[$i]}" = "yes" ] && DHCP_OPTIONS="$DHCP_OPTIONS -L"
        [ -n "${DHCP_IPADDR[$i]}" ] && DHCP_OPTIONS="$DHCP_OPTIONS -r ${DHCP_IPADDR[$i]}"
        echo "Polling for DHCP server on interface ${1}:"
        # If you set a timeout, you get one, even if the kernel doesn't think that
        # your device is connected, in case /sys isn't right (which it usually isn't
        # except right after the device is loaded, when it usually is):
        #### (start commented out)
        # This is deactivated for now since the kernel has been returning incorrect
        # results concerning whether the interface carrier is detected.
        #if [ -z "${DHCP_TIMEOUT[$i]}" ]; then
        #  /sbin/ip link set dev ${1} up && sleep 1
        #  CONNSTATUS="$(cat /sys/class/net/${1}/carrier 2> /dev/null)"
        #  /sbin/ip link set dev ${1} down
        #  if [ "$CONNSTATUS" = "0" ]; then
        #    # The kernel has just told us the cable isn't even plugged in, but we will
        #    # give any DHCP server a short chance to reply anyway:
        #    echo "No carrier detected on ${1}.  Reducing DHCP timeout to 15 seconds."
        #    DHCP_TIMEOUT[$i]=15
        #  fi
        #fi
        #### (end commented out)
        # 15 seconds should be a reasonable default DHCP timeout.  30 was too much.
        echo "/etc/rc.d/rc.inet1:  /sbin/dhcpcd -L -t ${DHCP_TIMEOUT[$i]:-15} ${DHCP_OPTIONS} ${1}" | $LOGGER
        /sbin/dhcpcd -L -t ${DHCP_TIMEOUT[$i]:-15} ${DHCP_OPTIONS} ${1}
        # If the dhcpcd call succeeds, add extra IP addresses, if defined, to interface
        if [ "$?" == "0" ] && [ -n "${IPALIASES[$i]}" ]; then
          num=0
          for ipalias in ${IPALIASES[$i]}; do
            /sbin/ip address add ${ipalias}/32 dev ${1} label ${1}:${num} ;
            num=$(($num + 1))
          done
        fi
      else # bring up interface using a static IP address
        if [ -n "${IPADDR[$i]}" ]; then # skip unconfigured interfaces
          # Set up the network card:
          echo "/etc/rc.d/rc.inet1:  /sbin/ip address add ${IPADDR[$i]}/${NETMASK[$i]} dev ${1}" | $LOGGER
          /sbin/ip address add ${IPADDR[$i]}/${NETMASK[$i]} dev ${1}
          if /sbin/ip link show dev ${1} | grep -wq "state DOWN" ; then
            /sbin/ip link set dev ${1} up  # Bring up interface
          fi
          # Add extra IP addresses, if defined, to interface
          if [ -n "${IPALIASES[$i]}" ]; then
            num=0
            for ipalias in ${IPALIASES[$i]}; do
              /sbin/ip address add ${ipalias}/32 dev ${1} label ${1}:${num} ;
              num=$(($num + 1))
            done
          fi
        else
          debug_log "${1} interface is not configured in /etc/rc.d/rc.inet1.conf"
        fi
      fi
    else
      debug_log "${1} is already up, skipping"
    fi 
  else
    debug_log "${1} interface does not exist (yet)"
  fi
}

# Function to take down a network interface:
if_down() {
  # Determine position 'i' of this interface in the IFNAME array:
  i=0
  while [ $i -lt $MAXNICS ]; do
    [ "${IFNAME[$i]}" = "${1}" ] && break
    i=$(($i+1))
  done
  if [ $i -ge $MAXNICS ]; then
    echo "/etc/rc.d/rc.inet1:  skipping ${1}, you might need to increase MAXNICS" | $LOGGER
    return
  fi
  if [ -e /sys/class/net/${1%%:*} ]; then
    if [ "${USE_DHCP[$i]}" = "yes" ]; then
      echo "/etc/rc.d/rc.inet1:  /sbin/dhcpcd -k -d ${1}" | $LOGGER
      /sbin/dhcpcd -k -d ${1} 2> /dev/null || /sbin/ip link set dev ${1} down
      sleep 1
    else
      echo "/etc/rc.d/rc.inet1:  /sbin/ip link set dev ${1} down" | $LOGGER
      /sbin/ip link set dev ${1} down
    fi
    if [ -x /etc/rc.d/rc.wireless ]; then
      . /etc/rc.d/rc.wireless ${1} stop # Kill wireless daemons if any.
    fi
    # If the interface is a bridge, then destroy it now:
    if [ -n "${BRNICS[$i]}" ]; then
      br_close $i
    fi
  fi
}

#####################
# GATEWAY FUNCTIONS #
#####################

# Function to bring up the gateway if there is not yet a default route:
gateway_up() {
  if ! /sbin/ip route show | grep -wq default ; then
    if [ -n "$GATEWAY" ]; then
      echo "/etc/rc.d/rc.inet1:  /sbin/ip route add default via ${GATEWAY}" | $LOGGER
      /sbin/ip route add default via ${GATEWAY} | $LOGGER
    fi
  fi
}

# Function to take down an existing default gateway:
gateway_down() {
  if /sbin/ip route show | grep -wq default ; then
    echo "/etc/rc.d/rc.inet1:  /sbin/ip route del default" | $LOGGER
    /sbin/ip route del default
  fi
}

# Function to start the network:
start() {
  lo_up
  virtif_create
  for i in "${IFNAME[@]}" ; do
    if_up $i
  done
  gateway_up
}

# Function to stop the network:
stop() {
  gateway_down
  for i in "${IFNAME[@]}" ; do
    if_down $i
  done
  virtif_destroy
  lo_down
}


############
### MAIN ###
############

case "$1" in
start|up) # "start" (or "up") brings up all configured interfaces:
  start
  ;;
stop|down) # "stop" (or "down") takes down all configured interfaces:
  stop
  ;;
restart) # "restart" restarts the network:
  stop
  start
  ;;
lo_start|lo_up) # Start the loopback interface:
  lo_up
  ;;
lo_stop|lo_down) # Stop the loopback interface:
  lo_down
  ;;
*_start|*_up) # Example: "eth1_start" (or "eth1_up") will start the specified interface 'eth1'
  INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1)
  if_up $INTERFACE
  gateway_up
  ;;
*_stop|*_down) # Example: "eth0_stop" (or "eth0_down") will stop the specified interface 'eth0'
  INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1)
  if_down $INTERFACE
  ;;
*_restart) # Example: "wlan0_restart" will take 'wlan0' down and up again
  INTERFACE=$(echo $1 | /bin/cut -d '_' -f 1)
  if_down $INTERFACE
  sleep 1
  if_up $INTERFACE
  gateway_up
  ;;
*) # The default is to bring up all configured interfaces:
  start
esac

# End of /etc/rc.d/rc.inet1