Saurav Das
Committed by Gerrit Code Review

A set of fixes to ensure that the FlowRuleManager can correctly account for flows

from the dataplane in a multi-table pipeline scenario

Change-Id: I9ca3ef9a77781f126a13538647c824b27f77101c
Showing 21 changed files with 294 additions and 108 deletions
......@@ -557,7 +557,7 @@ public class BgpRouter {
rule = new DefaultFlowRule(deviceId, selector.build(),
treatment.build(), CONTROLLER_PRIORITY,
appId, 0, true, FlowRule.Type.ACL);
appId, 0, true, FlowRule.Type.DEFAULT);
ops = install ? ops.add(rule) : ops.remove(rule);
......
......@@ -74,7 +74,7 @@ public class TunnellingConnectivityManager {
selector.matchTcpSrc(BGP_PORT);
packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
appId, FlowRule.Type.ACL);
appId, FlowRule.Type.DEFAULT);
selector = DefaultTrafficSelector.builder();
......@@ -84,7 +84,7 @@ public class TunnellingConnectivityManager {
selector.matchTcpDst(BGP_PORT);
packetService.requestPackets(selector.build(), PacketPriority.CONTROL,
appId, FlowRule.Type.ACL);
appId, FlowRule.Type.DEFAULT);
}
public void stop() {
......
......@@ -61,6 +61,23 @@ public class DefaultFlowRule implements FlowRule {
}
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority, long flowId,
int timeout, boolean permanent, Type tableType) {
this.deviceId = deviceId;
this.priority = priority;
this.selector = selector;
this.treatment = treatment;
this.timeout = timeout;
this.permanent = permanent;
this.created = System.currentTimeMillis();
this.appId = (short) (flowId >>> 48);
this.groupId = new DefaultGroupId((short) ((flowId >>> 32) & 0xFFFF));
this.id = FlowId.valueOf(flowId);
this.type = tableType;
}
public DefaultFlowRule(DeviceId deviceId, TrafficSelector selector,
TrafficTreatment treatment, int priority, ApplicationId appId,
int timeout, boolean permanent) {
this(deviceId, selector, treatment, priority, appId, new DefaultGroupId(0),
......
......@@ -355,31 +355,29 @@ public class FlowRuleManager
@Override
public void pushFlowMetrics(DeviceId deviceId, Iterable<FlowEntry> flowEntries) {
Set<FlowEntry> storedRules = Sets.newHashSet(store.getFlowEntries(deviceId));
for (FlowEntry rule : flowEntries) {
try {
if (storedRules.remove(rule)) {
// we both have the rule, let's update some info then.
flowAdded(rule);
} else {
// the device has a rule the store does not have
extraneousFlow(rule);
}
} catch (Throwable e) {
log.debug("Can't process added or extra rule {}", e.getMessage());
continue;
for (FlowEntry rule : flowEntries) {
try {
if (storedRules.remove(rule)) {
// we both have the rule, let's update some info then.
flowAdded(rule);
} else {
// the device has a rule the store does not have
extraneousFlow(rule);
}
} catch (Throwable e) {
log.debug("Can't process added or extra rule {}", e.getMessage());
continue;
}
for (FlowEntry rule : storedRules) {
try {
// there are rules in the store that aren't on the switch
flowMissing(rule);
} catch (Throwable e) {
log.debug("Can't add missing flow rule {}", e.getMessage());
continue;
}
}
for (FlowEntry rule : storedRules) {
try {
// there are rules in the store that aren't on the switch
flowMissing(rule);
} catch (Throwable e) {
log.debug("Can't add missing flow rule {}", e.getMessage());
continue;
}
}
}
......
......@@ -20,6 +20,7 @@ import java.util.List;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.types.TableId;
/**
* Represents to provider facing side of a switch.
......@@ -38,7 +39,7 @@ public interface OpenFlowSwitch {
/* VLAN table */
VLAN,
/* L2 table */
/* Ethertype table */
ETHER,
/* Class of Service table */
......@@ -52,6 +53,8 @@ public interface OpenFlowSwitch {
ACL,
/* Single table */
NONE,
/* First table in multi-table */
FIRST,
}
......@@ -64,21 +67,22 @@ public interface OpenFlowSwitch {
public void sendMsg(OFMessage msg);
/**
* Writes to the OFMessage list to the driver.
* Writes the OFMessage list to the driver.
*
* @param msgs the messages to be written
*/
public void sendMsg(List<OFMessage> msgs);
/**
* Writes to the OFMessage list to the driver.
* TableType is used to determine the table ID for the OFMessage.
* The switch driver that supports multi-table should implement the function.
* Transforms FlowMod messages by setting the correct table-ids and sending
* them to the switch. TableType is used to determine the table ID for the OFMessage.
* Switch drivers that supports multi-table pipelines should implement this
* method.
*
* @param msg the message to be written
* @param tableType the type of table in which the OFMessage needs to put
* @param tableType the type of table in which the FlowMods need to be inserted
*/
public void sendMsg(OFMessage msg, TableType tableType);
public void transformAndSendMsg(OFMessage msg, TableType tableType);
/**
* Handle a message from the switch.
......@@ -189,4 +193,11 @@ public interface OpenFlowSwitch {
*/
public String channelId();
/**
* Returns the TableType corresponding to the TableId used to identify
* a table in an OpenFlow switch.
* @param tid identifies a table in an OpenFlow switch using TableId
* @return TableType corresponding to 'tid' identifying the type of table
*/
public TableType getTableType(TableId tid);
}
......
......@@ -110,13 +110,6 @@ public abstract class AbstractOpenFlowSwitch implements OpenFlowSwitchDriver {
}
@Override
public void sendMsg(OFMessage msg, TableType tableType) {
if (role == RoleState.MASTER) {
this.write(msg);
}
}
@Override
public abstract void write(OFMessage msg);
@Override
......
......@@ -23,6 +23,7 @@ import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
import org.onosproject.openflow.controller.driver.OpenFlowAgent;
import org.onosproject.openflow.controller.driver.OpenFlowSwitchDriver;
import org.onosproject.openflow.controller.driver.RoleHandler;
......@@ -38,6 +39,7 @@ import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.types.TableId;
import org.projectfloodlight.openflow.types.U64;
import static org.junit.Assert.assertEquals;
......@@ -111,7 +113,7 @@ public class RoleManagerTest {
}
@Override
public void sendMsg(OFMessage msg, TableType tableType) {
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
}
@Override
......@@ -309,6 +311,10 @@ public class RoleManagerTest {
return "1.2.3.4:1";
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
}
}
......
......@@ -29,6 +29,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.types.TableId;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -125,6 +126,17 @@ public final class DriverManager implements OpenFlowSwitchDriverFactory {
return Collections.unmodifiableList(ports.getEntries());
}
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
};
}
......
......@@ -16,6 +16,7 @@
package org.onosproject.openflow.drivers;
import com.google.common.collect.Lists;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
......@@ -26,6 +27,7 @@ import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.instruction.OFInstructionGotoTable;
import org.projectfloodlight.openflow.types.TableId;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
......@@ -33,7 +35,7 @@ import java.util.List;
* Corsa switch driver for BGP Router deployment.
*/
public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
private static final int FIRST_TABLE = 0;
private static final int VLAN_MPLS_TABLE = 1;
private static final int VLAN_TABLE = 2;
private static final int MPLS_TABLE = 3;
......@@ -48,18 +50,45 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
setSwitchDescription(desc);
}
/**
* Used by the default sendMsg to 'write' to the switch.
* This method is indirectly used by generic onos services like proxyarp
* to request packets from the default flow table. In a multi-table
* pipeline, these requests are redirected to the correct table.
*
* For the Corsa switch, the equivalent table is the LOCAL TABLE
*
*/
@Override
public void write(OFMessage msg) {
this.write(Collections.singletonList(msg));
if (msg.getType() == OFType.FLOW_MOD) {
OFFlowMod flowMod = (OFFlowMod) msg;
OFFlowMod.Builder builder = flowMod.createBuilder();
builder.setTableId(TableId.of(LOCAL_TABLE));
channel.write(Collections.singletonList(builder.build()));
} else {
channel.write(Collections.singletonList(msg));
}
}
@Override
public void write(List<OFMessage> msgs) {
channel.write(msgs);
List<OFMessage> newMsgs = new ArrayList<OFMessage>();
for (OFMessage msg : msgs) {
if (msg.getType() == OFType.FLOW_MOD) {
OFFlowMod flowMod = (OFFlowMod) msg;
OFFlowMod.Builder builder = flowMod.createBuilder();
builder.setTableId(TableId.of(LOCAL_TABLE));
newMsgs.add(builder.build());
} else {
newMsgs.add(msg);
}
}
channel.write(newMsgs);
}
@Override
public void sendMsg(OFMessage msg, TableType type) {
public void transformAndSendMsg(OFMessage msg, TableType type) {
if (msg.getType() == OFType.FLOW_MOD) {
OFFlowMod flowMod = (OFFlowMod) msg;
OFFlowMod.Builder builder = flowMod.createBuilder();
......@@ -142,19 +171,47 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
case ACL:
builder.setTableId(TableId.of(LOCAL_TABLE));
break;
case FIRST:
builder.setTableId(TableId.of(FIRST_TABLE));
break;
case NONE:
builder.setTableId(TableId.of(0));
builder.setTableId(TableId.of(LOCAL_TABLE));
break;
default:
log.warn("Unknown table type: {}", type);
}
builder.setInstructions(newInstructions);
OFMessage msgnew = builder.build();
this.write(msgnew);
channel.write(Collections.singletonList(msgnew));
log.debug("Installed {}", msgnew);
} else {
this.write(msg);
channel.write(Collections.singletonList(msg));
}
}
@Override
public TableType getTableType(TableId tid) {
switch (tid.getValue()) {
case VLAN_MPLS_TABLE:
return TableType.VLAN_MPLS;
case VLAN_TABLE:
return TableType.VLAN;
case ETHER_TABLE:
return TableType.ETHER;
case COS_MAP_TABLE:
return TableType.COS;
case FIB_TABLE:
return TableType.IP;
case MPLS_TABLE:
return TableType.MPLS;
case LOCAL_TABLE:
return TableType.NONE;
case FIRST_TABLE:
return TableType.FIRST;
default:
log.warn("Unknown table type: {}", tid.getValue());
return TableType.NONE;
}
}
......
......@@ -30,6 +30,7 @@ import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortOptical;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.types.TableId;
import java.io.IOException;
import java.util.ArrayList;
......@@ -209,5 +210,15 @@ public class OFOpticalSwitchImplLINC13 extends AbstractOpenFlowSwitch {
return true;
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
......
......@@ -25,6 +25,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
......@@ -1216,4 +1217,15 @@ public class OFSwitchImplCPqD13 extends AbstractOpenFlowSwitch {
this.channel.write(msgs);
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE; // XXX this needs to be fixed
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
......
......@@ -24,6 +24,7 @@ import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.types.TableId;
/**
* OFDescriptionStatistics Vendor (Manufacturer Desc.): Nicira, Inc. Make
......@@ -85,5 +86,15 @@ public class OFSwitchImplOVS10 extends AbstractOpenFlowSwitch {
return Collections.unmodifiableList(features.getPorts());
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
......
......@@ -237,4 +237,15 @@ public class OFSwitchImplOVS13 extends AbstractOpenFlowSwitch {
write(tableMissEntry);
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
......
......@@ -17,6 +17,7 @@ package org.onosproject.openflow.drivers;
import org.onosproject.openflow.controller.Dpid;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeAlreadyStarted;
import org.onosproject.openflow.controller.driver.SwitchDriverSubHandshakeCompleted;
......@@ -167,7 +168,7 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
}
@Override
public void sendMsg(OFMessage m, TableType tableType) {
public void transformAndSendMsg(OFMessage m, TableType tableType) {
if (m.getType() == OFType.FLOW_MOD) {
OFFlowMod flowMod = (OFFlowMod) m;
......@@ -571,4 +572,10 @@ public class OFSwitchImplSpringOpenTTP extends AbstractOpenFlowSwitch {
.build();
write(br);
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE; // XXX this needs to be fixed
}
}
......
......@@ -49,6 +49,7 @@ import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PacketListener;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
......@@ -56,6 +57,7 @@ import org.projectfloodlight.openflow.protocol.OFPortReason;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
......@@ -310,10 +312,6 @@ public class OpenFlowDeviceProviderTest {
}
@Override
public void sendMsg(OFMessage msg, TableType tableType) {
}
@Override
public void handleMessage(OFMessage fromSwitch) {
}
......@@ -395,6 +393,17 @@ public class OpenFlowDeviceProviderTest {
return "1.2.3.4:1";
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
}
......
......@@ -34,6 +34,7 @@ import org.onosproject.net.flow.DefaultTrafficTreatment;
import org.onosproject.net.flow.FlowEntry;
import org.onosproject.net.flow.FlowEntry.FlowEntryState;
import org.onosproject.net.flow.FlowRule;
import org.onosproject.net.flow.FlowRule.Type;
import org.onosproject.net.flow.TrafficSelector;
import org.onosproject.net.flow.TrafficTreatment;
import org.onosproject.openflow.controller.Dpid;
......@@ -87,6 +88,7 @@ public class FlowEntryBuilder {
public enum FlowType { STAT, REMOVED, MOD }
private final FlowType type;
private Type tableType = FlowRule.Type.DEFAULT;
public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry) {
......@@ -99,6 +101,17 @@ public class FlowEntryBuilder {
this.type = FlowType.STAT;
}
public FlowEntryBuilder(Dpid dpid, OFFlowStatsEntry entry, Type tableType) {
this.stat = entry;
this.match = entry.getMatch();
this.actions = getActions(entry);
this.dpid = dpid;
this.removed = null;
this.flowMod = null;
this.type = FlowType.STAT;
this.tableType = tableType;
}
public FlowEntryBuilder(Dpid dpid, OFFlowRemoved removed) {
this.match = removed.getMatch();
this.removed = removed;
......@@ -127,7 +140,8 @@ public class FlowEntryBuilder {
case STAT:
rule = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)),
buildSelector(), buildTreatment(), stat.getPriority(),
stat.getCookie().getValue(), stat.getIdleTimeout(), false);
stat.getCookie().getValue(), stat.getIdleTimeout(), false,
tableType);
return new DefaultFlowEntry(rule, FlowEntryState.ADDED,
stat.getDurationSec(), stat.getPacketCount().getValue(),
stat.getByteCount().getValue());
......
......@@ -266,6 +266,8 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
return OpenFlowSwitch.TableType.ETHER;
case COS:
return OpenFlowSwitch.TableType.COS;
case FIRST:
return OpenFlowSwitch.TableType.FIRST;
default:
return OpenFlowSwitch.TableType.NONE;
}
......
......@@ -45,26 +45,17 @@ import org.onosproject.openflow.controller.OpenFlowEventListener;
import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.RoleState;
import org.projectfloodlight.openflow.protocol.OFActionType;
import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFErrorType;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
import org.projectfloodlight.openflow.protocol.OFFlowStatsEntry;
import org.projectfloodlight.openflow.protocol.OFFlowStatsReply;
import org.projectfloodlight.openflow.protocol.OFInstructionType;
import org.projectfloodlight.openflow.protocol.OFMessage;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.OFStatsType;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.instruction.OFInstructionApplyActions;
import org.projectfloodlight.openflow.types.OFPort;
import org.slf4j.Logger;
import java.util.Collections;
......@@ -85,8 +76,6 @@ import static org.slf4j.LoggerFactory.getLogger;
@Component(immediate = true)
public class OpenFlowRuleProvider extends AbstractProvider implements FlowRuleProvider {
private static final int LOWEST_PRIORITY = 0;
private final Logger log = getLogger(getClass());
@Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
......@@ -160,7 +149,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
Optional.empty()).buildFlowAdd());
} else {
OpenFlowSwitch.TableType type = getTableType(flowRule.type());
sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
sw.transformAndSendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
Optional.empty()).buildFlowAdd(),
type);
}
......@@ -181,7 +170,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
Optional.empty()).buildFlowDel());
} else {
sw.sendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
sw.transformAndSendMsg(FlowModBuilder.builder(flowRule, sw.factory(),
Optional.empty()).buildFlowDel(), getTableType(flowRule.type()));
}
}
......@@ -225,7 +214,7 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
if (fbe.target().type() == FlowRule.Type.DEFAULT) {
sw.sendMsg(mod);
} else {
sw.sendMsg(mod, getTableType(fbe.target().type()));
sw.transformAndSendMsg(mod, getTableType(fbe.target().type()));
}
}
OFBarrierRequest.Builder builder = sw.factory()
......@@ -253,12 +242,38 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
return OpenFlowSwitch.TableType.ETHER;
case COS:
return OpenFlowSwitch.TableType.COS;
case FIRST:
return OpenFlowSwitch.TableType.FIRST;
default:
return OpenFlowSwitch.TableType.NONE;
}
}
private FlowRule.Type getType(OpenFlowSwitch.TableType tableType) {
switch (tableType) {
case NONE:
return FlowRule.Type.DEFAULT;
case IP:
return FlowRule.Type.IP;
case MPLS:
return FlowRule.Type.MPLS;
case ACL:
return FlowRule.Type.ACL;
case VLAN_MPLS:
return FlowRule.Type.VLAN_MPLS;
case VLAN:
return FlowRule.Type.VLAN;
case ETHER:
return FlowRule.Type.ETHER;
case COS:
return FlowRule.Type.COS;
case FIRST:
return FlowRule.Type.FIRST;
default:
return FlowRule.Type.DEFAULT;
}
}
private class InternalFlowProvider
......@@ -354,41 +369,18 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
private void pushFlowMetrics(Dpid dpid, OFFlowStatsReply replies) {
DeviceId did = DeviceId.deviceId(Dpid.uri(dpid));
OpenFlowSwitch sw = controller.getSwitch(dpid);
List<FlowEntry> flowEntries = replies.getEntries().stream()
.filter(entry -> !tableMissRule(dpid, entry))
.map(entry -> new FlowEntryBuilder(dpid, entry).build())
.map(entry -> new FlowEntryBuilder(dpid, entry,
getType(sw.getTableType(entry.getTableId())))
.build())
.collect(Collectors.toList());
providerService.pushFlowMetrics(did, flowEntries);
}
private boolean tableMissRule(Dpid dpid, OFFlowStatsEntry reply) {
if (reply.getMatch().getMatchFields().iterator().hasNext()) {
return false;
}
if (reply.getVersion().equals(OFVersion.OF_10)) {
return reply.getPriority() == LOWEST_PRIORITY
&& reply.getActions().isEmpty();
}
for (OFInstruction ins : reply.getInstructions()) {
if (ins.getType() == OFInstructionType.APPLY_ACTIONS) {
OFInstructionApplyActions apply = (OFInstructionApplyActions) ins;
List<OFAction> acts = apply.getActions();
for (OFAction act : acts) {
if (act.getType() == OFActionType.OUTPUT) {
OFActionOutput out = (OFActionOutput) act;
if (out.getPort() == OFPort.CONTROLLER) {
return true;
}
}
}
}
}
return false;
}
}
/**
......
package org.onosproject.provider.of.group.impl;
import com.google.common.collect.Lists;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
......@@ -41,6 +42,7 @@ import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.errormsg.OFGroupModFailedErrorMsg;
import org.projectfloodlight.openflow.types.OFGroup;
import org.projectfloodlight.openflow.types.TableId;
import java.util.Collection;
import java.util.List;
......@@ -310,11 +312,6 @@ public class OpenFlowGroupProviderTest {
}
@Override
public void sendMsg(OFMessage msg, TableType tableType) {
}
@Override
public void handleMessage(OFMessage fromSwitch) {
}
......@@ -398,5 +395,15 @@ public class OpenFlowGroupProviderTest {
public String channelId() {
return null;
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
}
\ No newline at end of file
......
......@@ -46,6 +46,7 @@ import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.OpenflowControllerAdapter;
import org.onosproject.openflow.controller.PacketListener;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
import org.onlab.packet.Ethernet;
import org.onlab.packet.ONLabLddp;
import org.projectfloodlight.openflow.protocol.OFFactory;
......@@ -56,6 +57,7 @@ import org.projectfloodlight.openflow.protocol.OFPortReason;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
......@@ -414,10 +416,6 @@ public class OpenFlowLinkProviderTest {
}
@Override
public void sendMsg(OFMessage msg, TableType tableType) {
}
@Override
public void handleMessage(OFMessage fromSwitch) {
}
......@@ -499,6 +497,15 @@ public class OpenFlowLinkProviderTest {
return "1.2.3.4:1";
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
}
......
......@@ -49,6 +49,7 @@ import org.onosproject.openflow.controller.OpenFlowSwitch;
import org.onosproject.openflow.controller.OpenFlowSwitchListener;
import org.onosproject.openflow.controller.PacketListener;
import org.onosproject.openflow.controller.RoleState;
import org.onosproject.openflow.controller.OpenFlowSwitch.TableType;
import org.onlab.packet.ARP;
import org.onlab.packet.Ethernet;
import org.projectfloodlight.openflow.protocol.OFFactory;
......@@ -60,6 +61,7 @@ import org.projectfloodlight.openflow.protocol.ver10.OFFactoryVer10;
import org.projectfloodlight.openflow.types.MacAddress;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.TableId;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
......@@ -347,10 +349,6 @@ public class OpenFlowPacketProviderTest {
}
@Override
public void sendMsg(OFMessage msg, TableType tableType) {
}
@Override
public void handleMessage(OFMessage fromSwitch) {
}
......@@ -432,6 +430,17 @@ public class OpenFlowPacketProviderTest {
return "1.2.3.4:1";
}
@Override
public TableType getTableType(TableId tid) {
return TableType.NONE;
}
@Override
public void transformAndSendMsg(OFMessage msg, TableType tableType) {
// TODO Auto-generated method stub
}
}
}
......