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/client/WEB-INF/classes/resources/messages.properties b/client/WEB-INF/classes/resources/messages.properties
index e7beaa9304d..93e73fa1c7b 100644
--- a/client/WEB-INF/classes/resources/messages.properties
+++ b/client/WEB-INF/classes/resources/messages.properties
@@ -2258,3 +2258,4 @@ message.please.select.ssh.key.pair.use.with.this.vm=Please select a ssh key pair
message.configure.firewall.rules.allow.traffic=Configure the rules to allow Traffic
message.configure.firewall.rules.block.traffic=Configure the rules to block Traffic
message.ldap.group.import=All The users from the given group name will be imported
+label.vpn.force.encapsulation=Force UDP Encapsulation of ESP Packets
diff --git a/client/WEB-INF/classes/resources/messages_nl_NL.properties b/client/WEB-INF/classes/resources/messages_nl_NL.properties
index 363be5f05ff..a4e199153ad 100644
--- a/client/WEB-INF/classes/resources/messages_nl_NL.properties
+++ b/client/WEB-INF/classes/resources/messages_nl_NL.properties
@@ -1726,6 +1726,7 @@ label.vpc=VPC
label.VPN.connection=VPN Connectie
label.vpn.customer.gateway=VPN Customer Gateway
label.VPN.customer.gateway=VPN Customer Gateway
+label.vpn.force.encapsulation=Forceer UDP Encapsulatie van ESP Packets
label.VPN.gateway=VPN Gateway
label.vpn=VPN
label.vsmctrlvlanid=Controle VLAN ID
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/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
index c4e134bd261..6b5f1d1baf5 100644
--- a/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
+++ b/core/test/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResourceTest.java
@@ -494,17 +494,17 @@ public class VirtualRoutingResourceTest implements VirtualRouterDeployer {
public void testSite2SiteVpnCfgCommand() {
_count = 0;
- Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), true, false);
+ Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), true, false, false);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
Answer answer = _resource.executeRequest(cmd);
assertTrue(answer.getResult());
- cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true);
+ cmd = new Site2SiteVpnCfgCommand(true, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true, false);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
answer = _resource.executeRequest(cmd);
assertTrue(answer.getResult());
- cmd = new Site2SiteVpnCfgCommand(false, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true);
+ cmd = new Site2SiteVpnCfgCommand(false, "64.10.1.10", "64.10.1.1", "192.168.1.1/16", "124.10.1.10", "192.168.100.1/24", "3des-sha1,aes128-sha1;modp1536", "3des-sha1,aes128-md5", "psk", Long.valueOf(1800), Long.valueOf(1800), false, true, false);
cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, ROUTERNAME);
answer = _resource.executeRequest(cmd);
assertTrue(answer.getResult());
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;
}
diff --git a/setup/db/db/schema-470to471.sql b/setup/db/db/schema-470to471.sql
index 08b7f625638..d632a72680d 100644
--- a/setup/db/db/schema-470to471.sql
+++ b/setup/db/db/schema-470to471.sql
@@ -18,3 +18,4 @@
--;
-- Schema upgrade from 4.7.0 to 4.7.1;
--;
+ALTER TABLE cloud.s2s_customer_gateway ADD COLUMN force_encap INT(1) NOT NULL DEFAULT 0 AFTER dpd;
diff --git a/systemvm/patches/debian/config/opt/cloud/bin/configure.py b/systemvm/patches/debian/config/opt/cloud/bin/configure.py
index deb4a74e042..fb82d80165e 100755
--- a/systemvm/patches/debian/config/opt/cloud/bin/configure.py
+++ b/systemvm/patches/debian/config/opt/cloud/bin/configure.py
@@ -527,6 +527,7 @@ class CsSite2SiteVpn(CsDataBag):
file.addeq(" pfs=%s" % CsHelper.bool_to_yn(obj['dpd']))
file.addeq(" keyingtries=2")
file.addeq(" auto=start")
+ file.addeq(" forceencaps=%s" % CsHelper.bool_to_yn(obj['encap']))
if obj['dpd']:
file.addeq(" dpddelay=30")
file.addeq(" dpdtimeout=120")
@@ -538,9 +539,9 @@ class CsSite2SiteVpn(CsDataBag):
file.commit()
logging.info("Configured vpn %s %s", leftpeer, rightpeer)
CsHelper.execute("ipsec auto --rereadall")
- CsHelper.execute("ipsec --add vpn-%s" % rightpeer)
+ CsHelper.execute("ipsec auto --add vpn-%s" % rightpeer)
if not obj['passive']:
- CsHelper.execute("ipsec --up vpn-%s" % rightpeer)
+ CsHelper.execute("ipsec auto --up vpn-%s" % rightpeer)
os.chmod(vpnsecretsfile, 0o400)
def convert_sec_to_h(self, val):
diff --git a/tools/marvin/marvin/lib/base.py b/tools/marvin/marvin/lib/base.py
index ab15a78c4ea..4e04ba82496 100755
--- a/tools/marvin/marvin/lib/base.py
+++ b/tools/marvin/marvin/lib/base.py
@@ -3572,6 +3572,8 @@ class VpnCustomerGateway:
cmd.esplifetime = services["esplifetime"]
if "dpd" in services:
cmd.dpd = services["dpd"]
+ if "forceencap" in services:
+ cmd.forceencap = services["forceencap"]
if account:
cmd.account = account
if domainid:
@@ -3599,6 +3601,8 @@ class VpnCustomerGateway:
cmd.esplifetime = services["esplifetime"]
if "dpd" in services:
cmd.dpd = services["dpd"]
+ if "forceencap" in services:
+ cmd.forceencap = services["forceencap"]
return(apiclient.updateVpnCustomerGateway(cmd))
def delete(self, apiclient):
diff --git a/ui/dictionary2.jsp b/ui/dictionary2.jsp
index 9d68974f045..4268104d825 100644
--- a/ui/dictionary2.jsp
+++ b/ui/dictionary2.jsp
@@ -1124,6 +1124,7 @@ under the License.
'message.desc.create.ssh.key.pair': '',
'message.removed.ssh.key.pair': '',
'message.please.select.ssh.key.pair.use.with.this.vm': '',
-'message.ldap.group.import': ''
+'message.ldap.group.import': '',
+'label.vpn.force.encapsulation': ''
});
diff --git a/ui/scripts/docs.js b/ui/scripts/docs.js
index ed6ab0c938c..e02cbdac6f4 100755
--- a/ui/scripts/docs.js
+++ b/ui/scripts/docs.js
@@ -1118,6 +1118,10 @@ cloudStack.docs = {
desc: 'Check this to make the virtual router query its IKE peer at regular intervals to ensure continued availability. It is recommended to have the same DPD setting on both sides of the VPN connection.',
externalLink: ''
},
+ helpVPNGatewayForceEncapsulation: {
+ desc: 'Force UDP encapsulation for ESP packets even if no NAT situation is detected. This may help to surmount restrictive firewalls. In order to force the peer to encapsulate packets, NAT detection payloads are faked',
+ externalLink: ''
+ },
// Copy template
helpCopyTemplateDestination: {
desc: 'The zone to which you want to copy the template',
@@ -1329,4 +1333,4 @@ cloudStack.docs = {
helpLdapLinkDomainAdmin: {
desc: 'domain admin of the linked domain. Specify a username in GROUP/OU of LDAP'
}
-};
+};
\ No newline at end of file
diff --git a/ui/scripts/network.js b/ui/scripts/network.js
index cdfbcaa2d5a..23792215b8f 100755
--- a/ui/scripts/network.js
+++ b/ui/scripts/network.js
@@ -6133,6 +6133,14 @@
docID: 'helpVPNGatewayDeadPeerDetection',
isBoolean: true,
isChecked: false
+ },
+
+ forceencap: {
+ label: 'label.vpn.force.encapsulation',
+ docID: 'helpVPNGatewayForceEncapsulation',
+ docID: 'helpVPNGatewayForceEncapsulation',
+ isBoolean: true,
+ isChecked: false
}
}
},
@@ -6144,7 +6152,8 @@
ipsecpsk: args.data.ipsecpsk,
ikelifetime: args.data.ikelifetime,
esplifetime: args.data.esplifetime,
- dpd: (args.data.dpd == "on")
+ dpd: (args.data.dpd == "on"),
+ forceencap: (args.data.forceencap == "on")
};
var ikepolicy = args.data.ikeEncryption + '-' + args.data.ikeHash;
@@ -6200,7 +6209,8 @@
ipsecpsk: args.data.ipsecpsk,
ikelifetime: args.data.ikelifetime,
esplifetime: args.data.esplifetime,
- dpd: (args.data.dpd == "on")
+ dpd: (args.data.dpd == "on"),
+ forceencap: (args.data.forceencap == "on")
};
var ikepolicy = args.data.ikeEncryption + '-' + args.data.ikeHash;
@@ -6469,6 +6479,13 @@
converter: cloudStack.converters.toBooleanText
},
+ forceencap: {
+ label: 'label.vpn.force.encapsulation',
+ isBoolean: true,
+ isEditable: true,
+ converter: cloudStack.converters.toBooleanText
+ },
+
id: {
label: 'label.id'
},
diff --git a/ui/scripts/vpc.js b/ui/scripts/vpc.js
index 4b10d8baeaf..f7f7329d6cd 100644
--- a/ui/scripts/vpc.js
+++ b/ui/scripts/vpc.js
@@ -2904,6 +2904,12 @@
return str ? 'Yes' : 'No';
}
},
+ forceencap: {
+ label: 'label.vpn.force.encapsulation',
+ converter: function(str) {
+ return str ? 'Yes' : 'No';
+ }
+ },
state: {
label: 'label.state'
},