Created
May 6, 2017 17:06
-
-
Save stereocat/556a526e297251f5ac9db5307f0adf7a to your computer and use it in GitHub Desktop.
Rewrite nettester_flowviewer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict"; | |
function build_flowdata(ssw_textarea, psw_textarea) { | |
var ssw_flows = build_flowdata_from(ssw_textarea); | |
var psw_flows = build_flowdata_from(psw_textarea); | |
var flows = ssw_flows.concat(psw_flows); | |
console.log(flows); | |
var nested_flows = nest_flowdata(flows); | |
console.log(nested_flows); | |
fill_flows(nested_flows); | |
setup_key(nested_flows); | |
console.log(nested_flows); | |
return nested_flows; | |
} | |
function nest_flowdata(flows) { | |
return d3.nest() | |
.key(function(d) { return d.switch; }) | |
.sortKeys(d3.ascending) | |
.key(function(d) { return d.in_port; }) | |
.sortKeys(function(a,b) { return a - b; }) | |
.map(flows); | |
} | |
function build_flowdata_from(flow_table_textarea) { | |
var lines = flow_table_textarea.value | |
.split("\n") | |
.filter(function (thisobj) { | |
// discard header, empty line, and so on. | |
return thisobj.match(/^\s+cookie/i); | |
}); | |
var numeric_values = ["priority", "in_port", "dl_vlan"]; | |
var mac_values = ["dl_dst", "dl_src"]; | |
return lines.map(function (line) { | |
// console.log("No: " + index + " line=", line); | |
var data = { // defaults | |
"switch" : flow_table_textarea.name, | |
"rule_str" : line, // original flow rule string | |
"in_port" : null, | |
"output" : null, | |
"priority" : null, | |
"vlan" : null, | |
"mac" : null, | |
"action_flood": false, | |
"flood_mark" : false | |
}; | |
numeric_values.forEach(function (nvalue) { | |
var re = new RegExp(nvalue + "=(\\d+)"); | |
var result = line.match(re); | |
if(result) { | |
if(nvalue === "dl_vlan") nvalue = "vlan_id"; | |
data[nvalue] = Number(result[1]); | |
} | |
}); | |
mac_values.forEach(function (svalue) { | |
var re = new RegExp(svalue + "=(\\S+)"); | |
var result = line.match(re); | |
// set svg item class key by mac_address | |
if(result) { | |
data["mac"] = result[1]; | |
} | |
}); | |
var result = line.match(/actions=(\S+)/); | |
if(result) { | |
var actions_str = result[1]; | |
if(actions_str.match(/FLOOD/)) { | |
// flood action only used in ssw | |
data.output = "FLOOD"; | |
data.action_flood = true; | |
data.flood_mark = true; | |
} | |
var res; | |
res = actions_str.match(/output:(\d+)/); | |
if(res) { | |
data.output = Number(res[1]); | |
} | |
res = actions_str.match(/mod_vlan_vid:(\d+)/); | |
if(res) { | |
data.vlan = res[1]; | |
} | |
} | |
return data; | |
}); | |
} | |
function fill_mac_for_switch_flows(sw_flows) { | |
var isp_flows = sw_flows["$1"]; // inter switch port | |
isp_flows.forEach(function(flow) { | |
if(!flow.action_flood && flow.mac) { | |
sw_flows["$" + flow.output].forEach(function(target_flow) { | |
target_flow.mac = flow.mac; | |
}); | |
} | |
}); | |
} | |
function mark_flood_for_psw_flows(psw_flows) { | |
var edge_ports = Object.keys(psw_flows).filter( | |
function(d) { return "$1" !== d; } | |
); | |
edge_ports.forEach(function(port) { | |
psw_flows[port].forEach(function(flow){ | |
// rule from psw edgeport includes flooding. | |
flow.flood_mark = true; | |
}); | |
}); | |
} | |
function gen_keys(sw, flow) { | |
var keys = [ "sw_" + sw.replace(/\$/g, "") ]; | |
if(!flow.action_flood && flow.mac) { | |
keys.push("mac_" + flow.mac.replace(/:/g, "")); | |
} | |
if(flow.flood_mark) { | |
keys.push("flood"); | |
} | |
if (sw === "$ssw") { | |
if(flow.in_port > 1) { // ssw edge port | |
keys.push("to_testee"); | |
} else { | |
keys.push("to_tester"); | |
} | |
} else { | |
if(flow.in_port > 1) { // psw edge port | |
keys.push("to_tester"); | |
} else { | |
keys.push("to_testee"); | |
} | |
} | |
return keys; | |
} | |
function setup_key(nested_flows) { | |
Object.keys(nested_flows).forEach(function(sw) { | |
var port_table = nested_flows[sw]; | |
Object.keys(port_table).forEach(function(port) { | |
var port_flows = port_table[port]; | |
port_flows.forEach(function(flow) { | |
flow.tags = gen_keys(sw, flow).join(" "); | |
}); | |
}); | |
}); | |
} | |
function fill_flows(nested_flows) { | |
var ssw_flows = nested_flows["$ssw"]; | |
fill_mac_for_switch_flows(ssw_flows); | |
console.log(ssw_flows); | |
var psw_flows = nested_flows["$psw"]; | |
fill_mac_for_switch_flows(psw_flows); | |
mark_flood_for_psw_flows(psw_flows); | |
console.log(psw_flows); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Flow viewer sample</title> | |
<link rel="stylesheet" type="text/css" href="flow_view.css"> | |
</head> | |
<body> | |
<h1>Flow viewer</h1> | |
<p>Run http server by</p> | |
<pre> | |
ruby -rwebrick -e 'WEBrick::HTTPServer.new(:DocumentRoot => "./", :Port => 8000).start' | |
</pre> | |
<form name="flow_tables"> | |
<p>SSW Flow-table: OVS (0xdad1c001)</p> | |
<textarea name="ssw" cols="100" rows="10"> | |
NXST_FLOW reply (xid=0x4): | |
cookie=0x0, duration=177.909s, table=0, n_packets=4, n_bytes=370, idle_age=72, priority=0,in_port=1,dl_vlan=2025,dl_dst=00:ba:dc:ab:1e:01 actions=strip_vlan,output:2 | |
cookie=0x0, duration=177.181s, table=0, n_packets=4, n_bytes=370, idle_age=70, priority=0,in_port=1,dl_vlan=2025,dl_dst=00:ba:dc:ab:1e:02 actions=strip_vlan,output:3 | |
cookie=0x0, duration=176.371s, table=0, n_packets=4, n_bytes=370, idle_age=68, priority=0,in_port=1,dl_vlan=2025,dl_dst=00:ba:dc:ab:1e:03 actions=strip_vlan,output:4 | |
cookie=0x0, duration=175.417s, table=0, n_packets=4, n_bytes=370, idle_age=65, priority=0,in_port=1,dl_vlan=2025,dl_dst=00:ba:dc:ab:1e:04 actions=strip_vlan,output:5 | |
cookie=0x0, duration=175.417s, table=0, n_packets=12, n_bytes=768, idle_age=67, priority=2,in_port=1,dl_vlan=2025,dl_dst=ff:ff:ff:ff:ff:ff actions=strip_vlan,FLOOD | |
cookie=0x0, duration=174.411s, table=0, n_packets=4, n_bytes=370, idle_age=63, priority=0,in_port=1,dl_vlan=2023,dl_dst=00:ba:dc:ab:1e:05 actions=strip_vlan,output:6 | |
cookie=0x0, duration=173.322s, table=0, n_packets=4, n_bytes=370, idle_age=61, priority=0,in_port=1,dl_vlan=2023,dl_dst=00:ba:dc:ab:1e:06 actions=strip_vlan,output:7 | |
cookie=0x0, duration=172.162s, table=0, n_packets=4, n_bytes=370, idle_age=59, priority=0,in_port=1,dl_vlan=2023,dl_dst=00:ba:dc:ab:1e:07 actions=strip_vlan,output:8 | |
cookie=0x0, duration=170.840s, table=0, n_packets=4, n_bytes=370, idle_age=57, priority=0,in_port=1,dl_vlan=2023,dl_dst=00:ba:dc:ab:1e:08 actions=strip_vlan,output:9 | |
cookie=0x0, duration=170.840s, table=0, n_packets=12, n_bytes=768, idle_age=59, priority=2,in_port=1,dl_vlan=2023,dl_dst=ff:ff:ff:ff:ff:ff actions=strip_vlan,FLOOD | |
cookie=0x0, duration=187.658s, table=0, n_packets=0, n_bytes=0, idle_age=187, priority=1,in_port=1,dl_dst=ff:ff:ff:ff:ff:ff actions=FLOOD | |
cookie=0x0, duration=177.919s, table=0, n_packets=12, n_bytes=984, idle_age=72, priority=0,in_port=2 actions=mod_vlan_vid:2025,output:1 | |
cookie=0x0, duration=177.197s, table=0, n_packets=12, n_bytes=984, idle_age=70, priority=0,in_port=3 actions=mod_vlan_vid:2025,output:1 | |
cookie=0x0, duration=176.375s, table=0, n_packets=12, n_bytes=984, idle_age=68, priority=0,in_port=4 actions=mod_vlan_vid:2025,output:1 | |
cookie=0x0, duration=175.457s, table=0, n_packets=12, n_bytes=984, idle_age=65, priority=0,in_port=5 actions=mod_vlan_vid:2025,output:1 | |
cookie=0x0, duration=174.458s, table=0, n_packets=12, n_bytes=984, idle_age=63, priority=0,in_port=6 actions=mod_vlan_vid:2023,output:1 | |
cookie=0x0, duration=173.374s, table=0, n_packets=12, n_bytes=984, idle_age=61, priority=0,in_port=7 actions=mod_vlan_vid:2023,output:1 | |
cookie=0x0, duration=172.200s, table=0, n_packets=12, n_bytes=984, idle_age=59, priority=0,in_port=8 actions=mod_vlan_vid:2023,output:1 | |
cookie=0x0, duration=170.899s, table=0, n_packets=12, n_bytes=984, idle_age=57, priority=0,in_port=9 actions=mod_vlan_vid:2023,output:1 | |
</textarea> | |
<p>PSW Flow-table: OFS</p> | |
<textarea name="psw" cols="100" rows="10"> | |
NXST_FLOW reply (xid=0x4): | |
cookie=0x0, duration=206.174s, table=0, n_packets=n/a, n_bytes=6489, idle_age=0, priority=0,in_port=7 actions=output:1 | |
cookie=0x0, duration=803.871s, table=0, n_packets=n/a, n_bytes=77622, idle_age=0, in_port=15 actions=output:14 | |
cookie=0x0, duration=205.010s, table=0, n_packets=n/a, n_bytes=5866, idle_age=7, priority=0,in_port=10 actions=output:1 | |
cookie=0x0, duration=207.260s, table=0, n_packets=n/a, n_bytes=11640, idle_age=0, priority=0,in_port=6 actions=output:1 | |
cookie=0x0, duration=203.698s, table=0, n_packets=n/a, n_bytes=5291, idle_age=6, priority=0,in_port=11 actions=output:1 | |
cookie=0x0, duration=805.384s, table=0, n_packets=n/a, n_bytes=42536, idle_age=0, in_port=12 actions=output:13 | |
cookie=0x0, duration=805.354s, table=0, n_packets=n/a, n_bytes=0, idle_age=805, in_port=13 actions=output:12 | |
cookie=0x0, duration=805.317s, table=0, n_packets=n/a, n_bytes=3056, idle_age=90, in_port=14 actions=output:15 | |
cookie=0x0, duration=203.709s, table=0, n_packets=n/a, n_bytes=1094, idle_age=90, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:08 actions=output:11 | |
cookie=0x0, duration=205.020s, table=0, n_packets=n/a, n_bytes=1524, idle_age=92, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:07 actions=output:10 | |
cookie=0x0, duration=208.276s, table=0, n_packets=n/a, n_bytes=1086, idle_age=98, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:04 actions=output:11 | |
cookie=0x0, duration=209.998s, table=0, n_packets=n/a, n_bytes=1090, idle_age=102, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:02 actions=output:7 | |
cookie=0x0, duration=209.194s, table=0, n_packets=n/a, n_bytes=1554, idle_age=100, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:03 actions=output:10 | |
cookie=0x0, duration=207.273s, table=0, n_packets=n/a, n_bytes=1242, idle_age=96, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:05 actions=output:6 | |
cookie=0x0, duration=206.186s, table=0, n_packets=n/a, n_bytes=1094, idle_age=94, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:06 actions=output:7 | |
cookie=0x0, duration=210.724s, table=0, n_packets=n/a, n_bytes=1086, idle_age=104, priority=0,in_port=1,dl_src=00:ba:dc:ab:1e:01 actions=output:6 | |
</textarea> | |
</form> | |
<p>View</p> | |
<div id="flow_view"></div> | |
<script src="https://d3js.org/d3.v4.min.js"></script> | |
<script src="https://d3js.org/d3-selection-multi.v1.min.js"></script> | |
<script src="./flow_data.js"></script> | |
<script src="./flow_view.js"></script> | |
<script type="text/javascript"> | |
build_flowdata( | |
document.flow_tables.ssw, | |
document.flow_tables.psw); | |
// draw_flow_tables(ssw_flows, psw_flows); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment