From 2340ebced38246427d9fadc7ea4b85851d3feb61 Mon Sep 17 00:00:00 2001 From: Salvatore Orlando Date: Fri, 16 Mar 2012 13:55:53 +0000 Subject: [PATCH] Now using vnets instead of network id for creating networks Fixed issues with vif scripts on 5.6FP1 Fixed ipv6 issue on 5.6FP1 Plus other various fixes and improvements Starting to remove debug code NOTE: Network is configured correctly but instances do not start. Possibly indefinite wait occuring on some commands --- .../network/ovs/OvsCreateTunnelCommand.java | 1 - .../xen/resource/CitrixResourceBase.java | 166 +++++++++++++++++- .../xenserver/xenserver56fp1/ovs-vif-flows.py | 15 +- .../src/com/cloud/api/ApiResponseHelper.java | 8 +- 4 files changed, 175 insertions(+), 15 deletions(-) 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); - } - -} + } + +}