Skip to content
Snippets Groups Projects
Commit eaad2b6f authored by Ryan Izard's avatar Ryan Izard
Browse files

OF-DPA utils integrated into Forwarding

parent faf34305
No related branches found
No related tags found
No related merge requests found
......@@ -28,6 +28,8 @@ import java.util.Set;
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.IOFSwitchListener;
import net.floodlightcontroller.core.PortChangeType;
import net.floodlightcontroller.core.internal.IOFSwitchService;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.module.FloodlightModuleException;
......@@ -49,11 +51,16 @@ import net.floodlightcontroller.routing.IRoutingService;
import net.floodlightcontroller.routing.Route;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.util.OFDPAUtils;
import net.floodlightcontroller.util.OFPortMode;
import net.floodlightcontroller.util.OFPortModeTuple;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowModCommand;
import org.projectfloodlight.openflow.protocol.OFGroupType;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPacketOut;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.match.Match;
......@@ -65,14 +72,16 @@ import org.projectfloodlight.openflow.types.IPv6Address;
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.U64;
import org.projectfloodlight.openflow.types.VlanVid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Forwarding extends ForwardingBase implements IFloodlightModule {
public class Forwarding extends ForwardingBase implements IFloodlightModule, IOFSwitchListener {
protected static Logger log = LoggerFactory.getLogger(Forwarding.class);
@Override
......@@ -509,5 +518,57 @@ public class Forwarding extends ForwardingBase implements IFloodlightModule {
@Override
public void startUp(FloodlightModuleContext context) {
super.startUp();
switchService.addOFSwitchListener(this);
}
@Override
public void switchAdded(DatapathId switchId) {
}
@Override
public void switchRemoved(DatapathId switchId) {
}
@Override
public void switchActivated(DatapathId switchId) {
IOFSwitch sw = switchService.getSwitch(switchId);
if (sw == null) {
log.warn("Switch {} was activated but had no switch object in the switch service. Perhaps it quickly disconnected", switchId);
return;
}
if (OFDPAUtils.isOFDPASwitch(sw)) {
sw.write(sw.getOFFactory().buildFlowDelete()
.setTableId(TableId.ALL)
.build()
);
sw.write(sw.getOFFactory().buildGroupDelete()
.setGroup(OFGroup.ANY)
.setGroupType(OFGroupType.ALL)
.build()
);
sw.write(sw.getOFFactory().buildGroupDelete()
.setGroup(OFGroup.ANY)
.setGroupType(OFGroupType.INDIRECT)
.build()
);
sw.write(sw.getOFFactory().buildBarrierRequest().build());
List<OFPortModeTuple> portModes = new ArrayList<OFPortModeTuple>();
for (OFPortDesc p : sw.getPorts()) {
portModes.add(OFPortModeTuple.of(p.getPortNo(), OFPortMode.ACCESS));
}
if (log.isWarnEnabled()) {
log.warn("For OF-DPA switch {}, initializing VLAN {} on ports {}", new Object[] { switchId, VlanVid.ZERO, portModes});
}
OFDPAUtils.addLearningSwitchPrereqs(sw, VlanVid.ZERO, portModes);
}
}
@Override
public void switchPortChanged(DatapathId switchId, OFPortDesc port, PortChangeType type) {
}
@Override
public void switchChanged(DatapathId switchId) {
}
}
......@@ -42,6 +42,7 @@ import net.floodlightcontroller.routing.Route;
import net.floodlightcontroller.topology.ITopologyService;
import net.floodlightcontroller.topology.NodePortTuple;
import net.floodlightcontroller.util.MatchUtils;
import net.floodlightcontroller.util.OFDPAUtils;
import net.floodlightcontroller.util.OFMessageDamper;
import net.floodlightcontroller.util.TimedCache;
......@@ -264,7 +265,7 @@ public abstract class ForwardingBase implements IOFMessageListener {
outPort });
}
/*if (OFDPAUtils.isOFDPASwitch(sw)) {
if (OFDPAUtils.isOFDPASwitch(sw)) {
OFDPAUtils.addLearningSwitchFlow(sw, cookie,
FLOWMOD_DEFAULT_PRIORITY,
FLOWMOD_DEFAULT_HARD_TIMEOUT,
......@@ -272,9 +273,9 @@ public abstract class ForwardingBase implements IOFMessageListener {
fmb.getMatch(),
null, // TODO how to determine output VLAN for lookup of L2 interface group
outPort);
} else {*/
} else {
messageDamper.write(sw, fmb.build());
/*}*/
}
/* Push the packet out the first hop switch */
if (sw.getId().equals(pinSwitch) &&
......
......@@ -268,7 +268,7 @@ public class OFDPAUtils {
for (OFPortModeTuple p : ports) {
if (sw.getOFFactory().getVersion().equals(OFVersion.OF_10) && (sw.getPort(p.getPort()) == null || p.getPort().getShortPortNumber() > 0xFF00)) {
throw new IllegalArgumentException("Port " + p.getPort().getPortNumber() + " is not a valid port on switch " + sw.getId().toString());
} else if (!sw.getOFFactory().getVersion().equals(OFVersion.OF_10) && (sw.getPort(p.getPort()) == null || p.getPort().getPortNumber() > 0xffFFff00)) {
} else if (!sw.getOFFactory().getVersion().equals(OFVersion.OF_10) && (sw.getPort(p.getPort()) == null || U32.of(p.getPort().getPortNumber()).compareTo(U32.of(0xffFFff00)) != -1)) {
throw new IllegalArgumentException("Port " + p.getPort().getPortNumber() + " is not a valid port on switch " + sw.getId().toString());
}
}
......@@ -285,7 +285,7 @@ public class OFDPAUtils {
actions.add(sw.getOFFactory().actions().output(p.getPort(), 0xffFFffFF));
OFGroupAdd ga = sw.getOFFactory().buildGroupAdd()
.setGroup(GroupIds.createL2Interface(p.getPort(), (vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan)))
.setGroup(GroupIds.createL2Interface(p.getPort(), vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan))
.setGroupType(OFGroupType.INDIRECT)
.setBuckets(Collections.singletonList(
sw.getOFFactory().buildBucket()
......@@ -302,14 +302,11 @@ public class OFDPAUtils {
List<OFBucket> bucketList = new ArrayList<OFBucket>(ports.size());
for (OFPortModeTuple p : ports) {
List<OFAction> actions = new ArrayList<OFAction>();
if (vlan.equals(VlanVid.ZERO) || p.getMode() == OFPortMode.ACCESS) {
actions.add(sw.getOFFactory().actions().popVlan());
}
actions.add(sw.getOFFactory().actions().output(p.getPort(), 0xffFFffFF));
actions.add(sw.getOFFactory().actions().group(GroupIds.createL2Interface(p.getPort(), vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan)));
bucketList.add(sw.getOFFactory().buildBucket().setActions(actions).build());
}
OFGroupAdd ga = sw.getOFFactory().buildGroupAdd() /* use the VLAN ID as the group ID */
.setGroup(GroupIds.createL2Flood(U16.of(vlan.getVlan()), vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan))
.setGroup(GroupIds.createL2Flood(U16.of((vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan).getVlan()), vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan))
.setGroupType(OFGroupType.ALL)
.setBuckets(bucketList)
.build();
......@@ -352,7 +349,7 @@ public class OFDPAUtils {
for (OFPortModeTuple p : ports) {
if (sw.getOFFactory().getVersion().equals(OFVersion.OF_10) && (sw.getPort(p.getPort()) == null || p.getPort().getShortPortNumber() > 0xFF00)) {
throw new IllegalArgumentException("Port " + p.getPort().getPortNumber() + " is not a valid port on switch " + sw.getId().toString());
} else if (!sw.getOFFactory().getVersion().equals(OFVersion.OF_10) && (sw.getPort(p.getPort()) == null || p.getPort().getPortNumber() > 0xffFFff00)) {
} else if (!sw.getOFFactory().getVersion().equals(OFVersion.OF_10) && (sw.getPort(p.getPort()) == null || U32.of(p.getPort().getPortNumber()).compareTo(U32.of(0xffFFff00)) != -1)) {
throw new IllegalArgumentException("Port " + p.getPort().getPortNumber() + " is not a valid port on switch " + sw.getId().toString());
}
}
......@@ -441,13 +438,15 @@ public class OFDPAUtils {
/*
* We will insert a DLF flow to send to controller in the bridging table (50).
*/
writeActions.add(sw.getOFFactory().actions().group(OFDPAUtils.GroupIds.createL2Flood(U16.of(vlan.getVlan()) /* ID */, vlan))); /* bogus action */
writeActions.add(sw.getOFFactory().actions().group(OFDPAUtils.GroupIds.createL2Flood(
U16.of((vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan).getVlan()) /* ID */,
vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan))); /* bogus action */
applyActions.add(sw.getOFFactory().actions().output(OFPort.CONTROLLER, 0xffFFffFF)); /* real, intended action */
instructions.add(sw.getOFFactory().instructions().writeActions(writeActions));
instructions.add(sw.getOFFactory().instructions().applyActions(applyActions));
instructions.add(sw.getOFFactory().instructions().gotoTable(Tables.POLICY_ACL)); /* must go to policy ACL otherwise dropped; bogus though */
fab = fab.setMatch(sw.getOFFactory().buildMatch()
.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlanVid(vlan)) /* must match on just VLAN; dst MAC wildcarded */
.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlanVid(vlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : vlan)) /* must match on just VLAN; dst MAC wildcarded */
.build())
.setInstructions(instructions)
.setPriority(DLF_PRIORITY) /* lower priority */
......@@ -526,10 +525,7 @@ public class OFDPAUtils {
*/
ArrayList<OFInstruction> instructions = new ArrayList<OFInstruction>();
ArrayList<OFAction> actions = new ArrayList<OFAction>();
if (outVlan.equals(VlanVid.ZERO)) {
actions.add(sw.getOFFactory().actions().popVlan());
}
actions.add(sw.getOFFactory().actions().group(GroupIds.createL2Interface(outPort, (outVlan.equals(VlanVid.ZERO) ? VlanVid.ofVlan(1) : outVlan))));
instructions.add(sw.getOFFactory().instructions().writeActions(actions));
instructions.add(sw.getOFFactory().instructions().gotoTable(Tables.POLICY_ACL)); /* must go here or dropped */
......
......@@ -31,6 +31,7 @@ import java.util.Set;
import net.floodlightcontroller.core.FloodlightContext;
import net.floodlightcontroller.core.IFloodlightProviderService;
import net.floodlightcontroller.core.IOFSwitch;
import net.floodlightcontroller.core.SwitchDescription;
import net.floodlightcontroller.core.internal.IOFSwitchService;
import net.floodlightcontroller.core.module.FloodlightModuleContext;
import net.floodlightcontroller.core.test.MockThreadPoolService;
......@@ -67,6 +68,7 @@ import org.projectfloodlight.openflow.protocol.OFFeaturesReply;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.match.Match;
import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFactory;
import org.projectfloodlight.openflow.protocol.OFMessage;
......@@ -99,6 +101,7 @@ public class ForwardingTest extends FloodlightTestCase {
protected MockThreadPoolService threadPool;
protected IOFSwitch sw1, sw2;
protected OFFeaturesReply swFeatures;
protected OFDescStatsReply swDescription;
protected IDevice srcDevice, dstDevice1, dstDevice2; /* reuse for IPv4 and IPv6 */
protected OFPacketIn packetIn;
protected OFPacketIn packetInIPv6;
......@@ -162,6 +165,7 @@ public class ForwardingTest extends FloodlightTestCase {
entityClassifier.startUp(fmc);
verify(topology);
swDescription = factory.buildDescStatsReply().build();
swFeatures = factory.buildFeaturesReply().setNBuffers(1000).build();
// Mock switches
sw1 = EasyMock.createMock(IOFSwitch.class);
......@@ -177,6 +181,9 @@ public class ForwardingTest extends FloodlightTestCase {
expect(sw1.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
expect(sw2.hasAttribute(IOFSwitch.PROP_SUPPORTS_OFPP_TABLE)).andReturn(true).anyTimes();
expect(sw1.getSwitchDescription()).andReturn(new SwitchDescription(swDescription)).anyTimes();
expect(sw2.getSwitchDescription()).andReturn(new SwitchDescription(swDescription)).anyTimes();
// Load the switch map
Map<DatapathId, IOFSwitch> switches = new HashMap<DatapathId, IOFSwitch>();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment