From de8ba55d857e72cbbd0c4bab4cf835ddf7bb79ac Mon Sep 17 00:00:00 2001 From: Naredula Janardhana Reddy Date: Tue, 24 Jan 2012 18:31:48 +0530 Subject: [PATCH 1/4] Bug 12496: Allowing guest vm's to access virtual router LB service --- .../debian/config/root/loadbalancer.sh | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/patches/systemvm/debian/config/root/loadbalancer.sh b/patches/systemvm/debian/config/root/loadbalancer.sh index b0039d5f68d..19b9e3007d0 100755 --- a/patches/systemvm/debian/config/root/loadbalancer.sh +++ b/patches/systemvm/debian/config/root/loadbalancer.sh @@ -78,8 +78,15 @@ ip_entry() { return 0 } +get_lb_vif_list() { +# add eth0 to the VIF_LIST if it is not there, this allows guest VMs to use the LB service. + local lb_list="$VIF_LIST eth0"; + lb_list=$(echo $lb_list | tr " " "\n" | sort | uniq | tr "\n" " ") + echo $lb_list +} fw_remove_backup() { - for vif in $VIF_LIST; do + local lb_vif_list=$(get_lb_vif_list) + for vif in $lb_vif_list; do sudo iptables -F back_load_balancer_$vif 2> /dev/null sudo iptables -D INPUT -i $vif -p tcp -j back_load_balancer_$vif 2> /dev/null sudo iptables -X back_load_balancer_$vif 2> /dev/null @@ -89,7 +96,8 @@ fw_remove_backup() { sudo iptables -X back_lb_stats 2> /dev/null } fw_restore() { - for vif in $VIF_LIST; do + local lb_vif_list=$(get_lb_vif_list) + for vif in $lb_vif_list; do sudo iptables -F load_balancer_$vif 2> /dev/null sudo iptables -D INPUT -i $vif -p tcp -j load_balancer_$vif 2> /dev/null sudo iptables -X load_balancer_$vif 2> /dev/null @@ -120,7 +128,8 @@ fw_entry() { local r=$(echo $removed | cut -d, -f1- --output-delimiter=" ") # back up the iptable rules by renaming before creating new. - for vif in $VIF_LIST; do + local lb_vif_list=$(get_lb_vif_list) + for vif in $lb_vif_list; do sudo iptables -E load_balancer_$vif back_load_balancer_$vif 2> /dev/null sudo iptables -N load_balancer_$vif 2> /dev/null sudo iptables -A INPUT -i $vif -p tcp -j load_balancer_$vif @@ -133,8 +142,8 @@ fw_entry() { do local pubIp=$(echo $i | cut -d: -f1) local dport=$(echo $i | cut -d: -f2) - - for vif in $VIF_LIST; do + local lb_vif_list=$(get_lb_vif_list) + for vif in $lb_vif_list; do #TODO : The below delete will be used only when we upgrade the from older verion to the newer one , the below delete become obsolute in the future. sudo iptables -D INPUT -i $vif -p tcp -d $pubIp --dport $dport -j ACCEPT 2> /dev/null From f558aa07c5ead3039efadf0546546442b1d3a289 Mon Sep 17 00:00:00 2001 From: Nitin Mehta Date: Wed, 25 Jan 2012 12:29:04 +0530 Subject: [PATCH 2/4] Bug 12740: Allow root admins and system user to bypass the ACL layer. Reviewed-By: Kishan --- server/src/com/cloud/user/AccountManagerImpl.java | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/server/src/com/cloud/user/AccountManagerImpl.java b/server/src/com/cloud/user/AccountManagerImpl.java index d1f12e361bf..ec7400f7fd9 100755 --- a/server/src/com/cloud/user/AccountManagerImpl.java +++ b/server/src/com/cloud/user/AccountManagerImpl.java @@ -299,6 +299,15 @@ public class AccountManagerImpl implements AccountManager, AccountService, Manag @Override public void checkAccess(Account caller, AccessType accessType, boolean sameOwner, ControlledEntity... entities) { + + if (caller.getId() == Account.ACCOUNT_ID_SYSTEM || isRootAdmin(caller.getType())) { + //no need to make permission checks if the system/root admin makes the call + if (s_logger.isTraceEnabled()) { + s_logger.trace("No need to make permission check for System/RootAdmin account, returning true"); + } + return; + } + HashMap> domains = new HashMap>(); Long ownerId = null; ControlledEntity prevEntity = null; From 5ca5851b1bfad452027da34beddced804e083b0a Mon Sep 17 00:00:00 2001 From: Naredula Janardhana Reddy Date: Wed, 25 Jan 2012 12:54:00 +0530 Subject: [PATCH 3/4] 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. --- .../VirtualRoutingResource.java | 3 + .../vmware/resource/VmwareResource.java | 5 +- .../xen/resource/CitrixResourceBase.java | 5 +- .../config/etc/iptables/iptables-router | 1 + .../systemvm/debian/config/root/firewall.sh | 6 ++ .../systemvm/debian/config/root/ipassoc.sh | 76 ++++++++++++++++++- 6 files changed, 92 insertions(+), 4 deletions(-) diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java index 65bc8d69fbc..66c333648a5 100755 --- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java @@ -635,6 +635,9 @@ public class VirtualRoutingResource implements Manager { String publicNic = "eth" + nicNum; command.add("-c", publicNic); + + command.add("-g", vlanGateway); + return command.execute(); } diff --git a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java index 978e2f71e80..c8d2c85a981 100755 --- a/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java +++ b/core/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java @@ -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); diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4c577f50d94..43cc13dc10d 100755 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -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()) { diff --git a/patches/systemvm/debian/config/etc/iptables/iptables-router b/patches/systemvm/debian/config/etc/iptables/iptables-router index 7124807eb39..50377df2db3 100644 --- a/patches/systemvm/debian/config/etc/iptables/iptables-router +++ b/patches/systemvm/debian/config/etc/iptables/iptables-router @@ -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 diff --git a/patches/systemvm/debian/config/root/firewall.sh b/patches/systemvm/debian/config/root/firewall.sh index d92d076923b..0a33dcbd371 100755 --- a/patches/systemvm/debian/config/root/firewall.sh +++ b/patches/systemvm/debian/config/root/firewall.sh @@ -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" ]) && diff --git a/patches/systemvm/debian/config/root/ipassoc.sh b/patches/systemvm/debian/config/root/ipassoc.sh index 9f67ff316f2..287d4d4b26b 100644 --- a/patches/systemvm/debian/config/root/ipassoc.sh +++ b/patches/systemvm/debian/config/root/ipassoc.sh @@ -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 ;; From e52ac3ae31a30045d4b729a03c04e81dae6b37d7 Mon Sep 17 00:00:00 2001 From: Naredula Janardhana Reddy Date: Fri, 20 Jan 2012 14:11:40 +0530 Subject: [PATCH 4/4] Bug 12808: Logging added, Improved remove_routing --- .../systemvm/debian/config/root/ipassoc.sh | 22 +++++++++++-------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/patches/systemvm/debian/config/root/ipassoc.sh b/patches/systemvm/debian/config/root/ipassoc.sh index 287d4d4b26b..8617a9cb0fd 100644 --- a/patches/systemvm/debian/config/root/ipassoc.sh +++ b/patches/systemvm/debian/config/root/ipassoc.sh @@ -136,19 +136,21 @@ convert_primary_to_32() { remove_routing() { local pubIp=$1 + logger -t cloud "$(basename $0):Remove routing $pubIp on interface $ethDev" 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" != "" ] + local ethMask=$(ip route list scope link dev $ethDev | 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 rule delete table $tableName + sudo ip route flush table $tableName sudo ip route flush cache + logger -t cloud "$(basename $0):Remove routing $pubIp - routes and rules deleted" fi } @@ -157,9 +159,9 @@ 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}') + local eth0Mask=$(ip route list scope link dev eth0 | awk '{print $1}') + local eth1Mask=$(ip route list scope link dev eth1 | awk '{print $1}') + local ethMask=$(ip route list scope link dev $ethDev | 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 @@ -170,6 +172,7 @@ copy_routes_from_main() { add_routing() { local pubIp=$1 + logger -t cloud "$(basename $0):Add routing $pubIp on interface $ethDev" local ipNoMask=$(echo $1 | awk -F'/' '{print $1}') local mask=$(echo $1 | awk -F'/' '{print $2}') @@ -182,7 +185,7 @@ add_routing() { then return 0; fi - echo "$tableNo $tableName" >> /etc/iproute2/rt_tables + sudo echo "$tableNo $tableName" >> /etc/iproute2/rt_tables fi copy_routes_from_main $tableName @@ -190,13 +193,14 @@ add_routing() { 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 ethMask=$(ip route list scope link dev $ethDev | 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 + logger -t cloud "$(basename $0):Add routing $pubIp rules added" fi return 0; }