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/28 01:30:36 UTC

[3/6] git commit: S2S VPN: CS-15650: Add connection status update to s2s vpn

S2S VPN: CS-15650: Add connection status update to s2s vpn


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

Branch: refs/heads/vpc
Commit: 8eee8f342eeb72418055defc4d1eb51ae155b592
Parents: 786d599
Author: Sheng Yang <sh...@citrix.com>
Authored: Fri Jul 27 16:18:52 2012 -0700
Committer: Sheng Yang <sh...@citrix.com>
Committed: Fri Jul 27 16:28:06 2012 -0700

----------------------------------------------------------------------
 .../agent/api/CheckS2SVpnConnectionsAnswer.java    |   55 ++++++++++
 .../agent/api/CheckS2SVpnConnectionsCommand.java   |   23 ++++
 .../virtualnetwork/VirtualRoutingResource.java     |   19 ++++
 .../debian/config/opt/cloud/bin/checks2svpn.sh     |    8 +-
 .../hypervisor/vmware/resource/VmwareResource.java |   31 ++++++
 .../xen/resource/CitrixResourceBase.java           |   16 +++
 .../router/VirtualNetworkApplianceManagerImpl.java |   85 ++++++++++++++-
 .../com/cloud/network/vpn/Site2SiteVpnManager.java |    6 +
 .../cloud/network/vpn/Site2SiteVpnManagerImpl.java |   13 +++
 9 files changed, 251 insertions(+), 5 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java b/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
new file mode 100644
index 0000000..b9e9a66
--- /dev/null
+++ b/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsAnswer.java
@@ -0,0 +1,55 @@
+package com.cloud.agent.api;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public class CheckS2SVpnConnectionsAnswer extends Answer {
+    Map<String, Boolean> ipToConnected;
+    Map<String, String> ipToDetail;
+    String details;
+    
+    protected CheckS2SVpnConnectionsAnswer() {
+        ipToConnected = new HashMap<String, Boolean>();
+        ipToDetail = new HashMap<String, String>();
+    }
+    
+    public CheckS2SVpnConnectionsAnswer(CheckS2SVpnConnectionsCommand cmd, boolean result, String details) {
+        super(cmd, result, details);
+        ipToConnected = new HashMap<String, Boolean>();
+        ipToDetail = new HashMap<String, String>();
+        this.details = details;
+        if (result) {
+            parseDetails(details);
+        }
+    }
+    
+    protected void parseDetails(String details) {
+        String[] lines = details.split("&");
+        for (String line : lines) {
+            String[] words = line.split(":");
+            if (words.length != 3) {
+                //Not something we can parse
+                return;
+            }
+            String ip = words[0];
+            boolean connected = words[1].equals("0");
+            String detail = words[2];
+            ipToConnected.put(ip, connected);
+            ipToDetail.put(ip, detail);
+        }
+    }
+    
+    public boolean isConnected(String ip) {
+        if (this.getResult()) {
+            return ipToConnected.get(ip);
+        }
+        return false;
+    }
+    
+    public String getDetail(String ip) {
+        if (this.getResult()) {
+            return ipToDetail.get(ip);
+        }
+        return null;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java
----------------------------------------------------------------------
diff --git a/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java b/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java
new file mode 100644
index 0000000..9401b47
--- /dev/null
+++ b/api/src/com/cloud/agent/api/CheckS2SVpnConnectionsCommand.java
@@ -0,0 +1,23 @@
+package com.cloud.agent.api;
+
+import java.util.List;
+
+import com.cloud.agent.api.routing.NetworkElementCommand;
+
+public class CheckS2SVpnConnectionsCommand extends NetworkElementCommand {
+    List<String> vpnIps;
+    
+    @Override
+    public boolean executeInSequence() {
+        return true;
+    }
+    
+    public CheckS2SVpnConnectionsCommand(List<String> vpnIps) {
+        super();
+        this.vpnIps = vpnIps;
+    }
+    
+    public List<String> getVpnIps() {
+        return vpnIps;
+    }
+}

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/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 fe6c45c..4081ff6 100755
--- a/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
+++ b/core/src/com/cloud/agent/resource/virtualnetwork/VirtualRoutingResource.java
@@ -42,6 +42,8 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BumpUpPriorityCommand;
 import com.cloud.agent.api.CheckRouterAnswer;
 import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.GetDomRVersionAnswer;
 import com.cloud.agent.api.GetDomRVersionCmd;
@@ -139,6 +141,8 @@ public class VirtualRoutingResource implements Manager {
                 return execute((GetDomRVersionCmd)cmd);
             } else if (cmd instanceof Site2SiteVpnCfgCommand) {
                 return execute((Site2SiteVpnCfgCommand)cmd);
+            } else if (cmd instanceof CheckS2SVpnConnectionsCommand) {
+                return execute((CheckS2SVpnConnectionsCommand)cmd);
             }
             else {
                 return Answer.createUnsupportedCommandAnswer(cmd);
@@ -500,6 +504,21 @@ public class VirtualRoutingResource implements Manager {
         return null;
     }
 
+    private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) {
+        final String routerIP = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+    
+        String args = "";
+        for (String ip : cmd.getVpnIps()) {
+            args += " " + ip;
+        }
+        
+        final String result = routerProxy("checkbatchs2svpn.sh", routerIP, args);
+        if (result == null || result.isEmpty()) {
+            return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed");
+        }
+        return new CheckS2SVpnConnectionsAnswer(cmd, true, result);
+    }
+
     protected Answer execute(CheckRouterCommand cmd) {
         final String routerPrivateIPAddress = cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
     

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh
----------------------------------------------------------------------
diff --git a/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh b/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh
index 3198824..e6bf9e5 100755
--- a/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh
+++ b/patches/systemvm/debian/config/opt/cloud/bin/checks2svpn.sh
@@ -12,20 +12,20 @@ cat /tmp/vpn-$1.status | grep "ISAKMP SA established" > /dev/null
 isakmpok=$?
 if [ $isakmpok -ne 0 ]
 then
-	echo "ISAKMP SA not found"
+	echo -n "ISAKMP SA not found"
         echo "Site-to-site VPN have not connected"
 	exit 12
 fi
-echo "ISAKMP SA found"
+echo -n "ISAKMP SA found;"
 
 cat /tmp/vpn-$1.status | grep "IPsec SA established" > /dev/null
 ipsecok=$?
 if [ $ipsecok -ne 0 ]
 then
-	echo "IPsec SA not found"
+	echo -n "IPsec SA not found;"
         echo "Site-to-site VPN have not connected"
 	exit 11
 fi
-echo "IPsec SA found"
+echo -n "IPsec SA found;"
 echo "Site-to-site VPN have connected"
 exit 0

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
----------------------------------------------------------------------
diff --git a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
index bb4198f..7c486d8 100755
--- a/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
+++ b/plugins/hypervisors/vmware/src/com/cloud/hypervisor/vmware/resource/VmwareResource.java
@@ -53,6 +53,8 @@ import com.cloud.agent.api.CheckOnHostAnswer;
 import com.cloud.agent.api.CheckOnHostCommand;
 import com.cloud.agent.api.CheckRouterAnswer;
 import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
 import com.cloud.agent.api.CheckVirtualMachineAnswer;
 import com.cloud.agent.api.CheckVirtualMachineCommand;
 import com.cloud.agent.api.Command;
@@ -1020,6 +1022,35 @@ public class VmwareResource implements StoragePoolResource, ServerResource, Vmwa
         return new Answer(cmd);
     }
     
+    protected CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) {
+        if (s_logger.isDebugEnabled()) {
+            s_logger.debug("Executing resource CheckS2SVpnConnectionsCommand: " + _gson.toJson(cmd));
+            s_logger.debug("Run command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + ", /opt/cloud/bin/checkbatchs2svpn.sh ");
+        }
+
+        Pair<Boolean, String> result;
+        try {
+            VmwareManager mgr = getServiceContext().getStockObject(VmwareManager.CONTEXT_STOCK_NAME);
+            String controlIp = getRouterSshControlIp(cmd);
+            result = SshHelper.sshExecute(controlIp, DEFAULT_DOMR_SSHPORT, "root", mgr.getSystemVMKeyFile(), null,
+                    "/opt/cloud/bin/checkbatchs2svpn.sh ");
+
+            if (!result.first()) {
+                s_logger.error("check site-to-site vpn connections command on domR " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " failed, message: " + result.second());
+
+                return new CheckS2SVpnConnectionsAnswer(cmd, false, result.second());
+            }
+
+            if (s_logger.isDebugEnabled()) {
+                s_logger.debug("check site-to-site vpn connections command on domain router " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP) + " completed");
+            }
+        } catch (Throwable e) {
+            String msg = "CheckS2SVpnConnectionsCommand failed due to " + VmwareHelper.getExceptionMessage(e);
+            s_logger.error(msg, e);
+            return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed");
+        }
+        return new CheckS2SVpnConnectionsAnswer(cmd, true, result.second());
+    }
     protected Answer execute(CheckRouterCommand cmd) {
         if (s_logger.isDebugEnabled()) {
             s_logger.debug("Executing resource CheckRouterCommand: " + _gson.toJson(cmd));

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/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 ef6a888..8f3ca0b 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
@@ -66,6 +66,8 @@ import com.cloud.agent.api.CheckOnHostAnswer;
 import com.cloud.agent.api.CheckOnHostCommand;
 import com.cloud.agent.api.CheckRouterAnswer;
 import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
 import com.cloud.agent.api.CheckVirtualMachineAnswer;
 import com.cloud.agent.api.CheckVirtualMachineCommand;
 import com.cloud.agent.api.CleanupNetworkRulesCmd;
@@ -549,6 +551,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
             return execute((SetStaticRouteCommand) cmd);
         } else if (clazz == Site2SiteVpnCfgCommand.class) {
             return execute((Site2SiteVpnCfgCommand) cmd);
+        } else if (clazz == CheckS2SVpnConnectionsCommand.class) {
+            return execute((CheckS2SVpnConnectionsCommand) cmd);
         } else {
             return Answer.createUnsupportedCommandAnswer(cmd);
         }
@@ -1400,6 +1404,18 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
         return new Answer(cmd);
     }
 
+    private CheckS2SVpnConnectionsAnswer execute(CheckS2SVpnConnectionsCommand cmd) {
+        Connection conn = getConnection();
+        String args = "checkbatchs2svpn.sh " + cmd.getAccessDetail(NetworkElementCommand.ROUTER_IP);
+        for (String ip : cmd.getVpnIps()) {
+            args += " " + ip;
+        }
+        String result = callHostPlugin(conn, "vmops", "routerProxy", "args", args);
+        if (result == null || result.isEmpty()) {
+            return new CheckS2SVpnConnectionsAnswer(cmd, false, "CheckS2SVpnConneciontsCommand failed");
+        }
+        return new CheckS2SVpnConnectionsAnswer(cmd, true, result);
+    }
 
     private CheckRouterAnswer execute(CheckRouterCommand cmd) {
         Connection conn = getConnection();

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/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 c812824..da6cc7c 100755
--- a/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
+++ b/server/src/com/cloud/network/router/VirtualNetworkApplianceManagerImpl.java
@@ -47,6 +47,8 @@ import com.cloud.agent.api.Answer;
 import com.cloud.agent.api.BumpUpPriorityCommand;
 import com.cloud.agent.api.CheckRouterAnswer;
 import com.cloud.agent.api.CheckRouterCommand;
+import com.cloud.agent.api.CheckS2SVpnConnectionsAnswer;
+import com.cloud.agent.api.CheckS2SVpnConnectionsCommand;
 import com.cloud.agent.api.Command;
 import com.cloud.agent.api.GetDomRVersionAnswer;
 import com.cloud.agent.api.GetDomRVersionCmd;
@@ -132,6 +134,11 @@ 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.Site2SiteCustomerGateway;
+import com.cloud.network.Site2SiteCustomerGatewayVO;
+import com.cloud.network.Site2SiteVpnConnection;
+import com.cloud.network.Site2SiteVpnConnectionVO;
+import com.cloud.network.Site2SiteVpnGatewayVO;
 import com.cloud.network.SshKeysDistriMonitor;
 import com.cloud.network.VirtualNetworkApplianceService;
 import com.cloud.network.VirtualRouterProvider;
@@ -165,6 +172,7 @@ import com.cloud.network.rules.StaticNat;
 import com.cloud.network.rules.StaticNatImpl;
 import com.cloud.network.rules.StaticNatRule;
 import com.cloud.network.rules.dao.PortForwardingRulesDao;
+import com.cloud.network.vpn.Site2SiteVpnManager;
 import com.cloud.offering.ServiceOffering;
 import com.cloud.offerings.NetworkOfferingVO;
 import com.cloud.offerings.dao.NetworkOfferingDao;
@@ -318,6 +326,8 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
     Site2SiteVpnGatewayDao _s2sVpnGatewayDao;
     @Inject
     Site2SiteVpnConnectionDao _s2sVpnConnectionDao;
+    @Inject
+    Site2SiteVpnManager _s2sVpnMgr;
     
     int _routerRamSize;
     int _routerCpuMHz;
@@ -901,7 +911,79 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
         }
     }
 
-
+    protected void updateSite2SiteVpnConnectionState(List<DomainRouterVO> routers) {
+        for (DomainRouterVO router : routers) {
+            List<Site2SiteVpnConnectionVO> conns = _s2sVpnMgr.getConnectionsForRouter(router);
+            if (conns == null || conns.isEmpty()) {
+                continue;
+            }
+            if (router.getState() != State.Running) {
+                for (Site2SiteVpnConnectionVO conn : conns) {
+                    conn.setState(Site2SiteVpnConnection.State.Disconnected);
+                    _s2sVpnConnectionDao.persist(conn);
+                }
+                continue;
+            }
+            List<String> ipList = new ArrayList<String>();
+            for (Site2SiteVpnConnectionVO conn : conns) {
+                if (conn.getState() != Site2SiteVpnConnection.State.Connected &&
+                        conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
+                    continue;
+                }
+                Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
+                ipList.add(gw.getGatewayIp());
+            }
+            String privateIP = router.getPrivateIpAddress();
+            HostVO host = _hostDao.findById(router.getHostId());
+            if (host == null || host.getStatus() != Status.Up) {
+                continue;
+            } else if (host.getManagementServerId() != ManagementServerNode.getManagementServerId()) {
+                /* Only cover hosts managed by this management server */
+                continue;
+            } else if (privateIP != null) {
+                final CheckS2SVpnConnectionsCommand command = new CheckS2SVpnConnectionsCommand(ipList);
+                command.setAccessDetail(NetworkElementCommand.ROUTER_IP, getRouterControlIp(router.getId()));
+                command.setAccessDetail(NetworkElementCommand.ROUTER_NAME, router.getInstanceName());
+                command.setWait(30);
+                final Answer origAnswer = _agentMgr.easySend(router.getHostId(), command);
+                CheckS2SVpnConnectionsAnswer answer = null;
+                if (origAnswer instanceof CheckS2SVpnConnectionsAnswer) {
+                    answer = (CheckS2SVpnConnectionsAnswer)origAnswer;
+                } else {
+                    s_logger.warn("Unable to update router " + router.getHostName() + "'s VPN connection status");
+                    continue;
+                }
+                if (!answer.getResult()) {
+                    s_logger.warn("Unable to update router " + router.getHostName() + "'s VPN connection status");
+                    continue;
+                }
+                for (Site2SiteVpnConnectionVO conn : conns) {
+                    if (conn.getState() != Site2SiteVpnConnection.State.Connected &&
+                            conn.getState() != Site2SiteVpnConnection.State.Disconnected) {
+                        continue;
+                    }
+                    Site2SiteVpnConnection.State oldState = conn.getState();
+                    Site2SiteCustomerGateway gw = _s2sCustomerGatewayDao.findById(conn.getCustomerGatewayId());
+                    if (answer.isConnected(gw.getGatewayIp())) {
+                        conn.setState(Site2SiteVpnConnection.State.Connected);
+                    } else {
+                        conn.setState(Site2SiteVpnConnection.State.Disconnected);
+                    }
+                    _s2sVpnConnectionDao.persist(conn);
+                    if (oldState != conn.getState()) {
+                        String title = "Site-to-site Vpn Connection to " + gw.getName() +
+                                " just switch from " + oldState + " to " + conn.getState();
+                        String context = "Site-to-site Vpn Connection to " + gw.getName() + " on router " + router.getHostName() + 
+                                "(id: " + router.getId() + ") " + " just switch from " + oldState + " to " + conn.getState();
+                        s_logger.info(context);
+                        _alertMgr.sendAlert(AlertManager.ALERT_TYPE_DOMAIN_ROUTER,
+                                router.getDataCenterIdToDeployIn(), router.getPodIdToDeployIn(), title, context);
+                    }
+                }
+            }
+        }
+    }
+    
     protected void updateRoutersRedundantState(List<DomainRouterVO> routers) {
         boolean updated = false;
         for (DomainRouterVO router : routers) {
@@ -1094,6 +1176,7 @@ public class VirtualNetworkApplianceManagerImpl implements VirtualNetworkApplian
                 s_logger.debug("Found " + routers.size() + " routers. ");
 
                 updateRoutersRedundantState(routers);
+                updateSite2SiteVpnConnectionState(routers);
 
                 /* FIXME assumed the a pair of redundant routers managed by same mgmt server,
                  * then the update above can get the latest status */

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/server/src/com/cloud/network/vpn/Site2SiteVpnManager.java
----------------------------------------------------------------------
diff --git a/server/src/com/cloud/network/vpn/Site2SiteVpnManager.java b/server/src/com/cloud/network/vpn/Site2SiteVpnManager.java
index a44c361..567b765 100644
--- a/server/src/com/cloud/network/vpn/Site2SiteVpnManager.java
+++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManager.java
@@ -1,7 +1,13 @@
 package com.cloud.network.vpn;
 
+import java.util.List;
+
+import com.cloud.network.Site2SiteVpnConnectionVO;
+import com.cloud.vm.DomainRouterVO;
+
 public interface Site2SiteVpnManager extends Site2SiteVpnService {
     boolean cleanupVpnConnectionByVpc(long vpcId);
     boolean cleanupVpnGatewayByVpc(long vpcId);
     void markDisconnectVpnConnByVpc(long vpcId);
+    List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router);
 }

http://git-wip-us.apache.org/repos/asf/incubator-cloudstack/blob/8eee8f34/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 0abedef..0647de5 100644
--- a/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
+++ b/server/src/com/cloud/network/vpn/Site2SiteVpnManagerImpl.java
@@ -60,6 +60,7 @@ import com.cloud.utils.db.SearchBuilder;
 import com.cloud.utils.db.SearchCriteria;
 import com.cloud.utils.exception.CloudRuntimeException;
 import com.cloud.utils.net.NetUtils;
+import com.cloud.vm.DomainRouterVO;
 
 @Local(value = { Site2SiteVpnManager.class, Site2SiteVpnService.class } )
 public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
@@ -591,4 +592,16 @@ public class Site2SiteVpnManagerImpl implements Site2SiteVpnManager, Manager {
             }
         }
     }
+
+    @Override
+    public List<Site2SiteVpnConnectionVO> getConnectionsForRouter(DomainRouterVO router) {
+        List<Site2SiteVpnConnectionVO> conns = new ArrayList<Site2SiteVpnConnectionVO>();
+        // One router for one VPC
+        Long vpcId = router.getVpcId();
+        if (router.getVpcId() == null) {
+            return conns;
+        }
+        conns.addAll(_vpnConnectionDao.listByVpcId(vpcId));
+        return conns;
+    }
 }