You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cloudstack.apache.org by ya...@apache.org on 2012/07/03 01:40:17 UTC

[6/13] git commit: CS-6840: Add hypervisor commands for site-to-site vpn

CS-6840: Add hypervisor commands for site-to-site vpn

Conflicts:

	plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java


Project: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/commit/8d4079d4
Tree: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/tree/8d4079d4
Diff: http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/diff/8d4079d4

Branch: refs/heads/vpc
Commit: 8d4079d477ee1461da4d88b8701964d647814326
Parents: cd98543
Author: Sheng Yang <sh...@citrix.com>
Authored: Wed Jun 27 19:00:56 2012 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Mon Jul 2 16:28:44 2012 -0700

----------------------------------------------------------------------
 .../agent/api/routing/Site2SiteVpnCfgCommand.java  |   99 +++++++++++----
 .../element/Site2SiteVpnServiceProvider.java       |    6 +-
 .../com/cloud/network/vpn/Site2SiteVpnService.java |    4 +-
 .../virtualnetwork/VirtualRoutingResource.java     |   39 ++++++
 .../xen/resource/CitrixResourceBase.java           |   41 ++++++-
 scripts/network/domr/s2s_vpn.sh                    |   26 ++++
 .../network/element/VirtualRouterElement.java      |   46 +-------
 .../network/element/VpcVirtualRouterElement.java   |   74 +++++++++++-
 .../router/VirtualNetworkApplianceManager.java     |    4 -
 .../router/VirtualNetworkApplianceManagerImpl.java |   33 -----
 .../router/VpcVirtualNetworkApplianceManager.java  |   16 +++
 .../VpcVirtualNetworkApplianceManagerImpl.java     |   54 ++++++++-
 .../cloud/network/vpn/Site2SiteVpnManagerImpl.java |   63 +++++++---
 13 files changed, 373 insertions(+), 132 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
index a0d1717..6e438f2 100644
--- a/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
+++ b/api/src/com/cloud/agent/api/routing/Site2SiteVpnCfgCommand.java
@@ -3,10 +3,15 @@ package com.cloud.agent.api.routing;
 public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
 
     private boolean create;
-    private String gatewayIp;
-    private String guestIp;
-    private String guestCidr;
+    private String localPublicIp;
+    private String localGuestCidr;
+    private String localPublicGateway;
+    private String peerGatewayIp;
+    private String peerGuestCidrList;
     private String ipsecPsk;
+    private String ikePolicy;
+    private String espPolicy;
+    private long lifetime;
     
 	@Override
     public boolean executeInSequence() {
@@ -17,12 +22,18 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
         this.create = false;
     }
     
-    public Site2SiteVpnCfgCommand (boolean create, String gatewayIp, String guestIp, String guestCidr, String ipsecPsk) {
+    public Site2SiteVpnCfgCommand (boolean create, String localPublicIp, String localPublicGateway, String localGuestCidr, 
+            String peerGatewayIp, String peerGuestCidrList, String ikePolicy, String espPolicy, long lifetime, String ipsecPsk) {
         this.create = create;
-        this.gatewayIp = gatewayIp;
-        this.guestIp = guestIp;
-        this.guestCidr = guestCidr;
+        this.setLocalPublicIp(localPublicIp);
+        this.setLocalPublicGateway(localPublicGateway);
+        this.setLocalGuestCidr(localGuestCidr);
+        this.setPeerGatewayIp(peerGatewayIp);
+        this.setPeerGuestCidrList(peerGuestCidrList);
         this.ipsecPsk = ipsecPsk;
+        this.ikePolicy = ikePolicy;
+        this.espPolicy = espPolicy;
+        this.lifetime = lifetime;
     }
     
     public boolean isCreate() {
@@ -33,37 +44,75 @@ public class Site2SiteVpnCfgCommand extends NetworkElementCommand {
         this.create = create;
     }
 
-    public String getGatewayIp() {
-        return gatewayIp;
+    public String getIpsecPsk() {
+        return ipsecPsk;
     }
 
-    public void setGatewayIp(String gatewayIp) {
-        this.gatewayIp = gatewayIp;
+    public void setIpsecPsk(String ipsecPsk) {
+        this.ipsecPsk = ipsecPsk;
     }
 
-    public String getGuestIp() {
-        return guestIp;
+    public String getIkePolicy() {
+        return ikePolicy;
     }
 
-    public void setGuestIp(String guestIp) {
-        this.guestIp = guestIp;
+    public void setIkePolicy(String ikePolicy) {
+        this.ikePolicy = ikePolicy;
     }
 
-    public String getGuestCidr() {
-        return guestCidr;
+    public String getEspPolicy() {
+        return espPolicy;
     }
 
-    public void setGuestCidr(String guestCidr) {
-        this.guestCidr = guestCidr;
+    public void setEspPolicy(String espPolicy) {
+        this.espPolicy = espPolicy;
     }
 
-    public String getIpsecPsk() {
-        return ipsecPsk;
+    public long getLifetime() {
+        return lifetime;
     }
 
-    public void setIpsecPsk(String ipsecPsk) {
-        this.ipsecPsk = ipsecPsk;
+    public void setLifetime(long lifetime) {
+        this.lifetime = lifetime;
+    }
+
+    public String getLocalPublicIp() {
+        return localPublicIp;
+    }
+
+    public void setLocalPublicIp(String localPublicIp) {
+        this.localPublicIp = localPublicIp;
+    }
+
+    public String getLocalGuestCidr() {
+        return localGuestCidr;
+    }
+
+    public void setLocalGuestCidr(String localGuestCidr) {
+        this.localGuestCidr = localGuestCidr;
+    }
+
+    public String getLocalPublicGateway() {
+        return localPublicGateway;
+    }
+
+    public void setLocalPublicGateway(String localPublicGateway) {
+        this.localPublicGateway = localPublicGateway;
+    }
+
+    public String getPeerGatewayIp() {
+        return peerGatewayIp;
+    }
+
+    public void setPeerGatewayIp(String peerGatewayIp) {
+        this.peerGatewayIp = peerGatewayIp;
+    }
+
+    public String getPeerGuestCidrList() {
+        return peerGuestCidrList;
+    }
+
+    public void setPeerGuestCidrList(String peerGuestCidrList) {
+        this.peerGuestCidrList = peerGuestCidrList;
     }
-    
-    
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java
index 8826283..0dc4a5a 100644
--- a/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java
+++ b/api/src/com/cloud/network/element/Site2SiteVpnServiceProvider.java
@@ -5,9 +5,7 @@ import com.cloud.network.Network;
 import com.cloud.network.Site2SiteVpnConnection;
 
 public interface Site2SiteVpnServiceProvider extends NetworkElement {
-    boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException;
+    boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException;
     
-    boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException;
-    
-    IpDeployer getIpDeployer(Network network);
+    boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/api/src/com/cloud/network/vpn/Site2SiteVpnService.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java
index 4ad4760..f3f188d 100644
--- a/api/src/com/cloud/network/vpn/Site2SiteVpnService.java
+++ b/api/src/com/cloud/network/vpn/Site2SiteVpnService.java
@@ -40,8 +40,8 @@ public interface Site2SiteVpnService {
     Site2SiteVpnConnection createVpnConnection(CreateVpnConnectionCmd cmd) throws NetworkRuleConflictException;
     Site2SiteCustomerGateway deleteCustomerGateway(DeleteVpnCustomerGatewayCmd deleteVpnCustomerGatewayCmd);
     Site2SiteVpnGateway deleteVpnGateway(DeleteVpnGatewayCmd deleteVpnGatewayCmd);
-    Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd deleteVpnConnectionCmd);
-    Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd resetVpnConnectionCmd);
+    Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd deleteVpnConnectionCmd) throws ResourceUnavailableException;
+    Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd resetVpnConnectionCmd) throws ResourceUnavailableException;
     List<Site2SiteCustomerGateway> searchForCustomerGateways(ListVpnCustomerGatewaysCmd listVpnCustomerGatewaysCmd);
     List<Site2SiteVpnGateway> searchForVpnGateways(ListVpnGatewaysCmd listVpnGatewaysCmd);
     List<Site2SiteVpnConnection> searchForVpnConnections(ListVpnConnectionsCmd listVpnConnectionsCmd);

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
----------------------------------------------------------------------
diff --git a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
index 54ae0f6..656ca37 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -57,6 +57,7 @@ import com.cloud.agent.api.routing.SetPortForwardingRulesAnswer;
 import com.cloud.agent.api.routing.SetPortForwardingRulesCommand;
 import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
+import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.to.IpAddressTO;
@@ -132,6 +133,8 @@ public class VirtualRoutingResource implements Manager {
                 return execute((VpnUsersCfgCommand)cmd);
             } else if (cmd instanceof GetDomRVersionCmd) {
                 return execute((GetDomRVersionCmd)cmd);
+            } else if (cmd instanceof Site2SiteVpnCfgCommand) {
+                return execute((Site2SiteVpnCfgCommand)cmd);
             }
             else {
                 return Answer.createUnsupportedCommandAnswer(cmd);
@@ -540,6 +543,42 @@ public class VirtualRoutingResource implements Manager {
     protected Answer execute(final WatchConsoleProxyLoadCommand cmd) {
         return executeProxyLoadScan(cmd, cmd.getProxyVmId(), cmd.getProxyVmName(), cmd.getProxyManagementIp(), cmd.getProxyCmdPort());
     }
+    
+    protected Answer execute(Site2SiteVpnCfgCommand cmd) {
+        String args;
+        if (cmd.isCreate()) {
+            args = "-A";
+            args += " -l ";
+	        args += cmd.getLocalPublicIp();
+            args += " -n ";
+	        args += cmd.getLocalGuestCidr();
+            args += " -g ";
+	        args += cmd.getLocalPublicGateway();
+            args += " -r ";
+	        args += cmd.getPeerGatewayIp();
+            args += " -N ";
+	        args += cmd.getPeerGuestCidrList();
+            args += " -e ";
+	        args += cmd.getEspPolicy();
+            args += " -i ";
+	        args += cmd.getIkePolicy();
+            args += " -t ";
+	        args += Long.toString(cmd.getLifetime());
+            args += " -s ";
+	        args += cmd.getIpsecPsk();
+        } else {
+            args = "-D";
+            args += " -r ";
+            args += cmd.getPeerGatewayIp();
+            args += " -N ";
+            args += cmd.getPeerGuestCidrList();
+        }
+        String result = routerProxy("ipsectunnel", cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP), args);
+        if (result != null) {
+            return new Answer(cmd, false, "Configure site to site VPN failed due to " + result);
+        }
+        return new Answer(cmd);
+    }
 
     private Answer executeProxyLoadScan(final Command cmd, final long proxyVmId, final String proxyVmName, final String proxyManagementIp, final int cmdPort) {
         String result = null;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index 835c892..bbd456f 100644
--- a/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/plugins/hypervisors/xen/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -158,6 +158,7 @@ import com.cloud.agent.api.routing.SetStaticNatRulesAnswer;
 import com.cloud.agent.api.routing.SetStaticNatRulesCommand;
 import com.cloud.agent.api.routing.SetStaticRouteAnswer;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
+import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.routing.VmDataCommand;
 import com.cloud.agent.api.routing.VpnUsersCfgCommand;
 import com.cloud.agent.api.storage.CopyVolumeAnswer;
@@ -546,6 +547,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((SetPortForwardingRulesVpcCommand) cmd);
         } else if (clazz == SetStaticRouteCommand.class) {
             return execute((SetStaticRouteCommand) cmd);
+        } else if (clazz == Site2SiteVpnCfgCommand.class) {
+            return execute((Site2SiteVpnCfgCommand) cmd);
         } else {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
@@ -7161,7 +7164,43 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return null;
     }
 
-    
+    protected Answer execute(Site2SiteVpnCfgCommand cmd) {
+        Connection conn = getConnection();
+        String args = "ipsectunnel.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        if (cmd.isCreate()) {
+            args += " -A";
+            args += " -l ";
+	        args += cmd.getLocalPublicIp();
+            args += " -n ";
+	        args += cmd.getLocalGuestCidr();
+            args += " -g ";
+	        args += cmd.getLocalPublicGateway();
+            args += " -r ";
+	        args += cmd.getPeerGatewayIp();
+            args += " -N ";
+	        args += cmd.getPeerGuestCidrList();
+            args += " -e ";
+	        args += cmd.getEspPolicy();
+            args += " -i ";
+	        args += cmd.getIkePolicy();
+            args += " -t ";
+	        args += Long.toString(cmd.getLifetime());
+            args += " -s ";
+	        args += cmd.getIpsecPsk();
+        } else {
+            args += " -D";
+            args += " -r ";
+            args += cmd.getPeerGatewayIp();
+            args += " -N ";
+            args += cmd.getPeerGuestCidrList();
+        }
+        String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new Answer(cmd, false, "Configure site to site VPN failed! ");
+        }
+        return new Answer(cmd);
+    }
+
     protected SetSourceNatAnswer execute(SetSourceNatCommand cmd) {
         //FIXME - add implementation here
         return null;

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/scripts/network/domr/s2s_vpn.sh
----------------------------------------------------------------------
diff --git a/scripts/network/domr/s2s_vpn.sh b/scripts/network/domr/s2s_vpn.sh
new file mode 100755
index 0000000..0bdccc4
--- /dev/null
+++ b/scripts/network/domr/s2s_vpn.sh
@@ -0,0 +1,26 @@
+#!/bin/bash
+# Copyright 2012 Citrix Systems, Inc. Licensed under the
+# Apache License, Version 2.0 (the "License"); you may not use this
+# file except in compliance with the License.  Citrix Systems, Inc.
+# reserves all rights not expressly granted by the License.
+# You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+# 
+# Automatically generated by addcopyright.py at 04/03/2012
+
+
+
+ 
+
+# @VERSION@
+
+cert="/root/.ssh/id_rsa.cloud"
+domr=$1
+shift
+ssh -p 3922 -o StrictHostKeyChecking=no -i $cert root@$domr "/opt/cloud/bin/ipsectunnel.sh $*" >/dev/null
+
+exit $?

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/element/VirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VirtualRouterElement.java b/server/src/com/cloud/network/element/VirtualRouterElement.java
index efa5cba..05d8a99 100755
--- a/server/src/com/cloud/network/element/VirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VirtualRouterElement.java
@@ -44,7 +44,6 @@ import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.RemoteAccessVpn;
-import com.cloud.network.Site2SiteVpnConnection;
 import com.cloud.network.VirtualRouterProvider;
 import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
 import com.cloud.network.VpnUser;
@@ -88,7 +87,7 @@ import com.google.gson.Gson;
 @Local(value = NetworkElement.class)
 public class VirtualRouterElement extends AdapterBase implements VirtualRouterElementService, DhcpServiceProvider, 
     UserDataServiceProvider, SourceNatServiceProvider, StaticNatServiceProvider, FirewallServiceProvider,
-        LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, Site2SiteVpnServiceProvider, IpDeployer {
+        LoadBalancingServiceProvider, PortForwardingServiceProvider, RemoteAccessVPNServiceProvider, IpDeployer {
     private static final Logger s_logger = Logger.getLogger(VirtualRouterElement.class);
 
     protected static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@@ -586,9 +585,6 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
         capabilities.put(Service.StaticNat, null);
         capabilities.put(Service.PortForwarding, null);
 
-        Map<Capability, String> s2sVpnCapabilities = new HashMap<Capability, String>();
-        s2sVpnCapabilities.put(Capability.SupportedSite2SiteVpnTypes, "ipsec");
-        
         return capabilities;
     }
 
@@ -880,46 +876,8 @@ public class VirtualRouterElement extends AdapterBase implements VirtualRouterEl
     public IpDeployer getIpDeployer(Network network) {
         return this;
     }
-    
+
     protected VirtualRouterProviderType getVirtualRouterProvider() {
         return VirtualRouterProviderType.VirtualRouter;
     }
-
-    @Override
-    public boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException {
-        if (!canHandle(network, Service.Site2SiteVpn)) {
-            return false;
-        }
-
-        List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId());
-            return true;
-        }
-
-        if (!_routerMgr.startSite2SiteVpn(network, conn, routers)) {
-            throw new CloudRuntimeException("Failed to apply firewall rules in network " + network.getId());
-        }
-
-        return true;
-    }
-
-    @Override
-    public boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn) throws ResourceUnavailableException {
-        if (!canHandle(network, Service.Site2SiteVpn)) {
-            return false;
-        }
-
-        List<DomainRouterVO> routers = _routerDao.listByNetworkAndRole(network.getId(), Role.VIRTUAL_ROUTER);
-        if (routers == null || routers.isEmpty()) {
-            s_logger.debug("Virtual router elemnt doesn't need to apply firewall rules on the backend; virtual router doesn't exist in the network " + network.getId());
-            return true;
-        }
-
-        if (!_routerMgr.stopSite2SiteVpn(network, conn, routers)) {
-            throw new CloudRuntimeException("Failed to apply firewall rules in network " + network.getId());
-        }
-
-        return true;
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
index c5e2efd..1ad4821 100644
--- a/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
+++ b/server/src/com/cloud/network/element/VpcVirtualRouterElement.java
@@ -28,6 +28,7 @@ import com.cloud.deploy.DeployDestination;
 import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
+import com.cloud.network.IpAddress;
 import com.cloud.network.Network;
 import com.cloud.network.Network.Capability;
 import com.cloud.network.Network.Provider;
@@ -35,6 +36,12 @@ import com.cloud.network.Network.Service;
 import com.cloud.network.NetworkService;
 import com.cloud.network.PublicIpAddress;
 import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.Site2SiteVpnGateway;
+import com.cloud.network.dao.IPAddressDao;
+import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
+import com.cloud.network.dao.Site2SiteVpnConnectionDao;
+import com.cloud.network.dao.Site2SiteVpnGatewayDao;
 import com.cloud.network.router.VirtualRouter;
 import com.cloud.network.router.VirtualRouter.Role;
 import com.cloud.network.router.VpcVirtualNetworkApplianceManager;
@@ -59,7 +66,7 @@ import com.cloud.vm.VirtualMachineProfile;
  * @author Alena Prokharchyk
  */
 @Local(value = NetworkElement.class)
-public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, NetworkACLServiceProvider{
+public class VpcVirtualRouterElement extends VirtualRouterElement implements VpcProvider, Site2SiteVpnServiceProvider, NetworkACLServiceProvider{
     private static final Logger s_logger = Logger.getLogger(VpcVirtualRouterElement.class);
     @Inject 
     NetworkService _ntwkService;
@@ -67,6 +74,14 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
     VpcManager _vpcMgr;
     @Inject
     VpcVirtualNetworkApplianceManager _vpcRouterMgr;
+    @Inject
+    Site2SiteCustomerGatewayDao _customerGatewayDao;
+    @Inject
+    Site2SiteVpnGatewayDao _vpnGatewayDao;
+    @Inject
+    Site2SiteVpnConnectionDao _vpnConnectionDao;
+    @Inject
+    IPAddressDao _ipAddressDao;
     
     
     private static final Map<Service, Map<Capability, String>> capabilities = setCapabilities();
@@ -419,4 +434,61 @@ public class VpcVirtualRouterElement extends VirtualRouterElement implements Vpc
             return true;
         }
     }
+
+    public boolean startSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException {
+        Site2SiteVpnGateway vpnGw = _vpnGatewayDao.findById(conn.getVpnGatewayId());
+        IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId());
+
+        /*
+        if (!canHandle(network, Service.Vpn)) {
+            return false;
+        }
+        */
+
+        Map<Capability, String> vpnCapabilities = capabilities.get(Service.Vpn);
+        if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) {
+            return false;
+        }
+
+        List<DomainRouterVO> routers = _vpcMgr.getVpcRouters(ip.getVpcId());
+        if (routers == null || routers.size() != 1) {
+            s_logger.debug("Cannot enable site-to-site VPN on the backend; virtual router doesn't exist in the vpc " + ip.getVpcId());
+            return true;
+        }
+
+        if (!_vpcRouterMgr.startSite2SiteVpn(conn, routers.get(0))) {
+            throw new CloudRuntimeException("Failed to apply site-to-site VPN in VPC " + ip.getVpcId());
+        }
+
+        return true;
+    }
+
+    @Override
+    public boolean stopSite2SiteVpn(Site2SiteVpnConnection conn) throws ResourceUnavailableException {
+        Site2SiteVpnGateway vpnGw = _vpnGatewayDao.findById(conn.getVpnGatewayId());
+        IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId());
+
+        /*
+        if (!canHandle(network, Service.Vpn)) {
+            return false;
+        }
+        */
+
+        Map<Capability, String> vpnCapabilities = capabilities.get(Service.Vpn);
+        if (!vpnCapabilities.get(Capability.VpnTypes).contains("s2svpn")) {
+            return false;
+        }
+
+        List<DomainRouterVO> routers = _vpcMgr.getVpcRouters(ip.getVpcId());
+        if (routers == null || routers.size() != 1) {
+            s_logger.debug("Cannot disable site-to-site VPN on the backend; virtual router doesn't exist in the vpc " + ip.getVpcId());
+            return true;
+        }
+
+        if (!_vpcRouterMgr.stopSite2SiteVpn(conn, routers.get(0))) {
+            throw new CloudRuntimeException("Failed to apply site-to-site VPN in VPC " + ip.getVpcId());
+        }
+
+        return true;
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
index 6861bf7..b2c1cd0 100644
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManager.java
@@ -94,8 +94,4 @@ public interface VirtualNetworkApplianceManager extends Manager, VirtualNetworkA
 	
 	boolean applyUserData(Network config, NicProfile nic, VirtualMachineProfile<UserVm> vm, DeployDestination dest, 
 	        List<DomainRouterVO> routers) throws ResourceUnavailableException;
-
-    boolean startSite2SiteVpn(Network network, Site2SiteVpnConnection conn, List<DomainRouterVO> routers) throws ResourceUnavailableException;
-
-    boolean stopSite2SiteVpn(Network network, Site2SiteVpnConnection conn, List<DomainRouterVO> routers) throws ResourceUnavailableException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
index a83a707..2e5481b 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -3207,37 +3207,4 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
         throw new UnsupportedOperationException("Unplug nic is not supported for vm of type " + vm.getType());
     }
     
-
-    @Override
-    public boolean startSite2SiteVpn(Network network, final Site2SiteVpnConnection conn, List<DomainRouterVO> routers) throws ResourceUnavailableException {
-        return applyRules(network, routers, "site2site vpn", false, null, false, new RuleApplier() {
-            @Override
-            public boolean execute(Network network, VirtualRouter router) throws ResourceUnavailableException {
-                return applySite2SiteVpn(router, conn);
-            }
-        });
-    }
-
-    protected boolean applySite2SiteVpn(VirtualRouter router, Site2SiteVpnConnection conn) throws ResourceUnavailableException {
-        Commands cmds = new Commands(OnError.Continue);
-        createApplySite2SiteVpnCommands(conn, router, cmds);
-        return sendCommandsToRouter(router, cmds);
-    }
-
-    private void createApplySite2SiteVpnCommands(Site2SiteVpnConnection conn, VirtualRouter router, Commands cmds) {
-        Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
-        String gatewayIp = gw.getGatewayIp();
-        String guestIp = gw.getGuestIp();
-        String guestCidr = gw.getGuestCidr();
-        String ipsecPsk = gw.getIpsecPsk();
-        
-        Site2SiteVpnCfgCommand startS2SVpnCmd = new Site2SiteVpnCfgCommand(true, gatewayIp, guestIp, guestCidr, ipsecPsk);
-        startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
-        startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_GUEST_IP, router.getGuestIpAddress());
-        startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
-        DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn());
-        startS2SVpnCmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
-
-        cmds.addCommand("startS2SVpn", startS2SVpnCmd);
-    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
index a17c7cf..f0a3cec 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManager.java
@@ -20,6 +20,7 @@ import com.cloud.exception.ConcurrentOperationException;
 import com.cloud.exception.InsufficientCapacityException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.Network;
+import com.cloud.network.Site2SiteVpnConnection;
 import com.cloud.network.VpcVirtualNetworkApplianceService;
 import com.cloud.network.rules.NetworkACL;
 import com.cloud.network.vpc.StaticRouteProfile;
@@ -84,4 +85,19 @@ public interface VpcVirtualNetworkApplianceManager extends VirtualNetworkApplian
      */
     boolean applyStaticRoutes(List<StaticRouteProfile> routes, List<DomainRouterVO> routers) throws ResourceUnavailableException;
 
+    /**
+     * @param conn
+     * @param routers
+     * @return
+     * @throws ResourceUnavailableException
+     */
+    boolean startSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException;
+
+    /**
+     * @param conn
+     * @param routers
+     * @return
+     * @throws ResourceUnavailableException
+     */
+    boolean stopSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException;
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
index de6b39d..f53ae24 100644
--- a/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VpcVirtualNetworkApplianceManagerImpl.java
@@ -36,6 +36,7 @@ import com.cloud.agent.api.routing.NetworkElementCommand;
 import com.cloud.agent.api.routing.SetNetworkACLCommand;
 import com.cloud.agent.api.routing.SetSourceNatCommand;
 import com.cloud.agent.api.routing.SetStaticRouteCommand;
+import com.cloud.agent.api.routing.Site2SiteVpnCfgCommand;
 import com.cloud.agent.api.to.IpAddressTO;
 import com.cloud.agent.api.to.NetworkACLTO;
 import com.cloud.agent.api.to.NicTO;
@@ -59,17 +60,23 @@ import com.cloud.network.Network;
 import com.cloud.network.Network.Provider;
 import com.cloud.network.Network.Service;
 import com.cloud.network.NetworkService;
+import com.cloud.network.NetworkVO;
 import com.cloud.network.Networks.BroadcastDomainType;
 import com.cloud.network.Networks.IsolationType;
 import com.cloud.network.Networks.TrafficType;
 import com.cloud.network.PhysicalNetwork;
 import com.cloud.network.PhysicalNetworkServiceProvider;
 import com.cloud.network.PublicIpAddress;
+import com.cloud.network.Site2SiteCustomerGatewayVO;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.Site2SiteVpnGatewayVO;
 import com.cloud.network.VirtualRouterProvider;
 import com.cloud.network.VirtualRouterProvider.VirtualRouterProviderType;
 import com.cloud.network.VpcVirtualNetworkApplianceService;
 import com.cloud.network.addr.PublicIp;
 import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.Site2SiteVpnConnectionDao;
+import com.cloud.network.firewall.NetworkACLService;
 import com.cloud.network.rules.NetworkACL;
 import com.cloud.network.vpc.NetworkACLManager;
 import com.cloud.network.vpc.PrivateGateway;
@@ -81,6 +88,7 @@ import com.cloud.network.vpc.VpcManager;
 import com.cloud.network.vpc.Dao.StaticRouteDao;
 import com.cloud.network.vpc.Dao.VpcDao;
 import com.cloud.network.vpc.Dao.VpcOfferingDao;
+import com.cloud.network.vpn.Site2SiteVpnService;
 import com.cloud.user.Account;
 import com.cloud.utils.Pair;
 import com.cloud.utils.component.Inject;
@@ -92,6 +100,7 @@ import com.cloud.vm.Nic;
 import com.cloud.vm.NicProfile;
 import com.cloud.vm.ReservationContext;
 import com.cloud.vm.VirtualMachine;
+import com.cloud.vm.VirtualMachine.State;
 import com.cloud.vm.VirtualMachineProfile;
 import com.cloud.vm.VirtualMachineProfile.Param;
 import com.cloud.vm.dao.VMInstanceDao;
@@ -823,7 +832,9 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
             createStaticRouteCommands(staticRouteProfiles, router, cmds);
         }
         
-        //4) REPROGRAM GUEST NETWORK
+        //4) REISSUE VPN CONNECTION
+        
+        //5) REPROGRAM GUEST NETWORK
         boolean reprogramGuestNtwks = true;
         if (profile.getParameter(Param.ReProgramGuestNetworks) != null 
                 && (Boolean) profile.getParameter(Param.ReProgramGuestNetworks) == false) {
@@ -1007,4 +1018,45 @@ public class VpcVirtualNetworkApplianceManagerImpl extends VirtualNetworkApplian
         cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
         cmds.addCommand(cmd);
     }
+
+    @Override
+    public boolean startSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException {
+        return applySite2SiteVpn(true, router, conn);
+    }
+
+    @Override
+    public boolean stopSite2SiteVpn(Site2SiteVpnConnection conn, VirtualRouter router) throws ResourceUnavailableException {
+        return applySite2SiteVpn(false, router, conn);
+    }
+
+    protected boolean applySite2SiteVpn(boolean isCreate, VirtualRouter router, Site2SiteVpnConnection conn) throws ResourceUnavailableException {
+        Commands cmds = new Commands(OnError.Continue);
+        createApplySite2SiteVpnCommands(conn, isCreate, router, cmds);
+        return sendCommandsToRouter(router, cmds);
+    }
+
+    private void createApplySite2SiteVpnCommands(Site2SiteVpnConnection conn, boolean isCreate, VirtualRouter router, Commands cmds) {
+        Site2SiteCustomerGatewayVO gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
+        Site2SiteVpnGatewayVO vpnGw = _s2sVpnGatewayDao.findById(conn.getVpnGatewayId());
+        IpAddress ip = _ipAddressDao.findById(vpnGw.getAddrId());
+        Vpc vpc = _vpcDao.findById(ip.getVpcId());
+        String localPublicIp = ip.getAddress().toString();
+        String localGuestCidr = vpc.getCidr();
+        String localPublicGateway = _vlanDao.findById(ip.getVlanId()).getVlanGateway();
+        String peerGatewayIp = gw.getGatewayIp();
+        String peerGuestCidrList = gw.getGuestCidrList();
+        String ipsecPsk = gw.getIpsecPsk();
+        String ikePolicy = gw.getIkePolicy();
+        String espPolicy = gw.getEspPolicy();
+        Long lifetime = gw.getLifetime();
+
+        Site2SiteVpnCfgCommand cmd = new Site2SiteVpnCfgCommand(isCreate, localPublicIp, localPublicGateway, localGuestCidr,
+                peerGatewayIp, peerGuestCidrList, ikePolicy, espPolicy, lifetime, ipsecPsk);
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
+        cmd.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+        DataCenterVO dcVo = _dcDao.findById(router.getDataCenterIdToDeployIn());
+        cmd.setAccessDetail(NetworkElementCommand.ZONE_NETWORK_TYPE, dcVo.getNetworkType().toString());
+        cmds.addCommand("applyS2SVpn", cmd);
+    }
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8d4079d4/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
index ef37ad0..bc634ef 100644
--- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
+++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
@@ -25,25 +25,22 @@ import com.cloud.exception.InvalidParameterValueException;
 import com.cloud.exception.NetworkRuleConflictException;
 import com.cloud.exception.ResourceUnavailableException;
 import com.cloud.network.IpAddress;
-import com.cloud.network.Network;
 import com.cloud.network.NetworkManager;
-import com.cloud.network.NetworkVO;
 import com.cloud.network.Site2SiteCustomerGateway;
 import com.cloud.network.Site2SiteCustomerGatewayVO;
 import com.cloud.network.Site2SiteVpnConnection;
-import com.cloud.network.Network.GuestType;
 import com.cloud.network.Site2SiteVpnConnection.State;
 import com.cloud.network.Site2SiteVpnConnectionVO;
 import com.cloud.network.Site2SiteVpnGateway;
 import com.cloud.network.Site2SiteVpnGatewayVO;
-import com.cloud.network.dao.NetworkDao;
+import com.cloud.network.dao.IPAddressDao;
 import com.cloud.network.dao.Site2SiteCustomerGatewayDao;
 import com.cloud.network.dao.Site2SiteVpnConnectionDao;
 import com.cloud.network.dao.Site2SiteVpnGatewayDao;
 import com.cloud.network.element.Site2SiteVpnServiceProvider;
+import com.cloud.network.vpc.Dao.VpcDao;
 import com.cloud.utils.component.Inject;
 import com.cloud.utils.component.Manager;
-import com.cloud.utils.db.GenericDao;
 import com.cloud.utils.net.NetUtils;
 
 @Local(value = Site2SiteVpnService.class)
@@ -54,7 +51,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
     @Inject Site2SiteVpnGatewayDao _vpnGatewayDao;
     @Inject Site2SiteVpnConnectionDao _vpnConnectionDao;
     @Inject NetworkManager _networkMgr;
-    @Inject NetworkDao _networkDao;
+    @Inject VpcDao _vpcDao;
+    @Inject IPAddressDao _ipAddressDao;
     
     String _name;
     
@@ -83,9 +81,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
     public Site2SiteVpnGateway createVpnGateway(CreateVpnGatewayCmd cmd) {
         Long ipId = cmd.getPublicIpId();
 	    IpAddress ip = _networkMgr.getIp(ipId);
-	    Network network = _networkDao.findById(ip.getAssociatedWithNetworkId());
-	    if (network.getGuestType() != GuestType.Isolated) {
-            throw new InvalidParameterValueException("The VPN gateway cannot create with non-isolated network " + ip.getAssociatedWithNetworkId());
+	    if (ip.getVpcId() == null) {
+            throw new InvalidParameterValueException("The VPN gateway cannot create with ip not belong to VPC");
 	    }
         Long domainId = ip.getDomainId();
         Long accountId = ip.getAccountId();
@@ -151,6 +148,7 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
                     + vpnGatewayId + " already existed!");
         }
         Site2SiteVpnConnectionVO conn = new Site2SiteVpnConnectionVO(vpnGatewayId, customerGatewayId);
+        conn.setState(State.Pending);
         _vpnConnectionDao.persist(conn);
         return conn;
     }
@@ -162,12 +160,10 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
             throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(pending or disconnected) to process!");
         }
 
-        Site2SiteVpnGatewayVO vpnGateway = _vpnGatewayDao.findById(conn.getVpnGatewayId());
-        Network network = _networkDao.findById(vpnGateway.getNetworkId());
         List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
         boolean result = true;
         for (Site2SiteVpnServiceProvider element : elements) {
-            result = result & element.startSite2SiteVpn(network, conn);
+            result = result & element.startSite2SiteVpn(conn);
         }
 
         if (result) {
@@ -175,6 +171,8 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
             _vpnConnectionDao.persist(conn);
             return conn;
         }
+        conn.setState(State.Error);
+        _vpnConnectionDao.persist(conn);
         return null;
     }
 
@@ -255,20 +253,51 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnService, Manager {
     }
 
     @Override
-    public Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd cmd) {
+    public Site2SiteVpnConnection deleteVpnConnection(DeleteVpnConnectionCmd cmd) throws ResourceUnavailableException {
         Long id = cmd.getId();
         Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
+        if (conn == null) {
+            throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to delete!");
+        }
         if (conn.getState() == State.Connected) {
-            //TODO disconnect it first
+            stopVpnConnection(id);
         }
-        return null;
+        _vpnConnectionDao.remove(id);
+        return conn;
+    }
+
+    private void stopVpnConnection(Long id) throws ResourceUnavailableException {
+        Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
+        if (conn.getState() != State.Connected) {
+            throw new InvalidParameterValueException("Site to site VPN connection " + id + " not in correct state(connected) to process disconnect!");
+        }
+
+        List <? extends Site2SiteVpnServiceProvider> elements = _networkMgr.getSite2SiteVpnElements();
+        boolean result = true;
+        conn.setState(State.Disconnecting);
+        for (Site2SiteVpnServiceProvider element : elements) {
+            result = result & element.stopSite2SiteVpn(conn);
+        }
+
+        if (result) {
+            conn.setState(State.Disconnected);
+            _vpnConnectionDao.persist(conn);
+        }
+        conn.setState(State.Error);
     }
 
     @Override
-    public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) {
+    public Site2SiteVpnConnection resetVpnConnection(ResetVpnConnectionCmd cmd) throws ResourceUnavailableException {
         Long id = cmd.getId();
         Site2SiteVpnConnectionVO conn = _vpnConnectionDao.findById(id);
-        return null;
+        if (conn == null) {
+            throw new InvalidParameterValueException("Fail to find site to site VPN connection " + id + " to reset!");
+        }
+        if (conn.getState() == State.Connected) {
+            stopVpnConnection(id);
+        }
+        startVpnConnection(id);
+        return conn;
     }
 
     @Override