alshabib

building flowmods

......@@ -53,7 +53,8 @@ public class DefaultTrafficTreatment implements TrafficTreatment {
case OUTPUT:
outputs.add(instruction);
break;
case MODIFICATION:
case L2MODIFICATION:
case L3MODIFICATION:
// TODO: enforce modification order if any
modifications.add(instruction);
break;
......
......@@ -227,7 +227,7 @@ public final class Criteria {
return Type.VLAN_PCP;
}
public Byte protocol() {
public Byte priority() {
return vlanPcp;
}
......
......@@ -5,12 +5,6 @@ package org.onlab.onos.net.flow.instructions;
*/
public interface Instruction {
interface SubType { }
public enum NoneSubType implements SubType {
NONE;
}
/**
* Represents the type of traffic treatment.
*/
......@@ -31,9 +25,14 @@ public interface Instruction {
GROUP,
/**
* Signifies that the traffic should be modified in some way.
* Signifies that the traffic should be modified in L2 way.
*/
L2MODIFICATION,
/**
* Signifies that the traffic should be modified in L3 way.
*/
MODIFICATION
L3MODIFICATION
}
// TODO: Create factory class 'Instructions' that will have various factory
......@@ -45,10 +44,4 @@ public interface Instruction {
*/
public Type type();
/**
* Returns the subtype of the modification instruction.
* @return type of instruction
*/
public SubType subtype();
}
......
......@@ -7,7 +7,6 @@ import org.onlab.onos.net.flow.instructions.L2ModificationInstruction.L2SubType;
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;
......@@ -61,16 +60,6 @@ public final class Instructions {
}
/**
* 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 +99,6 @@ public final class Instructions {
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 +109,6 @@ public final class Instructions {
public Type type() {
return Type.DROP;
}
@Override
public SubType subtype() {
return NoneSubType.NONE;
}
}
......@@ -152,11 +127,6 @@ public final class Instructions {
public Type type() {
return Type.OUTPUT;
}
@Override
public SubType subtype() {
return NoneSubType.NONE;
}
}
}
......
......@@ -12,7 +12,7 @@ public abstract class L2ModificationInstruction implements Instruction {
/**
* Represents the type of traffic treatment.
*/
public enum L2SubType implements SubType {
public enum L2SubType {
/**
* Ether src modification.
*/
......@@ -24,11 +24,6 @@ public abstract class L2ModificationInstruction implements Instruction {
L2_DST,
/**
* Ethertype modification.
*/
L2_TYPE,
/**
* VLAN id modification.
*/
VLAN_ID,
......@@ -42,12 +37,11 @@ public abstract class L2ModificationInstruction implements Instruction {
// 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,16 @@ public abstract class L2ModificationInstruction implements Instruction {
*/
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 +69,6 @@ public abstract class L2ModificationInstruction implements Instruction {
}
/**
* 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 +80,7 @@ public abstract class L2ModificationInstruction implements Instruction {
}
@Override
public SubType subtype() {
public L2SubType subtype() {
return L2SubType.VLAN_ID;
}
......@@ -130,7 +102,7 @@ public abstract class L2ModificationInstruction implements Instruction {
}
@Override
public SubType subtype() {
public L2SubType subtype() {
return L2SubType.VLAN_PCP;
}
......
......@@ -11,7 +11,7 @@ public abstract class L3ModificationInstruction implements Instruction {
/**
* Represents the type of traffic treatment.
*/
public enum L3SubType implements SubType {
public enum L3SubType {
/**
* Ether src modification.
*/
......@@ -20,12 +20,7 @@ public abstract class L3ModificationInstruction implements Instruction {
/**
* Ether dst modification.
*/
L3_DST,
/**
* Ethertype modification.
*/
L3_PROTO,
L3_DST
//TODO: remaining types
}
......@@ -34,11 +29,11 @@ public abstract class L3ModificationInstruction implements Instruction {
* 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,16 @@ public abstract class L3ModificationInstruction implements Instruction {
*/
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 +59,4 @@ public abstract class L3ModificationInstruction implements Instruction {
}
}
/**
* 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;
}
}
}
......
......@@ -2,6 +2,10 @@ package org.onlab.onos.provider.of.flow.impl;
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.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.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,8 +96,172 @@ public class OpenFlowRuleProvider extends AbstractProvider implements FlowRulePr
}
@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().toString()));
break;
case IPV4_SRC:
ip = (IPCriterion) c;
mBuilder.setExact(MatchField.IPV4_SRC, IPv4Address.of(ip.ip().toString()));
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
......