Bug 12808:

Summary of changes:
  - Mutiple routing table for each public interface is added (previously there is only one routing table ). when the packet is send out of public interface corresponding per-interface routing table will be used. per-interface routing table will modified when ever ip/interface added/deleted.
  - New parameter is added to ipassoc command  to include the default gateway for every interface/ip. prevously it is using only one public interface to send out, default gateway is obtained at the boot up time.
  - In the DNAT case. In the revese path(from guest vm to outside, or when DNAT packet receives from the eth0) the public ip/source ip will not be available till POSTROUTING. to overcome this, DNAT connection are marked with routing table number at the time of connection creation, in the reverse path the routing table# from DNAT connection is used to detect per-interface routing table.
This commit is contained in:
Naredula Janardhana Reddy 2012-01-25 12:54:00 +05:30
parent f558aa07c5
commit 5ca5851b1b
6 changed files with 92 additions and 4 deletions

View File

@ -635,6 +635,9 @@ public class VirtualRoutingResource implements Manager {
String publicNic = "eth" + nicNum;
command.add("-c", publicNic);
command.add("-g", vlanGateway);
return command.execute();
}

View File

@ -752,7 +752,10 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
}
args += " -c ";
args += "eth" + publicNicInfo.first();
args += "eth" + publicNicInfo.first();
args += " -g ";
args += vlanGateway;
if (s_logger.isDebugEnabled()) {
s_logger.debug("Run command on domain router " + privateIpAddress + ", /root/ipassoc.sh " + args);

View File

@ -1639,7 +1639,10 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
args += " -c ";
args += "eth" + correctVif.getDevice(conn);
args += " -g ";
args += vlanGateway;
String result = callHostPlugin(conn, "vmops", "ipassoc", "args", args);
if (result == null || result.isEmpty()) {

View File

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

View File

@ -59,6 +59,7 @@ tcp_or_udp_entry() {
local op=$5
local proto=$6
local cidrs=$7
logger -t cloud "$(basename $0): creating port fwd entry for PAT: public ip=$publicIp \
instance ip=$instIp proto=$proto port=$port dport=$dport op=$op"
@ -67,11 +68,16 @@ tcp_or_udp_entry() {
# the delete operation may have errored out but the only possible reason is
# that the rules didn't exist in the first place
local dev=$(ip_to_dev $publicIp)
local tableNo=$(echo $dev | awk -F'eth' '{print $2}')
# shortcircuit the process if error and it is an append operation
# continue if it is delete
(sudo iptables -t nat $op PREROUTING --proto $proto -i $dev -d $publicIp \
--destination-port $port -j DNAT \
--to-destination $instIp:$dport &>> $OUTFILE || [ "$op" == "-D" ]) &&
(sudo iptables -t mangle $op PREROUTING --proto $proto -i $dev -d $publicIp \
--destination-port $port -j MARK --set-mark $tableNo) &&
(sudo iptables -t mangle $op PREROUTING --proto $proto -i $dev -d $publicIp \
--destination-port $port -m state --state NEW -j CONNMARK --save-mark) &&
(sudo iptables -t nat $op OUTPUT --proto $proto -d $publicIp \
--destination-port $port -j DNAT \
--to-destination $instIp:$dport &>> $OUTFILE || [ "$op" == "-D" ]) &&

View File

@ -134,6 +134,72 @@ convert_primary_to_32() {
done
}
remove_routing() {
local pubIp=$1
local ipNoMask=$(echo $pubIp | awk -F'/' '{print $1}')
local mask=$(echo $pubIp | awk -F'/' '{print $2}')
local tableNo=$(echo $ethDev | awk -F'eth' '{print $2}')
local tableName="Table_$ethDev"
local ethMask=$(ip route show | grep $ethDev | grep src | awk '{print $1}')
if [ "$ethMask" != "" ]
then
# rules and routes will be deleted for the last ip of the interface.
sudo ip route delete throw $ethMask table $tableName proto static
sudo ip rule delete from $ethMask table $tableName
sudo ip rule delete fwmark $tableNo table $tableName
sudo ip route flush cache
fi
}
# copy eth0,eth1 and the current public interface
copy_routes_from_main() {
local tableName=$1
#get the network masks from the main table
local eth0Mask=$(ip route show | grep eth0 | grep src | awk '{print $1}')
local eth1Mask=$(ip route show | grep eth1 | grep src | awk '{print $1}')
local ethMask=$(ip route show | grep $ethDev | grep src | awk '{print $1}')
# eth0,eth1 and other know routes will be skipped, so as main routing table will decide the route. This will be useful if the interface is down and up.
sudo ip route add throw $eth0Mask table $tableName proto static
sudo ip route add throw $eth1Mask table $tableName proto static
sudo ip route add throw $ethMask table $tableName proto static
return 0;
}
add_routing() {
local pubIp=$1
local ipNoMask=$(echo $1 | awk -F'/' '{print $1}')
local mask=$(echo $1 | awk -F'/' '{print $2}')
local tableName="Table_$ethDev"
local tablePresent=$(grep $tableName /etc/iproute2/rt_tables)
local tableNo=$(echo $ethDev | awk -F'eth' '{print $2}')
if [ "$tablePresent" == "" ]
then
if [ "$tableNo" == ""]
then
return 0;
fi
echo "$tableNo $tableName" >> /etc/iproute2/rt_tables
fi
copy_routes_from_main $tableName
# NOTE: this entry will be deleted if the interface is down without knowing to Management server, in that case all the outside traffic will be send through main routing table or it will be the first public NIC.
sudo ip route add default via $defaultGwIP table $tableName proto static
sudo ip route flush cache
local ethMask=$(ip route show | grep $ethDev | grep src | awk '{print $1}')
local rulePresent=$(ip rule show | grep $ethMask)
if [ "$rulePresent" == "" ]
then
# rules will be added while adding the first ip of the interface
sudo ip rule add from $ethMask table $tableName
sudo ip rule add fwmark $tableNo table $tableName
fi
return 0;
}
add_nat_entry() {
local pubIp=$1
@ -167,6 +233,7 @@ add_nat_entry() {
sudo ip link set $ethDev up
sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
fi
add_routing $1
return 0
}
@ -182,6 +249,7 @@ del_nat_entry() {
sudo iptables -t nat -D POSTROUTING -j SNAT -o $ethDev --to-source $ipNoMask;
sudo ip addr del dev $ethDev "$ipNoMask/$mask"
remove_routing $1
if [ $? -gt 0 -a $? -ne 2 ]
then
return 1
@ -205,7 +273,7 @@ add_an_ip () {
sudo ip link set $ethDev up
sudo arping -c 3 -I $ethDev -A -U -s $ipNoMask $ipNoMask;
fi
add_routing $1
return $?
}
@ -236,6 +304,7 @@ remove_an_ip () {
fi
result=$?
fi
remove_routing $1
if [ $result -gt 0 -a $result -ne 2 ]
then
return 1
@ -268,7 +337,7 @@ then
if_keep_state=1
fi
while getopts 'fADa:l:c:' OPTION
while getopts 'fADa:l:c:g:' OPTION
do
case $OPTION in
A) Aflag=1
@ -285,6 +354,9 @@ do
c) cflag=1
ethDev="$OPTARG"
;;
g) gflag=1
defaultGwIP="$OPTARG"
;;
?) usage
unlock_exit 2 $lock $locked
;;