Bug 13297,13375,12705 :

Summary of changes :
        - Added a new flag -s to ipassoc command to carry if the ip address is
used for SNAT or not.
        - SNAT is completly decoupled from the first flag. first flag is used
to decide if the ip address is first ip address of the interface.
        - -s and -f are independent, SNAT can be enabled on the non-first ip
also.
This commit is contained in:
Naredula Janardhana Reddy 2012-02-01 12:39:10 +05:30
parent fc7758c455
commit 72fb7256d7
6 changed files with 60 additions and 36 deletions

View File

@ -624,9 +624,9 @@ public class VirtualRoutingResource implements Manager {
}
String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
if (sourceNat) {
command.add("-f");
command.add("-l", publicIpAddress + "/" + cidrSize);
} else if (firstIP) {
command.add("-s");
}
if (firstIP) {
command.add( "-f");
command.add( "-l", publicIpAddress + "/" + cidrSize);
} else {

View File

@ -741,10 +741,9 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
if (sourceNat) {
args += " -f ";
args += " -l ";
args += publicIpAddress + "/" + cidrSize;
} else if (firstIP) {
args += " -s ";
}
if (firstIP) {
args += " -f ";
args += " -l ";
args += publicIpAddress + "/" + cidrSize;

View File

@ -1625,10 +1625,9 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
String cidrSize = Long.toString(NetUtils.getCidrSize(vlanNetmask));
if (sourceNat) {
args += " -f";
args += " -l ";
args += publicIpAddress + "/" + cidrSize;
} else if (firstIP) {
args += " -s";
}
if (firstIP) {
args += " -f";
args += " -l ";
args += publicIpAddress + "/" + cidrSize;

View File

@ -30,7 +30,5 @@ COMMIT
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -m state --state ESTABLISHED,RELATED -j CONNMARK --restore-mark
COMMIT
*mangle
-A POSTROUTING -p udp --dport bootpc -j CHECKSUM --checksum-fill
COMMIT

View File

@ -204,10 +204,33 @@ add_routing() {
fi
return 0;
}
add_snat() {
if [ "$sflag" == "0" ]
then
return 0;
fi
add_nat_entry() {
local pubIp=$1
logger -t cloud "$(basename $0):Adding nat entry for ip $pubIp on interface $ethDev"
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
logger -t cloud "$(basename $0):Added SourceNAT $pubIp on interface $ethDev"
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
sudo iptables -t nat -I POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
return $?
}
remove_snat() {
if [ "$sflag" == "0" ]
then
return 0;
fi
local pubIp=$1
logger -t cloud "$(basename $0):Removing SourceNAT $pubIp on interface $ethDev"
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask;
return $?
}
add_first_ip() {
local pubIp=$1
logger -t cloud "$(basename $0):Adding first ip $pubIp on interface $ethDev"
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
local mask=$(echo $1 | awk -F'/' '{print $2}')
sudo ip link show $ethDev | grep "state DOWN" > /dev/null
@ -220,18 +243,20 @@ add_nat_entry() {
# remove if duplicat ip with 32 mask, this happens when we are promting the ip to primary
sudo ip addr del dev $ethDev $ipNoMask/32 > /dev/null
fi
sudo iptables -D FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -D FORWARD -i eth0 -o $ethDev -j ACCEPT
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
sudo iptables -A FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -A FORWARD -i eth0 -o $ethDev -j ACCEPT
sudo iptables -t nat -I POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
add_snat $1
if [ $? -gt 0 -a $? -ne 2 ]
then
logger -t cloud "$(basename $0):Failed adding nat entry for ip $pubIp on interface $ethDev"
logger -t cloud "$(basename $0):Failed adding source nat entry for ip $pubIp on interface $ethDev"
return 1
fi
logger -t cloud "$(basename $0):Added nat entry for ip $pubIp on interface $ethDev"
logger -t cloud "$(basename $0):Added first ip $pubIp on interface $ethDev"
if [ $if_keep_state -ne 1 -o $old_state -ne 0 ]
then
sudo ip link set $ethDev up
@ -242,22 +267,24 @@ add_nat_entry() {
return 0
}
del_nat_entry() {
remove_first_ip() {
local pubIp=$1
logger -t cloud "$(basename $0):Deleting nat entry for ip $pubIp on interface $ethDev"
logger -t cloud "$(basename $0):Removing first ip $pubIp on interface $ethDev"
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
local mask=$(echo $1 | awk -F'/' '{print $2}')
[ "$mask" == "" ] && mask="32"
sudo iptables -D FORWARD -i $ethDev -o eth0 -m state --state RELATED,ESTABLISHED -j ACCEPT
sudo iptables -D FORWARD -i eth0 -o $ethDev -j ACCEPT
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask;
remove_snat $1
sudo ip addr del dev $ethDev "$ipNoMask/$mask"
remove_routing $1
if [ $? -gt 0 -a $? -ne 2 ]
then
remove_routing $1
return 1
fi
remove_routing $1
return $?
}
@ -271,7 +298,7 @@ add_an_ip () {
local old_state=$?
sudo ip addr add dev $ethDev $pubIp ;
add_snat $1
if [ $if_keep_state -ne 1 -o $old_state -ne 0 ]
then
sudo ip link set $ethDev up
@ -289,12 +316,14 @@ remove_an_ip () {
local mask=$(echo $1 | awk -F'/' '{print $2}')
local existingIpMask=$(sudo ip addr show dev $ethDev | grep inet | awk '{print $2}' | grep -w $ipNoMask)
[ "$existingIpMask" == "" ] && return 0
remove_snat $1
local existingMask=$(echo $existingIpMask | awk -F'/' '{print $2}')
if [ "$existingMask" == "32" ]
then
sudo ip addr del dev $ethDev $existingIpMask
result=$?
fi
if [ "$existingMask" != "32" ]
then
replaceIpMask=`sudo ip addr show dev $ethDev | grep inet | grep -v $existingIpMask | awk '{print $2}' | sort -t/ -k2 -n|tail -1`
@ -303,21 +332,21 @@ remove_an_ip () {
sudo ip addr del dev $ethDev $replaceIpMask;
replaceIp=`echo $replaceIpMask | awk -F/ '{print $1}'`;
sudo ip addr add dev $ethDev $replaceIp/$existingMask;
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask ;
sudo iptables -t nat -A POSTROUTING -j SNAT -o $ethDev --to-source $replaceIp ;
fi
result=$?
fi
remove_routing $1
if [ $result -gt 0 -a $result -ne 2 ]
then
remove_routing $1
return 1
fi
remove_routing $1
return 0
}
#set -x
sflag=0
lflag=
fflag=
cflag=
@ -341,7 +370,7 @@ then
if_keep_state=1
fi
while getopts 'fADa:l:c:g:' OPTION
while getopts 'sfADa:l:c:g:' OPTION
do
case $OPTION in
A) Aflag=1
@ -352,6 +381,8 @@ do
;;
f) fflag=1
;;
s) sflag=1
;;
l) lflag=1
publicIp="$OPTARG"
;;
@ -383,7 +414,7 @@ fi
if [ "$fflag" == "1" ] && [ "$Aflag" == "1" ]
then
add_nat_entry $publicIp &&
add_first_ip $publicIp &&
add_vpn_chain_for_ip $publicIp &&
add_fw_chain_for_ip $publicIp
unlock_exit $? $lock $locked
@ -398,7 +429,7 @@ fi
if [ "$fflag" == "1" ] && [ "$Dflag" == "1" ]
then
del_nat_entry $publicIp &&
remove_first_ip $publicIp &&
del_fw_chain_for_ip $publicIp &&
del_vpn_chain_for_ip $publicIp
unlock_exit $? $lock $locked

View File

@ -2502,10 +2502,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()];
int i = 0;
boolean firstIP = true;
/* If the first IP is not source NAT, then don't treat it as first IP. It would happen if it's the first IP for public nic other than first one */
if (!ipAddrList.get(0).isSourceNat()) {
firstIP = false;
}
for (final PublicIpAddress ipAddr : ipAddrList) {
boolean add = (ipAddr.getState() == IpAddress.State.Releasing ? false : true);