implementing flowremoved handling
diff --git a/providers/of/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java b/providers/of/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
index 38ba59b..9eed3c9 100644
--- a/providers/of/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
+++ b/providers/of/flow/src/main/java/org/onlab/onos/provider/of/flow/impl/OpenFlowRuleProvider.java
@@ -2,58 +2,29 @@
import static org.slf4j.LoggerFactory.getLogger;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-
import org.apache.felix.scr.annotations.Activate;
import org.apache.felix.scr.annotations.Component;
import org.apache.felix.scr.annotations.Deactivate;
import org.apache.felix.scr.annotations.Reference;
import org.apache.felix.scr.annotations.ReferenceCardinality;
import org.onlab.onos.net.DeviceId;
+import org.onlab.onos.net.flow.DefaultFlowRule;
import org.onlab.onos.net.flow.FlowEntry;
import org.onlab.onos.net.flow.FlowRule;
import org.onlab.onos.net.flow.FlowRuleProvider;
import org.onlab.onos.net.flow.FlowRuleProviderRegistry;
import org.onlab.onos.net.flow.FlowRuleProviderService;
-import org.onlab.onos.net.flow.criteria.Criteria.EthCriterion;
-import org.onlab.onos.net.flow.criteria.Criteria.EthTypeCriterion;
-import org.onlab.onos.net.flow.criteria.Criteria.IPCriterion;
-import org.onlab.onos.net.flow.criteria.Criteria.IPProtocolCriterion;
-import org.onlab.onos.net.flow.criteria.Criteria.PortCriterion;
-import org.onlab.onos.net.flow.criteria.Criteria.VlanIdCriterion;
-import org.onlab.onos.net.flow.criteria.Criteria.VlanPcpCriterion;
-import org.onlab.onos.net.flow.criteria.Criterion;
-import org.onlab.onos.net.flow.instructions.Instruction;
-import org.onlab.onos.net.flow.instructions.Instructions.OutputInstruction;
-import org.onlab.onos.net.flow.instructions.L2ModificationInstruction;
-import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
-import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
-import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModVlanPcpInstruction;
-import org.onlab.onos.net.flow.instructions.L3ModificationInstruction;
-import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
import org.onlab.onos.net.provider.AbstractProvider;
import org.onlab.onos.net.provider.ProviderId;
import org.onlab.onos.net.topology.TopologyService;
import org.onlab.onos.of.controller.Dpid;
import org.onlab.onos.of.controller.OpenFlowController;
+import org.onlab.onos.of.controller.OpenFlowEventListener;
import org.onlab.onos.of.controller.OpenFlowSwitch;
-import org.projectfloodlight.openflow.protocol.OFFactory;
-import org.projectfloodlight.openflow.protocol.OFFlowMod;
-import org.projectfloodlight.openflow.protocol.OFFlowModFlags;
-import org.projectfloodlight.openflow.protocol.action.OFAction;
-import org.projectfloodlight.openflow.protocol.match.Match;
-import org.projectfloodlight.openflow.protocol.match.MatchField;
-import org.projectfloodlight.openflow.types.EthType;
-import org.projectfloodlight.openflow.types.IPv4Address;
-import org.projectfloodlight.openflow.types.IpProtocol;
-import org.projectfloodlight.openflow.types.MacAddress;
-import org.projectfloodlight.openflow.types.OFBufferId;
-import org.projectfloodlight.openflow.types.OFPort;
-import org.projectfloodlight.openflow.types.OFVlanVidMatch;
-import org.projectfloodlight.openflow.types.VlanPcp;
-import org.projectfloodlight.openflow.types.VlanVid;
+import org.onlab.onos.of.controller.OpenFlowSwitchListener;
+import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
+import org.projectfloodlight.openflow.protocol.OFMessage;
+import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.slf4j.Logger;
/**
@@ -105,168 +76,10 @@
private void applyRule(FlowRule flowRule) {
OpenFlowSwitch sw = controller.getSwitch(Dpid.dpid(flowRule.deviceId().uri()));
- Match match = buildMatch(flowRule.selector().criteria(), sw.factory());
- List<OFAction> actions =
- buildActions(flowRule.treatment().instructions(), sw.factory());
-
- //TODO: what to do without bufferid? do we assume that there will be a pktout as well?
- OFFlowMod fm = sw.factory().buildFlowModify()
- .setBufferId(OFBufferId.NO_BUFFER)
- .setActions(actions)
- .setMatch(match)
- .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
- .setIdleTimeout(10)
- .setHardTimeout(10)
- .setPriority(flowRule.priority())
- .build();
- sw.sendMsg(fm);
+ sw.sendMsg(new FlowModBuilder(flowRule, sw.factory()).buildFlowMod());
}
- private List<OFAction> buildActions(List<Instruction> instructions, OFFactory factory) {
- List<OFAction> acts = new LinkedList<>();
- for (Instruction i : instructions) {
- switch (i.type()) {
- case DROP:
- log.warn("Saw drop action; assigning drop action");
- return new LinkedList<>();
- case L2MODIFICATION:
- acts.add(buildL2Modification(i, factory));
- case L3MODIFICATION:
- acts.add(buildL3Modification(i, factory));
- case OUTPUT:
- OutputInstruction out = (OutputInstruction) i;
- acts.add(factory.actions().buildOutput().setPort(
- OFPort.of((int) out.port().toLong())).build());
- break;
- case GROUP:
- default:
- log.warn("Instruction type {} not yet implemented.", i.type());
- }
- }
- return acts;
- }
-
- private OFAction buildL3Modification(Instruction i, OFFactory factory) {
- L3ModificationInstruction l3m = (L3ModificationInstruction) i;
- ModIPInstruction ip;
- switch (l3m.subtype()) {
- case L3_DST:
- ip = (ModIPInstruction) i;
- return factory.actions().setNwDst(IPv4Address.of(ip.ip().toInt()));
- case L3_SRC:
- ip = (ModIPInstruction) i;
- return factory.actions().setNwSrc(IPv4Address.of(ip.ip().toInt()));
- default:
- log.warn("Unimplemented action type {}.", l3m.subtype());
- break;
- }
- return null;
- }
-
- private OFAction buildL2Modification(Instruction i, OFFactory factory) {
- L2ModificationInstruction l2m = (L2ModificationInstruction) i;
- ModEtherInstruction eth;
- switch (l2m.subtype()) {
- case L2_DST:
- eth = (ModEtherInstruction) l2m;
- return factory.actions().setDlDst(MacAddress.of(eth.mac().toLong()));
- case L2_SRC:
- eth = (ModEtherInstruction) l2m;
- return factory.actions().setDlSrc(MacAddress.of(eth.mac().toLong()));
- case VLAN_ID:
- ModVlanIdInstruction vlanId = (ModVlanIdInstruction) l2m;
- return factory.actions().setVlanVid(VlanVid.ofVlan(vlanId.vlanId.toShort()));
- case VLAN_PCP:
- ModVlanPcpInstruction vlanPcp = (ModVlanPcpInstruction) l2m;
- return factory.actions().setVlanPcp(VlanPcp.of(vlanPcp.vlanPcp()));
- default:
- log.warn("Unimplemented action type {}.", l2m.subtype());
- break;
- }
- return null;
- }
-
- private Match buildMatch(List<Criterion> criteria, OFFactory factory) {
- Match.Builder mBuilder = factory.buildMatch();
- EthCriterion eth;
- IPCriterion ip;
- for (Criterion c : criteria) {
- switch (c.type()) {
- case IN_PORT:
- PortCriterion inport = (PortCriterion) c;
- mBuilder.setExact(MatchField.IN_PORT, OFPort.of((int) inport.port().toLong()));
- break;
- case ETH_SRC:
- eth = (EthCriterion) c;
- mBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(eth.mac().toLong()));
- break;
- case ETH_DST:
- eth = (EthCriterion) c;
- mBuilder.setExact(MatchField.ETH_DST, MacAddress.of(eth.mac().toLong()));
- break;
- case ETH_TYPE:
- EthTypeCriterion ethType = (EthTypeCriterion) c;
- mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType()));
- break;
- case IPV4_DST:
- ip = (IPCriterion) c;
- mBuilder.setExact(MatchField.IPV4_DST, IPv4Address.of(ip.ip().toInt()));
- break;
- case IPV4_SRC:
- ip = (IPCriterion) c;
- mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toInt()));
- break;
- case IP_PROTO:
- IPProtocolCriterion p = (IPProtocolCriterion) c;
- mBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(p.protocol()));
- break;
- case VLAN_PCP:
- VlanPcpCriterion vpcp = (VlanPcpCriterion) c;
- mBuilder.setExact(MatchField.VLAN_PCP, VlanPcp.of(vpcp.priority()));
- break;
- case VLAN_VID:
- VlanIdCriterion vid = (VlanIdCriterion) c;
- mBuilder.setExact(MatchField.VLAN_VID,
- OFVlanVidMatch.ofVlanVid(VlanVid.ofVlan(vid.vlanId().toShort())));
- break;
- case ARP_OP:
- case ARP_SHA:
- case ARP_SPA:
- case ARP_THA:
- case ARP_TPA:
- case ICMPV4_CODE:
- case ICMPV4_TYPE:
- case ICMPV6_CODE:
- case ICMPV6_TYPE:
- case IN_PHY_PORT:
- case IPV6_DST:
- case IPV6_EXTHDR:
- case IPV6_FLABEL:
- case IPV6_ND_SLL:
- case IPV6_ND_TARGET:
- case IPV6_ND_TLL:
- case IPV6_SRC:
- case IP_DSCP:
- case IP_ECN:
- case METADATA:
- case MPLS_BOS:
- case MPLS_LABEL:
- case MPLS_TC:
- case PBB_ISID:
- case SCTP_DST:
- case SCTP_SRC:
- case TCP_DST:
- case TCP_SRC:
- case TUNNEL_ID:
- case UDP_DST:
- case UDP_SRC:
- default:
- log.warn("Action type {} not yet implemented.", c.type());
- }
- }
- return mBuilder.build();
- }
@Override
public void removeFlowRule(FlowRule... flowRules) {
@@ -283,6 +96,45 @@
//TODO: InternalFlowRuleProvider listening to stats and error and flowremoved.
// possibly barriers as well. May not be internal at all...
+ private class InternalFlowProvider
+ implements OpenFlowSwitchListener, OpenFlowEventListener {
+
+
+ @Override
+ public void switchAdded(Dpid dpid) {
+
+
+ }
+
+ @Override
+ public void switchRemoved(Dpid dpid) {
+
+
+ }
+
+ @Override
+ public void portChanged(Dpid dpid, OFPortStatus status) {
+ //TODO: Decide whether to evict flows internal store.
+ }
+
+ @Override
+ public void handleMessage(Dpid dpid, OFMessage msg) {
+ switch (msg.getType()) {
+ case FLOW_REMOVED:
+ OFFlowRemoved removed = (OFFlowRemoved) msg;
+ FlowRule fr = new DefaultFlowRule(DeviceId.deviceId(Dpid.uri(dpid)), null, null);
+ providerService.flowRemoved(fr);
+ break;
+ case STATS_REPLY:
+ case BARRIER_REPLY:
+ case ERROR:
+ default:
+ log.warn("Unhandled message type: {}", msg.getType());
+ }
+
+ }
+
+ }
}