From 6da3bc123767874fcc58f85a0dd1b51b5c60a497 Mon Sep 17 00:00:00 2001 From: Michael Andersen Date: Wed, 23 Dec 2015 21:12:41 +0100 Subject: [PATCH] [CORE] Add Force UDP Encapsulation option to Site2Site VPN --- .../cloud/network/Site2SiteCustomerGateway.java | 2 ++ .../org/apache/cloudstack/api/ApiConstants.java | 3 ++- .../user/vpn/CreateVpnCustomerGatewayCmd.java | 5 +++++ .../user/vpn/UpdateVpnCustomerGatewayCmd.java | 5 +++++ .../Site2SiteCustomerGatewayResponse.java | 6 ++++++ .../response/Site2SiteVpnConnectionResponse.java | 9 +++++++++ .../agent/api/routing/Site2SiteVpnCfgCommand.java | 12 +++++++++++- .../facade/Site2SiteVpnConfigItem.java | 2 +- .../virtualnetwork/model/Site2SiteVpn.java | 13 +++++++++++-- .../network/dao/Site2SiteCustomerGatewayVO.java | 15 ++++++++++++++- server/src/com/cloud/api/ApiResponseHelper.java | 3 ++- .../cloud/network/router/CommandSetupHelper.java | 3 ++- .../network/vpn/Site2SiteVpnManagerImpl.java | 13 ++++++++++++- 13 files changed, 82 insertions(+), 9 deletions(-) diff --git a/api/src/com/cloud/network/Site2SiteCustomerGateway.java b/api/src/com/cloud/network/Site2SiteCustomerGateway.java index 2de4ff2bcc8..f9a88bdd845 100644 --- a/api/src/com/cloud/network/Site2SiteCustomerGateway.java +++ b/api/src/com/cloud/network/Site2SiteCustomerGateway.java @@ -39,6 +39,8 @@ public interface Site2SiteCustomerGateway extends ControlledEntity, Identity, In public Boolean getDpd(); + public Boolean getEncap(); + public Date getRemoved(); String getName(); diff --git a/api/src/org/apache/cloudstack/api/ApiConstants.java b/api/src/org/apache/cloudstack/api/ApiConstants.java index 742d2f42abf..934972cf319 100644 --- a/api/src/org/apache/cloudstack/api/ApiConstants.java +++ b/api/src/org/apache/cloudstack/api/ApiConstants.java @@ -492,6 +492,7 @@ public class ApiConstants { public static final String IKE_LIFETIME = "ikelifetime"; public static final String ESP_LIFETIME = "esplifetime"; public static final String DPD = "dpd"; + public static final String FORCE_ENCAP = "forceencap"; public static final String FOR_VPC = "forvpc"; public static final String SHRINK_OK = "shrinkok"; public static final String NICIRA_NVP_DEVICE_ID = "nvpdeviceid"; @@ -641,4 +642,4 @@ public class ApiConstants { public enum VMDetails { all, group, nics, stats, secgrp, tmpl, servoff, diskoff, iso, volume, min, affgrp; } -} \ No newline at end of file +} diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java index 8bd0646ed39..0fb496cc043 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/CreateVpnCustomerGatewayCmd.java @@ -75,6 +75,9 @@ public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.DPD, type = CommandType.BOOLEAN, required = false, description = "If DPD is enabled for VPN connection") private Boolean dpd; + @Parameter(name = ApiConstants.FORCE_ENCAP, type = CommandType.BOOLEAN, required = false, description = "Force Encapsulation for NAT traversal") + private Boolean encap; + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the account associated with the gateway. Must be used with the domainId parameter.") private String accountName; @@ -129,6 +132,8 @@ public class CreateVpnCustomerGatewayCmd extends BaseAsyncCmd { return dpd; } + public Boolean getEncap() { return encap; } + public String getAccountName() { return accountName; } diff --git a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java index ceb67d510a0..3b188b85ca9 100644 --- a/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java +++ b/api/src/org/apache/cloudstack/api/command/user/vpn/UpdateVpnCustomerGatewayCmd.java @@ -81,6 +81,9 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { @Parameter(name = ApiConstants.DPD, type = CommandType.BOOLEAN, required = false, description = "If DPD is enabled for VPN connection") private Boolean dpd; + @Parameter(name = ApiConstants.FORCE_ENCAP, type = CommandType.BOOLEAN, required = false, description = "Force encapsulation for Nat Traversal") + private Boolean encap; + @Parameter(name = ApiConstants.ACCOUNT, type = CommandType.STRING, description = "the account associated with the gateway. Must be used with the domainId parameter.") private String accountName; @@ -135,6 +138,8 @@ public class UpdateVpnCustomerGatewayCmd extends BaseAsyncCmd { return dpd; } + public Boolean getEncap() { return encap; } + ///////////////////////////////////////////////////// /////////////// API Implementation/////////////////// ///////////////////////////////////////////////////// diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java b/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java index 2bda8f93f4d..232c3f21261 100644 --- a/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java +++ b/api/src/org/apache/cloudstack/api/response/Site2SiteCustomerGatewayResponse.java @@ -74,6 +74,10 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponse implements Co @Param(description = "if DPD is enabled for customer gateway") private Boolean dpd; + @SerializedName(ApiConstants.FORCE_ENCAP) + @Param(description = "if Force NAT Encapsulation is enabled for customer gateway") + private Boolean encap; + @SerializedName(ApiConstants.ACCOUNT) @Param(description = "the owner") private String accountName; @@ -142,6 +146,8 @@ public class Site2SiteCustomerGatewayResponse extends BaseResponse implements Co this.dpd = dpd; } + public void setEncap(Boolean encap) { this.encap = encap; } + public void setRemoved(Date removed) { this.removed = removed; } diff --git a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java b/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java index c00a4d4aa52..c5450a69607 100644 --- a/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java +++ b/api/src/org/apache/cloudstack/api/response/Site2SiteVpnConnectionResponse.java @@ -87,6 +87,11 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont //from CustomerGateway private Boolean dpd; + @SerializedName(ApiConstants.FORCE_ENCAP) + @Param(description = "if Force NAT Encapsulation is enabled for customer gateway") + //from CustomerGateway + private Boolean encap; + @SerializedName(ApiConstants.STATE) @Param(description = "State of vpn connection") private String state; @@ -175,6 +180,10 @@ public class Site2SiteVpnConnectionResponse extends BaseResponse implements Cont this.dpd = dpd; } + public void setEncap(Boolean encap) { + this.encap = encap; + } + public void setState(String state) { this.state = state; } diff --git a/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java index 68b38091a94..685cf4049c7 100644 --- a/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java +++ b/core/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java @@ -34,6 +34,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { private long espLifetime; private boolean dpd; private boolean passive; + private boolean encap; @Override public boolean executeInSequence() { @@ -45,7 +46,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { } public Site2SiteVpnCfgCommand(boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, String peerGatewayIp, String peerGuestCidrList, - String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd, boolean passive) { + String ikePolicy, String espPolicy, String ipsecPsk, Long ikeLifetime, Long espLifetime, Boolean dpd, boolean passive, boolean encap) { this.create = create; this.setLocalPublicIp(localPublicIp); this.setLocalPublicGateway(localPublicGateway); @@ -59,6 +60,7 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { this.espLifetime = espLifetime; this.dpd = dpd; this.passive = passive; + this.encap = encap; } public boolean isCreate() { @@ -117,6 +119,14 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand { this.dpd = dpd; } + public Boolean getEncap() { + return encap; + } + + public void setEncap(Boolean encap) { + this.encap = encap; + } + public String getLocalPublicIp() { return localPublicIp; } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java b/core/src/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java index 6509b78019d..5bb466c5935 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/facade/Site2SiteVpnConfigItem.java @@ -36,7 +36,7 @@ public class Site2SiteVpnConfigItem extends AbstractConfigItemFacade { final Site2SiteVpn site2siteVpn = new Site2SiteVpn(command.getLocalPublicIp(), command.getLocalGuestCidr(), command.getLocalPublicGateway(), command.getPeerGatewayIp(), command.getPeerGuestCidrList(), command.getEspPolicy(), command.getIkePolicy(), command.getIpsecPsk(), command.getIkeLifetime(), command.getEspLifetime(), command.isCreate(), command.getDpd(), - command.isPassive()); + command.isPassive(), command.getEncap()); return generateConfigItems(site2siteVpn); } diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java b/core/src/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java index 63b04c5a65a..232e99f099a 100644 --- a/core/src/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java +++ b/core/src/com/cloud/agent/resource/virtualnetwork/model/Site2SiteVpn.java @@ -23,7 +23,7 @@ public class Site2SiteVpn extends ConfigBase { private String localPublicIp, localGuestCidr, localPublicGateway, peerGatewayIp, peerGuestCidrList, espPolicy, ikePolicy, ipsecPsk; private Long ikeLifetime, espLifetime; - private boolean create, dpd, passive; + private boolean create, dpd, passive, encap; public Site2SiteVpn() { super(ConfigBase.SITE2SITEVPN); @@ -31,7 +31,7 @@ public class Site2SiteVpn extends ConfigBase { public Site2SiteVpn(String localPublicIp, String localGuestCidr, String localPublicGateway, String peerGatewayIp, String peerGuestCidrList, String espPolicy, String ikePolicy, - String ipsecPsk, Long ikeLifetime, Long espLifetime, boolean create, Boolean dpd, boolean passive) { + String ipsecPsk, Long ikeLifetime, Long espLifetime, boolean create, Boolean dpd, boolean passive, boolean encap) { super(ConfigBase.SITE2SITEVPN); this.localPublicIp = localPublicIp; this.localGuestCidr = localGuestCidr; @@ -46,6 +46,7 @@ public class Site2SiteVpn extends ConfigBase { this.create = create; this.dpd = dpd; this.passive = passive; + this.encap = encap; } public String getLocalPublicIp() { @@ -152,4 +153,12 @@ public class Site2SiteVpn extends ConfigBase { this.passive = passive; } + public boolean getEncap() { + return encap; + } + + public void setEncap(boolean encap) { + this.encap = encap; + } + } diff --git a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java index 5bcf361836f..f1d3ef32712 100644 --- a/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java +++ b/engine/schema/src/com/cloud/network/dao/Site2SiteCustomerGatewayVO.java @@ -70,6 +70,9 @@ public class Site2SiteCustomerGatewayVO implements Site2SiteCustomerGateway { @Column(name = "dpd") private boolean dpd; + @Column(name = "force_encap") + private boolean encap; + @Column(name = "domain_id") private Long domainId; @@ -83,7 +86,7 @@ public class Site2SiteCustomerGatewayVO implements Site2SiteCustomerGateway { } public Site2SiteCustomerGatewayVO(String name, long accountId, long domainId, String gatewayIp, String guestCidrList, String ipsecPsk, String ikePolicy, - String espPolicy, long ikeLifetime, long espLifetime, boolean dpd) { + String espPolicy, long ikeLifetime, long espLifetime, boolean dpd, boolean encap) { this.name = name; this.gatewayIp = gatewayIp; this.guestCidrList = guestCidrList; @@ -93,6 +96,7 @@ public class Site2SiteCustomerGatewayVO implements Site2SiteCustomerGateway { this.ikeLifetime = ikeLifetime; this.espLifetime = espLifetime; this.dpd = dpd; + this.encap = encap; uuid = UUID.randomUUID().toString(); this.accountId = accountId; this.domainId = domainId; @@ -193,6 +197,15 @@ public class Site2SiteCustomerGatewayVO implements Site2SiteCustomerGateway { this.dpd = dpd; } + @Override + public Boolean getEncap() { + return encap; + } + + public void setEncap(boolean encap) { + this.encap = encap; + } + @Override public String getUuid() { return uuid; diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 5d691c634fc..c8eb5f41f21 100644 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3001,7 +3001,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIkeLifetime(result.getIkeLifetime()); response.setEspLifetime(result.getEspLifetime()); response.setDpd(result.getDpd()); - + response.setEncap(result.getEncap()); response.setRemoved(result.getRemoved()); response.setObjectName("vpncustomergateway"); @@ -3041,6 +3041,7 @@ public class ApiResponseHelper implements ResponseGenerator { response.setIkeLifetime(customerGateway.getIkeLifetime()); response.setEspLifetime(customerGateway.getEspLifetime()); response.setDpd(customerGateway.getDpd()); + response.setEncap(customerGateway.getEncap()); } } diff --git a/server/src/com/cloud/network/router/CommandSetupHelper.java b/server/src/com/cloud/network/router/CommandSetupHelper.java index 925961d3fb7..04427baf749 100644 --- a/server/src/com/cloud/network/router/CommandSetupHelper.java +++ b/server/src/com/cloud/network/router/CommandSetupHelper.java @@ -857,9 +857,10 @@ public class CommandSetupHelper { final Long ikeLifetime = gw.getIkeLifetime(); final Long espLifetime = gw.getEspLifetime(); final Boolean dpd = gw.getDpd(); + final Boolean encap = gw.getEncap(); final Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr, peerGatewayIp, peerGuestCidrList, ikePolicy, - espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive()); + espPolicy, ipsecPsk, ikeLifetime, espLifetime, dpd, conn.isPassive(), encap); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, _routerControlHelper.getRouterControlIp(router.getId())); cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName()); diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java index deebc6d9d1c..37465262e16 100644 --- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java +++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java @@ -218,6 +218,11 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn dpd = false; } + Boolean encap = cmd.getEncap(); + if (encap == null) { + encap = false; + } + long accountId = owner.getAccountId(); if (_customerGatewayDao.findByGatewayIpAndAccountId(gatewayIp, accountId) != null) { throw new InvalidParameterValueException("The customer gateway with ip " + gatewayIp + " already existed in the system!"); @@ -229,7 +234,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn checkCustomerGatewayCidrList(peerCidrList); Site2SiteCustomerGatewayVO gw = - new Site2SiteCustomerGatewayVO(name, accountId, owner.getDomainId(), gatewayIp, peerCidrList, ipsecPsk, ikePolicy, espPolicy, ikeLifetime, espLifetime, dpd); + new Site2SiteCustomerGatewayVO(name, accountId, owner.getDomainId(), gatewayIp, peerCidrList, ipsecPsk, ikePolicy, espPolicy, ikeLifetime, espLifetime, dpd, encap); _customerGatewayDao.persist(gw); return gw; } @@ -467,6 +472,11 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn dpd = false; } + Boolean encap = cmd.getEncap(); + if (encap == null) { + encap = false; + } + checkCustomerGatewayCidrList(guestCidrList); long accountId = gw.getAccountId(); @@ -488,6 +498,7 @@ public class Site2SiteVpnManagerImpl extends ManagerBase implements Site2SiteVpn gw.setIkeLifetime(ikeLifetime); gw.setEspLifetime(espLifetime); gw.setDpd(dpd); + gw.setEncap(encap); _customerGatewayDao.persist(gw); return gw; }