mirror of
				https://github.com/apache/cloudstack.git
				synced 2025-11-04 00:02:37 +01:00 
			
		
		
		
	Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com> (cherry picked from commit 888f67f0bdc3e76c452c2dc3f7715f2df12bda7d) Signed-off-by: Rohit Yadav <rohit.yadav@shapeblue.com>
		
			
				
	
	
		
			317 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
			
		
		
	
	
			317 lines
		
	
	
		
			9.5 KiB
		
	
	
	
		
			Bash
		
	
	
		
			Executable File
		
	
	
	
	
#!/usr/bin/env bash
 | 
						|
# Licensed to the Apache Software Foundation (ASF) under one
 | 
						|
# or more contributor license agreements.  See the NOTICE file
 | 
						|
# distributed with this work for additional information
 | 
						|
# regarding copyright ownership.  The ASF licenses this file
 | 
						|
# to you under the Apache License, Version 2.0 (the
 | 
						|
# "License"); you may not use this file except in compliance
 | 
						|
# with the License.  You may obtain a copy of the License at
 | 
						|
#
 | 
						|
#   http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
#
 | 
						|
# Unless required by applicable law or agreed to in writing,
 | 
						|
# software distributed under the License is distributed on an
 | 
						|
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 | 
						|
# KIND, either express or implied.  See the License for the
 | 
						|
# specific language governing permissions and limitations
 | 
						|
# under the License.
 | 
						|
 | 
						|
# guestnw.sh -- create/destroy guest network 
 | 
						|
# @VERSION@
 | 
						|
 | 
						|
source /root/func.sh
 | 
						|
source /opt/cloud/bin/vpc_func.sh
 | 
						|
 | 
						|
lock="biglock"
 | 
						|
locked=$(getLockFile $lock)
 | 
						|
if [ "$locked" != "1" ]
 | 
						|
then
 | 
						|
    exit 1
 | 
						|
fi
 | 
						|
 | 
						|
usage() {
 | 
						|
  printf "Usage:\n %s -A  -M <mac> -d <dev> -i <ip address> -g <gateway> -m <network mask> -s <dns ip> -e < domain> [-f] \n" $(basename $0) >&2
 | 
						|
  printf " %s -D -d <dev> -i <ip address> \n" $(basename $0) >&2
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
destroy_acl_chain() {
 | 
						|
  sudo iptables -t mangle -F ACL_OUTBOUND_$dev 2>/dev/null
 | 
						|
  sudo iptables -t mangle -D PREROUTING -m state --state NEW -i $dev -s $subnet/$mask ! -d $ip -j ACL_OUTBOUND_$dev  2>/dev/null
 | 
						|
  sudo iptables -t mangle -X ACL_OUTBOUND_$dev 2>/dev/null
 | 
						|
  sudo iptables -F ACL_INBOUND_$dev 2>/dev/null
 | 
						|
  sudo iptables -D FORWARD -o $dev -d $subnet/$mask -j ACL_INBOUND_$dev  2>/dev/null
 | 
						|
  sudo iptables -X ACL_INBOUND_$dev 2>/dev/null
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
create_acl_chain() {
 | 
						|
  destroy_acl_chain
 | 
						|
  sudo iptables -t mangle -N ACL_OUTBOUND_$dev 2>/dev/null
 | 
						|
  sudo iptables -t mangle -A ACL_OUTBOUND_$dev -j ACCEPT 2>/dev/null
 | 
						|
  sudo iptables -t mangle -A PREROUTING -m state --state NEW -i $dev -s $subnet/$mask ! -d $ip -j ACL_OUTBOUND_$dev  2>/dev/null
 | 
						|
  sudo iptables -N ACL_INBOUND_$dev 2>/dev/null
 | 
						|
  # drop if no rules match (this will be the last rule in the chain)
 | 
						|
  sudo iptables -A ACL_INBOUND_$dev -j DROP 2>/dev/null
 | 
						|
  sudo iptables -A FORWARD -o $dev -d $subnet/$mask -j ACL_INBOUND_$dev  2>/dev/null
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
setup_apache2() {
 | 
						|
  logger -t cloud "Setting up apache web server for $dev"
 | 
						|
  cp /etc/apache2/vhostexample.conf /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  sed -i -e "s/<VirtualHost.*:80>/<VirtualHost $ip:80>/" /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  sed -i -e "s/<VirtualHost.*:443>/<VirtualHost $ip:443>/" /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  sed -i -e "s/\tServerName.*/\tServerName vhost$dev.cloudinternal.com/" /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  sed -i -e "s/Listen .*:80/Listen $ip:80/g" /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  sed -i -e "s/Listen .*:443/Listen $ip:443/g" /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  service apache2 restart
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT
 | 
						|
  sudo iptables -A INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT
 | 
						|
}
 | 
						|
 | 
						|
desetup_apache2() {
 | 
						|
  logger -t cloud "Desetting up apache web server for $dev"
 | 
						|
  rm -f /etc/apache2/conf.d/vhost$dev.conf
 | 
						|
  service apache2 restart
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 80 -j ACCEPT
 | 
						|
}
 | 
						|
 | 
						|
 | 
						|
setup_dnsmasq() {
 | 
						|
  logger -t cloud "Setting up dnsmasq for network $ip/$mask "
 | 
						|
  # setup rules to allow dhcp/dns request
 | 
						|
  sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p udp -m udp --dport 53 -j ACCEPT
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p tcp -m tcp --dport 53 -j ACCEPT
 | 
						|
  sudo iptables -A INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT
 | 
						|
  sudo iptables -A INPUT -i $dev -d $ip -p udp -m udp --dport 53 -j ACCEPT
 | 
						|
  sudo iptables -A INPUT -i $dev -d $ip -p tcp -m tcp --dport 53 -j ACCEPT
 | 
						|
  # setup static 
 | 
						|
  sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf
 | 
						|
  echo "dhcp-range=interface:$dev,set:interface-$dev,$ip,static" >> /etc/dnsmasq.d/cloud.conf
 | 
						|
  # setup DOMAIN
 | 
						|
  [ -z $DOMAIN ] && DOMAIN="cloudnine.internal"
 | 
						|
 | 
						|
  sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,15.*$/d" /etc/dnsmasq.d/cloud.conf
 | 
						|
  echo "dhcp-option=tag:interface-$dev,15,$DOMAIN" >> /etc/dnsmasq.d/cloud.conf
 | 
						|
  service dnsmasq restart
 | 
						|
  sleep 1
 | 
						|
} 
 | 
						|
 | 
						|
desetup_dnsmasq() {
 | 
						|
  logger -t cloud "Desetting up dnsmasq for network $ip/$mask "
 | 
						|
  # remove rules to allow dhcp/dns request
 | 
						|
  sudo iptables -D INPUT -i $dev -p udp -m udp --dport 67 -j ACCEPT
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p udp -m udp --dport 53 -j ACCEPT
 | 
						|
  sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,option:router.*$/d" /etc/dnsmasq.d/cloud.conf
 | 
						|
  sed -i -e "/^[#]*dhcp-option=tag:interface-$dev,6.*$/d" /etc/dnsmasq.d/cloud.conf
 | 
						|
  sed -i -e "/^[#]*dhcp-range=interface:$dev/d" /etc/dnsmasq.d/cloud.conf
 | 
						|
  service dnsmasq restart
 | 
						|
  sleep 1
 | 
						|
}
 | 
						|
 | 
						|
setup_passwdsvcs() {
 | 
						|
  logger -t cloud "Setting up password service for network $ip/$mask, eth $dev "
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 8080 -j ACCEPT
 | 
						|
  sudo iptables -A INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 8080 -j ACCEPT
 | 
						|
  nohup bash /opt/cloud/bin/vpc_passwd_server $ip >/dev/null 2>&1 &
 | 
						|
}
 | 
						|
 | 
						|
desetup_passwdsvcs() {
 | 
						|
  logger -t cloud "Desetting up password service for network $ip/$mask, eth $dev "
 | 
						|
  sudo iptables -D INPUT -i $dev -d $ip -p tcp -m state --state NEW --dport 8080 -j ACCEPT
 | 
						|
  pid=`ps -ef | grep passwd_server_ip.py | grep $ip | grep -v grep | awk '{print $2}'`
 | 
						|
  if [ -n "$pid" ]
 | 
						|
  then
 | 
						|
    kill -9 $pid
 | 
						|
  fi 
 | 
						|
}
 | 
						|
 | 
						|
create_guest_network() {
 | 
						|
  # need to wait for eth device to appear before configuring it
 | 
						|
  timer=0
 | 
						|
 | 
						|
  # match dev based on mac, if passed
 | 
						|
  if [[ ! -z "$mac" ]]; then
 | 
						|
    logger -t cloud "$(basename $0): mac $mac passed, trying to match to device"
 | 
						|
    while [ ! $timer -gt 15 ]; do 
 | 
						|
      for i in `ls /sys/class/net`; do
 | 
						|
        if grep -q $mac /sys/class/net/$i/address; then
 | 
						|
          dev=$i
 | 
						|
          logger -t cloud "$(basename $0): matched dev $i to mac $mac, dev is now $dev"
 | 
						|
          timer=15
 | 
						|
          break
 | 
						|
        fi
 | 
						|
      done
 | 
						|
      sleep 1;
 | 
						|
      timer=$[timer + 1]
 | 
						|
    done
 | 
						|
  else
 | 
						|
    while ! `grep -q $dev /proc/net/dev` ; do
 | 
						|
      logger -t cloud "$(basename $0):Waiting for interface $dev to appear, $timer seconds"
 | 
						|
      sleep 1;
 | 
						|
      if [ $timer -gt 15 ]; then
 | 
						|
        logger -t cloud "$(basename $0):interface $dev never appeared"
 | 
						|
        break
 | 
						|
      fi
 | 
						|
      timer=$[timer + 1]
 | 
						|
    done
 | 
						|
  fi
 | 
						|
 | 
						|
  logger -t cloud " $(basename $0): Create network on interface $dev,  gateway $gw, network $ip/$mask "
 | 
						|
  # setup ip configuration
 | 
						|
  sudo ip addr add dev $dev $ip/$mask brd +
 | 
						|
  sudo ip link set $dev up
 | 
						|
  sudo arping -c 3 -I $dev -A -U -s $ip $ip
 | 
						|
  echo 1 > /proc/sys/net/ipv4/conf/$dev/rp_filter
 | 
						|
  # restore mark from  connection mark
 | 
						|
  local tableName="Table_$dev"
 | 
						|
  sudo ip route add $subnet/$mask dev $dev table $tableName proto static
 | 
						|
  sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
 | 
						|
  sudo iptables -t nat -D POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip
 | 
						|
  sudo iptables -t mangle -A PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
 | 
						|
  # set up hairpin
 | 
						|
  sudo iptables -t nat -A POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip
 | 
						|
  create_acl_chain
 | 
						|
  setup_dnsmasq
 | 
						|
  setup_apache2
 | 
						|
  setup_passwdsvcs
 | 
						|
 | 
						|
  #enable rps, rfs
 | 
						|
  enable_rpsrfs $dev
 | 
						|
}
 | 
						|
 | 
						|
enable_rpsrfs() {
 | 
						|
 | 
						|
    if [  -f /etc/rpsrfsenable ]
 | 
						|
    then
 | 
						|
        enable=$(cat /etc/rpsrfsenable)
 | 
						|
        if [ $enable -eq 0 ]
 | 
						|
        then
 | 
						|
            return 0
 | 
						|
        fi
 | 
						|
    else
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
 | 
						|
    proc=$(cat /proc/cpuinfo | grep "processor" | wc -l)
 | 
						|
    if [ $proc -le 1 ]
 | 
						|
    then
 | 
						|
        return 0
 | 
						|
    fi
 | 
						|
    dev=$1
 | 
						|
 | 
						|
    num=1
 | 
						|
    num=$(($num<<$proc))
 | 
						|
    num=$(($num-1));
 | 
						|
    echo $num;
 | 
						|
    hex=$(printf "%x\n" $num)
 | 
						|
    echo $hex;
 | 
						|
    #enable rps
 | 
						|
    echo $hex > /sys/class/net/$dev/queues/rx-0/rps_cpus
 | 
						|
 | 
						|
    #enble rfs
 | 
						|
    rps_flow_entries=$(cat /proc/sys/net/core/rps_sock_flow_entries)
 | 
						|
 | 
						|
    if [ $rps_flow_entries -eq 0 ]
 | 
						|
    then
 | 
						|
        echo 256 > /proc/sys/net/core/rps_sock_flow_entries
 | 
						|
    fi
 | 
						|
 | 
						|
    echo 256 > /sys/class/net/$dev/queues/rx-0/rps_flow_cnt
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
destroy_guest_network() {
 | 
						|
  logger -t cloud " $(basename $0): Create network on interface $dev,  gateway $gw, network $ip/$mask "
 | 
						|
 | 
						|
  sudo ip addr del dev $dev $ip/$mask
 | 
						|
  sudo iptables -t mangle -D PREROUTING -i $dev -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
 | 
						|
  sudo iptables -t nat -D POSTROUTING -s $subnet/$mask -o $dev -j SNAT --to-source $ip
 | 
						|
  destroy_acl_chain
 | 
						|
  desetup_dnsmasq
 | 
						|
  desetup_apache2
 | 
						|
  desetup_passwdsvcs
 | 
						|
}
 | 
						|
 | 
						|
#set -x
 | 
						|
iflag=0
 | 
						|
mflag=0
 | 
						|
nflag=0
 | 
						|
dflag=
 | 
						|
gflag=
 | 
						|
Cflag=
 | 
						|
Dflag=
 | 
						|
Mflag=
 | 
						|
 | 
						|
op=""
 | 
						|
 | 
						|
 | 
						|
while getopts 'CDn:m:M:d:i:g:s:e:' OPTION
 | 
						|
do
 | 
						|
  case $OPTION in
 | 
						|
  C)	Cflag=1
 | 
						|
		op="-C"
 | 
						|
		;;
 | 
						|
  D)	Dflag=1
 | 
						|
		op="-D"
 | 
						|
		;;
 | 
						|
  n)	nflag=1
 | 
						|
		subnet="$OPTARG"
 | 
						|
		;;
 | 
						|
  m)	mflag=1
 | 
						|
		mask="$OPTARG"
 | 
						|
		;;
 | 
						|
  M)    Mflag=1
 | 
						|
                mac="$OPTARG"
 | 
						|
                ;;
 | 
						|
  d)	dflag=1
 | 
						|
  		dev="$OPTARG"
 | 
						|
  		;;
 | 
						|
  i)	iflag=1
 | 
						|
		ip="$OPTARG"
 | 
						|
  		;;
 | 
						|
  g)	gflag=1
 | 
						|
  		gw="$OPTARG"
 | 
						|
                ;;
 | 
						|
  s)    sflag=1
 | 
						|
                DNS="$OPTARG"
 | 
						|
                ;;
 | 
						|
  e)    eflag=1
 | 
						|
		DOMAIN="$OPTARG"
 | 
						|
  		;;
 | 
						|
  ?)	usage
 | 
						|
                unlock_exit 2 $lock $locked
 | 
						|
		;;
 | 
						|
  esac
 | 
						|
done
 | 
						|
 | 
						|
vpccidr=$(getVPCcidr)
 | 
						|
 | 
						|
if [ "$Cflag$Dflag$dflag" != "11" ]
 | 
						|
then
 | 
						|
    usage
 | 
						|
    unlock_exit 2 $lock $locked
 | 
						|
fi
 | 
						|
 | 
						|
if [ "$Cflag" == "1" ] && [ "$iflag$gflag$mflag" != "111" ]
 | 
						|
then
 | 
						|
    usage
 | 
						|
    unlock_exit 2 $lock $locked
 | 
						|
fi
 | 
						|
 | 
						|
 | 
						|
if [ "$Cflag" == "1" ]
 | 
						|
then  
 | 
						|
  create_guest_network 
 | 
						|
fi
 | 
						|
 | 
						|
 | 
						|
if [ "$Dflag" == "1" ]
 | 
						|
then
 | 
						|
  destroy_guest_network
 | 
						|
fi
 | 
						|
 | 
						|
unlock_exit 0 $lock $locked
 |