diff --git a/api/src/com/cloud/network/ovs/OvsFetchInterfaceAnswer.java b/api/src/com/cloud/network/ovs/OvsFetchInterfaceAnswer.java
new file mode 100644
index 00000000000..53c0c13ee2f
--- /dev/null
+++ b/api/src/com/cloud/network/ovs/OvsFetchInterfaceAnswer.java
@@ -0,0 +1,59 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.network.ovs;
+
+import com.cloud.agent.api.Answer;
+import com.cloud.agent.api.Command;
+
+public class OvsFetchInterfaceAnswer extends Answer {
+ String ip;
+ String netmask;
+ String mac;
+ String label;
+
+ public OvsFetchInterfaceAnswer(Command cmd, boolean success, String details) {
+ super(cmd, success, details);
+ this.label = ((OvsFetchInterfaceCommand)cmd).getLabel();
+ }
+
+ public OvsFetchInterfaceAnswer(Command cmd, boolean success,
+ String details, String ip, String netmask, String mac) {
+ super(cmd, success, details);
+ this.ip = ip;
+ this.netmask = netmask;
+ this.mac = mac;
+ this.label = ((OvsFetchInterfaceCommand)cmd).getLabel();
+ }
+
+ public String getIp() {
+ return ip;
+ }
+
+ public String getNetmask() {
+ return netmask;
+ }
+
+ public String getMac() {
+ return mac;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+}
diff --git a/api/src/com/cloud/network/ovs/OvsFetchInterfaceCommand.java b/api/src/com/cloud/network/ovs/OvsFetchInterfaceCommand.java
new file mode 100644
index 00000000000..4e42506a4fd
--- /dev/null
+++ b/api/src/com/cloud/network/ovs/OvsFetchInterfaceCommand.java
@@ -0,0 +1,39 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.network.ovs;
+
+import com.cloud.agent.api.Command;
+
+public class OvsFetchInterfaceCommand extends Command {
+ String label;
+
+ @Override
+ public boolean executeInSequence() {
+ return true;
+ }
+
+ public OvsFetchInterfaceCommand(String label) {
+ this.label = label;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+}
diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
index f762689ee82..8164b57a521 100644
--- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
+++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java
@@ -179,6 +179,8 @@ import com.cloud.network.ovs.OvsCreateTunnelCommand;
import com.cloud.network.ovs.OvsDeleteFlowCommand;
import com.cloud.network.ovs.OvsDestroyBridgeCommand;
import com.cloud.network.ovs.OvsDestroyTunnelCommand;
+import com.cloud.network.ovs.OvsFetchInterfaceAnswer;
+import com.cloud.network.ovs.OvsFetchInterfaceCommand;
import com.cloud.network.ovs.OvsSetTagAndFlowAnswer;
import com.cloud.network.ovs.OvsSetTagAndFlowCommand;
import com.cloud.network.ovs.OvsSetupBridgeCommand;
@@ -210,6 +212,7 @@ import com.xensource.xenapi.HostMetrics;
import com.xensource.xenapi.Network;
import com.xensource.xenapi.PBD;
import com.xensource.xenapi.PIF;
+import com.xensource.xenapi.PIF.Record;
import com.xensource.xenapi.Pool;
import com.xensource.xenapi.SR;
import com.xensource.xenapi.Session;
@@ -478,6 +481,8 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
return execute((CheckSshCommand)cmd);
} else if (clazz == SecurityGroupRulesCmd.class) {
return execute((SecurityGroupRulesCmd) cmd);
+ } else if (clazz == OvsFetchInterfaceCommand.class) {
+ return execute((OvsFetchInterfaceCommand)cmd);
} else if (clazz == OvsCreateGreTunnelCommand.class) {
return execute((OvsCreateGreTunnelCommand)cmd);
} else if (clazz == OvsSetTagAndFlowCommand.class) {
@@ -4940,6 +4945,28 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
}
+ private OvsFetchInterfaceAnswer execute(OvsFetchInterfaceCommand cmd) {
+
+ String label = cmd.getLabel();
+ s_logger.debug("### Will look for network with name-label:" + label + " on host " + _host.ip);
+ Connection conn = getConnection();
+ try {
+ XsLocalNetwork nw = this.getNetworkByName(conn, label);
+ s_logger.debug("### Network object:" + nw.getNetwork().getUuid(conn));
+ PIF pif = nw.getPif(conn);
+ Record pifRec = pif.getRecord(conn);
+ s_logger.debug("### PIF object:" + pifRec.uuid + "(" + pifRec.device + ")");
+ return new OvsFetchInterfaceAnswer(cmd, true, "Interface " + pifRec.device + " retrieved successfully",
+ pifRec.IP, pifRec.netmask, pifRec.MAC);
+ } catch (Exception e) {
+ e.printStackTrace();
+ return new OvsFetchInterfaceAnswer(cmd, false, "EXCEPTION:" + e.getMessage());
+ }
+
+
+ }
+
+
private OvsCreateGreTunnelAnswer execute(OvsCreateGreTunnelCommand cmd) {
_isOvs = true;
diff --git a/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java b/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
index 62826ec6d08..50a82427506 100644
--- a/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
+++ b/server/src/com/cloud/network/ovs/OvsTunnelManagerImpl.java
@@ -33,7 +33,15 @@ import com.cloud.configuration.dao.ConfigurationDao;
import com.cloud.deploy.DeployDestination;
import com.cloud.host.HostVO;
import com.cloud.host.dao.HostDao;
+import com.cloud.hypervisor.Hypervisor.HypervisorType;
import com.cloud.network.Network;
+import com.cloud.network.Networks.TrafficType;
+import com.cloud.network.PhysicalNetwork;
+import com.cloud.network.PhysicalNetworkTrafficType;
+import com.cloud.network.dao.PhysicalNetworkDao;
+import com.cloud.network.dao.PhysicalNetworkTrafficTypeDao;
+import com.cloud.network.ovs.dao.OvsTunnelInterfaceDao;
+import com.cloud.network.ovs.dao.OvsTunnelInterfaceVO;
import com.cloud.network.ovs.dao.OvsTunnelNetworkDao;
import com.cloud.network.ovs.dao.OvsTunnelNetworkVO;
import com.cloud.utils.component.Inject;
@@ -62,9 +70,11 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
@Inject ConfigurationDao _configDao;
@Inject NicDao _nicDao;
@Inject HostDao _hostDao;
+ @Inject PhysicalNetworkTrafficTypeDao _physNetTTDao;
@Inject UserVmDao _userVmDao;
@Inject DomainRouterDao _routerDao;
@Inject OvsTunnelNetworkDao _tunnelNetworkDao;
+ @Inject OvsTunnelInterfaceDao _tunnelInterfaceDao;
@Inject AgentManager _agentMgr;
@Override
@@ -101,6 +111,40 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
return ta;
}
+ @DB
+ protected OvsTunnelInterfaceVO createInterfaceRecord(String ip, String netmask, String mac,
+ long hostId, String label) {
+ OvsTunnelInterfaceVO ti = null;
+ try {
+ ti = new OvsTunnelInterfaceVO(ip, netmask, mac, hostId, label);
+ //TODO: Is locking really necessary here?
+ OvsTunnelInterfaceVO lock = _tunnelInterfaceDao.acquireInLockTable(Long.valueOf(1));
+ if (lock == null) {
+ s_logger.warn("Cannot lock table ovs_tunnel_account");
+ return null;
+ }
+ _tunnelInterfaceDao.persist(ti);
+ _tunnelInterfaceDao.releaseFromLockTable(lock.getId());
+ } catch (EntityExistsException e) {
+ s_logger.debug("A record for the interface for network " + label +
+ " on host id " + hostId + " already exists");
+ }
+ return ti;
+ }
+
+
+ private String handleFetchInterfaceAnswer(Answer[] answers, Long hostId){
+ OvsFetchInterfaceAnswer ans = (OvsFetchInterfaceAnswer) answers[0];
+ String s = String.format(
+ "(ip:%1$s, netmask:%2$s, mac:%3$s, label:%4s, host:%5l)",
+ ans.getIp(), ans.getNetmask(), ans.getMac(), ans.getLabel(), hostId);
+ s_logger.debug("### About to add DB entry for:" + s);
+ OvsTunnelInterfaceVO ti = createInterfaceRecord(ans.getIp(), ans.getNetmask(), ans.getMac(),
+ hostId, ans.getLabel());
+ s_logger.debug("### Interface added to DB - id:" + ti.getId());
+ return ti.getIp();
+ }
+
private void handleCreateTunnelAnswer(Answer[] answers){
OvsCreateTunnelAnswer r = (OvsCreateTunnelAnswer) answers[0];
String s = String.format(
@@ -203,9 +247,43 @@ public class OvsTunnelManagerImpl implements OvsTunnelManager {
}
//FIXME: Why are we cancelling the exception here?
try {
- //HACK HACK HACK - Should not use public IP
- String myIp = dest.getHost().getPublicIpAddress();
- boolean noHost = true;
+ String myIp = null;
+ // Fetch physical network and associated tags
+ // If no tag specified, look for this network
+ // TODO: Should we Make this a configuration option?
+ String physNetLabel = "cloud-public";
+ Long physNetId = nw.getPhysicalNetworkId();
+ PhysicalNetworkTrafficType physNetTT = _physNetTTDao.findBy(physNetId, TrafficType.Guest);
+ s_logger.debug("### Physical network:" + physNetId + " - traffic type:" + physNetTT.getUuid());
+ HypervisorType hvType = dest.getHost().getHypervisorType();
+
+ switch (hvType) {
+ case XenServer:
+ String label = physNetTT.getXenNetworkLabel();
+ if ((label!=null) && (!label.equals(""))) {
+ physNetLabel = label;
+ }
+ break;
+ default:
+ throw new CloudRuntimeException("Hypervisor " + hvType.toString() + " unsupported by OVS Tunnel Manager");
+ }
+
+ // Try to fetch GRE endpoint IP address for cloud db
+ // If not found, then find it on the hypervisor
+ OvsTunnelInterfaceVO tunnelIface = _tunnelInterfaceDao.getByHostAndLabel(hostId, physNetLabel);
+ if (tunnelIface == null) {
+ //Now find and fetch configuration for physical interface for network with label on target host
+ Commands fetchIfaceCmds = new Commands(new OvsFetchInterfaceCommand(physNetLabel));
+ s_logger.debug("Ask host " + hostId + " to retrieve interface for phy net with label:" + physNetLabel);
+ Answer[] fetchIfaceAnswers = _agentMgr.send(hostId, fetchIfaceCmds);
+
+ //And finally save it for future use
+ myIp = handleFetchInterfaceAnswer(fetchIfaceAnswers, hostId);
+ } else {
+ myIp = tunnelIface.getIp();
+ }
+
+ boolean noHost = true;
for (Long i : toHostIds) {
HostVO rHost = _hostDao.findById(i);
Commands cmds = new Commands(
diff --git a/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java b/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java
new file mode 100644
index 00000000000..3298ca686a9
--- /dev/null
+++ b/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDao.java
@@ -0,0 +1,32 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.network.ovs.dao;
+
+import java.util.List;
+
+import com.cloud.utils.db.GenericDao;
+
+public interface OvsTunnelInterfaceDao extends
+ GenericDao {
+
+ OvsTunnelInterfaceVO getByHostAndLabel(long hostId, String label);
+
+ List listByLabel(String label);
+
+}
diff --git a/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java b/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java
new file mode 100644
index 00000000000..5adf63d3362
--- /dev/null
+++ b/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceDaoImpl.java
@@ -0,0 +1,65 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.network.ovs.dao;
+
+import java.util.List;
+
+import javax.ejb.Local;
+
+import com.cloud.utils.db.GenericDaoBase;
+import com.cloud.utils.db.SearchBuilder;
+import com.cloud.utils.db.SearchCriteria;
+import com.cloud.utils.db.SearchCriteria.Op;
+
+@Local(value = { OvsTunnelInterfaceDao.class })
+public class OvsTunnelInterfaceDaoImpl extends
+ GenericDaoBase implements OvsTunnelInterfaceDao {
+
+ protected final SearchBuilder hostAndLabelSearch;
+ protected final SearchBuilder labelSearch;
+
+ public OvsTunnelInterfaceDaoImpl() {
+ hostAndLabelSearch = createSearchBuilder();
+ hostAndLabelSearch.and("host_id", hostAndLabelSearch.entity().getHostId(), Op.EQ);
+ hostAndLabelSearch.and("label", hostAndLabelSearch.entity().getLabel(), Op.EQ);
+ hostAndLabelSearch.done();
+
+ labelSearch = createSearchBuilder();
+ labelSearch.and("label", labelSearch.entity().getLabel(), Op.EQ);
+ labelSearch.done();
+
+ }
+
+ @Override
+ public OvsTunnelInterfaceVO getByHostAndLabel(long hostId, String label) {
+ SearchCriteria sc = hostAndLabelSearch.create();
+ sc.setParameters("host_id", hostId);
+ sc.setParameters("label", label);
+ return findOneBy(sc);
+ }
+
+ @Override
+ public List listByLabel(String label) {
+ SearchCriteria sc = labelSearch.create();
+ sc.setParameters("label", label);
+ return listBy(sc);
+ }
+
+
+}
diff --git a/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java b/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java
new file mode 100644
index 00000000000..0b2699dcf4c
--- /dev/null
+++ b/server/src/com/cloud/network/ovs/dao/OvsTunnelInterfaceVO.java
@@ -0,0 +1,111 @@
+/**
+ * Copyright (C) 2010 Cloud.com, Inc. All rights reserved.
+ *
+ * This software is licensed under the GNU General Public License v3 or later.
+ *
+ * It is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or any later version.
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+package com.cloud.network.ovs.dao;
+
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.Table;
+
+@Entity
+@Table(name=("ovs_tunnel_interface"))
+public class OvsTunnelInterfaceVO {
+ @Id
+ @GeneratedValue(strategy = GenerationType.IDENTITY)
+ @Column(name = "id")
+ private long id;
+
+ @Column(name = "ip")
+ private String ip;
+
+ @Column(name = "netmask")
+ private String netmask;
+
+ @Column(name = "mac")
+ private String mac;
+
+ @Column(name = "host_id")
+ private long hostId;
+
+ @Column(name = "label")
+ private String label;
+
+ public OvsTunnelInterfaceVO() {
+
+ }
+
+ public OvsTunnelInterfaceVO(String ip, String netmask, String mac, long hostId, String label) {
+ this.ip = ip;
+ this.netmask = netmask;
+ this.mac = mac;
+ this.hostId = hostId;
+ this.label = label;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public String getIp() {
+ return ip;
+ }
+
+ public void setIp(String ip) {
+ this.ip = ip;
+ }
+
+ public String getNetmask() {
+ return netmask;
+ }
+
+ public void setNetmask(String netmask) {
+ this.netmask = netmask;
+ }
+
+ public String getMac() {
+ return mac;
+ }
+
+ public void setMac(String mac) {
+ this.mac = mac;
+ }
+
+ public long getHostId() {
+ return hostId;
+ }
+
+ public void setHostId(long hostId) {
+ this.hostId = hostId;
+ }
+
+ public String getLabel() {
+ return label;
+ }
+
+ public void setLabel(String label) {
+ this.label = label;
+ }
+
+}