mirror of
https://github.com/apache/cloudstack.git
synced 2025-10-26 08:42:29 +01:00
bug 7722: open vswitch -
fix a race condition, create tunnel sync correct drop flow, this fix a flooding case which may cause openvswitch hang in kernel
This commit is contained in:
parent
80f6db937f
commit
488dd424aa
@ -369,6 +369,24 @@ def get_interface_on_port(nameOruuid):
|
||||
return str.split(",")
|
||||
return None
|
||||
|
||||
def get_gre_ports(bridge):
|
||||
portUuids = get_ports_on_bridge(bridge)
|
||||
if portUuids == None:
|
||||
pr("WARNING:No ports on bridge %s" % bridge)
|
||||
return []
|
||||
|
||||
OfPorts = []
|
||||
for i in portUuids:
|
||||
iface = get_filed_of_port(i, "interfaces")
|
||||
iface = strip(iface, "both")
|
||||
type = get_field_of_interface(iface, "type")
|
||||
if type == 'gre':
|
||||
port = get_field_of_interface(iface, "ofport")
|
||||
if port != '[]':
|
||||
OfPorts.append(port)
|
||||
|
||||
return OfPorts
|
||||
|
||||
def get_ofports_by_tag(bridge, tag):
|
||||
portUuids = get_ports_on_bridge(bridge)
|
||||
if portUuids == None:
|
||||
@ -395,11 +413,16 @@ def format_flow(inPort, vlan, mac, outPut):
|
||||
priority=10000 actions=strip_vlan,output:%s" % (inPort, vlan, mac, outPut)
|
||||
return flow
|
||||
|
||||
def format_drop_flow(inPort, vlan):
|
||||
flow = "in_port=%s dl_vlan=%s priority=0 idle_timeout=0 hard_timeout=0 \
|
||||
actions=drop" % (inPort, vlan)
|
||||
def format_drop_flow(inPort):
|
||||
flow = "in_port=%s priority=1000 idle_timeout=0 hard_timeout=0 \
|
||||
actions=drop" % inPort
|
||||
return flow
|
||||
|
||||
def add_drop_flow(bridge, inPorts):
|
||||
for i in inPorts:
|
||||
flow = format_drop_flow(i)
|
||||
add_flow(bridge, flow)
|
||||
|
||||
def del_flow(bridge, mac):
|
||||
param = "dl_dst=%s" % mac
|
||||
flow = ["ovs-ofctl del-flows %s" % bridge, '"%s"' % param]
|
||||
@ -477,9 +500,6 @@ def create_flow (bridge, vifName, mac, vlans):
|
||||
for v in vlans.split(","):
|
||||
try:
|
||||
(vlan, inPort) = v.split(":")
|
||||
flow = format_drop_flow(inPort, vlan)
|
||||
add_flow(bridge, flow)
|
||||
|
||||
flow = format_flow(inPort, vlan, mac, output)
|
||||
add_flow(bridge, flow)
|
||||
except Exception, e:
|
||||
@ -490,6 +510,10 @@ def create_flow (bridge, vifName, mac, vlans):
|
||||
flow = format_normal_flow()
|
||||
add_flow(bridge, flow)
|
||||
|
||||
inports = get_gre_ports(bridge)
|
||||
for i in inports:
|
||||
add_drop_flow(bridge, i)
|
||||
|
||||
return errors["SUCCESS"]
|
||||
######################## End Flow creation utils ##########################
|
||||
|
||||
@ -669,7 +693,7 @@ def ovs_get_domid_vifrs_hostuuid(session, vmName):
|
||||
try:
|
||||
vm = session.xenapi.VM.get_by_name_label(vmName)
|
||||
if len(vm) != 1:
|
||||
return 'NO_VM'
|
||||
return (-1, [], "-1")
|
||||
vm_rec = session.xenapi.VM.get_record(vm[0])
|
||||
vm_vifs = vm_rec.get('VIFs')
|
||||
vifrs = []
|
||||
|
||||
@ -50,30 +50,7 @@ public class OvsListener implements Listener {
|
||||
Set<Long> failedFlowVms = new HashSet<Long>();
|
||||
try {
|
||||
for (Answer ans : answers) {
|
||||
if (ans instanceof OvsCreateGreTunnelAnswer) {
|
||||
OvsCreateGreTunnelAnswer r = (OvsCreateGreTunnelAnswer) ans;
|
||||
String s = String
|
||||
.format("(hostIP:%1$s, remoteIP:%2$s, bridge:%3$s, greKey:%4$s)",
|
||||
r.getHostIp(), r.getRemoteIp(),
|
||||
r.getBridge(), r.getKey());
|
||||
if (!r.getResult()) {
|
||||
s_logger.warn("Create GRE tunnel failed due to "
|
||||
+ r.getDetails() + s);
|
||||
} else {
|
||||
GreTunnelVO tunnel = _tunnelDao.getByFromAndTo(
|
||||
r.getFrom(), r.getTo());
|
||||
if (tunnel == null) {
|
||||
throw new GreTunnelException(
|
||||
"No record matches from = " + r.getFrom() + " to = " + r.getTo());
|
||||
} else {
|
||||
tunnel.setInPort(r.getPort());
|
||||
_tunnelDao.update(tunnel.getId(), tunnel);
|
||||
s_logger.info("Create GRE tunnel success" + s
|
||||
+ " from " + r.getFrom() + " to "
|
||||
+ r.getTo() + " inport=" + r.getPort());
|
||||
}
|
||||
}
|
||||
} else if (ans instanceof OvsSetTagAndFlowAnswer) {
|
||||
if (ans instanceof OvsSetTagAndFlowAnswer) {
|
||||
OvsSetTagAndFlowAnswer r = (OvsSetTagAndFlowAnswer) ans;
|
||||
if (!r.getResult()) {
|
||||
s_logger.warn("Failed to set flow for VM "
|
||||
|
||||
@ -17,6 +17,7 @@ import javax.persistence.EntityExistsException;
|
||||
import org.apache.log4j.Logger;
|
||||
|
||||
import com.cloud.agent.AgentManager;
|
||||
import com.cloud.agent.api.Answer;
|
||||
import com.cloud.agent.manager.Commands;
|
||||
import com.cloud.configuration.Config;
|
||||
import com.cloud.configuration.dao.ConfigurationDao;
|
||||
@ -294,6 +295,31 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
|
||||
return target.getVlan();
|
||||
}
|
||||
|
||||
private void handleCreateTunnelAnswer(Answer[] answers) throws GreTunnelException {
|
||||
OvsCreateGreTunnelAnswer r = (OvsCreateGreTunnelAnswer) answers[0];
|
||||
String s = String.format(
|
||||
"(hostIP:%1$s, remoteIP:%2$s, bridge:%3$s, greKey:%4$s)",
|
||||
r.getHostIp(), r.getRemoteIp(), r.getBridge(), r.getKey());
|
||||
|
||||
if (!r.getResult()) {
|
||||
s_logger.warn("Create GRE tunnel failed due to " + r.getDetails()
|
||||
+ s);
|
||||
} else {
|
||||
GreTunnelVO tunnel = _tunnelDao.getByFromAndTo(r.getFrom(), r.getTo());
|
||||
if (tunnel == null) {
|
||||
throw new GreTunnelException("No record matches from = "
|
||||
+ r.getFrom() + " to = " + r.getTo());
|
||||
} else {
|
||||
tunnel.setInPort(r.getPort());
|
||||
_tunnelDao.update(tunnel.getId(), tunnel);
|
||||
s_logger.info("Create GRE tunnel success" + s + " from "
|
||||
+ r.getFrom() + " to " + r.getTo() + " inport="
|
||||
+ r.getPort());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@DB
|
||||
protected void CheckAndCreateTunnel(VMInstanceVO instance,
|
||||
DeployDestination dest) throws GreTunnelException {
|
||||
@ -309,7 +335,6 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
|
||||
final Transaction txn = Transaction.currentTxn();
|
||||
long hostId = dest.getHost().getId();
|
||||
long accountId = instance.getAccountId();
|
||||
//TODO: considerate router?
|
||||
List<UserVmVO>vms = _userVmDao.listByAccountId(accountId);
|
||||
DomainRouterVO router = _routerDao.findBy(accountId, instance.getDataCenterId());
|
||||
List<VMInstanceVO>ins = new ArrayList<VMInstanceVO>();
|
||||
@ -360,14 +385,16 @@ public class OvsNetworkManagerImpl implements OvsNetworkManager {
|
||||
new OvsCreateGreTunnelCommand(
|
||||
rHost.getPrivateIpAddress(), "1", hostId,
|
||||
i.longValue()));
|
||||
_agentMgr.send(hostId, cmds , _ovsListener);
|
||||
s_logger.debug("Ask host " + hostId + " to create gre tunnel to " + i.longValue());
|
||||
Answer[] answers = _agentMgr.send(hostId, cmds);
|
||||
handleCreateTunnelAnswer(answers);
|
||||
}
|
||||
|
||||
for (Long i : fromHostIds) {
|
||||
Commands cmd2s = new Commands(new OvsCreateGreTunnelCommand(myIp, "1", i.longValue(), hostId));
|
||||
_agentMgr.send(i.longValue(), cmd2s , _ovsListener);
|
||||
s_logger.debug("Ask host " + i.longValue() + " to create gre tunnel to " + hostId);
|
||||
Answer[] answers = _agentMgr.send(i.longValue(), cmd2s);
|
||||
handleCreateTunnelAnswer(answers);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user