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

Cleaned up some more. Ported static flow pusher and REST API

parent 2a1fbbf2
No related branches found
No related tags found
No related merge requests found
......@@ -26,6 +26,7 @@ import net.floodlightcontroller.core.module.FloodlightModuleConfigFileNotFoundEx
import net.floodlightcontroller.core.module.FloodlightModuleException;
import net.floodlightcontroller.core.module.FloodlightModuleLoader;
import net.floodlightcontroller.core.module.IFloodlightModuleContext;
import net.floodlightcontroller.restserver.IRestApiService;
/**
* Host for the Floodlight main method
......@@ -58,21 +59,17 @@ public class Main {
FloodlightModuleLoader fml = new FloodlightModuleLoader();
try {
IFloodlightModuleContext moduleContext = fml.loadModulesFromConfig(settings.getModuleFile());
//TODO @Ryan I don't think we need this anymore... Run REST server
//IRestApiService restApi = moduleContext.getServiceImpl(IRestApiService.class);
//restApi.run();
// Run the main floodlight module
//IFloodlightProviderService controller =
// moduleContext.getServiceImpl(IFloodlightProviderService.class);
// This call blocks, it has to be the last line in the main
//controller.run();
// @Ryan TODO This should probably be implemented and run as a normal service for consistency;
// although, it does need all modules to be loaded and their prior to running.
IRestApiService restApi = moduleContext.getServiceImpl(IRestApiService.class);
restApi.run();
} catch (FloodlightModuleConfigFileNotFoundException e) {
// we really want to log the message, not the stack trace
logger.error("Could not read config file: {}", e.getMessage());
System.exit(1);
}
try {
fml.runModules(); // this should run the controller module and all modules
fml.runModules(); // run the controller module and all modules
} catch (FloodlightModuleException e) {
logger.error("Failed to run controller modules", e);
System.exit(1);
......
......@@ -701,7 +701,6 @@ public class OFSwitch implements IOFSwitchBackend {
@Override
public void write(OFMessage m) {
log.debug("Possible OFConnections to write to: {}", connections);
log.debug("Channel info: {} {}", connections.get(OFAuxId.MAIN).getRemoteInetAddress(), connections.get(OFAuxId.MAIN).isConnected());
connections.get(OFAuxId.MAIN).write(m);
}
......
......@@ -19,8 +19,6 @@ package net.floodlightcontroller.core.module;
import java.util.Collection;
import java.util.Map;
import org.projectfloodlight.openflow.protocol.OFType;
/**
* Defines an interface for loadable Floodlight modules.
*
......
......@@ -98,8 +98,8 @@ public class StaticFlowEntries {
* @param fm The OFFlowMod to set defaults for
* @param entryName The name of the entry. Used to compute the cookie.
*/
public static void initDefaultFlowMod(OFFlowMod fm, String entryName) {
fm = fm.createBuilder().setIdleTimeout((short) 0) // infinite
public static OFFlowMod initDefaultFlowMod(OFFlowMod fm, String entryName) {
return fm.createBuilder().setIdleTimeout((short) 0) // infinite
.setHardTimeout((short) 0) // infinite
.setBufferId(OFBufferId.NO_BUFFER)
.setOutPort(OFPort.ANY)
......@@ -378,7 +378,7 @@ public class StaticFlowEntries {
message="Unexpected action '{action}', '{subaction}'",
explanation="A static flow entry contained an invalid action",
recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
public static void parseActionString(OFFlowMod flowMod, String actionstr, Logger log) {
public static OFFlowMod parseActionString(OFFlowMod flowMod, String actionstr, Logger log) {
List<OFAction> actions = new LinkedList<OFAction>();
if (actionstr != null) {
actionstr = actionstr.toLowerCase();
......@@ -433,7 +433,7 @@ public class StaticFlowEntries {
}
log.debug("action {}", actions);
flowMod.createBuilder().setActions(actions).build();
return flowMod.createBuilder().setActions(actions).build();
}
@LogMessageDoc(level="ERROR",
......
......@@ -54,6 +54,7 @@ import net.floodlightcontroller.util.FlowModUtils;
import net.floodlightcontroller.util.MatchString;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFFlowDeleteStrict;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowRemoved;
......@@ -269,6 +270,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
StringBuffer matchString = new StringBuffer();
OFFlowMod.Builder fmb = OFFactories.getFactory(OFVersion.OF_13).buildFlowModify();
OFFlowMod fm = fmb.build();
if (!row.containsKey(COLUMN_SWITCH) || !row.containsKey(COLUMN_NAME)) {
log.debug(
......@@ -283,7 +285,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
entryName = (String) row.get(COLUMN_NAME);
if (!entries.containsKey(switchName))
entries.put(switchName, new HashMap<String, OFFlowMod>());
StaticFlowEntries.initDefaultFlowMod(fmb.build(), entryName);
fm = StaticFlowEntries.initDefaultFlowMod(fm, entryName);
for (String key : row.keySet()) {
if (row.get(key) == null)
......@@ -303,14 +305,14 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
return;
}
} else if (key.equals(COLUMN_ACTIONS)){
StaticFlowEntries.parseActionString(fmb.build(), (String) row.get(COLUMN_ACTIONS), log);
fm = StaticFlowEntries.parseActionString(fm, (String) row.get(COLUMN_ACTIONS), log);
} else if (key.equals(COLUMN_COOKIE)) {
fmb.setCookie(
StaticFlowEntries.computeEntryCookie(fmb.build(),
fm = fm.createBuilder().setCookie(
StaticFlowEntries.computeEntryCookie(fm,
Integer.valueOf((String) row.get(COLUMN_COOKIE)),
entryName));
entryName)).build();
} else if (key.equals(COLUMN_PRIORITY)) {
fmb.setPriority(U16.t(Integer.valueOf((String) row.get(COLUMN_PRIORITY))));
fm = fm.createBuilder().setPriority(U16.t(Integer.valueOf((String) row.get(COLUMN_PRIORITY)))).build();
} else { // the rest of the keys are for OFMatch().fromString()
if (matchString.length() > 0)
matchString.append(",");
......@@ -332,7 +334,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
try {
//TODO @Ryan new fromString() method here. Should verify it especially
fmb.setMatch(MatchString.fromString(match, OFVersion.OF_13));
fm = fm.createBuilder().setMatch(MatchString.fromString(match, OFVersion.OF_13)).build();
} catch (IllegalArgumentException e) {
log.debug(
"ignoring flow entry {} on switch {} with illegal OFMatch() key: "
......@@ -340,7 +342,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
return;
}
entries.get(switchName).put(entryName, fmb.build());
entries.get(switchName).put(entryName, fm);
}
@Override
......@@ -402,6 +404,7 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
if (dpidOldFlowMod != null) {
oldFlowMod = entriesFromStorage.get(dpidOldFlowMod).remove(entry);
}
// pre-existing case. should modify or delete, but not add
if (oldFlowMod != null && newFlowMod != null) {
// set the new flow mod to modify a pre-existing rule if these fields match
if (oldFlowMod.getMatch().equals(newFlowMod.getMatch())
......@@ -418,10 +421,11 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
}
}
}
// write the new flow
// new case. should add a flow, not modify or delete
if (newFlowMod != null) {
entriesFromStorage.get(dpid).put(entry, newFlowMod);
outQueue.add(newFlowMod);
OFFlowAdd addTmp = FlowModUtils.toFlowAdd(newFlowMod);
entriesFromStorage.get(dpid).put(entry, addTmp);
outQueue.add(addTmp);
entry2dpid.put(entry, dpid);
} else {
entriesFromStorage.get(dpid).remove(entry);
......
......@@ -2,16 +2,15 @@ package net.floodlightcontroller.testmodule;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Collections;
import java.util.Map;
import org.projectfloodlight.openflow.protocol.OFFactories;
import org.projectfloodlight.openflow.protocol.OFFlowMod;
import org.projectfloodlight.openflow.protocol.OFFlowAdd;
import org.projectfloodlight.openflow.protocol.OFVersion;
import org.projectfloodlight.openflow.protocol.action.OFAction;
import org.projectfloodlight.openflow.protocol.action.OFActionOutput;
import org.projectfloodlight.openflow.types.DatapathId;
import org.projectfloodlight.openflow.types.OFBufferId;
import org.projectfloodlight.openflow.types.OFPort;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
......@@ -57,16 +56,18 @@ public class TestModule implements IFloodlightModule {
@Override
public void startUp(FloodlightModuleContext context)
throws FloodlightModuleException {
OFFlowMod.Builder fmb = OFFactories.getFactory(OFVersion.OF_13).buildFlowModify();
OFActionOutput.Builder aob = OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput();
List<OFAction> al = new ArrayList<OFAction>();
al.add(aob.setPort(OFPort.ALL).build());
fmb.setActions(al);
fmb.setBufferId(OFBufferId.NO_BUFFER);
fmb.setIdleTimeout(10);
fmb.setHardTimeout(60);
fmb.setOutPort(OFPort.ALL); // let's try and mimic the hub module, but with a flow instead
// is this really necessary with the OFOutputAction explicitly set?
OFFlowAdd.Builder fmb = /*sw.getOFFactory()*/OFFactories.getFactory(OFVersion.OF_13).buildFlowAdd();
//Match.Builder mb = OFFactories.getFactory(OFVersion.OF_13).buildMatch();
//fmb.setBufferId(OFBufferId.NO_BUFFER)
//fmb.setXid(pi.getXid());
/*.setMatch(pi.getMatch())*/
// set actions
OFActionOutput.Builder actionBuilder = /*sw.getOFFactory()*/OFFactories.getFactory(OFVersion.OF_13).actions().buildOutput();
actionBuilder.setPort(OFPort.ALL);
fmb.setActions(Collections.singletonList((OFAction) actionBuilder.build()));
fmb.setOutPort(OFPort.ALL);
// we aren't matching anything specifically, so all should be wildcarded by default
// in on any port, with any header attributes, send out all ports = Hub module
......@@ -76,6 +77,8 @@ public class TestModule implements IFloodlightModule {
e.printStackTrace();
}
sfps.addFlow("test-flow", fmb.build(), DatapathId.of(1)); // This should add the flow, regardless whether or not the switch is connected, I believe. If it connects in a second, it should be pushed.
//sfps.deleteFlow("test-flow");
}
}
/**
* Copyright 2013, Big Switch Networks, Inc.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License. You may obtain
* a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations
* under the License.
**/
package net.floodlightcontroller.util;
import java.util.Arrays;
/**
* The class representing MAC address.
*
* @author Sho Shimizu (sho.shimizu@gmail.com)
*/
public class MACAddress {
public static final int MAC_ADDRESS_LENGTH = 6;
private byte[] address = new byte[MAC_ADDRESS_LENGTH];
public MACAddress(byte[] address) {
this.address = Arrays.copyOf(address, MAC_ADDRESS_LENGTH);
}
/**
* Returns a MAC address instance representing the value of the specified {@code String}.
* @param address the String representation of the MAC Address to be parsed.
* @return a MAC Address instance representing the value of the specified {@code String}.
* @throws IllegalArgumentException if the string cannot be parsed as a MAC address.
*/
public static MACAddress valueOf(String address) {
String[] elements = address.split(":");
if (elements.length != MAC_ADDRESS_LENGTH) {
throw new IllegalArgumentException(
"Specified MAC Address must contain 12 hex digits" +
" separated pairwise by :'s.");
}
byte[] addressInBytes = new byte[MAC_ADDRESS_LENGTH];
for (int i = 0; i < MAC_ADDRESS_LENGTH; i++) {
String element = elements[i];
addressInBytes[i] = (byte)Integer.parseInt(element, 16);
}
return new MACAddress(addressInBytes);
}
/**
* Returns a MAC address instance representing the specified {@code byte} array.
* @param address the byte array to be parsed.
* @return a MAC address instance representing the specified {@code byte} array.
* @throws IllegalArgumentException if the byte array cannot be parsed as a MAC address.
*/
public static MACAddress valueOf(byte[] address) {
if (address.length != MAC_ADDRESS_LENGTH) {
throw new IllegalArgumentException("the length is not " + MAC_ADDRESS_LENGTH);
}
return new MACAddress(address);
}
/**
* Returns a MAC address instance representing the specified {@code long} value.
* The lower 48 bits of the long value are used to parse as a MAC address.
* @param address the long value to be parsed. The lower 48 bits are used for a MAC address.
* @return a MAC address instance representing the specified {@code long} value.
* @throws IllegalArgumentException if the long value cannot be parsed as a MAC address.
*/
public static MACAddress valueOf(long address) {
byte[] addressInBytes = new byte[] {
(byte)((address >> 40) & 0xff),
(byte)((address >> 32) & 0xff),
(byte)((address >> 24) & 0xff),
(byte)((address >> 16) & 0xff),
(byte)((address >> 8 ) & 0xff),
(byte)((address >> 0) & 0xff)
};
return new MACAddress(addressInBytes);
}
/**
* Returns the length of the {@code MACAddress}.
* @return the length of the {@code MACAddress}.
*/
public int length() {
return address.length;
}
/**
* Returns the value of the {@code MACAddress} as a {@code byte} array.
* @return the numeric value represented by this object after conversion to type {@code byte} array.
*/
public byte[] toBytes() {
return Arrays.copyOf(address, address.length);
}
/**
* Returns the value of the {@code MACAddress} as a {@code long}.
* @return the numeric value represented by this object after conversion to type {@code long}.
*/
public long toLong() {
long mac = 0;
for (int i = 0; i < 6; i++) {
long t = (address[i] & 0xffL) << ((5 - i) * 8);
mac |= t;
}
return mac;
}
/**
* Returns {@code true} if the MAC address is the broadcast address.
* @return {@code true} if the MAC address is the broadcast address.
*/
public boolean isBroadcast() {
for (byte b : address) {
if (b != -1) // checks if equal to 0xff
return false;
}
return true;
}
/**
* Returns {@code true} if the MAC address is the multicast address.
* @return {@code true} if the MAC address is the multicast address.
*/
public boolean isMulticast() {
if (isBroadcast()) {
return false;
}
return (address[0] & 0x01) != 0;
}
@Override
public boolean equals(Object o) {
if (o == this) {
return true;
}
if (!(o instanceof MACAddress)) {
return false;
}
MACAddress other = (MACAddress)o;
return Arrays.equals(this.address, other.address);
}
@Override
public int hashCode() {
return Arrays.hashCode(this.address);
}
@Override
public String toString() {
StringBuilder builder = new StringBuilder();
for (byte b: address) {
if (builder.length() > 0) {
builder.append(":");
}
builder.append(String.format("%02X", b & 0xFF));
}
return builder.toString();
}
}
......@@ -6,9 +6,10 @@ net.floodlightcontroller.threadpool.ThreadPool,\
net.floodlightcontroller.debugcounter.DebugCounterServiceImpl,\
net.floodlightcontroller.restserver.RestApiServer,\
net.floodlightcontroller.perfmon.PktInProcessingTime,\
net.floodlightcontroller.hub.Hub,\
net.floodlightcontroller.testmodule.TestModule,\
net.floodlightcontroller.debugevent.DebugEventService,\
net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher
net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher,\
net.floodlightcontroller.restserver.RestApiServer
org.sdnplatform.sync.internal.SyncManager.authScheme=CHALLENGE_RESPONSE
org.sdnplatform.sync.internal.SyncManager.keyStorePath=/etc/floodlight/auth_credentials.jceks
org.sdnplatform.sync.internal.SyncManager.dbPath=/var/lib/floodlight/
......
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