mirror of
https://github.com/opennetworkinglab/onos.git
synced 2026-05-05 04:06:49 +02:00
Supports downlink trace functionality in OpenstackNetworkingUI
Change-Id: Ide25681e83d34b22393483b3b06e8834693a18ec (cherry picked from commit 5aef9826f6232d2605bbe11a97b9487c56f575a4)
This commit is contained in:
parent
3f274d982b
commit
4e037f5c2f
@ -3,6 +3,7 @@ include_defs('//apps/openstacknode/openstack4j.bucklet')
|
||||
COMPILE_DEPS = [
|
||||
'//lib:CORE_DEPS',
|
||||
'//lib:openstack4j-core',
|
||||
"//apps/openstacknode/api:onos-apps-openstacknode-api",
|
||||
]
|
||||
|
||||
osgi_jar_with_tests (
|
||||
|
||||
@ -7,6 +7,7 @@ load(
|
||||
|
||||
COMPILE_DEPS = CORE_DEPS + [
|
||||
"@openstack4j_core//jar",
|
||||
"//apps/openstacknode/api:onos-apps-openstacknode-api",
|
||||
]
|
||||
|
||||
osgi_jar_with_tests(
|
||||
|
||||
@ -700,7 +700,7 @@ public final class OpenstackNetworkingUtil {
|
||||
* @param dstIp dst ip address
|
||||
* @param srcInstancePort src instance port
|
||||
* @param osNetService openstack networking service
|
||||
* @param uplink true if this request if uplink
|
||||
* @param uplink true if this request is for uplink
|
||||
* @return flow trace request string
|
||||
*/
|
||||
public static String traceRequestString(String srcIp,
|
||||
|
||||
@ -11,6 +11,7 @@ COMPILE_DEPS = [
|
||||
'//apps/openstacknode/api:onos-apps-openstacknode-api',
|
||||
'//apps/openstacktelemetry/api:onos-apps-openstacktelemetry-api',
|
||||
'//apps/openstacknetworking/api:onos-apps-openstacknetworking-api',
|
||||
'//apps/openstacknetworking/app:onos-apps-openstacknetworking-app',
|
||||
]
|
||||
|
||||
EXCLUDED_BUNDLES = [
|
||||
|
||||
@ -8,6 +8,7 @@ COMPILE_DEPS = CORE_DEPS + JACKSON + CLI + REST + [
|
||||
"//apps/openstacknode/api:onos-apps-openstacknode-api",
|
||||
"//apps/openstacktelemetry/api:onos-apps-openstacktelemetry-api",
|
||||
"//apps/openstacknetworking/api:onos-apps-openstacknetworking-api",
|
||||
"//apps/openstacknetworking/app:onos-apps-openstacknetworking-app",
|
||||
"@sshd_core//jar",
|
||||
]
|
||||
|
||||
|
||||
@ -104,17 +104,20 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
private static final String FLOW_TRACE_RESULT = "flowTraceResult";
|
||||
private static final String SRC_DEVICE_ID = "srcDeviceId";
|
||||
private static final String DST_DEVICE_ID = "dstDeviceId";
|
||||
private static final String UPLINK = "uplink";
|
||||
private static final String OVS_VERSION_2_8 = "2.8";
|
||||
private static final String OVS_VERSION_2_7 = "2.7";
|
||||
private static final String OVS_VERSION_2_6 = "2.6";
|
||||
private static final String FLAT = "FLAT";
|
||||
|
||||
private static final String VXLAN = "VXLAN";
|
||||
private static final String VLAN = "VLAN";
|
||||
private static final String DL_DST = "dl_dst=";
|
||||
private static final String NW_DST = "nw_dst=";
|
||||
private static final String DEFAULT_REQUEST_STRING = "sudo ovs-appctl ofproto/trace br-int ip,in_port=";
|
||||
private static final String DEFAULT_REQUEST_STRING = "sudo ovs-appctl ofproto/trace br-int ip";
|
||||
private static final String IN_PORT = "in_port=";
|
||||
private static final String NW_SRC = "nw_src=";
|
||||
private static final String COMMA = ",";
|
||||
|
||||
private static final String TUN_ID = "tun_id=";
|
||||
|
||||
private static final long TIMEOUT_MS = 5000;
|
||||
private static final long WAIT_OUTPUT_STREAM_SECOND = 2;
|
||||
@ -230,12 +233,15 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
String dstIp = string(payload, DST_IP);
|
||||
String srcDeviceId = string(payload, SRC_DEVICE_ID);
|
||||
String dstDeviceId = string(payload, DST_DEVICE_ID);
|
||||
log.info("Flow trace request called with src IP: {}, dst IP: {}, src device ID: {}, dst device Id: {}",
|
||||
boolean uplink = bool(payload, UPLINK);
|
||||
log.info("Flow trace request called with" +
|
||||
"src IP: {}, dst IP: {}, src device ID: {}, dst device Id: {}, uplink: ",
|
||||
srcIp,
|
||||
dstIp,
|
||||
srcDeviceId,
|
||||
dstDeviceId);
|
||||
eventExecutor.execute(() -> processFlowTraceRequest(srcIp, dstIp, srcDeviceId));
|
||||
dstDeviceId,
|
||||
uplink);
|
||||
eventExecutor.execute(() -> processFlowTraceRequest(srcIp, dstIp, srcDeviceId, dstDeviceId, uplink));
|
||||
}
|
||||
}
|
||||
|
||||
@ -443,7 +449,8 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
sendMessagetoUi(FLOW_STATS_ADD_RESULT, statsResult);
|
||||
}
|
||||
|
||||
private void processFlowTraceRequest(String srcIp, String dstIp, String srcDeviceId) {
|
||||
private void processFlowTraceRequest(String srcIp, String dstIp, String srcDeviceId, String dstDeviceId,
|
||||
boolean uplink) {
|
||||
boolean traceSuccess = true;
|
||||
|
||||
ObjectMapper mapper = new ObjectMapper();
|
||||
@ -454,6 +461,7 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
|
||||
OpenstackNode srcOpenstackNode = osNodeService.node(DeviceId.deviceId(srcDeviceId));
|
||||
if (srcOpenstackNode == null) {
|
||||
log.error("There's no openstack node information for device {}", srcDeviceId);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -463,52 +471,138 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
String traceResultForward = sendTraceRequestToNode(srcIp, dstIp, srcOpenstackNode);
|
||||
if (traceResultForward == null) {
|
||||
String traceResultString = sendTraceRequestToNode(srcIp, dstIp, srcOpenstackNode, uplink);
|
||||
|
||||
if (traceResultString == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
log.debug("traceResultForward raw data: {}", traceResultForward);
|
||||
log.debug("traceResultString raw data: {}", traceResultString);
|
||||
|
||||
ObjectNode traceResultForwardJson = null;
|
||||
ObjectNode traceResultJson = null;
|
||||
|
||||
Device srcDevice = deviceService.getDevice(srcOpenstackNode.intgBridge());
|
||||
if (srcDevice.swVersion().startsWith(OVS_VERSION_2_8)) {
|
||||
traceResultForwardJson = Ovs28FlowTraceResultParser.flowTraceResultInJson(
|
||||
traceResultForward.trim(), srcOpenstackNode.hostname());
|
||||
if (srcDevice.swVersion().startsWith(OVS_VERSION_2_8) ||
|
||||
srcDevice.swVersion().startsWith(OVS_VERSION_2_7)) {
|
||||
traceResultJson = Ovs28FlowTraceResultParser.flowTraceResultInJson(
|
||||
traceResultString.trim(), srcOpenstackNode.hostname());
|
||||
} else {
|
||||
log.error("Currently OVS version {} is not supported",
|
||||
deviceService.getDevice(srcOpenstackNode.intgBridge()));
|
||||
}
|
||||
|
||||
if (traceResultForwardJson == null) {
|
||||
if (traceResultJson == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
traceResultArray.add(traceResultForwardJson);
|
||||
traceResultArray.add(traceResultJson);
|
||||
|
||||
log.debug("traceResultForward Json: {}", traceResultForwardJson);
|
||||
log.debug("traceResultForward Json: {}", traceResultJson);
|
||||
|
||||
if (!traceResultForwardJson.get(IS_SUCCESS).asBoolean()) {
|
||||
if (!traceResultJson.get(IS_SUCCESS).asBoolean()) {
|
||||
traceSuccess = false;
|
||||
}
|
||||
|
||||
traceResult.put(TRACE_SUCCESS, traceSuccess);
|
||||
|
||||
traceResult.put(SRC_IP, srcIp);
|
||||
traceResult.put(DST_IP, dstIp);
|
||||
traceResult.put(SRC_DEVICE_ID, srcDeviceId);
|
||||
traceResult.put(DST_DEVICE_ID, dstDeviceId);
|
||||
traceResult.put(UPLINK, uplink);
|
||||
|
||||
log.debug("traceResult Json: {}", traceResult);
|
||||
|
||||
sendMessagetoUi(FLOW_TRACE_RESULT, traceResult);
|
||||
|
||||
}
|
||||
|
||||
private String sendTraceRequestToNode(String srcIp, String dstIp, OpenstackNode openstackNode) {
|
||||
private String sendTraceRequestToNode(String srcIp, String dstIp, OpenstackNode openstackNode, boolean uplink) {
|
||||
|
||||
Optional<InstancePort> instancePort = instancePortService.instancePorts().stream()
|
||||
.filter(port -> port.ipAddress().getIp4Address().toString().equals(srcIp)
|
||||
&& port.deviceId().equals(openstackNode.intgBridge()))
|
||||
.findAny();
|
||||
|
||||
if (!instancePort.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String requestString = traceRequestString(srcIp, dstIp,
|
||||
instancePort.get(), osNetService, uplink);
|
||||
|
||||
return sendTraceRequestToNode(requestString, openstackNode);
|
||||
}
|
||||
|
||||
private String traceRequestString(String srcIp,
|
||||
String dstIp,
|
||||
InstancePort srcInstancePort,
|
||||
OpenstackNetworkService osNetService,
|
||||
boolean uplink) {
|
||||
|
||||
StringBuilder requestStringBuilder = new StringBuilder(DEFAULT_REQUEST_STRING);
|
||||
|
||||
if (uplink) {
|
||||
|
||||
requestStringBuilder.append(COMMA)
|
||||
.append(IN_PORT)
|
||||
.append(srcInstancePort.portNumber().toString())
|
||||
.append(COMMA)
|
||||
.append(NW_SRC)
|
||||
.append(srcIp)
|
||||
.append(COMMA);
|
||||
|
||||
if (osNetService.networkType(srcInstancePort.networkId()).equals(VXLAN) ||
|
||||
osNetService.networkType(srcInstancePort.networkId()).equals(VLAN)) {
|
||||
if (srcIp.equals(dstIp)) {
|
||||
dstIp = osNetService.gatewayIp(srcInstancePort.portId());
|
||||
requestStringBuilder.append(DL_DST)
|
||||
.append(DEFAULT_GATEWAY_MAC_STR).append(COMMA);
|
||||
} else if (!osNetService.ipPrefix(srcInstancePort.portId()).contains(IpAddress.valueOf(dstIp))) {
|
||||
requestStringBuilder.append(DL_DST)
|
||||
.append(DEFAULT_GATEWAY_MAC_STR)
|
||||
.append(COMMA);
|
||||
}
|
||||
} else {
|
||||
if (srcIp.equals(dstIp)) {
|
||||
dstIp = osNetService.gatewayIp(srcInstancePort.portId());
|
||||
}
|
||||
}
|
||||
|
||||
requestStringBuilder.append(NW_DST)
|
||||
.append(dstIp)
|
||||
.append("\n");
|
||||
} else {
|
||||
requestStringBuilder.append(COMMA)
|
||||
.append(NW_SRC)
|
||||
.append(dstIp)
|
||||
.append(COMMA);
|
||||
|
||||
if (osNetService.networkType(srcInstancePort.networkId()).equals(VXLAN) ||
|
||||
osNetService.networkType(srcInstancePort.networkId()).equals(VLAN)) {
|
||||
requestStringBuilder.append(TUN_ID)
|
||||
.append(osNetService.segmentId(srcInstancePort.networkId()))
|
||||
.append(COMMA);
|
||||
}
|
||||
requestStringBuilder.append(NW_DST)
|
||||
.append(srcIp)
|
||||
.append("\n");
|
||||
|
||||
}
|
||||
|
||||
return requestStringBuilder.toString();
|
||||
}
|
||||
|
||||
private String sendTraceRequestToNode(String requestString,
|
||||
OpenstackNode node) {
|
||||
String traceResult = null;
|
||||
OpenstackSshAuth sshAuth = openstackNode.sshAuthInfo();
|
||||
OpenstackSshAuth sshAuth = node.sshAuthInfo();
|
||||
|
||||
try (SshClient client = SshClient.setUpDefaultClient()) {
|
||||
client.start();
|
||||
|
||||
try (ClientSession session = client
|
||||
.connect(sshAuth.id(), openstackNode.managementIp().getIp4Address().toString(), SSH_PORT)
|
||||
.connect(sshAuth.id(), node.managementIp().getIp4Address().toString(), SSH_PORT)
|
||||
.verify(TIMEOUT_MS, TimeUnit.SECONDS).getSession()) {
|
||||
session.addPasswordIdentity(sshAuth.password());
|
||||
session.auth().verify(TIMEOUT_MS, TimeUnit.SECONDS);
|
||||
@ -516,11 +610,6 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
|
||||
try (ClientChannel channel = session.createChannel(ClientChannel.CHANNEL_SHELL)) {
|
||||
|
||||
String requestString = traceRequestString(srcIp, dstIp, openstackNode);
|
||||
if (requestString == null) {
|
||||
return null;
|
||||
}
|
||||
|
||||
log.debug("requestString: {}", requestString);
|
||||
final InputStream inputStream =
|
||||
new ByteArrayInputStream(requestString.getBytes());
|
||||
@ -566,40 +655,4 @@ public class OpenstackNetworkingUiMessageHandler extends UiMessageHandler {
|
||||
|
||||
return traceResult;
|
||||
}
|
||||
|
||||
private String traceRequestString(String srcIp, String dstIp, OpenstackNode openstackNode) {
|
||||
|
||||
Optional<InstancePort> instancePort = instancePortService.instancePorts().stream()
|
||||
.filter(port -> port.ipAddress().getIp4Address().toString().equals(srcIp)
|
||||
&& port.deviceId().equals(openstackNode.intgBridge()))
|
||||
.findAny();
|
||||
|
||||
if (!instancePort.isPresent()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
String requestString = DEFAULT_REQUEST_STRING
|
||||
+ instancePort.get().portNumber().toString()
|
||||
+ COMMA
|
||||
+ NW_SRC
|
||||
+ srcIp
|
||||
+ COMMA;
|
||||
|
||||
if (osNetService.networkType(instancePort.get().networkId()).equals(VXLAN)) {
|
||||
if (srcIp.equals(dstIp)) {
|
||||
dstIp = osNetService.gatewayIp(instancePort.get().portId());
|
||||
requestString = requestString + DL_DST + DEFAULT_GATEWAY_MAC_STR + COMMA;
|
||||
} else if (!osNetService.ipPrefix(instancePort.get().portId()).contains(IpAddress.valueOf(dstIp))) {
|
||||
requestString = requestString + DL_DST + DEFAULT_GATEWAY_MAC_STR + COMMA;
|
||||
}
|
||||
} else if (osNetService.networkType(instancePort.get().networkId()).equals(FLAT)) {
|
||||
if (srcIp.equals(dstIp)) {
|
||||
dstIp = osNetService.gatewayIp(instancePort.get().portId());
|
||||
}
|
||||
}
|
||||
|
||||
requestString = requestString + NW_DST + dstIp + "\n";
|
||||
|
||||
return requestString;
|
||||
}
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@
|
||||
var flowStatsDstIp = null;
|
||||
|
||||
var traceInfoDialogId = 'traceInfoDialogId',
|
||||
traceInfoDialogOpt = {
|
||||
traceInfoDialogOpt = {
|
||||
width: 350,
|
||||
edge: 'left',
|
||||
margin: 20,
|
||||
@ -278,7 +278,7 @@
|
||||
}
|
||||
|
||||
function flowTraceResultBtn() {
|
||||
sts.sendFlowTraceRequest(traceSrc, traceDst, srcDeviceId, dstDeviceId);
|
||||
sts.sendFlowTraceRequest(traceSrc, traceDst, srcDeviceId, dstDeviceId, true);
|
||||
ds.closeDialog();
|
||||
traceSrc = null;
|
||||
traceDst = null;
|
||||
|
||||
@ -28,6 +28,12 @@
|
||||
// injected refs
|
||||
var $log, fs, flash, wss, ds;
|
||||
|
||||
var traceSrc = null;
|
||||
var traceDst = null;
|
||||
var srcDeviceId = null;
|
||||
var dstDeviceId = null;
|
||||
var uplink = null;
|
||||
|
||||
// constants
|
||||
var displayStart = 'openstackNetworkingUiStart',
|
||||
displayUpdate = 'openstackNetworkingUiUpdate',
|
||||
@ -76,12 +82,13 @@
|
||||
flash.flash('sendFlowStatsRemoveRequest called');
|
||||
}
|
||||
|
||||
function sendFlowTraceRequest(src, dst, srcDeviceId, dstDeviceId) {
|
||||
function sendFlowTraceRequest(src, dst, srcDeviceId, dstDeviceId, uplink) {
|
||||
wss.sendEvent(flowTraceRequest, {
|
||||
srcIp: src,
|
||||
dstIp: dst,
|
||||
srcDeviceId: srcDeviceId,
|
||||
dstDeviceId: dstDeviceId,
|
||||
uplink: uplink,
|
||||
});
|
||||
flash.flash('sendFlowTraceRequest called');
|
||||
}
|
||||
@ -175,11 +182,32 @@
|
||||
hideMargin: -20
|
||||
}
|
||||
var traceSuccess = data.traceSuccess == true ? "SUCCESS" : "FALSE";
|
||||
ds.openDialog(flowTraceResultDialogId, flowTraceResultDialogOpt)
|
||||
.setTitle('Flow Trace Result: ' + traceSuccess)
|
||||
.addContent(createTraceResultInfoDiv(data))
|
||||
.addOk(dOk, 'Close')
|
||||
.bindKeys();
|
||||
traceSrc = data.srcIp;
|
||||
traceDst = data.dstIp;
|
||||
srcDeviceId = data.srcDeviceId;
|
||||
dstDeviceId = data.dstDeviceId;
|
||||
uplink = data.uplink;
|
||||
|
||||
if (data.uplink == true) {
|
||||
ds.openDialog(flowTraceResultDialogId, flowTraceResultDialogOpt)
|
||||
.setTitle('Flow Trace Result: ' + traceSuccess)
|
||||
.addContent(createTraceResultInfoDiv(data))
|
||||
.addOk(downlinkTraceRequestBtn, 'Downlink Trace')
|
||||
.bindKeys();
|
||||
} else {
|
||||
ds.openDialog(flowTraceResultDialogId, flowTraceResultDialogOpt)
|
||||
.setTitle('Flow Trace Result: ' + traceSuccess)
|
||||
.addContent(createTraceResultInfoDiv(data))
|
||||
.addOk(dOk, 'Close')
|
||||
.bindKeys();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function downlinkTraceRequestBtn() {
|
||||
sendFlowTraceRequest(traceSrc, traceDst, srcDeviceId, dstDeviceId, false);
|
||||
ds.closeDialog();
|
||||
flash.flash('Send Downlink Flow Trace Request')
|
||||
}
|
||||
|
||||
function createTraceResultInfoDiv(data) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user