diff --git a/core/src/com/cloud/agent/api/routing/IPAssocCommand.java b/core/src/com/cloud/agent/api/routing/IPAssocCommand.java index ec1761a6e5a..42122d16716 100644 --- a/core/src/com/cloud/agent/api/routing/IPAssocCommand.java +++ b/core/src/com/cloud/agent/api/routing/IPAssocCommand.java @@ -35,11 +35,12 @@ public class IPAssocCommand extends RoutingCommand { private String vlanGateway; private String vlanNetmask; private String vifMacAddress; + private String guestIp; protected IPAssocCommand() { } - public IPAssocCommand(String routerName, String privateIpAddress, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress) { + public IPAssocCommand(String routerName, String privateIpAddress, String ipAddress, boolean add, boolean firstIP, boolean sourceNat, String vlanId, String vlanGateway, String vlanNetmask, String vifMacAddress, String guestIp) { this.setRouterName(routerName); this.routerIp = privateIpAddress; this.publicIp = ipAddress; @@ -50,8 +51,13 @@ public class IPAssocCommand extends RoutingCommand { this.vlanGateway = vlanGateway; this.vlanNetmask = vlanNetmask; this.vifMacAddress = vifMacAddress; + this.guestIp = guestIp; } + public String getGuestIp(){ + return guestIp; + } + public String getRouterIp() { return routerIp; } diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 4af59c6a16e..83f9ea55e3c 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -1288,7 +1288,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR } protected void assignPublicIpAddress(final String vmName, final String privateIpAddress, final String publicIpAddress, final boolean add, final boolean firstIP, - final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress) throws InternalErrorException { + final boolean sourceNat, final String vlanId, final String vlanGateway, final String vlanNetmask, final String vifMacAddress, String guestIp) throws InternalErrorException { try { Connection conn = getConnection(); @@ -1328,24 +1328,37 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR throw new InternalErrorException("Failed to find DomR VIF to associate/disassociate IP with."); } - String args; - if (add) { - args = "-A"; - } else { - args = "-D"; + String args = null; + + if(guestIp!=null) + { + args += " -G "; + args += guestIp; + args += " -l "; + args += publicIpAddress; + args += " -i "; + args += privateIpAddress; } - if (sourceNat) { - args += " -f"; + else + { + if (add) { + args = "-A"; + } else { + args = "-D"; + } + if (sourceNat) { + args += " -f"; + } + args += " -i "; + args += privateIpAddress; + args += " -l "; + args += publicIpAddress; + args += " -c "; + args += "eth" + correctVif.getDevice(conn); + args += " -g "; + args += vlanGateway; } - args += " -i "; - args += privateIpAddress; - args += " -l "; - args += publicIpAddress; - args += " -c "; - args += "eth" + correctVif.getDevice(conn); - args += " -g "; - args += vlanGateway; - + String result = callHostPlugin("vmops", "ipassoc", "args", args); if (result == null || result.isEmpty()) { throw new InternalErrorException("Xen plugin \"ipassoc\" failed."); @@ -1388,7 +1401,7 @@ public abstract class CitrixResourceBase implements StoragePoolResource, ServerR protected Answer execute(final IPAssocCommand cmd) { try { assignPublicIpAddress(cmd.getRouterName(), cmd.getRouterIp(), cmd.getPublicIp(), cmd.isAdd(), cmd.isFirstIP(), cmd.isSourceNat(), cmd.getVlanId(), - cmd.getVlanGateway(), cmd.getVlanNetmask(), cmd.getVifMacAddress()); + cmd.getVlanGateway(), cmd.getVlanNetmask(), cmd.getVifMacAddress(), cmd.getGuestIp()); } catch (InternalErrorException e) { return new Answer(cmd, false, e.getMessage()); } diff --git a/core/src/com/cloud/server/ManagementServer.java b/core/src/com/cloud/server/ManagementServer.java index eebb93f3f5e..f3973baa180 100755 --- a/core/src/com/cloud/server/ManagementServer.java +++ b/core/src/com/cloud/server/ManagementServer.java @@ -409,12 +409,13 @@ public interface ManagementServer { * @param accountId * @param domainId * @param zoneId + * @param vmId * @return allocated IP address in the zone specified * @throws InsufficientAddressCapacityException if no more addresses are available * @throws InvalidParameterValueException if no router for that user exists in the zone specified * @throws InternalErrorException if the new address could not be sent down to the router */ - String associateIpAddress(long userId, long accountId, long domainId, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, InvalidParameterValueException, InternalErrorException; + String associateIpAddress(long userId, long accountId, long domainId, long zoneId, long vmId) throws ResourceAllocationException, InsufficientAddressCapacityException, InvalidParameterValueException, InternalErrorException; long associateIpAddressAsync(long userId, long accountId, long domainId, long zoneId); diff --git a/scripts/network/domr/ipassoc.sh b/scripts/network/domr/ipassoc.sh index 14d932c5308..e1f764a4efc 100755 --- a/scripts/network/domr/ipassoc.sh +++ b/scripts/network/domr/ipassoc.sh @@ -50,6 +50,20 @@ check_gw() { return $?; } +#Add 1:1 NAT entry +add_one_to_one_nat_entry() { + local guestIp=$1 + local publicIp=$2 + local dIp=$3 + ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$dIp "\ + iptables -t nat -A PREROUTING -i eth2 -d $publicIp -j DNAT --to-destination $guestIp + iptables -t nat -A POSTROUTING -o $eth2 -s $guestIp -j SNAT --to-source $publicIp + iptables -P FORWARD DROP + iptables -A FORWARD -m state --state RELATED,ESTABLISHED -j ACCEPT + iptables -A FORWARD -i $eth2 -o $eth1 -d $guestIp -m state --state NEW -j ACCEPT + iptables -A FORWARD -i $eth1 -o $eth2 -s $guestIp -m state --state NEW -j ACCEPT +} + #Add the NAT entries into iptables in the routing domain add_nat_entry() { local dRIp=$1 @@ -120,9 +134,10 @@ vflag= gflag= nflag= cflag= +Gflag= op="" -while getopts 'fADr:i:a:l:v:g:n:c:' OPTION +while getopts 'fADr:i:a:l:v:g:n:c:G:' OPTION do case $OPTION in A) Aflag=1 @@ -157,6 +172,9 @@ do c) cflag=1 correctVif="$OPTARG" ;; + G) Gflag=1 + guestIp = "$OPTARG" + ;; ?) usage exit 2 ;; @@ -182,6 +200,12 @@ then exit 3 fi +#1:1 NAT +if [ "$Gflag" == "1" ] +then + add_one_to_one_nat_entry $guestIp $publicIp $domRIp + exit $? +fi if [ "$fflag" == "1" ] && [ "$Aflag" == "1" ] then diff --git a/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java b/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java index 5c338d569b0..a179550c43e 100644 --- a/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java +++ b/server/src/com/cloud/api/commands/AssociateIPAddrCmd.java @@ -108,13 +108,13 @@ public class AssociateIPAddrCmd extends BaseCmd { } //vmId == 0 => general flow - //vmId = 1 => 1:1 NAT + //vmId != 0 => 1:1 NAT if(vmId == null){ vmId = Long.valueOf(0); } try { - newIpAddr = getManagementServer().associateIpAddress(userId.longValue(), accountId.longValue(), domainId.longValue(), zoneId.longValue()); + newIpAddr = getManagementServer().associateIpAddress(userId.longValue(), accountId.longValue(), domainId.longValue(), zoneId.longValue(), vmId.longValue()); } catch (ResourceAllocationException rae) { if (rae.getResourceType().equals("vm")) throw new ServerApiException (BaseCmd.VM_ALLOCATION_ERROR, rae.getMessage()); else if (rae.getResourceType().equals("ip")) throw new ServerApiException (BaseCmd.IP_ALLOCATION_ERROR, rae.getMessage()); diff --git a/server/src/com/cloud/network/NetworkManager.java b/server/src/com/cloud/network/NetworkManager.java index 1b1dcedcd6e..f47d133f3e8 100644 --- a/server/src/com/cloud/network/NetworkManager.java +++ b/server/src/com/cloud/network/NetworkManager.java @@ -176,9 +176,10 @@ public interface NetworkManager extends Manager { * @param router router object to send the association to * @param ipAddrList list of public IP addresses * @param add true if associate, false if disassociate + * @param vmId * @return */ - boolean associateIP(DomainRouterVO router, List ipAddrList, boolean add) throws ResourceAllocationException; + boolean associateIP(DomainRouterVO router, List ipAddrList, boolean add, long vmId) throws ResourceAllocationException; boolean updateFirewallRule(FirewallRuleVO fwRule, String oldPrivateIP, String oldPrivatePort); boolean executeAssignToLoadBalancer(AssignToLoadBalancerExecutor executor, LoadBalancerParam param); diff --git a/server/src/com/cloud/network/NetworkManagerImpl.java b/server/src/com/cloud/network/NetworkManagerImpl.java index a7dcca27e58..f40f4717c9c 100644 --- a/server/src/com/cloud/network/NetworkManagerImpl.java +++ b/server/src/com/cloud/network/NetworkManagerImpl.java @@ -1118,7 +1118,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager ipAddrList.add(ipVO.getAddress()); } if (!ipAddrList.isEmpty()) { - final boolean success = associateIP(router, ipAddrList, true); + final boolean success = associateIP(router, ipAddrList, true, 0); if (!success) { return false; } @@ -1353,7 +1353,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager } @Override - public boolean associateIP(final DomainRouterVO router, final List ipAddrList, final boolean add) { + public boolean associateIP(final DomainRouterVO router, final List ipAddrList, final boolean add, long vmId) { final Command [] cmds = new Command[ipAddrList.size()]; int i=0; boolean sourceNat = false; @@ -1374,7 +1374,12 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager vifMacAddress = macAddresses[1]; } - cmds[i++] = new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ipAddress, add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress); + String vmGuestAddress = null; + if(vmId!=0){ + vmGuestAddress = _vmDao.findById(vmId).getGuestIpAddress(); + } + + cmds[i++] = new IPAssocCommand(router.getInstanceName(), router.getPrivateIpAddress(), ipAddress, add, firstIP, sourceNat, vlanId, vlanGateway, vlanNetmask, vifMacAddress, vmGuestAddress); sourceNat = false; } @@ -1717,7 +1722,7 @@ public class NetworkManagerImpl implements NetworkManager, VirtualMachineManager s_logger.debug("Disassociate ip " + router.getName()); } - if (associateIP(router, ipAddrs, false)) { + if (associateIP(router, ipAddrs, false, 0)) { _ipAddressDao.unassignIpAddress(ipAddress); } else { if (s_logger.isDebugEnabled()) { diff --git a/server/src/com/cloud/server/ManagementServerImpl.java b/server/src/com/cloud/server/ManagementServerImpl.java index 2ebf529e3f2..417c48e3c10 100755 --- a/server/src/com/cloud/server/ManagementServerImpl.java +++ b/server/src/com/cloud/server/ManagementServerImpl.java @@ -1488,7 +1488,7 @@ public class ManagementServerImpl implements ManagementServer { boolean success = true; String params = "\nsourceNat=" + false + "\ndcId=" + zoneId; ArrayList dummyipAddrList = new ArrayList(); - success = _networkMgr.associateIP(router,ipAddrsList, true); + success = _networkMgr.associateIP(router,ipAddrsList, true, 0); String errorMsg = "Unable to assign public IP address pool"; if (!success) { s_logger.debug(errorMsg); @@ -1519,7 +1519,7 @@ public class ManagementServerImpl implements ManagementServer { @Override @DB - public String associateIpAddress(long userId, long accountId, long domainId, long zoneId) throws ResourceAllocationException, InsufficientAddressCapacityException, + public String associateIpAddress(long userId, long accountId, long domainId, long zoneId, long vmId) throws ResourceAllocationException, InsufficientAddressCapacityException, InvalidParameterValueException, InternalErrorException { Transaction txn = Transaction.currentTxn(); AccountVO account = null; @@ -1571,7 +1571,7 @@ public class ManagementServerImpl implements ManagementServer { ipAddrs.add(ipAddress); if (router.getState() == State.Running) { - success = _networkMgr.associateIP(router, ipAddrs, true); + success = _networkMgr.associateIP(router, ipAddrs, true, vmId); if (!success) { errorMsg = "Unable to assign public IP address."; }