mirror of
https://github.com/apache/cloudstack.git
synced 2025-11-04 00:02:37 +01:00
couple of bug fixes
This commit is contained in:
parent
015b667c6a
commit
e487b24bb6
@ -206,6 +206,7 @@ public class VpcVO implements Vpc {
|
||||
@Override
|
||||
public IAMEntityType getEntityType() {
|
||||
return IAMEntityType.Vpc;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean usesDistributedRouter() {
|
||||
|
||||
@ -5284,15 +5284,17 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
public Answer execute(OvsVpcPhysicalTopologyConfigCommand cmd) {
|
||||
Connection conn = getConnection();
|
||||
try {
|
||||
Network nw = findOrCreateTunnelNetwork(conn, cmd.getBridgeName());
|
||||
String bridgeName = nw.getBridge(conn);;
|
||||
String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_network_topology", "bridge",
|
||||
cmd.getBridgeName(), "config", cmd.getVpcConfigInJson());
|
||||
if (result.equalsIgnoreCase("SUCCESS")) {
|
||||
bridgeName, "config", cmd.getVpcConfigInJson(), "host-id", ((Long)cmd.getHostId()).toString());
|
||||
if (result.startsWith("SUCCESS")) {
|
||||
return new Answer(cmd, true, result);
|
||||
} else {
|
||||
return new Answer(cmd, false, result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("caught exception while updating host with latest routing polcies", e);
|
||||
s_logger.warn("caught exception while updating host with latest VPC topology", e);
|
||||
return new Answer(cmd, false, e.getMessage());
|
||||
}
|
||||
}
|
||||
@ -5303,13 +5305,13 @@ public abstract class CitrixResourceBase implements ServerResource, HypervisorRe
|
||||
String result = callHostPlugin(conn, "ovstunnel", "configure_ovs_bridge_for_routing_policies", "bridge",
|
||||
cmd.getBridgeName(), "host-id", ((Long)cmd.getHostId()).toString(), "config",
|
||||
cmd.getVpcConfigInJson());
|
||||
if (result.equalsIgnoreCase("SUCCESS")) {
|
||||
if (result.startsWith("SUCCESS")) {
|
||||
return new Answer(cmd, true, result);
|
||||
} else {
|
||||
return new Answer(cmd, false, result);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.warn("caught exception while updating host with latest VPC topology", e);
|
||||
s_logger.warn("caught exception while updating host with latest routing policies", e);
|
||||
return new Answer(cmd, false, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
@ -56,4 +56,9 @@ public interface OvsNetworkTopologyGuru extends Manager {
|
||||
* get the list of all Vm id's in the network that are running on the host
|
||||
*/
|
||||
public List<Long> getActiveVmsInNetworkOnHost(long vpcId, long hostId);
|
||||
|
||||
/**
|
||||
* get the list of all Vpc id's in which, a VM has a nic in the network that is part of VPC
|
||||
*/
|
||||
public List<Long> getVpcIdsVmIsPartOf(long vmId);
|
||||
}
|
||||
|
||||
@ -187,4 +187,22 @@ public class OvsNetworkTopologyGuruImpl extends ManagerBase implements OvsNetwor
|
||||
}
|
||||
return vmIds;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Long> getVpcIdsVmIsPartOf(long vmId) {
|
||||
List<Long> vpcIds = new ArrayList<>();
|
||||
List<NicVO> nics = _nicDao.listByVmId(vmId);
|
||||
if (nics == null)
|
||||
return null;
|
||||
|
||||
for (Nic nic: nics) {
|
||||
Network network = _networkDao.findById(nic.getNetworkId());
|
||||
if (network != null && network.getTrafficType() == Networks.TrafficType.Guest && network.getVpcId() != null) {
|
||||
if (!vpcIds.contains(network.getVpcId())) {
|
||||
vpcIds.add(network.getVpcId());
|
||||
}
|
||||
}
|
||||
}
|
||||
return vpcIds;
|
||||
}
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import com.cloud.network.vpc.dao.VpcDao;
|
||||
import com.cloud.network.vpc.VpcManager;
|
||||
import com.cloud.network.vpc.VpcVO;
|
||||
import com.cloud.network.vpc.dao.NetworkACLDao;
|
||||
import com.cloud.vm.VMInstanceVO;
|
||||
import com.cloud.vm.dao.VMInstanceDao;
|
||||
import com.cloud.vm.Nic;
|
||||
import com.cloud.vm.NicVO;
|
||||
@ -80,13 +81,14 @@ import com.cloud.network.ovs.dao.OvsTunnel;
|
||||
import com.cloud.utils.component.ManagerBase;
|
||||
import com.cloud.utils.concurrency.NamedThreadFactory;
|
||||
import com.cloud.utils.db.DB;
|
||||
import com.cloud.utils.fsm.StateListener;
|
||||
import com.cloud.utils.exception.CloudRuntimeException;
|
||||
import com.cloud.vm.dao.DomainRouterDao;
|
||||
import com.cloud.vm.dao.NicDao;
|
||||
|
||||
@Component
|
||||
@Local(value = {OvsTunnelManager.class})
|
||||
public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager {
|
||||
public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManager, StateListener<VirtualMachine.State, VirtualMachine.Event, VirtualMachine> {
|
||||
public static final Logger s_logger = Logger.getLogger(OvsTunnelManagerImpl.class.getName());
|
||||
|
||||
// boolean _isEnabled;
|
||||
@ -133,7 +135,12 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
|
||||
_executorPool = Executors.newScheduledThreadPool(10, new NamedThreadFactory("OVS"));
|
||||
_cleanupExecutor = Executors.newScheduledThreadPool(1, new NamedThreadFactory("OVS-Cleanup"));
|
||||
|
||||
// register for network ACL updated for a VPC.
|
||||
_messageBus.subscribe("Network_ACL_Replaced", new NetworkAclEventsSubscriber());
|
||||
|
||||
// register for VM state transition updates
|
||||
VirtualMachine.State.getStateMachine().registerListener(this);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -540,92 +547,6 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
|
||||
return "OVS-DR-VPC-Bridge" + vpcId;
|
||||
}
|
||||
|
||||
public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
|
||||
try {
|
||||
s_logger.debug("Sending VPC topology update to the host " + hostId);
|
||||
updateCmd.setHostId(hostId);
|
||||
updateCmd.setBridgeName(bridgeName);
|
||||
Answer ans = _agentMgr.send(hostId, updateCmd);
|
||||
if (ans.getResult()) {
|
||||
s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
|
||||
return true;
|
||||
} else {
|
||||
s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
assert (vpc != null): "invalid vpc id";
|
||||
|
||||
List<? extends Network> vpcNetworks = _vpcMgr.getVpcNetworks(vpcId);
|
||||
List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
|
||||
List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
|
||||
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
|
||||
|
||||
for (Long hostId : hostIds) {
|
||||
HostVO hostDetails = _hostDao.findById(hostId);
|
||||
String remoteIp = null;
|
||||
for (Network network: vpcNetworks) {
|
||||
try {
|
||||
remoteIp = getGreEndpointIP(hostDetails, network);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
|
||||
hosts.add(host);
|
||||
}
|
||||
|
||||
for (Network network: vpcNetworks) {
|
||||
String key = network.getBroadcastUri().getAuthority();
|
||||
long gre_key;
|
||||
if (key.contains(".")) {
|
||||
String[] parts = key.split("\\.");
|
||||
gre_key = Long.parseLong(parts[1]);
|
||||
} else {
|
||||
try {
|
||||
gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
|
||||
OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
|
||||
network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
|
||||
tiers.add(tier);
|
||||
}
|
||||
|
||||
for (long vmId: vmIds) {
|
||||
VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Nic> vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
|
||||
for (Nic vmNic :_nicDao.listByVmId(vmId)) {
|
||||
Network network = _networkDao.findById(vmNic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest) {
|
||||
OvsVpcPhysicalTopologyConfigCommand.Nic nic = new OvsVpcPhysicalTopologyConfigCommand.Nic(
|
||||
vmNic.getIp4Address(), vmNic.getMacAddress(), ((Long)vmNic.getNetworkId()).toString());
|
||||
vmNics.add(nic);
|
||||
}
|
||||
}
|
||||
OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
|
||||
vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
|
||||
vms.add(vm);
|
||||
}
|
||||
return new OvsVpcPhysicalTopologyConfigCommand(
|
||||
hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
|
||||
tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
|
||||
vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
|
||||
vpc.getCidr());
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void checkAndCreateVpcTunnelNetworks(Host host, long vpcId) {
|
||||
|
||||
@ -731,16 +652,158 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
|
||||
s_logger.warn("Ovs Tunnel network created tunnel failed", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
|
||||
for (Long id: vpcSpannedHostIds) {
|
||||
if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
|
||||
s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on with rest of" +
|
||||
"the host update.");
|
||||
@Override
|
||||
public boolean preStateTransitionEvent(VirtualMachine.State oldState,
|
||||
VirtualMachine.Event event, VirtualMachine.State newState,
|
||||
VirtualMachine vo, boolean status, Object opaque) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean postStateTransitionEvent(VirtualMachine.State oldState, VirtualMachine.Event event,
|
||||
VirtualMachine.State newState, VirtualMachine vm,
|
||||
boolean status, Object opaque) {
|
||||
|
||||
if (!status) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (VirtualMachine.State.isVmStarted(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling start of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmStopped(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling stop of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
} else if (VirtualMachine.State.isVmMigrated(oldState, event, newState)) {
|
||||
if (s_logger.isTraceEnabled()) {
|
||||
s_logger.trace("Security Group Mgr: handling migration of vm id" + vm.getId());
|
||||
}
|
||||
handleVmStateChange((VMInstanceVO)vm);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void handleVmStateChange(VMInstanceVO vm) {
|
||||
|
||||
// get the VPC's impacted with the VM start
|
||||
List<Long> vpcIds = _ovsNetworkToplogyGuru.getVpcIdsVmIsPartOf(vm.getId());
|
||||
if (vpcIds == null || vpcIds.isEmpty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (Long vpcId: vpcIds) {
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
if (vpc == null || !vpc.usesDistributedRouter()) {
|
||||
return;
|
||||
}
|
||||
|
||||
// get the list of hosts on which VPC spans (i.e hosts that need to be aware of VPC topology change update)
|
||||
List<Long> vpcSpannedHostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
|
||||
String bridgeName=generateBridgeNameForVpc(vpcId);
|
||||
|
||||
OvsVpcPhysicalTopologyConfigCommand topologyConfigCommand = prepareVpcTopologyUpdate(vpcId);
|
||||
for (Long id: vpcSpannedHostIds) {
|
||||
if (!sendVpcTopologyChangeUpdate(topologyConfigCommand, id, bridgeName)) {
|
||||
s_logger.debug("Failed to send VPC topology change update to host : " + id + ". Moving on " +
|
||||
"with rest of the host update.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean sendVpcTopologyChangeUpdate(OvsVpcPhysicalTopologyConfigCommand updateCmd, long hostId, String bridgeName) {
|
||||
try {
|
||||
s_logger.debug("Sending VPC topology update to the host " + hostId);
|
||||
updateCmd.setHostId(hostId);
|
||||
updateCmd.setBridgeName(bridgeName);
|
||||
Answer ans = _agentMgr.send(hostId, updateCmd);
|
||||
if (ans.getResult()) {
|
||||
s_logger.debug("Successfully updated the host " + hostId + " with latest VPC topology." );
|
||||
return true;
|
||||
} else {
|
||||
s_logger.debug("Failed to update the host " + hostId + " with latest VPC topology." );
|
||||
return false;
|
||||
}
|
||||
} catch (Exception e) {
|
||||
s_logger.debug("Failed to updated the host " + hostId + " with latest VPC topology." );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
OvsVpcPhysicalTopologyConfigCommand prepareVpcTopologyUpdate(long vpcId) {
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
assert (vpc != null): "invalid vpc id";
|
||||
|
||||
List<? extends Network> vpcNetworks = _vpcMgr.getVpcNetworks(vpcId);
|
||||
List<Long> hostIds = _ovsNetworkToplogyGuru.getVpcSpannedHosts(vpcId);
|
||||
List<Long> vmIds = _ovsNetworkToplogyGuru.getAllActiveVmsInVpc(vpcId);
|
||||
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Host> hosts = new ArrayList<>();
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Tier> tiers = new ArrayList<>();
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Vm> vms = new ArrayList<>();
|
||||
|
||||
for (Long hostId : hostIds) {
|
||||
HostVO hostDetails = _hostDao.findById(hostId);
|
||||
String remoteIp = null;
|
||||
for (Network network: vpcNetworks) {
|
||||
try {
|
||||
remoteIp = getGreEndpointIP(hostDetails, network);
|
||||
} catch (Exception e) {
|
||||
|
||||
}
|
||||
}
|
||||
OvsVpcPhysicalTopologyConfigCommand.Host host = new OvsVpcPhysicalTopologyConfigCommand.Host(hostId, remoteIp);
|
||||
hosts.add(host);
|
||||
}
|
||||
|
||||
for (Network network: vpcNetworks) {
|
||||
String key = network.getBroadcastUri().getAuthority();
|
||||
long gre_key;
|
||||
if (key.contains(".")) {
|
||||
String[] parts = key.split("\\.");
|
||||
gre_key = Long.parseLong(parts[1]);
|
||||
} else {
|
||||
try {
|
||||
gre_key = Long.parseLong(BroadcastDomainType.getValue(key));
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
NicVO nic = _nicDao.findByIp4AddressAndNetworkId(network.getGateway(), network.getId());
|
||||
OvsVpcPhysicalTopologyConfigCommand.Tier tier = new OvsVpcPhysicalTopologyConfigCommand.Tier(gre_key,
|
||||
network.getUuid(), network.getGateway(), nic.getMacAddress(), network.getCidr());
|
||||
tiers.add(tier);
|
||||
}
|
||||
|
||||
for (long vmId: vmIds) {
|
||||
VirtualMachine vmInstance = _vmInstanceDao.findById(vmId);
|
||||
List<OvsVpcPhysicalTopologyConfigCommand.Nic> vmNics = new ArrayList<OvsVpcPhysicalTopologyConfigCommand.Nic>();
|
||||
for (Nic vmNic :_nicDao.listByVmId(vmId)) {
|
||||
Network network = _networkDao.findById(vmNic.getNetworkId());
|
||||
if (network.getTrafficType() == TrafficType.Guest) {
|
||||
OvsVpcPhysicalTopologyConfigCommand.Nic nic = new OvsVpcPhysicalTopologyConfigCommand.Nic(
|
||||
vmNic.getIp4Address(), vmNic.getMacAddress(), network.getUuid());
|
||||
vmNics.add(nic);
|
||||
}
|
||||
}
|
||||
OvsVpcPhysicalTopologyConfigCommand.Vm vm = new OvsVpcPhysicalTopologyConfigCommand.Vm(
|
||||
vmInstance.getHostId(), vmNics.toArray(new OvsVpcPhysicalTopologyConfigCommand.Nic[vmNics.size()]));
|
||||
vms.add(vm);
|
||||
}
|
||||
return new OvsVpcPhysicalTopologyConfigCommand(
|
||||
hosts.toArray(new OvsVpcPhysicalTopologyConfigCommand.Host[hosts.size()]),
|
||||
tiers.toArray(new OvsVpcPhysicalTopologyConfigCommand.Tier[tiers.size()]),
|
||||
vms.toArray(new OvsVpcPhysicalTopologyConfigCommand.Vm[vms.size()]),
|
||||
vpc.getCidr());
|
||||
}
|
||||
|
||||
// Subscriber to ACL replace events. On acl replace event, if the vpc is enabled for distributed routing
|
||||
// send the ACL update to all the hosts on which VPC spans
|
||||
public class NetworkAclEventsSubscriber implements MessageSubscriber {
|
||||
@ -755,14 +818,14 @@ public class OvsTunnelManagerImpl extends ManagerBase implements OvsTunnelManage
|
||||
for (Long id: vpcSpannedHostIds) {
|
||||
if (!sendVpcRoutingPolicyChangeUpdate(cmd, id, bridgeName)) {
|
||||
s_logger.debug("Failed to send VPC routing policy change update to host : " + id +
|
||||
". Moving on with rest of the host updates.");
|
||||
". But moving on with sending the host updates to the rest of the hosts.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
|
||||
private OvsVpcRoutingPolicyConfigCommand prepareVpcRoutingPolicyUpdate(long vpcId) {
|
||||
VpcVO vpc = _vpcDao.findById(vpcId);
|
||||
assert (vpc != null): "invalid vpc id";
|
||||
List<OvsVpcRoutingPolicyConfigCommand.Acl> acls = new ArrayList<>();
|
||||
|
||||
@ -239,7 +239,7 @@ def clear_flooding_rules_for_port(bridge, ofport):
|
||||
|
||||
def add_flooding_rules_for_port(bridge, in_ofport, out_ofports):
|
||||
action = "".join("output:%s," %ofport for ofport in out_ofports)[:-1]
|
||||
add_flow(bridge, priority=1100, in_port=in_ofport, table=1, actions=action)
|
||||
add_flow(bridge, priority=1100, in_port=in_ofport, table=2, actions=action)
|
||||
|
||||
def get_ofport_for_vif(vif_name):
|
||||
return do_cmd([VSCTL_PATH, "get", "interface", vif_name, "ofport"])
|
||||
@ -259,28 +259,30 @@ def get_vif_name_from_macaddress(macaddress):
|
||||
return "vif"+vm_domain_id+"."+vif_device_id
|
||||
|
||||
def add_mac_lookup_table_entry(bridge, mac_address, out_of_port):
|
||||
add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions="output:%s" % out_of_port)
|
||||
action = "output=%s" %out_of_port
|
||||
add_flow(bridge, priority=1100, dl_dst=mac_address, table=1, actions=action)
|
||||
|
||||
def delete_mac_lookup_table_entry(bridge, mac_address):
|
||||
del_flows(bridge, dl_dst=mac_address, table=1)
|
||||
|
||||
def add_ip_lookup_table_entry(bridge, ip, dst_tier_gateway_mac, dst_vm_mac):
|
||||
action_str = "mod_dl_sr:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac +",resubmit(,5)"
|
||||
addflow = [OFCTL_PATH, "add-flow", bridge, "table=4", "nw_dst=%s" % ip, "actions=%s" %action_str]
|
||||
action_str = "mod_dl_src:%s" % dst_tier_gateway_mac + ",mod_dl_dst:%s" % dst_vm_mac + ",resubmit(,5)"
|
||||
action_str = "table=4, ip, nw_dst=%s" % ip + ", actions=%s" %action_str
|
||||
addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
|
||||
do_cmd(addflow)
|
||||
|
||||
def get_vms_on_host(vpc, host_id):
|
||||
all_vms = vpc.vms
|
||||
vms_on_host = []
|
||||
for vm in all_vms:
|
||||
if vm.hostid == host_id:
|
||||
if str(vm.hostid) == (host_id):
|
||||
vms_on_host.append(vm)
|
||||
return vms_on_host
|
||||
|
||||
def get_network_details(vpc, network_uuid):
|
||||
tiers = vpc.tiers
|
||||
for tier in tiers:
|
||||
if tier.networkuuid == network_uuid:
|
||||
if str(tier.networkuuid) == (network_uuid):
|
||||
return tier
|
||||
return None
|
||||
|
||||
@ -338,20 +340,22 @@ def configure_bridge_for_network_topology(bridge, this_host_id, json_config):
|
||||
add_ip_lookup_table_entry(bridge, ip, network.gatewaymac, mac_addr)
|
||||
|
||||
# Add flow entry to send with intra tier traffic from the NIC to L2 lookup path)
|
||||
addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
|
||||
"nw_dst=%s" %network.cidr, "actions=resubmit(,1)"]
|
||||
action_str = "table=0, in_port=%s," %of_port + " ip, nw_dst=%s," %network.cidr + " actions=resubmit(,1)"
|
||||
addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
|
||||
do_cmd(addflow)
|
||||
|
||||
#add flow entry to send inter-tier traffic from the NIC to egress ACL table(to L3 lookup path)
|
||||
addflow = [OFCTL_PATH, "add-flow", bridge, "table=0", "in_port=%s" % of_port,
|
||||
"dl_dst=%s" %network.gatewaymac, "nw_dst=%s" %vpconfig.cidr, "actions=resubmit(,3)"]
|
||||
action_str = "table=0, in_port=%s," % of_port + " ip, dl_dst=%s," %network.gatewaymac +\
|
||||
"nw_dst=%s," %vpconfig.cidr + "actions=resubmit(,3)"
|
||||
addflow = [OFCTL_PATH, "add-flow", bridge, action_str]
|
||||
|
||||
do_cmd(addflow)
|
||||
|
||||
# get the list of hosts on which VPC spans from the JSON config
|
||||
vpc_spanning_hosts = vpconfig.hosts
|
||||
|
||||
for host in vpc_spanning_hosts:
|
||||
if this_host_id == host.hostid:
|
||||
if str(this_host_id) == str(host.hostid):
|
||||
continue
|
||||
other_host_vms = get_vms_on_host(vpconfig, host.hostid)
|
||||
for vm in other_host_vms:
|
||||
|
||||
@ -21,9 +21,11 @@
|
||||
import copy
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
|
||||
import cloudstack_pluginlib as pluginlib
|
||||
|
||||
pluginlib.setup_logging("/var/log/cloud/ovstunnel.log")
|
||||
|
||||
def clear_flows(bridge, this_vif_ofport, vif_ofports):
|
||||
# Remove flow entries originating from given ofport
|
||||
@ -83,18 +85,26 @@ def main(command, vif_raw):
|
||||
|
||||
bridge = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'iface-to-br', this_vif])
|
||||
|
||||
# find xs network for this bridge, verify is used for ovs tunnel network
|
||||
# find xs network for this bridge, verify is used for ovs tunnel network
|
||||
xs_nw_uuid = pluginlib.do_cmd([pluginlib.XE_PATH, "network-list",
|
||||
"bridge=%s" % bridge, "--minimal"])
|
||||
ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
|
||||
ovs_tunnel_network = False
|
||||
try:
|
||||
ovs_tunnel_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
|
||||
"uuid=%s" % xs_nw_uuid,
|
||||
"param-name=other-config",
|
||||
"param-key=is-ovs-tun-network", "--minimal"])
|
||||
except:
|
||||
pass
|
||||
|
||||
ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
|
||||
ovs_vpc_distributed_vr_network = False
|
||||
try:
|
||||
ovs_vpc_distributed_vr_network = pluginlib.do_cmd([pluginlib.XE_PATH,"network-param-get",
|
||||
"uuid=%s" % xs_nw_uuid,
|
||||
"param-name=other-config",
|
||||
"param-key=is-ovs_vpc_distributed_vr_network", "--minimal"])
|
||||
except:
|
||||
pass
|
||||
|
||||
if ovs_tunnel_network == 'True':
|
||||
vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
|
||||
@ -121,6 +131,7 @@ def main(command, vif_raw):
|
||||
apply_flows(bridge, this_vif_ofport, vif_ofports)
|
||||
|
||||
|
||||
# handle case where brdige is setup for VPC and VPC is enabled for distributed routing
|
||||
if ovs_vpc_distributed_vr_network == 'True':
|
||||
vlan = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'br-to-vlan', bridge])
|
||||
if vlan != '0':
|
||||
@ -136,15 +147,15 @@ def main(command, vif_raw):
|
||||
|
||||
ports = vsctl_output.split('\n')
|
||||
for port in ports:
|
||||
if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', vif, 'ofport'])
|
||||
if vif.startswith('vif'):
|
||||
if_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', port, 'ofport'])
|
||||
if port.startswith('vif'):
|
||||
# check VIF is in same network as that of plugged vif
|
||||
if vif_network_id != pluginlib.get_network_id_for_vif(port):
|
||||
continue
|
||||
vnet_vif_ofports.append(if_ofport)
|
||||
vnet_all_ofports.append(if_ofport)
|
||||
|
||||
if vif.startswith('t'):
|
||||
if port.startswith('t'):
|
||||
# check tunnel port is in same network as that of plugged vif
|
||||
if vif_network_id != pluginlib.get_network_id_for_tunnel_port(port):
|
||||
continue
|
||||
@ -159,7 +170,8 @@ def main(command, vif_raw):
|
||||
for port in vnet_tunnelif_ofports:
|
||||
pluginlib.add_flooding_rules_for_port(bridge, port, vnet_vif_ofports)
|
||||
|
||||
# send on all VIF and tunnel port excluding the port on which packet arrived
|
||||
# for a packet arrived from VIF port send on all VIF and tunnel port excluding the port
|
||||
# on which packet arrived
|
||||
for port in vnet_vif_ofports:
|
||||
vnet_all_ofports_copy = copy.copy(vnet_all_ofports)
|
||||
vnet_all_ofports_copy.remove(port)
|
||||
@ -167,6 +179,7 @@ def main(command, vif_raw):
|
||||
|
||||
#learn that MAC is reachable through the VIF port
|
||||
mac = pluginlib.get_macaddress_of_vif(this_vif)
|
||||
this_vif_ofport = pluginlib.do_cmd([pluginlib.VSCTL_PATH, 'get', 'Interface', this_vif, 'ofport'])
|
||||
pluginlib.add_mac_lookup_table_entry(bridge, mac, this_vif_ofport)
|
||||
|
||||
if command == 'offline':
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user