flowruleprovider builds flowmods
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
index 6064263..0bf4ea8 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/DefaultTrafficTreatment.java
@@ -53,7 +53,8 @@
case OUTPUT:
outputs.add(instruction);
break;
- case MODIFICATION:
+ case L2MODIFICATION:
+ case L3MODIFICATION:
// TODO: enforce modification order if any
modifications.add(instruction);
break;
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java b/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java
index c7c2fc8..9cae5f9 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/criteria/Criteria.java
@@ -227,7 +227,7 @@
return Type.VLAN_PCP;
}
- public Byte protocol() {
+ public Byte priority() {
return vlanPcp;
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java
index 8c41a04..f05d238 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instruction.java
@@ -5,12 +5,6 @@
*/
public interface Instruction {
- interface SubType { }
-
- public enum NoneSubType implements SubType {
- NONE;
- }
-
/**
* Represents the type of traffic treatment.
*/
@@ -31,9 +25,14 @@
GROUP,
/**
- * Signifies that the traffic should be modified in some way.
+ * Signifies that the traffic should be modified in L2 way.
*/
- MODIFICATION
+ L2MODIFICATION,
+
+ /**
+ * Signifies that the traffic should be modified in L3 way.
+ */
+ L3MODIFICATION
}
// TODO: Create factory class 'Instructions' that will have various factory
@@ -45,10 +44,4 @@
*/
public Type type();
- /**
- * Returns the subtype of the modification instruction.
- * @return type of instruction
- */
- public SubType subtype();
-
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java
index 06903e5..439db77 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/Instructions.java
@@ -7,10 +7,10 @@
import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.L3SubType;
import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPInstruction;
-import org.onlab.onos.net.flow.instructions.L3ModificationInstruction.ModIPProtoInstruction;
import org.onlab.packet.IpAddress;
import org.onlab.packet.MacAddress;
import org.onlab.packet.VlanId;
+
/**
* Factory class for creating various traffic treatment instructions.
*/
@@ -61,16 +61,6 @@
}
/**
- * Creates a L2 type modification.
- * @param l2Type the type to change to
- * @return a L2 modifications
- */
- public static L2ModificationInstruction modL2Type(Short l2Type) {
- checkNotNull(l2Type, "L2 type cannot be null");
- return new L2ModificationInstruction.ModEtherTypeInstruction(l2Type);
- }
-
- /**
* Creates a Vlan id modification.
* @param vlanId the vlan id to modify to.
* @return a L2 modification
@@ -110,15 +100,6 @@
return new ModIPInstruction(L3SubType.L3_DST, addr);
}
- /**
- * Creates an L3 protocol modification.
- * @param proto the protocol to change to
- * @return a L3 modification
- */
- public static L3ModificationInstruction modIPProto(Byte proto) {
- checkNotNull(proto, "IP protocol cannot be null");
- return new ModIPProtoInstruction(proto);
- }
/*
* Output instructions
@@ -129,11 +110,6 @@
public Type type() {
return Type.DROP;
}
-
- @Override
- public SubType subtype() {
- return NoneSubType.NONE;
- }
}
@@ -152,11 +128,6 @@
public Type type() {
return Type.OUTPUT;
}
-
- @Override
- public SubType subtype() {
- return NoneSubType.NONE;
- }
}
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L2ModificationInstruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L2ModificationInstruction.java
index 5490de2..78eaaa9 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L2ModificationInstruction.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L2ModificationInstruction.java
@@ -12,7 +12,7 @@
/**
* Represents the type of traffic treatment.
*/
- public enum L2SubType implements SubType {
+ public enum L2SubType {
/**
* Ether src modification.
*/
@@ -24,11 +24,6 @@
L2_DST,
/**
- * Ethertype modification.
- */
- L2_TYPE,
-
- /**
* VLAN id modification.
*/
VLAN_ID,
@@ -42,12 +37,11 @@
// TODO: Create factory class 'Instructions' that will have various factory
// to create specific instructions.
- @Override
- public abstract SubType subtype();
+ public abstract L2SubType subtype();
@Override
public Type type() {
- return Type.MODIFICATION;
+ return Type.L2MODIFICATION;
}
/**
@@ -55,16 +49,17 @@
*/
public static final class ModEtherInstruction extends L2ModificationInstruction {
- private final SubType subtype;
+ private final L2SubType subtype;
private final MacAddress mac;
- public ModEtherInstruction(SubType subType, MacAddress addr) {
+ public ModEtherInstruction(L2SubType subType, MacAddress addr) {
+
this.subtype = subType;
this.mac = addr;
}
@Override
- public SubType subtype() {
+ public L2SubType subtype() {
return this.subtype;
}
@@ -75,28 +70,6 @@
}
/**
- * Represents a L2 type modification instruction.
- */
- public static final class ModEtherTypeInstruction extends L2ModificationInstruction {
-
- public final short l2Type;
-
- public ModEtherTypeInstruction(short l2Type) {
- this.l2Type = l2Type;
- }
-
- @Override
- public SubType subtype() {
- return L2SubType.L2_TYPE;
- }
-
- public short l2Type() {
- return this.l2Type;
- }
-
- }
-
- /**
* Represents a VLAN id modification instruction.
*/
public static final class ModVlanIdInstruction extends L2ModificationInstruction {
@@ -108,7 +81,7 @@
}
@Override
- public SubType subtype() {
+ public L2SubType subtype() {
return L2SubType.VLAN_ID;
}
@@ -130,7 +103,7 @@
}
@Override
- public SubType subtype() {
+ public L2SubType subtype() {
return L2SubType.VLAN_PCP;
}
diff --git a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L3ModificationInstruction.java b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L3ModificationInstruction.java
index 126c1f9..cf25f10 100644
--- a/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L3ModificationInstruction.java
+++ b/core/api/src/main/java/org/onlab/onos/net/flow/instructions/L3ModificationInstruction.java
@@ -11,7 +11,7 @@
/**
* Represents the type of traffic treatment.
*/
- public enum L3SubType implements SubType {
+ public enum L3SubType {
/**
* Ether src modification.
*/
@@ -20,12 +20,7 @@
/**
* Ether dst modification.
*/
- L3_DST,
-
- /**
- * Ethertype modification.
- */
- L3_PROTO,
+ L3_DST
//TODO: remaining types
}
@@ -34,11 +29,11 @@
* Returns the subtype of the modification instruction.
* @return type of instruction
*/
- public abstract SubType subtype();
+ public abstract L3SubType subtype();
@Override
public Type type() {
- return Type.MODIFICATION;
+ return Type.L3MODIFICATION;
}
/**
@@ -46,16 +41,17 @@
*/
public static final class ModIPInstruction extends L3ModificationInstruction {
- private final SubType subtype;
+ private final L3SubType subtype;
private final IpAddress ip;
- public ModIPInstruction(SubType subType, IpAddress addr) {
+ public ModIPInstruction(L3SubType subType, IpAddress addr) {
+
this.subtype = subType;
this.ip = addr;
}
@Override
- public SubType subtype() {
+ public L3SubType subtype() {
return this.subtype;
}
@@ -64,26 +60,4 @@
}
}
-
- /**
- * Represents a L3 proto modification instruction.
- */
- public static final class ModIPProtoInstruction extends L3ModificationInstruction {
-
- public final Byte proto;
-
- public ModIPProtoInstruction(Byte proto) {
- this.proto = proto;
- }
-
- @Override
- public SubType subtype() {
- return L3SubType.L3_PROTO;
- }
-
- public short proto() {
- return this.proto;
- }
-
- }
}
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 29a716d..db6590a 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,6 +2,10 @@
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;
@@ -13,10 +17,41 @@
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.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.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.OFPort;
+import org.projectfloodlight.openflow.types.OFVlanVidMatch;
+import org.projectfloodlight.openflow.types.VlanPcp;
+import org.projectfloodlight.openflow.types.VlanVid;
import org.slf4j.Logger;
/**
@@ -61,10 +96,174 @@
}
@Override
public void applyFlowRule(FlowRule... flowRules) {
- // TODO Auto-generated method stub
+ for (int i = 0; i < flowRules.length; i++) {
+ applyRule(flowRules[i]);
+ }
}
+ 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()
+ .setActions(actions)
+ .setMatch(match)
+ .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
+ .setIdleTimeout(10)
+ .setHardTimeout(10)
+ .setPriority(flowRule.priority())
+ .build();
+
+ sw.sendMsg(fm);
+
+ }
+
+ 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 acts;
+ case L2MODIFICATION:
+ acts.add(buildL2Modification(i, factory));
+ case L3MODIFICATION:
+ acts.add(buildL3Modification(i, factory));
+ case OUTPUT:
+ 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()));
+ 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) {
// TODO Auto-generated method stub