Skip to content
Snippets Groups Projects
Commit 5fad7e12 authored by hwchiu's avatar hwchiu
Browse files

Make the WEBUI shows the flow info

1. Modify the wm/core/switch/${id}/flow/json's return format, it use a
array to shows the flow entries, e.g. I think this format is more convenience for restapi caller.

"flows": [
        {
            "byte_count": "2498",
            "cookie": "0",
            "duration_sec": "4",
            "flags": "0",
            "hard_timeout_sec": "0",
            "idle_timeout_sec": "0",
            "instructions": {
                "apply_actions": {
                    "output": "-3"
                }
            },
            "match": {},
            "packet_count": "33",
            "priority": "32768",
            "table_id": "0",
            "version": "OF_13"
        },
        {
            "byte_count": "0",
            "cookie": "9007199254740992",
            "duration_sec": "2",
            "flags": "0",
            "hard_timeout_sec": "0",
            "idle_timeout_sec": "5",
            "instructions": {
                "apply_actions": {
                    "output": "1"
                }
            },
            "match": {
                "dl_dst": "e6:85:22:16:59:87",
                "dl_src": "b2:ac:81:4a:92:57",
                "dl_type": "2054",
                "ingress_port": "2"
            },
            "packet_count": "0",
            "priority": "0",
            "table_id": "0",
            "version": "OF_13"
        },
2. Adding the new coloum write_actions and replace the original action field to apply_actions.
3. Since the OF1.1+ use the OXM format to present the match filed, we don't need to use the wildcard to check what kind of the fild be used in the flow, we can directly use the query result. If we want to make it compatible with OF1.0, we need to use the version field to check in the javascript and modify the way how we get the match rules.
4. It has only been test with the default forwarding module and the flow entries looks right. It need to be tested with other match rule and actions.
5. replace the tab with 4-spaces
parent 478b00ca
No related branches found
No related tags found
No related merge requests found
...@@ -107,7 +107,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { ...@@ -107,7 +107,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> {
switch (reply.getStatType()) { switch (reply.getStatType()) {
case PORT: case PORT:
// handle port // handle port
serializePortReply((List<OFPortStatsReply>) reply.getValues(), jGen); serializePortReply((List<OFPortStatsReply>) reply.getValues(), jGen);
break; break;
case QUEUE: case QUEUE:
// handle queue // handle queue
...@@ -146,7 +146,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { ...@@ -146,7 +146,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> {
case METER_FEATURES: case METER_FEATURES:
break; break;
case PORT_DESC: case PORT_DESC:
serializePortDescReply((List<OFPortDescStatsReply>) reply.getValues(), jGen); serializePortDescReply((List<OFPortDescStatsReply>) reply.getValues(), jGen);
break; break;
default: default:
break; break;
...@@ -155,49 +155,53 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { ...@@ -155,49 +155,53 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> {
} }
public void serializePortReply(List<OFPortStatsReply> portReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ public void serializePortReply(List<OFPortStatsReply> portReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
OFPortStatsReply portReply = portReplies.get(0); // we will get only one PortReply and it will contains many OFPortStatsEntry ? OFPortStatsReply portReply = portReplies.get(0); // we will get only one PortReply and it will contains many OFPortStatsEntry ?
jGen.writeStringField("version", portReply.getVersion().toString()); //return the enum name jGen.writeStringField("version", portReply.getVersion().toString()); //return the enum name
jGen.writeFieldName("port"); jGen.writeFieldName("port");
jGen.writeStartArray(); jGen.writeStartArray();
for(OFPortStatsEntry entry : portReply.getEntries()) { for(OFPortStatsEntry entry : portReply.getEntries()) {
jGen.writeStartObject(); jGen.writeStartObject();
jGen.writeStringField("portNumber",entry.getPortNo().toString()); jGen.writeStringField("portNumber",entry.getPortNo().toString());
jGen.writeNumberField("receivePackets", entry.getRxPackets().getValue()); jGen.writeNumberField("receivePackets", entry.getRxPackets().getValue());
jGen.writeNumberField("transmitPackets", entry.getTxPackets().getValue()); jGen.writeNumberField("transmitPackets", entry.getTxPackets().getValue());
jGen.writeNumberField("receiveBytes", entry.getRxBytes().getValue()); jGen.writeNumberField("receiveBytes", entry.getRxBytes().getValue());
jGen.writeNumberField("transmitBytes", entry.getTxBytes().getValue()); jGen.writeNumberField("transmitBytes", entry.getTxBytes().getValue());
jGen.writeNumberField("receiveDropped", entry.getRxDropped().getValue()); jGen.writeNumberField("receiveDropped", entry.getRxDropped().getValue());
jGen.writeNumberField("transmitDropped", entry.getTxDropped().getValue()); jGen.writeNumberField("transmitDropped", entry.getTxDropped().getValue());
jGen.writeNumberField("receiveErrors", entry.getRxErrors().getValue()); jGen.writeNumberField("receiveErrors", entry.getRxErrors().getValue());
jGen.writeNumberField("transmitErrors", entry.getTxErrors().getValue()); jGen.writeNumberField("transmitErrors", entry.getTxErrors().getValue());
jGen.writeNumberField("receiveFrameErrors", entry.getRxFrameErr().getValue()); jGen.writeNumberField("receiveFrameErrors", entry.getRxFrameErr().getValue());
jGen.writeNumberField("receiveOverrunErrors", entry.getRxOverErr().getValue()); jGen.writeNumberField("receiveOverrunErrors", entry.getRxOverErr().getValue());
jGen.writeNumberField("receiveCRCErrors", entry.getRxCrcErr().getValue()); jGen.writeNumberField("receiveCRCErrors", entry.getRxCrcErr().getValue());
jGen.writeNumberField("collisions", entry.getCollisions().getValue()); jGen.writeNumberField("collisions", entry.getCollisions().getValue());
if (OFVersion.OF_13 == entry.getVersion()) { if (OFVersion.OF_13 == entry.getVersion()) {
jGen.writeNumberField("durationSec", entry.getDurationSec()); jGen.writeNumberField("durationSec", entry.getDurationSec());
jGen.writeNumberField("durationNsec", entry.getDurationNsec()); jGen.writeNumberField("durationNsec", entry.getDurationNsec());
} }
jGen.writeEndObject(); jGen.writeEndObject();
} }
jGen.writeEndArray(); jGen.writeEndArray();
} }
public void serializeFlowReply(List<OFFlowStatsReply> flowReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ public void serializeFlowReply(List<OFFlowStatsReply> flowReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
int flowCount = 0; int flowCount = 0;
for (OFFlowStatsReply flowReply : flowReplies) { // for each flow stats reply for (OFFlowStatsReply flowReply : flowReplies) { // for each flow stats reply
//Dose the switch will reply multiple OFFlowStatsReply ?
//Or we juse need to use the first item of the list.
List<OFFlowStatsEntry> entries = flowReply.getEntries(); List<OFFlowStatsEntry> entries = flowReply.getEntries();
jGen.writeFieldName("flows");
jGen.writeStartArray();
for (OFFlowStatsEntry entry : entries) { // for each flow for (OFFlowStatsEntry entry : entries) { // for each flow
jGen.writeStartObject();
// list flow stats/info // list flow stats/info
jGen.writeObjectFieldStart("flow" + Integer.toString(flowCount++)); // need to have different object names or JSON parser might only show the last one
jGen.writeStringField("version", entry.getVersion().toString()); // return the enum name jGen.writeStringField("version", entry.getVersion().toString()); // return the enum name
jGen.writeNumberField("cookie", entry.getCookie().getValue()); jGen.writeNumberField("cookie", entry.getCookie().getValue());
jGen.writeNumberField("table_id", entry.getTableId().getValue()); jGen.writeNumberField("tableId", entry.getTableId().getValue());
jGen.writeNumberField("packet_count", entry.getPacketCount().getValue()); jGen.writeNumberField("packetCount", entry.getPacketCount().getValue());
jGen.writeNumberField("byte_count", entry.getByteCount().getValue()); jGen.writeNumberField("byteCount", entry.getByteCount().getValue());
jGen.writeNumberField("duration_sec", entry.getDurationSec()); jGen.writeNumberField("durationSeconds", entry.getDurationSec());
jGen.writeNumberField("priority", entry.getPriority()); jGen.writeNumberField("priority", entry.getPriority());
jGen.writeNumberField("idle_timeout_sec", entry.getIdleTimeout()); jGen.writeNumberField("idleTimeoutSec", entry.getIdleTimeout());
jGen.writeNumberField("hard_timeout_sec", entry.getHardTimeout()); jGen.writeNumberField("hardTimeoutSec", entry.getHardTimeout());
jGen.writeNumberField("flags", entry.getFlags()); jGen.writeNumberField("flags", entry.getFlags());
// list flow matches // list flow matches
jGen.writeObjectFieldStart("match"); jGen.writeObjectFieldStart("match");
...@@ -372,6 +376,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { ...@@ -372,6 +376,7 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> {
} // end not-empty instructions (else) } // end not-empty instructions (else)
jGen.writeEndObject(); jGen.writeEndObject();
} // end for each OFFlowStatsReply entry } // end for each OFFlowStatsReply entry
jGen.writeEndArray();
} // end for each OFStatsReply } // end for each OFStatsReply
} // end method } // end method
...@@ -577,55 +582,55 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> { ...@@ -577,55 +582,55 @@ public class StatsReplySerializer extends JsonSerializer<StatsReply> {
} }
public void serializePortDescReply(List<OFPortDescStatsReply> portDescReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{ public void serializePortDescReply(List<OFPortDescStatsReply> portDescReplies, JsonGenerator jGen) throws IOException, JsonProcessingException{
OFPortDescStatsReply portDescReply = portDescReplies.get(0); // we will get only one PortDescReply and it will contains many OFPortDescStatsEntry ? OFPortDescStatsReply portDescReply = portDescReplies.get(0); // we will get only one PortDescReply and it will contains many OFPortDescStatsEntry ?
jGen.writeStringField("version", portDescReply.getVersion().toString()); //return the enum name jGen.writeStringField("version", portDescReply.getVersion().toString()); //return the enum name
jGen.writeFieldName("portDesc"); jGen.writeFieldName("portDesc");
jGen.writeStartArray(); jGen.writeStartArray();
for(OFPortDesc entry : portDescReply.getEntries()) { for(OFPortDesc entry : portDescReply.getEntries()) {
jGen.writeStartObject(); jGen.writeStartObject();
jGen.writeStringField("portNumber",entry.getPortNo().toString()); jGen.writeStringField("portNumber",entry.getPortNo().toString());
jGen.writeStringField("hardwareAddress", entry.getHwAddr().toString()); jGen.writeStringField("hardwareAddress", entry.getHwAddr().toString());
jGen.writeStringField("name", entry.getName()); jGen.writeStringField("name", entry.getName());
switch(entry.getVersion()) { switch(entry.getVersion()) {
case OF_10: case OF_10:
jGen.writeNumberField("config", OFPortConfigSerializerVer10.toWireValue(entry.getConfig())); jGen.writeNumberField("config", OFPortConfigSerializerVer10.toWireValue(entry.getConfig()));
jGen.writeNumberField("state", OFPortStateSerializerVer10.toWireValue(entry.getState())); jGen.writeNumberField("state", OFPortStateSerializerVer10.toWireValue(entry.getState()));
jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getCurr())); jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getCurr()));
jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getAdvertised())); jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getAdvertised()));
jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getSupported())); jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getSupported()));
jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getPeer())); jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer10.toWireValue(entry.getPeer()));
break; break;
case OF_11: case OF_11:
jGen.writeNumberField("config", OFPortConfigSerializerVer11.toWireValue(entry.getConfig())); jGen.writeNumberField("config", OFPortConfigSerializerVer11.toWireValue(entry.getConfig()));
jGen.writeNumberField("state", OFPortStateSerializerVer11.toWireValue(entry.getState())); jGen.writeNumberField("state", OFPortStateSerializerVer11.toWireValue(entry.getState()));
jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getCurr())); jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getCurr()));
jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getAdvertised())); jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getAdvertised()));
jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getSupported())); jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getSupported()));
jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getPeer())); jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer11.toWireValue(entry.getPeer()));
break; break;
case OF_12: case OF_12:
jGen.writeNumberField("config", OFPortConfigSerializerVer12.toWireValue(entry.getConfig())); jGen.writeNumberField("config", OFPortConfigSerializerVer12.toWireValue(entry.getConfig()));
jGen.writeNumberField("state", OFPortStateSerializerVer12.toWireValue(entry.getState())); jGen.writeNumberField("state", OFPortStateSerializerVer12.toWireValue(entry.getState()));
jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getCurr())); jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getCurr()));
jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getAdvertised())); jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getAdvertised()));
jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getSupported())); jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getSupported()));
jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getPeer())); jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer12.toWireValue(entry.getPeer()));
break; break;
case OF_13: case OF_13:
jGen.writeNumberField("config", OFPortConfigSerializerVer13.toWireValue(entry.getConfig())); jGen.writeNumberField("config", OFPortConfigSerializerVer13.toWireValue(entry.getConfig()));
jGen.writeNumberField("state", OFPortStateSerializerVer13.toWireValue(entry.getState())); jGen.writeNumberField("state", OFPortStateSerializerVer13.toWireValue(entry.getState()));
jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getCurr())); jGen.writeNumberField("currentFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getCurr()));
jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getAdvertised())); jGen.writeNumberField("advertisedFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getAdvertised()));
jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getSupported())); jGen.writeNumberField("supportedFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getSupported()));
jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getPeer())); jGen.writeNumberField("peerFeatures", OFPortFeaturesSerializerVer13.toWireValue(entry.getPeer()));
break; break;
} }
if (OFVersion.OF_10 != entry.getVersion()) { if (OFVersion.OF_10 != entry.getVersion()) {
jGen.writeNumberField("currSpeed",entry.getCurrSpeed()); jGen.writeNumberField("currSpeed",entry.getCurrSpeed());
jGen.writeNumberField("maxSpeed",entry.getMaxSpeed()); jGen.writeNumberField("maxSpeed",entry.getMaxSpeed());
} }
jGen.writeEndObject(); jGen.writeEndObject();
} }
jGen.writeEndArray(); jGen.writeEndArray();
} }
} }
...@@ -73,7 +73,6 @@ window.Switch = Backbone.Model.extend({ ...@@ -73,7 +73,6 @@ window.Switch = Backbone.Model.extend({
dataType:"json", dataType:"json",
success:function (data) { success:function (data) {
//console.log("fetched switch " + self.id + " ports"); //console.log("fetched switch " + self.id + " ports");
console.log(data['port']);
var old_ids = self.ports.pluck('id'); var old_ids = self.ports.pluck('id');
//console.log("old_ids" + old_ids); //console.log("old_ids" + old_ids);
...@@ -103,7 +102,6 @@ window.Switch = Backbone.Model.extend({ ...@@ -103,7 +102,6 @@ window.Switch = Backbone.Model.extend({
console.log("removing port " + p); console.log("removing port " + p);
self.remove({id:p}); self.remove({id:p});
}); });
console.log(self.ports);
} }
}), }),
$.ajax({ $.ajax({
...@@ -111,7 +109,7 @@ window.Switch = Backbone.Model.extend({ ...@@ -111,7 +109,7 @@ window.Switch = Backbone.Model.extend({
dataType:"json", dataType:"json",
success:function (data) { success:function (data) {
//console.log("fetched switch " + self.id + " features"); //console.log("fetched switch " + self.id + " features");
console.log(data['portDesc']); //console.log(data['portDesc']);
// update port models // update port models
_.each(data['portDesc'], function(p) { _.each(data['portDesc'], function(p) {
p.id = self.id+'-'+p.portNumber; p.id = self.id+'-'+p.portNumber;
...@@ -168,7 +166,7 @@ window.Switch = Backbone.Model.extend({ ...@@ -168,7 +166,7 @@ window.Switch = Backbone.Model.extend({
dataType:"json", dataType:"json",
success:function (data) { success:function (data) {
//console.log("fetched switch " + self.id + " flows"); //console.log("fetched switch " + self.id + " flows");
var flows = data[self.id]; var flows = data['flows'];
//console.log(flows); //console.log(flows);
// create flow models // create flow models
...@@ -178,81 +176,31 @@ window.Switch = Backbone.Model.extend({ ...@@ -178,81 +176,31 @@ window.Switch = Backbone.Model.extend({
// build human-readable match // build human-readable match
f.matchHTML = ''; f.matchHTML = '';
if(!(f.match.wildcards & (1<<0))) { // input port if(f.hasOwnProperty('match')) {
f.matchHTML += "port=" + f.match.inputPort + ", "; _.each(f.match, function(value , key) {
f.matchHTML += key + "=" + value +" ";
},f);
} }
if(!(f.match.wildcards & (1<<1))) { // VLAN ID
f.matchHTML += "VLAN=" + f.match.dataLayerVirtualLan + ", ";
}
if(!(f.match.wildcards & (1<<20))) { // VLAN prio
f.matchHTML += "prio=" + f.match.dataLayerVirtualLanPriorityCodePoint + ", ";
}
if(!(f.match.wildcards & (1<<2))) { // src MAC
f.matchHTML += "src=<a href='/host/" + f.match.dataLayerSource + "'>" +
f.match.dataLayerSource + "</a>, ";
}
if(!(f.match.wildcards & (1<<3))) { // dest MAC
f.matchHTML += "dest=<a href='/host/" + f.match.dataLayerDestination + "'>" +
f.match.dataLayerDestination + "</a>, ";
}
if(!(f.match.wildcards & (1<<4))) { // Ethertype
// TODO print a human-readable name instead of hex
f.matchHTML += "ethertype=" + f.match.dataLayerType + ", ";
}
if(!(f.match.wildcards & (1<<5))) { // IP protocol
// TODO print a human-readable name
f.matchHTML += "proto=" + f.match.networkProtocol + ", ";
}
if(!(f.match.wildcards & (1<<6))) { // TCP/UDP source port
f.matchHTML += "IP src port=" + f.match.transportSource + ", ";
}
if(!(f.match.wildcards & (1<<7))) { // TCP/UDP dest port
f.matchHTML += "IP dest port=" + f.match.transportDestination + ", ";
}
if(!(f.match.wildcards & (32<<8))) { // src IP
f.matchHTML += "src=" + f.match.networkSource + ", ";
}
if(!(f.match.wildcards & (32<<14))) { // dest IP
f.matchHTML += "dest=" + f.match.networkDestination + ", ";
}
if(!(f.match.wildcards & (1<<21))) { // IP TOS
f.matchHTML += "TOS=" + f.match.networkTypeOfService + ", ";
}
// remove trailing ", "
f.matchHTML = f.matchHTML.substr(0, f.matchHTML.length - 2); f.matchHTML = f.matchHTML.substr(0, f.matchHTML.length - 2);
// build human-readable action list f.applyActionText = '';
f.actionText = _.reduce(f.actions, function (memo, a) { f.writeActionText = '';
switch (a.type) { if(f.hasOwnProperty('instructions')) {
case "OUTPUT": if(f.instructions.hasOwnProperty('apply_actions')) {
return memo + "output " + a.port + ', '; _.each(f.instructions.apply_actions, function(value, key) {
case "OPAQUE_ENQUEUE": f.applyActionText += key + ":" + value +" ";
return memo + "enqueue " + a.port + ':' + a.queueId + ', '; },f);
case "STRIP_VLAN": }
return memo + "strip VLAN, "; if(f.instructions.hasOwnProperty('write_actions')) {
case "SET_VLAN_ID": _.each(f.instructions.write_actions, function(value, key) {
return memo + "VLAN=" + a.virtualLanIdentifier + ', '; f.writeActionText += key + ":" + value +" ";
case "SET_VLAN_PCP": },f);
return memo + "prio=" + a.virtualLanPriorityCodePoint + ', ';
case "SET_DL_SRC":
return memo + "src=" + a.dataLayerAddress + ', ';
case "SET_DL_DST":
return memo + "dest=" + a.dataLayerAddress + ', ';
case "SET_NW_TOS":
return memo + "TOS=" + a.networkTypeOfService + ', ';
case "SET_NW_SRC":
return memo + "src=" + a.networkAddress + ', ';
case "SET_NW_DST":
return memo + "dest=" + a.networkAddress + ', ';
case "SET_TP_SRC":
return memo + "src port=" + a.transportPort + ', ';
case "SET_TP_DST":
return memo + "dest port=" + a.transportPort + ', ';
} }
}, "");
// remove trailing ", "
f.actionText = f.actionText.substr(0, f.actionText.length - 2);
}
// build human-readable action list
f.applyActionText = f.applyActionText.substr(0, f.applyActionText.length - 2);
f.writeActionText = f.writeActionText.substr(0, f.writeActionText.length - 2);
//console.log(f); //console.log(f);
self.flows.add(f, {silent: true}); self.flows.add(f, {silent: true});
}); });
......
<td><%= cookie %></td><td><%= priority %></td><td><%= matchHTML %></td><td><%= actionText %></td><td><%= packetCount %></td><td><%= byteCount %></td><td><%= durationSeconds %> s</td><td><%= idleTimeout %> s</td> <td><%= cookie %></td><td><%= priority %></td><td><%= matchHTML %></td><td><%= applyActionText %></td><td><%= writeActionText %></td><td><%= packetCount %></td><td><%= byteCount %></td><td><%= durationSeconds %> s</td><td><%= idleTimeoutSec %> s</td>
...@@ -2,7 +2,7 @@ ...@@ -2,7 +2,7 @@
<h1>Flows (<%= nflows %>)</h1> <h1>Flows (<%= nflows %>)</h1>
</div> </div>
<table class="table table-striped flow-table"> <table class="table table-striped flow-table">
<thead><tr><th>Cookie</th><th>Priority</th><th>Match</th><th>Action</th><th>Packets</th><th>Bytes</th><th>Age</th><th>Timeout</th></tr></thead> <thead><tr><th>Cookie</th><th>Priority</th><th>Match</th><th>Apply Actions</th><th>Write Actions</th><th>Packets</th><th>Bytes</th><th>Age</th><th>Timeout</th></tr></thead>
<tbody> <tbody>
<!-- flows will be inserted here by FlowListView:render --> <!-- flows will be inserted here by FlowListView:render -->
</tbody> </tbody>
...@@ -16,4 +16,4 @@ ...@@ -16,4 +16,4 @@
<li><a href="">&rarr;</a> <li><a href="">&rarr;</a>
</ul></div> </ul></div>
--> -->
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment