Skip to content

Commit e045883

Browse files
committed
introduce OvsNetworkTopologyGuru that has convinenace functions to
- get the hosts on which VPC spans given vpc id - get the VM's in the VPC - get the hosts on which a network spans - get the VPC's to which a hosts is part of - get VM's of a VPC on a hosts introduces capability to build a physical toplogy representation of a VPC. This json file is encapsulated in OvsVpcPhysicalTopologyConfigCommand, and is used to send full topology to hypervisor hosts. On hypervisor this json config can be used to setup tunnels, configure bridge, add flow rules etc Ovs GURU, to use different broasdcast scheme VS://vpcid.gerkey for the networks in VPC that use distributed routing each VIF and tunnel interface to carry the network UUID in other/options config
1 parent 100df92 commit e045883

19 files changed

Lines changed: 737 additions & 160 deletions

File tree

api/src/com/cloud/agent/api/to/NicTO.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,4 +80,12 @@ public void setNicSecIps(List<String> secIps) {
8080
public List<String> getNicSecIps() {
8181
return nicSecIps;
8282
}
83+
84+
public String getNetworkUuid() {
85+
return super.getUuid();
86+
}
87+
88+
public void setNetworkUuid(String uuid) {
89+
super.setUuid(uuid);
90+
}
8391
}

plugins/hypervisors/kvm/src/com/cloud/hypervisor/kvm/resource/LibvirtComputingResource.java

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1388,23 +1388,22 @@ private OvsFetchInterfaceAnswer execute(OvsFetchInterfaceCommand cmd) {
13881388
}
13891389

13901390
private Answer execute(OvsSetupBridgeCommand cmd) {
1391-
findOrCreateTunnelNetwork(cmd.getKey());
1391+
findOrCreateTunnelNetwork(cmd.getBridgeName());
13921392
configureTunnelNetwork(cmd.getNetworkId(), cmd.getHostId(),
1393-
cmd.getKey());
1393+
cmd.getBridgeName());
13941394
s_logger.debug("OVS Bridge configured");
13951395
return new Answer(cmd, true, null);
13961396
}
13971397

13981398
private Answer execute(OvsDestroyBridgeCommand cmd) {
1399-
destroyTunnelNetwork(cmd.getKey());
1399+
destroyTunnelNetwork(cmd.getBridgeName());
14001400
s_logger.debug("OVS Bridge destroyed");
14011401
return new Answer(cmd, true, null);
14021402
}
14031403

1404-
private synchronized void destroyTunnelNetwork(int key) {
1404+
private synchronized void destroyTunnelNetwork(String bridge) {
14051405
try {
1406-
findOrCreateTunnelNetwork(key);
1407-
String bridge = "OVSTunnel" + key;
1406+
findOrCreateTunnelNetwork(bridge);
14081407
Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
14091408
cmd.add("destroy_ovs_bridge");
14101409
cmd.add("--bridge", bridge);
@@ -1423,9 +1422,8 @@ private synchronized void destroyTunnelNetwork(int key) {
14231422
}
14241423
}
14251424

1426-
private synchronized boolean findOrCreateTunnelNetwork(long key) {
1425+
private synchronized boolean findOrCreateTunnelNetwork(String nwName) {
14271426
try {
1428-
String nwName = "OVSTunnel" + key;
14291427
if (checkNetwork(nwName)) {
14301428
return true;
14311429
}
@@ -1443,10 +1441,9 @@ private synchronized boolean findOrCreateTunnelNetwork(long key) {
14431441
}
14441442

14451443
private synchronized boolean configureTunnelNetwork(long networkId,
1446-
long hostId, int key) {
1444+
long hostId, String nwName) {
14471445
try {
1448-
findOrCreateTunnelNetwork(key);
1449-
String nwName = "OVSTunnel" + key;
1446+
findOrCreateTunnelNetwork(nwName);
14501447
String configuredHosts = Script
14511448
.runSimpleBashScript("ovs-vsctl get bridge " + nwName
14521449
+ " other_config:ovs_host_setup");
@@ -1463,7 +1460,7 @@ private synchronized boolean configureTunnelNetwork(long networkId,
14631460
if (!configured) {
14641461
Script cmd = new Script(_ovsTunnelPath, _timeout, s_logger);
14651462
cmd.add("setup_ovs_bridge");
1466-
cmd.add("--key", String.valueOf(key));
1463+
cmd.add("--key", nwName);
14671464
cmd.add("--cs_host_id", ((Long)hostId).toString());
14681465
cmd.add("--bridge", nwName);
14691466
String result = cmd.execute();
@@ -1481,16 +1478,16 @@ private synchronized boolean configureTunnelNetwork(long networkId,
14811478
}
14821479

14831480
private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) {
1484-
String bridge = "OVSTunnel" + cmd.getKey();
1481+
String bridge = cmd.getNetworkName();
14851482
try {
1486-
if (!findOrCreateTunnelNetwork(cmd.getKey())) {
1483+
if (!findOrCreateTunnelNetwork(bridge)) {
14871484
s_logger.debug("Error during bridge setup");
14881485
return new OvsCreateTunnelAnswer(cmd, false,
14891486
"Cannot create network", bridge);
14901487
}
14911488

14921489
configureTunnelNetwork(cmd.getNetworkId(), cmd.getFrom(),
1493-
cmd.getKey());
1490+
cmd.getNetworkName());
14941491
Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
14951492
command.add("create_tunnel");
14961493
command.add("--bridge", bridge);
@@ -1515,16 +1512,15 @@ private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) {
15151512

15161513
private Answer execute(OvsDestroyTunnelCommand cmd) {
15171514
try {
1518-
if (!findOrCreateTunnelNetwork(cmd.getKey())) {
1515+
if (!findOrCreateTunnelNetwork(cmd.getBridgeName())) {
15191516
s_logger.warn("Unable to find tunnel network for GRE key:"
1520-
+ cmd.getKey());
1517+
+ cmd.getBridgeName());
15211518
return new Answer(cmd, false, "No network found");
15221519
}
15231520

1524-
String bridge = "OVSTunnel" + cmd.getKey();
15251521
Script command = new Script(_ovsTunnelPath, _timeout, s_logger);
15261522
command.add("destroy_tunnel");
1527-
command.add("--bridge", bridge);
1523+
command.add("--bridge", cmd.getBridgeName());
15281524
command.add("--iface_name", cmd.getInPortName());
15291525
String result = command.execute();
15301526
if (result == null) {

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

Lines changed: 68 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
import com.cloud.agent.api.OvsSetTagAndFlowAnswer;
149149
import com.cloud.agent.api.OvsSetTagAndFlowCommand;
150150
import com.cloud.agent.api.OvsSetupBridgeCommand;
151+
import com.cloud.agent.api.OvsVpcPhysicalTopologyConfigCommand;
151152
import com.cloud.agent.api.PerformanceMonitorAnswer;
152153
import com.cloud.agent.api.PerformanceMonitorCommand;
153154
import com.cloud.agent.api.PingCommand;
@@ -507,6 +508,8 @@ public Answer executeRequest(Command cmd) {
507508
return execute((OvsSetTagAndFlowCommand)cmd);
508509
} else if (clazz == OvsDeleteFlowCommand.class) {
509510
return execute((OvsDeleteFlowCommand)cmd);
511+
} else if (clazz == OvsVpcPhysicalTopologyConfigCommand.class) {
512+
return execute((OvsVpcPhysicalTopologyConfigCommand) cmd);
510513
} else if (clazz == CleanupNetworkRulesCmd.class) {
511514
return execute((CleanupNetworkRulesCmd)cmd);
512515
} else if (clazz == NetworkRulesSystemVmCommand.class) {
@@ -964,15 +967,14 @@ private synchronized Network setupvSwitchNetwork(Connection conn) {
964967
/**
965968
* This method just creates a XenServer network following the tunnel network naming convention
966969
*/
967-
private synchronized Network findOrCreateTunnelNetwork(Connection conn, long key) {
970+
private synchronized Network findOrCreateTunnelNetwork(Connection conn, String nwName) {
968971
try {
969-
String nwName = "OVSTunnel" + key;
970972
Network nw = null;
971973
Network.Record rec = new Network.Record();
972974
Set<Network> networks = Network.getByNameLabel(conn, nwName);
973975

974976
if (networks.size() == 0) {
975-
rec.nameDescription = "tunnel network id# " + key;
977+
rec.nameDescription = "tunnel network id# " + nwName;
976978
rec.nameLabel = nwName;
977979
//Initialize the ovs-host-setup to avoid error when doing get-param in plugin
978980
Map<String, String> otherConfig = new HashMap<String, String>();
@@ -981,7 +983,7 @@ private synchronized Network findOrCreateTunnelNetwork(Connection conn, long key
981983
nw = Network.create(conn, rec);
982984
// Plug dom0 vif only when creating network
983985
if (!is_xcp())
984-
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
986+
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + nwName);
985987
s_logger.debug("### Xen Server network for tunnels created:" + nwName);
986988
} else {
987989
nw = networks.iterator().next();
@@ -997,10 +999,10 @@ private synchronized Network findOrCreateTunnelNetwork(Connection conn, long key
997999
/**
9981000
* This method creates a XenServer network and configures it for being used as a L2-in-L3 tunneled network
9991001
*/
1000-
private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, int key) {
1002+
private synchronized Network configureTunnelNetwork(Connection conn, long networkId, long hostId, String bridgeName) {
10011003
try {
1002-
Network nw = findOrCreateTunnelNetwork(conn, key);
1003-
String nwName = "OVSTunnel" + key;
1004+
Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
1005+
String nwName = bridgeName;
10041006
//Invoke plugin to setup the bridge which will be used by this network
10051007
String bridge = nw.getBridge(conn);
10061008
Map<String, String> nwOtherConfig = nw.getOtherConfig(conn);
@@ -1018,11 +1020,20 @@ private synchronized Network configureTunnelNetwork(Connection conn, long networ
10181020
if (!configured) {
10191021
// Plug dom0 vif only if not done before for network and host
10201022
if (!is_xcp())
1021-
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + key);
1022-
String result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
1023-
"key", String.valueOf(key),
1024-
"xs_nw_uuid", nw.getUuid(conn),
1025-
"cs_host_id", ((Long)hostId).toString());
1023+
enableXenServerNetwork(conn, nw, nwName, "tunnel network for account " + bridgeName);
1024+
String result;
1025+
if (bridgeName.startsWith("OVS-DR-VPC-Bridge")) {
1026+
result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge_for_distributed_routing", "bridge", bridge,
1027+
"key", bridgeName,
1028+
"xs_nw_uuid", nw.getUuid(conn),
1029+
"cs_host_id", ((Long)hostId).toString());
1030+
} else {
1031+
result = callHostPlugin(conn, "ovstunnel", "setup_ovs_bridge", "bridge", bridge,
1032+
"key", bridgeName,
1033+
"xs_nw_uuid", nw.getUuid(conn),
1034+
"cs_host_id", ((Long)hostId).toString());
1035+
}
1036+
10261037
//Note down the fact that the ovs bridge has been setup
10271038
String[] res = result.split(":");
10281039
if (res.length != 2 || !res[0].equalsIgnoreCase("SUCCESS")) {
@@ -1037,9 +1048,9 @@ private synchronized Network configureTunnelNetwork(Connection conn, long networ
10371048
}
10381049
}
10391050

1040-
private synchronized void destroyTunnelNetwork(Connection conn, int key) {
1051+
private synchronized void destroyTunnelNetwork(Connection conn, String bridgeName) {
10411052
try {
1042-
Network nw = findOrCreateTunnelNetwork(conn, key);
1053+
Network nw = findOrCreateTunnelNetwork(conn, bridgeName);
10431054
String bridge = nw.getBridge(conn);
10441055
String result = callHostPlugin(conn, "ovstunnel", "destroy_ovs_bridge", "bridge", bridge);
10451056
String[] res = result.split(":");
@@ -1079,8 +1090,7 @@ protected Network getNetwork(Connection conn, NicTO nic) throws XenAPIException,
10791090
_isOvs = true;
10801091
return setupvSwitchNetwork(conn);
10811092
} else {
1082-
long vnetId = Long.parseLong(BroadcastDomainType.getValue(uri));
1083-
return findOrCreateTunnelNetwork(conn, vnetId);
1093+
return findOrCreateTunnelNetwork(conn, getOvsTunnelNetworkName(BroadcastDomainType.getValue(uri)));
10841094
}
10851095
} else if (type == BroadcastDomainType.Storage) {
10861096
if (uri == null) {
@@ -1102,6 +1112,19 @@ protected Network getNetwork(Connection conn, NicTO nic) throws XenAPIException,
11021112
throw new CloudRuntimeException("Unable to support this type of network broadcast domain: " + nic.getBroadcastUri());
11031113
}
11041114

1115+
private String getOvsTunnelNetworkName(String broadcastUri) {
1116+
if (broadcastUri.contains(".")) {
1117+
String[] parts = broadcastUri.split(".");
1118+
return "OVS-DR-VPC-Bridge"+parts[0];
1119+
} else {
1120+
try {
1121+
return "OVSTunnel" + broadcastUri;
1122+
} catch (Exception e) {
1123+
return null;
1124+
}
1125+
}
1126+
}
1127+
11051128
protected VIF createVif(Connection conn, String vmName, VM vm, VirtualMachineTO vmSpec, NicTO nic) throws XmlRpcException, XenAPIException {
11061129
assert (nic.getUuid() != null) : "Nic should have a uuid value";
11071130

@@ -1122,7 +1145,7 @@ protected VIF createVif(Connection conn, String vmName, VM vm, VirtualMachineTO
11221145
if (vmSpec != null) {
11231146
vifr.otherConfig.put("cloudstack-vm-id", vmSpec.getUuid());
11241147
}
1125-
1148+
vifr.otherConfig.put("cloudstack-network-id", nic.getNetworkUuid());
11261149
vifr.network = getNetwork(conn, nic);
11271150

11281151
if (nic.getNetworkRateMbps() != null && nic.getNetworkRateMbps().intValue() != -1) {
@@ -5220,30 +5243,30 @@ protected boolean can_bridge_firewall(Connection conn) {
52205243

52215244
private Answer execute(OvsSetupBridgeCommand cmd) {
52225245
Connection conn = getConnection();
5223-
findOrCreateTunnelNetwork(conn, cmd.getKey());
5224-
configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getKey());
5246+
findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
5247+
configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getHostId(), cmd.getBridgeName());
52255248
s_logger.debug("OVS Bridge configured");
52265249
return new Answer(cmd, true, null);
52275250
}
52285251

52295252
private Answer execute(OvsDestroyBridgeCommand cmd) {
52305253
Connection conn = getConnection();
5231-
destroyTunnelNetwork(conn, cmd.getKey());
5254+
destroyTunnelNetwork(conn, cmd.getBridgeName());
52325255
s_logger.debug("OVS Bridge destroyed");
52335256
return new Answer(cmd, true, null);
52345257
}
52355258

52365259
private Answer execute(OvsDestroyTunnelCommand cmd) {
52375260
Connection conn = getConnection();
52385261
try {
5239-
Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkId());
5262+
Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
52405263
if (nw == null) {
5241-
s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getKey());
5264+
s_logger.warn("Unable to find tunnel network for GRE key:" + cmd.getBridgeName());
52425265
return new Answer(cmd, false, "No network found");
52435266
}
52445267

52455268
String bridge = nw.getBridge(conn);
5246-
String result = callHostPlugin(conn, "ovstunnel", "destroy_tunnel", "bridge", bridge, "in_port", cmd.getInPortName());
5269+
String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge", bridge, "in_port", cmd.getInPortName());
52475270
if (result.equalsIgnoreCase("SUCCESS")) {
52485271
return new Answer(cmd, true, result);
52495272
} else {
@@ -5255,6 +5278,22 @@ private Answer execute(OvsDestroyTunnelCommand cmd) {
52555278
}
52565279
}
52575280

5281+
public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
5282+
Connection conn = getConnection();
5283+
try {
5284+
String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
5285+
cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString());
5286+
if (result.equalsIgnoreCase("SUCCESS")) {
5287+
return new Answer(cmd, true, result);
5288+
} else {
5289+
return new Answer(cmd, false, result);
5290+
}
5291+
} catch (Exception e) {
5292+
s_logger.warn("caught exception while updating host with latest VPC topology", e);
5293+
return new Answer(cmd, false, e.getMessage());
5294+
}
5295+
}
5296+
52585297
private Answer execute(UpdateHostPasswordCommand cmd) {
52595298
_password.add(cmd.getNewPassword());
52605299
return new Answer(cmd, true, null);
@@ -5264,17 +5303,19 @@ private OvsCreateTunnelAnswer execute(OvsCreateTunnelCommand cmd) {
52645303
Connection conn = getConnection();
52655304
String bridge = "unknown";
52665305
try {
5267-
Network nw = findOrCreateTunnelNetwork(conn, cmd.getKey());
5306+
Network nw = findOrCreateTunnelNetwork(conn, cmd.getNetworkName());
52685307
if (nw == null) {
52695308
s_logger.debug("Error during bridge setup");
52705309
return new OvsCreateTunnelAnswer(cmd, false, "Cannot create network", bridge);
52715310
}
52725311

5273-
configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getKey());
5312+
configureTunnelNetwork(conn, cmd.getNetworkId(), cmd.getFrom(), cmd.getNetworkName());
52745313
bridge = nw.getBridge(conn);
52755314
String result =
5276-
callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(), "key", cmd.getKey().toString(), "from",
5277-
cmd.getFrom().toString(), "to", cmd.getTo().toString());
5315+
callHostPlugin(conn, "ovstunnel", "create_tunnel", "bridge", bridge, "remote_ip", cmd.getRemoteIp(),
5316+
"key", cmd.getKey().toString(), "from",
5317+
cmd.getFrom().toString(), "to", cmd.getTo().toString(), "cloudstack-network-id",
5318+
cmd.getNetworkUuid());
52785319
String[] res = result.split(":");
52795320
if (res.length == 2 && res[0].equalsIgnoreCase("SUCCESS")) {
52805321
return new OvsCreateTunnelAnswer(cmd, true, result, res[1], bridge);

plugins/network-elements/ovs/resources/META-INF/cloudstack/ovs/spring-ovs-context.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,5 +38,5 @@
3838
<bean id="ovsTunnelManagerImpl" class="com.cloud.network.ovs.OvsTunnelManagerImpl" />
3939
<bean id="ovsTunnelInterfaceDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelInterfaceDaoImpl" />
4040
<bean id="ovsTunnelNetworkDaoImpl" class="com.cloud.network.ovs.dao.OvsTunnelNetworkDaoImpl" />
41-
41+
<bean id="ovsNetworkTopologyGuruImpl" class="com.cloud.network.ovs.OvsNetworkTopologyGuruImpl"/>
4242
</beans>

plugins/network-elements/ovs/src/com/cloud/agent/api/OvsCreateTunnelCommand.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,13 @@
2020
public class OvsCreateTunnelCommand extends Command {
2121
Integer key;
2222
String remoteIp;
23+
String networkName;
2324
Long from;
2425
Long to;
2526
long networkId;
2627

28+
String networkUuid;
29+
2730
// for debug info
2831
String fromIp;
2932

@@ -33,13 +36,15 @@ public boolean executeInSequence() {
3336
}
3437

3538
public OvsCreateTunnelCommand(String remoteIp, Integer key, Long from,
36-
Long to, long networkId, String fromIp) {
39+
Long to, long networkId, String fromIp, String networkName, String networkUuid) {
3740
this.remoteIp = remoteIp;
3841
this.key = key;
3942
this.from = from;
4043
this.to = to;
4144
this.networkId = networkId;
4245
this.fromIp = fromIp;
46+
this.networkName = networkName;
47+
this.networkUuid = networkUuid;
4348
}
4449

4550
public Integer getKey() {
@@ -66,4 +71,16 @@ public String getFromIp() {
6671
return fromIp;
6772
}
6873

74+
public String getNetworkName() {
75+
return networkName;
76+
}
77+
78+
79+
public String getNetworkUuid() {
80+
return networkUuid;
81+
}
82+
83+
public void setNetworkUuid(String networkUuid) {
84+
this.networkUuid = networkUuid;
85+
}
6986
}

0 commit comments

Comments
 (0)