diff --git a/api/src/com/cloud/network/ovs/OvsCreateTunnelCommand.java b/api/src/com/cloud/network/ovs/OvsCreateTunnelCommand.java index c05cb9d5edd..df16618f21e 100644 --- a/api/src/com/cloud/network/ovs/OvsCreateTunnelCommand.java +++ b/api/src/com/cloud/network/ovs/OvsCreateTunnelCommand.java @@ -30,7 +30,6 @@ public class OvsCreateTunnelCommand extends Command { } public OvsCreateTunnelCommand(String remoteIp, Integer key, Long from, Long to, long networkId, String fromIp) { - this.remoteIp = remoteIp; this.key = key; this.from = from; diff --git a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java index 10bf81254c8..ffdfb62624a 100644 --- a/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java +++ b/core/src/com/cloud/hypervisor/xen/resource/CitrixResourceBase.java @@ -492,6 +492,170 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe return execute((OvsCreateTunnelCommand)cmd); } else if (clazz == OvsSetupBridgeCommand.class) { return execute((OvsSetupBridgeCommand)cmd); + } else if (clazz == OvsDestroyBridgeCommand.class) { + return execute((OvsDestroyBridgeCommand)cmd); + } else if (clazz == OvsDestroyTunnelCommand.class) { + return execute((OvsDestroyTunnelCommand)cmd); + } else if (clazz == UpdateHostPasswordCommand.class) { + return execute((UpdateHostPasswordCommand)cmd); + } else if (cmd instanceof CheckRouterCommand) { + return execute((CheckRouterCommand)cmd); + } else if (cmd instanceof SetFirewallRulesCommand) { + return execute((SetFirewallRulesCommand)cmd); + } else if (cmd instanceof BumpUpPriorityCommand) { + return execute((BumpUpPriorityCommand)cmd); + } else if (cmd instanceof ClusterSyncCommand) { + return execute((ClusterSyncCommand)cmd); + } else if (cmd instanceof GetDomRVersionCmd) { + return execute((GetDomRVersionCmd)cmd); + } else if (clazz == CheckNetworkCommand.class) { + return execute((CheckNetworkCommand) cmd); + } else { + return Answer.createUnsupportedCommandAnswer(cmd); + } + } + + + protected XsLocalNetwork getNativeNetworkForTraffic(Connection conn, TrafficType type, String name) throws XenAPIException, XmlRpcException { + if (name != null) { + if (s_logger.isDebugEnabled()) { + s_logger.debug("Looking for network named " + name); + } + return getNetworkByName(conn, name); + } + + if (type == TrafficType.Guest) { + return new XsLocalNetwork(Network.getByUuid(conn, _host.guestNetwork), null, PIF.getByUuid(conn, _host.guestPif), null); + } else if (type == TrafficType.Control) { + setupLinkLocalNetwork(conn); + return new XsLocalNetwork(Network.getByUuid(conn, _host.linkLocalNetwork)); + } else if (type == TrafficType.Management) { + return new XsLocalNetwork(Network.getByUuid(conn, _host.privateNetwork), null, PIF.getByUuid(conn, _host.privatePif), null); + } else if (type == TrafficType.Public) { + return new XsLocalNetwork(Network.getByUuid(conn, _host.publicNetwork), null, PIF.getByUuid(conn, _host.publicPif), null); + } else if (type == TrafficType.Storage) { + return new XsLocalNetwork(Network.getByUuid(conn, _host.storageNetwork1), null, PIF.getByUuid(conn, _host.storagePif1), null); + } + + throw new CloudRuntimeException("Unsupported network type: " + type); + } + + /** + * This is a tricky to create network in xenserver. + * if you create a network then create bridge by brctl or openvswitch yourself, + * then you will get an expection that is "REQUIRED_NETWROK" when you start a + * vm with this network. The soultion is, create a vif of dom0 and plug it in + * network, xenserver will create the bridge on behalf of you + * @throws XmlRpcException + * @throws XenAPIException + */ + private void enableXenServerNetwork(Connection conn, Network nw, + String vifNameLabel, String networkDesc) throws XenAPIException, XmlRpcException { + /* Make sure there is a physical bridge on this network */ + VIF dom0vif = null; + Pair vm = getControlDomain(conn); + VM dom0 = vm.first(); + // Create a VIF unless there's not already another VIF + Set dom0Vifs = dom0.getVIFs(conn); + for (VIF vif:dom0Vifs) { + vif.getRecord(conn); + if (vif.getNetwork(conn).getUuid(conn) == nw.getUuid(conn)) { + dom0vif = vif; + s_logger.debug("### A dom0 VIF has already been found - No need to create one"); + } + } + if (dom0vif == null) { + s_logger.debug("Create a vif on dom0 for " + networkDesc); + VIF.Record vifr = new VIF.Record(); + vifr.VM = dom0; + vifr.device = getLowestAvailableVIFDeviceNum(conn, dom0); + if (vifr.device == null) { + s_logger.debug("Failed to create " + networkDesc + ", no vif available"); + return; + } + Map config = new HashMap(); + config.put("nameLabel", vifNameLabel); + vifr.otherConfig = config; + vifr.MAC = "FE:FF:FF:FF:FF:FF"; + vifr.network = nw; + + dom0vif = VIF.create(conn, vifr); + } + // At this stage we surely have a VIF + dom0vif.plug(conn); + dom0vif.unplug(conn); + synchronized(_tmpDom0Vif) { + _tmpDom0Vif.add(dom0vif); + } + + } + + private synchronized Network setupvSwitchNetwork(Connection conn) { + try { + if (_host.vswitchNetwork == null) { + Network vswitchNw = null; + Network.Record rec = new Network.Record(); + String nwName = Networks.BroadcastScheme.VSwitch.toString(); + Set networks = Network.getByNameLabel(conn, nwName); + + if (networks.size() == 0) { + rec.nameDescription = "vswitch network for " + nwName; + rec.nameLabel = nwName; + vswitchNw = Network.create(conn, rec); + } else { + vswitchNw = networks.iterator().next(); + } + + enableXenServerNetwork(conn, vswitchNw, "vswitch", "vswicth network"); + _host.vswitchNetwork = vswitchNw; + } + return _host.vswitchNetwork; + } catch (Exception e) { + e.printStackTrace(); + } + + return null; + } + + /** + * This method just creates a XenServer network following the tunnel network naming convention + */ + private synchronized Network findOrCreateTunnelNetwork(Connection conn, long networkId) { + try { + String nwName = "OVSTunnel" + networkId; + Network nw = null; + Network.Record rec = new Network.Record(); + Set networks = Network.getByNameLabel(conn, nwName); + + if (networks.size() == 0) { + rec.nameDescription = "tunnel network id# " + networkId; + rec.nameLabel = nwName; + //Initialize the ovs-host-setup to avoid error when doing get-param in plugin + Map otherConfig = new HashMap(); + otherConfig.put("ovs-host-setup", ""); + rec.otherConfig = otherConfig; + nw = Network.create(conn, rec); + // Plug dom0 vif only when creating network + enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + networkId); + s_logger.debug("### Xen Server network for tunnels created:" + nwName); + } else { + nw = networks.iterator().next(); + s_logger.debug("### Xen Server network for tunnels found:" + nwName); + } + return nw; + } catch (Exception e) { + s_logger.warn("createTunnelNetwork failed", e); + return null; + } + } + + /** + * This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network + */ + private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, int key) { + try { + Network nw = findOrCreateTunnelNetwork(conn, networkId); +>>>>>>> fb7dcaa... Now using vnets instead of network id for creating networks //Invoke plugin to setup the bridge which will be used by this network String bridge = nw.getBridge(conn); Map nwOtherConfig = nw.getOtherConfig(conn); @@ -4648,7 +4812,7 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe Connection conn = getConnection(); s_logger.debug("### About to destroy tunnel network"); try { - Network nw = findTunnelNetwork(conn, cmd.getNetworkId()); + Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkId()); if (nw == null) { s_logger.warn("### Unable to find tunnel network"); return new Answer(cmd, false, "No network found"); diff --git a/scripts/vm/hypervisor/xenserver/xenserver56fp1/ovs-vif-flows.py b/scripts/vm/hypervisor/xenserver/xenserver56fp1/ovs-vif-flows.py index 937c892224c..e2d7b423f4e 100644 --- a/scripts/vm/hypervisor/xenserver/xenserver56fp1/ovs-vif-flows.py +++ b/scripts/vm/hypervisor/xenserver/xenserver56fp1/ovs-vif-flows.py @@ -77,15 +77,12 @@ def main(command, vif_raw): if this_vif == vif: this_vif_ofport = vif_ofport vif_ofports.append(vif_ofport) - # So regardless of whether the VIF is brought online or offline we - # will always execute the same action - if command == 'offline': - clear_flows(bridge, this_vif_ofport, vif_ofports) - if command == 'online': - apply_flows(bridge, this_vif_ofport, vif_ofports) - - + if command == 'offline': + clear_flows(bridge, this_vif_ofport, vif_ofports) + + if command == 'online': + apply_flows(bridge, this_vif_ofport, vif_ofports) if __name__ == "__main__": @@ -95,4 +92,4 @@ if __name__ == "__main__": sys.exit(1) else: command, vif_raw = sys.argv[1:3] - main(command, vif_raw) \ No newline at end of file + main(command, vif_raw) diff --git a/server/src/com/cloud/api/ApiResponseHelper.java b/server/src/com/cloud/api/ApiResponseHelper.java index 9147a6a12ce..4ea7492e1e8 100755 --- a/server/src/com/cloud/api/ApiResponseHelper.java +++ b/server/src/com/cloud/api/ApiResponseHelper.java @@ -3355,12 +3355,12 @@ public class ApiResponseHelper implements ResponseGenerator { response.setNetmask(result.getNetmask()); response.setGateway(result.getGateway()); response.setObjectName("storagenetworkiprange"); - return response; + return response; } @Override public Long getIdentiyId(String tableName, String token) { return ApiDispatcher.getIdentiyId(tableName, token); - } - -} + } + +}