Implementing ACL flow
Change-Id: I65c4ed0f1fd078ef31f6058ba64db6ed47fd2b78
diff --git a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
index 5d4a9ec..7162554 100644
--- a/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
+++ b/src/main/java/net/onrc/onos/core/drivermanager/OFSwitchImplCPqD13.java
@@ -18,6 +18,7 @@
import net.floodlightcontroller.core.SwitchDriverSubHandshakeCompleted;
import net.floodlightcontroller.core.SwitchDriverSubHandshakeNotStarted;
import net.floodlightcontroller.core.internal.OFSwitchImplBase;
+import net.floodlightcontroller.util.MACAddress;
import net.onrc.onos.core.configmanager.INetworkConfigService;
import net.onrc.onos.core.configmanager.INetworkConfigService.NetworkConfigState;
import net.onrc.onos.core.configmanager.INetworkConfigService.SwitchConfigStatus;
@@ -55,6 +56,7 @@
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFErrorMsg;
import org.projectfloodlight.openflow.protocol.OFFactory;
+import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFGroupDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFGroupFeaturesStatsReply;
import org.projectfloodlight.openflow.protocol.OFGroupType;
@@ -65,6 +67,8 @@
import org.projectfloodlight.openflow.protocol.OFStatsReply;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
+import org.projectfloodlight.openflow.protocol.match.Match.Builder;
+import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthDst;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthSrc;
import org.projectfloodlight.openflow.protocol.oxm.OFOxmEthType;
@@ -74,12 +78,14 @@
import org.projectfloodlight.openflow.protocol.oxm.OFOxmVlanVid;
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.OFGroup;
import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
import org.projectfloodlight.openflow.types.TableId;
+import org.projectfloodlight.openflow.types.TransportPort;
import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.util.HexString;
@@ -881,30 +887,31 @@
}
// set flow-mod
- OFMessage ipFlow = null;
- if (op == MatchActionOperations.Operator.ADD) {
- ipFlow = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_IPv4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(priority)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- } else {
- ipFlow = factory.buildFlowDeleteStrict()
- .setTableId(TableId.of(TABLE_IPv4_UNICAST))
- .setMatch(match)
- .setInstructions(instructions)
- .setPriority(priority)
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
+ OFFlowMod.Builder fmBuilder = null;
+ switch (op) {
+ case ADD:
+ fmBuilder = factory.buildFlowAdd();
+ break;
+ case REMOVE:
+ fmBuilder = factory.buildFlowDeleteStrict();
+ break;
+ // case MODIFY: // TODO
+ // fmBuilder = factory.buildFlowModifyStrict();
+ // break;
+ default:
+ log.warn("Unsupported MatchAction Operator: {}", op);
+ return null;
}
+ OFMessage ipFlow = fmBuilder
+ .setTableId(TableId.of(TABLE_IPv4_UNICAST))
+ .setMatch(match)
+ .setInstructions(instructions)
+ .setPriority(priority)
+ .setBufferId(OFBufferId.NO_BUFFER)
+ .setIdleTimeout(0)
+ .setHardTimeout(0)
+ .setXid(getNextTransactionId())
+ .build();
log.debug("{} ip-rule {}-{} in sw {}",
(op == MatchActionOperations.Operator.ADD) ? "Adding" : "Deleting",
match, writeActions,
@@ -944,30 +951,33 @@
instructions.add(writeInstr);
instructions.add(gotoInstr);
- OFMessage mplsFlow = null;
- if (op == MatchActionOperations.Operator.ADD) {
- mplsFlow = factory.buildFlowAdd()
- .setTableId(TableId.of(TABLE_MPLS))
- .setMatch(matchlabel)
- .setInstructions(instructions)
- .setPriority(MAX_PRIORITY) // exact match and exclusive
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
- } else {
- mplsFlow = factory.buildFlowDeleteStrict()
- .setTableId(TableId.of(TABLE_MPLS))
- .setMatch(matchlabel)
- .setInstructions(instructions)
- .setPriority(MAX_PRIORITY) // exact match and exclusive
- .setBufferId(OFBufferId.NO_BUFFER)
- .setIdleTimeout(0)
- .setHardTimeout(0)
- .setXid(getNextTransactionId())
- .build();
+ // set flow-mod
+ OFFlowMod.Builder fmBuilder = null;
+ switch (op) {
+ case ADD:
+ fmBuilder = factory.buildFlowAdd();
+ break;
+ case REMOVE:
+ fmBuilder = factory.buildFlowDeleteStrict();
+ break;
+ // case MODIFY: // TODO
+ // fmBuilder = factory.buildFlowModifyStrict();
+ // break;
+ default:
+ log.warn("Unsupported MatchAction Operator: {}", op);
+ return null;
}
+
+ OFMessage mplsFlow = fmBuilder
+ .setTableId(TableId.of(TABLE_MPLS))
+ .setMatch(matchlabel)
+ .setInstructions(instructions)
+ .setPriority(MAX_PRIORITY) // exact match and exclusive
+ .setBufferId(OFBufferId.NO_BUFFER)
+ .setIdleTimeout(0)
+ .setHardTimeout(0)
+ .setXid(getNextTransactionId())
+ .build();
log.debug("{} mpls-rule {}-{} in sw {}",
(op == MatchActionOperations.Operator.ADD) ? "Adding" : "Deleting",
matchlabel, writeActions,
@@ -976,8 +986,102 @@
}
private OFMessage getAclEntry(MatchActionOperationEntry mao) {
+ MatchAction ma = mao.getTarget();
+ Operator op = mao.getOperator();
+ PacketMatch packetMatch = (PacketMatch) ma.getMatch();
+ Builder matchBuilder = factory.buildMatch();
- OFMessage aclFlow = null;
+ // set match
+ int inport = 0;
+ if (ma.getSwitchPort() != null) {
+ inport = (int) ma.getSwitchPort().getPortNumber().value();
+ }
+ final MACAddress srcMac = packetMatch.getSrcMacAddress();
+ final MACAddress dstMac = packetMatch.getDstMacAddress();
+ final Short etherType = packetMatch.getEtherType();
+ final IPv4Net srcIp = packetMatch.getSrcIpAddress();
+ final IPv4Net dstIp = packetMatch.getDstIpAddress();
+ final Byte ipProto = packetMatch.getIpProtocolNumber();
+ final Short srcTcpPort = packetMatch.getSrcTcpPortNumber();
+ final Short dstTcpPort = packetMatch.getDstTcpPortNumber();
+ if (inport > 0) {
+ matchBuilder.setExact(MatchField.IN_PORT,
+ OFPort.of(inport));
+ }
+ if (srcMac != null) {
+ matchBuilder.setExact(MatchField.ETH_SRC, MacAddress.of(srcMac.toLong()));
+ }
+ if (dstMac != null) {
+ matchBuilder.setExact(MatchField.ETH_DST, MacAddress.of(dstMac.toLong()));
+ }
+ if (etherType != null) {
+ matchBuilder.setExact(MatchField.ETH_TYPE, EthType.of(etherType));
+ }
+ if (srcIp != null) {
+ matchBuilder.setMasked(MatchField.IPV4_SRC,
+ IPv4Address.of(srcIp.address().value())
+ .withMaskOfLength(srcIp.prefixLen()));
+ }
+ if (dstIp != null) {
+ matchBuilder.setMasked(MatchField.IPV4_DST,
+ IPv4Address.of(dstIp.address().value())
+ .withMaskOfLength(dstIp.prefixLen()));
+ }
+ if (ipProto != null) {
+ matchBuilder.setExact(MatchField.IP_PROTO, IpProtocol.of(ipProto));
+ }
+ if (srcTcpPort != null) {
+ matchBuilder.setExact(MatchField.TCP_SRC, TransportPort.of(srcTcpPort));
+ }
+ if (dstTcpPort != null) {
+ matchBuilder.setExact(MatchField.TCP_DST, TransportPort.of(dstTcpPort));
+ }
+
+ // set actions
+ List<OFAction> applyActions = new ArrayList<OFAction>();
+ for (Action action : ma.getActions()) {
+ OFAction ofAction = getOFAction(action);
+ if (ofAction != null) {
+ applyActions.add(ofAction);
+ }
+ }
+
+ // set instructions
+ OFInstruction clearInstr = factory.instructions().clearActions();
+ OFInstruction applyInstr = factory.instructions().buildApplyActions()
+ .setActions(applyActions).build();
+ List<OFInstruction> instructions = new ArrayList<OFInstruction>();
+ instructions.add(clearInstr);
+ instructions.add(applyInstr);
+
+ // set flow-mod
+ OFFlowMod.Builder fmBuilder = null;
+ switch (op) {
+ case ADD:
+ fmBuilder = factory.buildFlowAdd();
+ break;
+ case REMOVE:
+ fmBuilder = factory.buildFlowDeleteStrict();
+ break;
+ // case MODIFY: // TODO
+ // fmBuilder = factory.buildFlowModifyStrict();
+ // break;
+ default:
+ log.warn("Unsupported MatchAction Operator: {}", op);
+ return null;
+ }
+
+ OFMessage aclFlow = fmBuilder
+ .setTableId(TableId.of(TABLE_ACL))
+ .setMatch(matchBuilder.build())
+ .setInstructions(instructions)
+ .setPriority(MAX_PRIORITY / 2) // TODO: wrong - should be MA
+ // priority
+ .setBufferId(OFBufferId.NO_BUFFER)
+ .setIdleTimeout(0)
+ .setHardTimeout(0)
+ .setXid(getNextTransactionId())
+ .build();
return aclFlow;
}
diff --git a/src/main/java/net/onrc/onos/core/matchaction/match/PacketMatch.java b/src/main/java/net/onrc/onos/core/matchaction/match/PacketMatch.java
index c49c3d8..6974a82 100644
--- a/src/main/java/net/onrc/onos/core/matchaction/match/PacketMatch.java
+++ b/src/main/java/net/onrc/onos/core/matchaction/match/PacketMatch.java
@@ -9,7 +9,8 @@
* A match object (traffic specifier) for packet nodes, flow-paths and intents.
* <p>
* This class does not have a switch ID and a in-port number. They are handled
- * by MatchAction, Flow and Intent classes.
+ * by MatchAction, Flow and Intent classes (for example MatchAction class has a
+ * separate SwitchPort field). Also, this class does not handle vlans or ttls.
* <p>
* TODO: This class should be extensible.
*/