From 980be4dfc9a325b8a7fafca7894611ca415675a7 Mon Sep 17 00:00:00 2001 From: Jayapal Date: Thu, 23 Feb 2017 11:10:47 +0530 Subject: [PATCH] CLOUDSTACK-9757: Fixed issue in traffic from additional public subnet (cherry picked from commit baac747089ef48ea6627a6aacf27156222862352) Signed-off-by: Rohit Yadav --- .../network/router/CommandSetupHelper.java | 27 ++++++++++++++++++- .../config/opt/cloud/bin/cs/CsAddress.py | 2 +- 2 files changed, 27 insertions(+), 2 deletions(-) diff --git a/server/src/com/cloud/network/router/CommandSetupHelper.java b/server/src/com/cloud/network/router/CommandSetupHelper.java index 3e4318a3269..13c80961e3f 100644 --- a/server/src/com/cloud/network/router/CommandSetupHelper.java +++ b/server/src/com/cloud/network/router/CommandSetupHelper.java @@ -668,19 +668,38 @@ public class CommandSetupHelper { for (final Map.Entry> vlanAndIp : vlanIpMap.entrySet()) { final List ipAddrList = vlanAndIp.getValue(); + // Source nat ip address should always be sent first + Collections.sort(ipAddrList, new Comparator() { + @Override + public int compare(final PublicIpAddress o1, final PublicIpAddress o2) { + final boolean s1 = o1.isSourceNat(); + final boolean s2 = o2.isSourceNat(); + return s1 ^ s2 ? s1 ^ true ? 1 : -1 : 0; + } + }); + + // Get network rate - required for IpAssoc final Integer networkRate = _networkModel.getNetworkRate(ipAddrList.get(0).getNetworkId(), router.getId()); final Network network = _networkModel.getNetwork(ipAddrList.get(0).getNetworkId()); final IpAddressTO[] ipsToSend = new IpAddressTO[ipAddrList.size()]; int i = 0; + boolean firstIP = true; for (final PublicIpAddress ipAddr : ipAddrList) { final boolean add = ipAddr.getState() == IpAddress.State.Releasing ? false : true; + boolean sourceNat = ipAddr.isSourceNat(); + /* enable sourceNAT for the first ip of the public interface + * For additional public subnet source nat rule needs to be added for vm to reach ips in that subnet + */ + if (firstIP) { + sourceNat = true; + } final String macAddress = vlanMacAddress.get(BroadcastDomainType.getValue(BroadcastDomainType.fromString(ipAddr.getVlanTag()))); - final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, false, ipAddr.isSourceNat(), BroadcastDomainType.fromString(ipAddr.getVlanTag()).toString(), ipAddr.getGateway(), + final IpAddressTO ip = new IpAddressTO(ipAddr.getAccountId(), ipAddr.getAddress().addr(), add, firstIP, sourceNat, BroadcastDomainType.fromString(ipAddr.getVlanTag()).toString(), ipAddr.getGateway(), ipAddr.getNetmask(), macAddress, networkRate, ipAddr.isOneToOneNat()); ip.setTrafficType(network.getTrafficType()); @@ -690,6 +709,12 @@ public class CommandSetupHelper { sourceNatIpAdd = new Pair(ip, ipAddr.getNetworkId()); addSourceNat = add; } + + //for additional public subnet on delete it is not sure which ip is set to first ip. So on delete we + //want to set sourcenat to true for all ips to delete source nat rules. + if (!firstIP || add) { + firstIP = false; + } } final IpAssocVpcCommand cmd = new IpAssocVpcCommand(ipsToSend); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); diff --git a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py index 4eac3483a97..e0eb350ead0 100755 --- a/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py +++ b/systemvm/patches/debian/config/opt/cloud/bin/cs/CsAddress.py @@ -571,7 +571,7 @@ class CsIP: if self.get_type() in ["guest"] and not cmdline.is_redundant(): pwdsvc = CsPasswdSvc(self.address['public_ip']).start() - if self.get_type() == "public" and self.config.is_vpc(): + if self.get_type() == "public" and self.config.is_vpc() and method == "add": if self.address["source_nat"]: vpccidr = cmdline.get_vpccidr() self.fw.append(