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

Merge pull request #576 from rizard/master

Features request via REST API bug fix and start on OF-DPA support
parents 9c6750b4 25206472
No related branches found
No related tags found
No related merge requests found
......@@ -3,6 +3,7 @@ package net.floodlightcontroller.core.internal;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
......@@ -24,10 +25,12 @@ import net.floodlightcontroller.core.SwitchDescription;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
import net.floodlightcontroller.core.annotations.LogMessageDocs;
import net.floodlightcontroller.core.internal.OFSwitchAppHandshakePlugin.PluginResultType;
import net.floodlightcontroller.util.OFDPAUtils;
import org.projectfloodlight.openflow.protocol.OFBadRequestCode;
import org.projectfloodlight.openflow.protocol.OFBarrierReply;
import org.projectfloodlight.openflow.protocol.OFBarrierRequest;
import org.projectfloodlight.openflow.protocol.OFBucket;
import org.projectfloodlight.openflow.protocol.OFControllerRole;
import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFDescStatsRequest;
......@@ -44,6 +47,7 @@ import org.projectfloodlight.openflow.protocol.OFFlowModFailedCode;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
import org.projectfloodlight.openflow.protocol.OFGetConfigReply;
import org.projectfloodlight.openflow.protocol.OFGetConfigRequest;
import org.projectfloodlight.openflow.protocol.OFGroupAdd;
import org.projectfloodlight.openflow.protocol.OFGroupDelete;
import org.projectfloodlight.openflow.protocol.OFGroupType;
import org.projectfloodlight.openflow.protocol.OFMessage;
......@@ -51,6 +55,7 @@ import org.projectfloodlight.openflow.protocol.OFNiciraControllerRole;
import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleReply;
import org.projectfloodlight.openflow.protocol.OFNiciraControllerRoleRequest;
import org.projectfloodlight.openflow.protocol.OFPacketIn;
import org.projectfloodlight.openflow.protocol.OFPortDesc;
import org.projectfloodlight.openflow.protocol.OFPortDescStatsReply;
import org.projectfloodlight.openflow.protocol.OFPortStatus;
import org.projectfloodlight.openflow.protocol.OFQueueGetConfigReply;
......@@ -68,12 +73,18 @@ import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.errormsg.OFBadRequestErrorMsg;
import org.projectfloodlight.openflow.protocol.errormsg.OFFlowModFailedErrorMsg;
import org.projectfloodlight.openflow.protocol.instruction.OFInstruction;
import org.projectfloodlight.openflow.protocol.match.MatchField;
import org.projectfloodlight.openflow.types.DatapathId;
import org.projectfloodlight.openflow.types.OFAuxId;
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.U16;
import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.VlanVid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -521,6 +532,142 @@ public class OFSwitchHandshakeHandler implements IOFConnectionListener {
}
}
private void addBroadcomOFDPAFlows() {
/*
* By default, we'll assume everyone's on the same VLAN,
* and all switch ports are configured as access ports.
* As such, all packets on the wire will be untagged
* and will only be tagged internally in the switch for
* pipeline processing.
*
* If you would like to configure trunks on switches, then
* each switch will need to be configured specifically, as
* we won't be able to automatically handle such a topology.
*
* Ingress port table (0) = empty --> default to VLAN table
* VLAN table (10) = match untagged, apply internal tag, goto termination MAC
* Termination MAC table (20) = match vlan tag and dst MAC, goto bridging table (default miss-->bridging)
* match only vlan tag, goto controller (DLF or Dest Lookup Failure)
* Bridging table (50) = default send to policy ACL table
* Policy ACL table (60) = priority=0 go to controller
* write action group of forwarding decision
* Group tables
* One per interface per VLAN
* One per VLAN (for flooding)
*
* TABLE_INGRESS = 0
* TABLE_VLAN = 10
* TABLE_MAC = 20
* TABLE_UNICAST = 30
* TABLE_MULTICAST = 40
* TABLE_BRIDGING = 50
* TABLE_ACL = 60
*/
/*
* Add flow to match all untagged packets from all ports in VLAN table
*/
List<OFAction> al = new ArrayList<OFAction>(1);
/* al.add(factory.actions().pushVlan(EthType.IPv4)); might not need this */
al.add(factory.actions().setVlanVid(VlanVid.ofVlan(1))); /* we'll use 1 internally, just because */
List<OFInstruction> il = new ArrayList<OFInstruction>(2);
il.add(factory.instructions().gotoTable(TableId.of(20))); /* 20 is the termination MAC table */
il.add(factory.instructions().applyActions(al));
OFFlowAdd fa = factory.buildFlowAdd()
.setTableId(TableId.of(10))
.setOutPort(OFPort.ANY)
.setBufferId(OFBufferId.NO_BUFFER)
.setCookie(U64.ZERO)
.setMatch(factory.buildMatch()
.setExact(MatchField.VLAN_VID, OFVlanVidMatch.UNTAGGED) /* this flow handles untagged */
/* do we have to match on the in port here? */
.build()
)
.setInstructions(il)
.setPriority(1000)
.build();
sw.write(fa);
/*
* The termination MAC flow table must proactively forward to controller specific dst MACs,
* so we need to wait to do wildcarded dst MACs in bridging table upon a miss. Send to bridging
* table by default here.
*/
/*
* Add flow to match all vlan=1 packets to forward to controller in bridging table (DLF).
* Default is to send to policy ACL if this does not match.
*/
al = new ArrayList<OFAction>(1);
al.add(factory.actions().output(OFPort.CONTROLLER, 0xffFFffFF));
il = new ArrayList<OFInstruction>(1);
il.add(factory.instructions().applyActions(al));
fa = factory.buildFlowAdd()
.setTableId(TableId.of(50))
.setOutPort(OFPort.ANY)
.setBufferId(OFBufferId.NO_BUFFER)
.setCookie(U64.ZERO)
.setMatch(factory.buildMatch()
.setExact(MatchField.VLAN_VID, OFVlanVidMatch.ofVlan(1)) /* this flow handles recently-tagged VLAN=1 */
.build()
)
.setInstructions(il)
.setPriority(1)
.build();
sw.write(fa);
/*
* Lastly, add a group for flooding and for each port.
* This group is only for VLAN=1.
*
* The flood group has buckets with goto group actions
* for each port's individual L2 group for VLAN=1.
*
* This means we must first add the individual groups.
*/
ArrayList<OFBucket> buckets = new ArrayList<OFBucket>();
for (OFPortDesc pd : this.sw.getPorts()) {
OFPort p = pd.getPortNo();
if ((p.getShortPortNumber() & 0xFF00) == 0) { /* TODO Is this correct for special ports? */
OFGroupAdd ga = factory.buildGroupAdd()
.setGroupType(OFGroupType.INDIRECT)
.setBuckets(Collections.singletonList(factory.buildBucket()
.setActions(
Collections.singletonList((OFAction) factory.actions().buildOutput()
.setMaxLen(0xffFFffFF)
.setPort(p)
.build()))
.build()))
.setGroup(OFDPAUtils.GroupIds.createL2Interface(p, VlanVid.ofVlan(100)))
.build();
sw.write(ga);
/*
* Add the port+bucket for creating the FLOOD group below.
* All L2_INTERFACE groups in a VLAN should be within a
* corresponding L2_FLOOD group of type ALL.
*/
buckets.add(factory.buildBucket().setActions(
Collections.singletonList(
(OFAction) factory.actions().buildOutput()
.setMaxLen(0xffFFffFF)
.setPort(p)
.build()
)
).build());
}
}
OFGroupAdd ga = factory.buildGroupAdd()
.setGroupType(OFGroupType.ALL)
.setBuckets(buckets)
.setGroup(OFDPAUtils.GroupIds.createL2Flood(U16.ZERO, VlanVid.ofVlan(100)))
.build();
sw.write(ga);
}
/**
* Default implementation for message handlers in any state.
*
......@@ -865,7 +1012,6 @@ public class OFSwitchHandshakeHandler implements IOFConnectionListener {
}
break;
default:
illegalMessageReceived(m);
break;
}
}
......
......@@ -118,7 +118,7 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
private ConcurrentHashMap<DatapathId, OFSwitchHandshakeHandler> switchHandlers;
private ConcurrentHashMap<DatapathId, IOFSwitchBackend> switches;
private ConcurrentHashMap<DatapathId, IOFSwitch> syncedSwitches;
private Set<DatapathId> pastSwitches;
private ISwitchDriverRegistry driverRegistry;
......@@ -676,6 +676,8 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
driverRegistry = new NaiveSwitchDriverRegistry(this);
this.switchListeners = new CopyOnWriteArraySet<IOFSwitchListener>();
this.pastSwitches = new HashSet<DatapathId>();
/* TODO @Ryan
try {
......@@ -1010,7 +1012,7 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
ChannelPipelineFactory pfact = useSsl ? new OpenflowPipelineFactory(this, floodlightProvider.getTimer(), this, debugCounterService, ofBitmaps, defaultFactory, keyStore, keyStorePassword) :
new OpenflowPipelineFactory(this, floodlightProvider.getTimer(), this, debugCounterService, ofBitmaps, defaultFactory);
bootstrap.setPipelineFactory(pfact);
InetSocketAddress sa = new InetSocketAddress(floodlightProvider.getOFPort());
final ChannelGroup cg = new DefaultChannelGroup();
......
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