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

Merge pull request #501 from rizard/v1.0

Lots of goodies (including SSL support for OpenFlow connections)
parents c5fe357f 0b5c1873
No related branches found
No related tags found
No related merge requests found
Showing
with 312 additions and 173 deletions
File added
File deleted
......@@ -587,6 +587,10 @@ class OFChannelHandler extends IdleStateAwareChannelHandler {
} else if (e.getCause() instanceof RejectedExecutionException) {
log.warn("Could not process message: queue full");
counters.rejectedExecutionException.increment();
} else if (e.getCause() instanceof IllegalArgumentException) {
log.error("Could not decode OpenFlow protocol version from switch {}. Perhaps the switch is trying to use SSL and the controller is not (or vice versa)? {}", getConnectionInfoString(), e.getCause());
counters.switchSslConfigurationError.increment();
ctx.getChannel().close();
} else {
log.error("Error while processing message from switch "
+ getConnectionInfoString()
......
......@@ -90,10 +90,13 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
private IStoreClient<DatapathId, SwitchSyncRepresentation> storeClient;
public static final String SWITCH_SYNC_STORE_NAME = OFSwitchManager.class.getCanonicalName() + ".stateStore";
private static String keyStorePassword;
private static String keyStore;
private static boolean useSsl = false;
private ConcurrentHashMap<DatapathId, OFSwitchHandshakeHandler> switchHandlers;
private ConcurrentHashMap<DatapathId, IOFSwitchBackend> switches;
private ConcurrentHashMap<DatapathId, IOFSwitch> syncedSwitches;
private ConcurrentHashMap<DatapathId, IOFSwitch> syncedSwitches;
private ISwitchDriverRegistry driverRegistry;
......@@ -631,7 +634,7 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
// Module variables
switchHandlers = new ConcurrentHashMap<DatapathId, OFSwitchHandshakeHandler>();
switches = new ConcurrentHashMap<DatapathId, IOFSwitchBackend>();
syncedSwitches = new ConcurrentHashMap<DatapathId, IOFSwitch>();
syncedSwitches = new ConcurrentHashMap<DatapathId, IOFSwitch>();
floodlightProvider.getTimer();
counters = new SwitchManagerCounters(debugCounterService);
driverRegistry = new NaiveSwitchDriverRegistry(this);
......@@ -649,6 +652,36 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
throw new FloodlightModuleException("Error while setting up sync store client", e);
} */
/*
* Get SSL config.
*
* If a password is blank, the password field may or may not be specified.
* If it is specified, an empty string will be expected for blank.
*
* The path MUST be specified if SSL is enabled.
*/
Map<String, String> configParams = context.getConfigParams(this);
String path = configParams.get("keyStorePath");
String pass = configParams.get("keyStorePassword");
String useSsl = configParams.get("useSsl");
if (useSsl == null || path == null || path.isEmpty() ||
(!useSsl.equalsIgnoreCase("yes") && !useSsl.equalsIgnoreCase("true") &&
!useSsl.equalsIgnoreCase("yep") && !useSsl.equalsIgnoreCase("ja") &&
!useSsl.equalsIgnoreCase("stimmt")
)
) {
log.warn("SSL disabled. Using unsecure connections between Floodlight and switches.");
OFSwitchManager.useSsl = false;
OFSwitchManager.keyStore = null;
OFSwitchManager.keyStorePassword = null;
} else {
log.warn("SSL enabled. Using secure connections between Floodlight and switches.");
log.info("SSL keystore path: {}, password: {}", path, (pass == null ? "" : pass));
OFSwitchManager.useSsl = true;
OFSwitchManager.keyStore = path;
OFSwitchManager.keyStorePassword = (pass == null ? "" : pass);
}
}
@Override
......@@ -687,8 +720,9 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
bootstrap.setOption("child.tcpNoDelay", true);
bootstrap.setOption("child.sendBufferSize", Controller.SEND_BUFFER_SIZE);
ChannelPipelineFactory pfact =
new OpenflowPipelineFactory(this, floodlightProvider.getTimer(), this, debugCounterService);
ChannelPipelineFactory pfact = useSsl ? new OpenflowPipelineFactory(this, floodlightProvider.getTimer(), this, debugCounterService, keyStore, keyStorePassword) :
new OpenflowPipelineFactory(this, floodlightProvider.getTimer(), this, debugCounterService);
bootstrap.setPipelineFactory(pfact);
InetSocketAddress sa = new InetSocketAddress(floodlightProvider.getOFPort());
final ChannelGroup cg = new DefaultChannelGroup();
......@@ -805,60 +839,60 @@ public class OFSwitchManager implements IOFSwitchManager, INewOFConnectionListen
switchAddedToStore(sw);
}
}
/**
* Called when we receive a store notification about a switch that
* has been removed from the sync store
* @param dpid
*/
private synchronized void switchRemovedFromStore(DatapathId dpid) {
if (floodlightProvider.getRole() != HARole.STANDBY) {
return; // only read from store if slave
}
IOFSwitch oldSw = syncedSwitches.remove(dpid);
if (oldSw != null) {
addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.REMOVED));
} else {
// TODO: the switch was deleted (tombstone) before we ever
// knew about it (or was deleted repeatedly). Can this
// happen? When/how?
}
}
/**
* Called when we receive a store notification about a switch that
* has been removed from the sync store
* @param dpid
*/
private synchronized void switchRemovedFromStore(DatapathId dpid) {
if (floodlightProvider.getRole() != HARole.STANDBY) {
return; // only read from store if slave
}
IOFSwitch oldSw = syncedSwitches.remove(dpid);
if (oldSw != null) {
addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.REMOVED));
} else {
// TODO: the switch was deleted (tombstone) before we ever
// knew about it (or was deleted repeatedly). Can this
// happen? When/how?
}
}
/**
* Called when we receive a store notification about a new or updated
* switch.
* @param sw
*/
private synchronized void switchAddedToStore(IOFSwitch sw) {
if (floodlightProvider.getRole() != HARole.STANDBY) {
return; // only read from store if slave
}
DatapathId dpid = sw.getId();
IOFSwitch oldSw = syncedSwitches.put(dpid, sw);
if (oldSw == null) {
addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.ADDED));
} else {
// The switch already exists in storage, see if anything
// has changed
sendNotificationsIfSwitchDiffers(oldSw, sw);
}
}
/**
* Check if the two switches differ in their ports or in other
* fields and if they differ enqueue a switch update
* @param oldSw
* @param newSw
*/
private synchronized void sendNotificationsIfSwitchDiffers(IOFSwitch oldSw, IOFSwitch newSw) {
/*TODO @Ryan Collection<PortChangeEvent> portDiffs = oldSw.comparePorts(newSw.getPorts());
* Called when we receive a store notification about a new or updated
* switch.
* @param sw
*/
private synchronized void switchAddedToStore(IOFSwitch sw) {
if (floodlightProvider.getRole() != HARole.STANDBY) {
return; // only read from store if slave
}
DatapathId dpid = sw.getId();
IOFSwitch oldSw = syncedSwitches.put(dpid, sw);
if (oldSw == null) {
addUpdateToQueue(new SwitchUpdate(dpid, SwitchUpdateType.ADDED));
} else {
// The switch already exists in storage, see if anything
// has changed
sendNotificationsIfSwitchDiffers(oldSw, sw);
}
}
/**
* Check if the two switches differ in their ports or in other
* fields and if they differ enqueue a switch update
* @param oldSw
* @param newSw
*/
private synchronized void sendNotificationsIfSwitchDiffers(IOFSwitch oldSw, IOFSwitch newSw) {
/*TODO @Ryan Collection<PortChangeEvent> portDiffs = oldSw.comparePorts(newSw.getPorts());
for (PortChangeEvent ev: portDiffs) {
SwitchUpdate update = new SwitchUpdate(newSw.getId(),
SwitchUpdateType.PORTCHANGED,
ev.port, ev.type);
addUpdateToQueue(update);
}*/
}
}
}
/**
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* 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.
**/
* Copyright 2011, Big Switch Networks, Inc.
* Originally created by David Erickson, Stanford University
*
* 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.core.internal;
import java.io.FileInputStream;
import java.security.KeyStore;
import javax.annotation.Nonnull;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManager;
import javax.net.ssl.TrustManagerFactory;
import org.jboss.netty.channel.ChannelPipeline;
import org.jboss.netty.channel.ChannelPipelineFactory;
import org.jboss.netty.channel.Channels;
import org.jboss.netty.handler.ssl.SslHandler;
import org.jboss.netty.handler.timeout.IdleStateHandler;
import org.jboss.netty.handler.timeout.ReadTimeoutHandler;
import org.jboss.netty.util.ExternalResourceReleasable;
import org.jboss.netty.util.Timer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import net.floodlightcontroller.debugcounter.IDebugCounterService;
/**
......@@ -31,92 +46,153 @@ import net.floodlightcontroller.debugcounter.IDebugCounterService;
* @author readams, sovietaced
*/
public class OpenflowPipelineFactory
implements ChannelPipelineFactory, ExternalResourceReleasable {
protected IOFSwitchManager switchManager;
protected INewOFConnectionListener connectionListener;
protected Timer timer;
protected IdleStateHandler idleHandler;
protected ReadTimeoutHandler readTimeoutHandler;
protected IDebugCounterService debugCounters;
public OpenflowPipelineFactory(IOFSwitchManager switchManager, Timer timer,
INewOFConnectionListener connectionListener,
IDebugCounterService debugCounters) {
super();
this.switchManager = switchManager;
this.connectionListener = connectionListener;
this.timer = timer;
this.debugCounters = debugCounters;
this.idleHandler = new IdleStateHandler(
timer,
PipelineIdleReadTimeout.MAIN,
PipelineIdleWriteTimeout.MAIN,
0);
this.readTimeoutHandler = new ReadTimeoutHandler(timer, 30);
}
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
OFChannelHandler handler = new OFChannelHandler(switchManager,
connectionListener,
pipeline,
debugCounters,
timer);
pipeline.addLast(PipelineHandler.OF_MESSAGE_DECODER,
new OFMessageDecoder());
pipeline.addLast(PipelineHandler.OF_MESSAGE_ENCODER,
new OFMessageEncoder());
pipeline.addLast(PipelineHandler.MAIN_IDLE, idleHandler);
pipeline.addLast(PipelineHandler.READ_TIMEOUT, readTimeoutHandler);
pipeline.addLast(PipelineHandler.CHANNEL_HANDSHAKE_TIMEOUT,
new HandshakeTimeoutHandler(
handler,
timer,
PipelineHandshakeTimeout.CHANNEL));
pipeline.addLast(PipelineHandler.CHANNEL_HANDLER, handler);
return pipeline;
}
@Override
public void releaseExternalResources() {
timer.stop();
}
public static class PipelineHandler {
final static String CHANNEL_HANDSHAKE_TIMEOUT = "channelhandshaketimeout";
final static String SWITCH_HANDSHAKE_TIMEOUT = "switchhandshaketimeout";
final static String CHANNEL_HANDLER = "channelhandler";
final static String MAIN_IDLE = "mainidle";
final static String AUX_IDLE = "auxidle";
final static String OF_MESSAGE_DECODER = "ofmessagedecoder";
final static String OF_MESSAGE_ENCODER = "ofmessageencoder";
final static String READ_TIMEOUT = "readtimeout";
}
/**
* Timeouts for parts of the handshake, in seconds
*/
public static class PipelineHandshakeTimeout {
final static int CHANNEL = 10;
final static int SWITCH = 30;
}
/**
* Timeouts for writes on connections, in seconds
*/
public static class PipelineIdleWriteTimeout {
final static int MAIN = 2;
final static int AUX = 15;
}
/**
* Timeouts for reads on connections, in seconds
*/
public static class PipelineIdleReadTimeout {
final static int MAIN = 3 * PipelineIdleWriteTimeout.MAIN;
final static int AUX = 3 * PipelineIdleWriteTimeout.AUX;
}
implements ChannelPipelineFactory, ExternalResourceReleasable {
private static final Logger log = LoggerFactory.getLogger(OpenflowPipelineFactory.class);
protected IOFSwitchManager switchManager;
protected INewOFConnectionListener connectionListener;
protected Timer timer;
protected IdleStateHandler idleHandler;
protected ReadTimeoutHandler readTimeoutHandler;
protected IDebugCounterService debugCounters;
private String keyStore;
private String keyStorePassword;
private void init(IOFSwitchManager switchManager, Timer timer,
INewOFConnectionListener connectionListener,
IDebugCounterService debugCounters) {
this.switchManager = switchManager;
this.connectionListener = connectionListener;
this.timer = timer;
this.debugCounters = debugCounters;
this.idleHandler = new IdleStateHandler(
timer,
PipelineIdleReadTimeout.MAIN,
PipelineIdleWriteTimeout.MAIN,
0);
this.readTimeoutHandler = new ReadTimeoutHandler(timer, 30);
}
public OpenflowPipelineFactory(IOFSwitchManager switchManager, Timer timer,
INewOFConnectionListener connectionListener,
IDebugCounterService debugCounters) {
super();
init(switchManager,timer, connectionListener, debugCounters);
this.keyStore = null;
this.keyStorePassword = null;
}
public OpenflowPipelineFactory(IOFSwitchManager switchManager, Timer timer,
INewOFConnectionListener connectionListener,
IDebugCounterService debugCounters,
@Nonnull String keyStore, @Nonnull String keyStorePassword) {
super();
init(switchManager,timer, connectionListener, debugCounters);
this.keyStore = keyStore;
this.keyStorePassword = keyStorePassword;
}
@Override
public ChannelPipeline getPipeline() throws Exception {
ChannelPipeline pipeline = Channels.pipeline();
OFChannelHandler handler = new OFChannelHandler(switchManager,
connectionListener,
pipeline,
debugCounters,
timer);
if (keyStore != null && keyStorePassword != null) {
try {
/* Set up factories and stores. */
TrustManagerFactory tmFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
KeyStore tmpKS = null;
tmFactory.init(tmpKS);
/* Use keystore/pass defined in properties file. */
KeyStore ks = KeyStore.getInstance("JKS");
ks.load(new FileInputStream(keyStore), keyStorePassword.toCharArray());
KeyManagerFactory kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm());
kmf.init(ks, keyStorePassword.toCharArray());
KeyManager[] km = kmf.getKeyManagers();
TrustManager[] tm = tmFactory.getTrustManagers();
/* Set up SSL prereqs for Netty. */
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(km, tm, null);
SSLEngine sslEngine = sslContext.createSSLEngine();
/* We are the server and we will create secure sessions. */
sslEngine.setUseClientMode(false);
sslEngine.setEnableSessionCreation(true);
/* These are redundant (default), but for clarity... */
sslEngine.setEnabledProtocols(sslEngine.getSupportedProtocols());
sslEngine.setEnabledCipherSuites(sslEngine.getSupportedCipherSuites());
/* First, decrypt w/handler+engine; then, proceed with rest of handlers. */
pipeline.addLast(PipelineHandler.SSL_TLS_ENCODER_DECODER, new SslHandler(sslEngine));
log.info("SSL OpenFlow socket initialized and handler ready for switch.");
} catch (Exception e) { /* There are lots of possible exceptions to catch, so this should get them all. */
log.error("Exception initializing SSL OpenFlow socket: {}", e.getMessage());
throw e; /* If we wanted secure but didn't get it, we should bail. */
}
}
/* SSL handler will have been added first if we're using it. */
pipeline.addLast(PipelineHandler.OF_MESSAGE_DECODER,
new OFMessageDecoder());
pipeline.addLast(PipelineHandler.OF_MESSAGE_ENCODER,
new OFMessageEncoder());
pipeline.addLast(PipelineHandler.MAIN_IDLE, idleHandler);
pipeline.addLast(PipelineHandler.READ_TIMEOUT, readTimeoutHandler);
pipeline.addLast(PipelineHandler.CHANNEL_HANDSHAKE_TIMEOUT,
new HandshakeTimeoutHandler(
handler,
timer,
PipelineHandshakeTimeout.CHANNEL));
pipeline.addLast(PipelineHandler.CHANNEL_HANDLER, handler);
return pipeline;
}
@Override
public void releaseExternalResources() {
timer.stop();
}
public static class PipelineHandler {
final static String CHANNEL_HANDSHAKE_TIMEOUT = "channelhandshaketimeout";
final static String SWITCH_HANDSHAKE_TIMEOUT = "switchhandshaketimeout";
final static String CHANNEL_HANDLER = "channelhandler";
final static String MAIN_IDLE = "mainidle";
final static String AUX_IDLE = "auxidle";
final static String OF_MESSAGE_DECODER = "ofmessagedecoder";
final static String OF_MESSAGE_ENCODER = "ofmessageencoder";
final static String READ_TIMEOUT = "readtimeout";
final static String SSL_TLS_ENCODER_DECODER = "ofsecurechannelencoderdecoder";
}
/**
* Timeouts for parts of the handshake, in seconds
*/
public static class PipelineHandshakeTimeout {
final static int CHANNEL = 10;
final static int SWITCH = 30;
}
/**
* Timeouts for writes on connections, in seconds
*/
public static class PipelineIdleWriteTimeout {
final static int MAIN = 2;
final static int AUX = 15;
}
/**
* Timeouts for reads on connections, in seconds
*/
public static class PipelineIdleReadTimeout {
final static int MAIN = 3 * PipelineIdleWriteTimeout.MAIN;
final static int AUX = 3 * PipelineIdleWriteTimeout.AUX;
}
}
......@@ -31,6 +31,7 @@ public class SwitchManagerCounters {
public final IDebugCounter roleReplyTimeout;
public final IDebugCounter roleReplyReceived;
public final IDebugCounter roleReplyErrorUnsupported;
public final IDebugCounter switchSslConfigurationError;
public SwitchManagerCounters(IDebugCounterService debugCounters) {
debugCounters.registerModule(prefix);
......@@ -199,6 +200,15 @@ public class SwitchManagerCounters {
"error from a switch in response to a role " +
"request indicating that the switch does not " +
"support roles.");
switchSslConfigurationError =
debugCounters.registerCounter(
prefix, "switch-ssl-configuration-error",
"Number of times the controller could not " +
"handshake with a switch due to an " +
"IllegalArgumentException, which is likely " +
"due to the switch trying to speak SSL whereas " +
"the controller wants to use vanilla TCP.");
}
public String getPrefix(){
......
......@@ -59,12 +59,9 @@ public class OFFlowModSerializer extends JsonSerializer<OFFlowMod> {
jGen.writeStringField("version", flowMod.getVersion().toString()); // return the enum names
jGen.writeStringField("command", flowMod.getCommand().toString());
jGen.writeNumberField("cookie", flowMod.getCookie().getValue());
jGen.writeNumberField("cookieMask", flowMod.getCookieMask().getValue());
jGen.writeStringField("tableId", flowMod.getTableId().toString());
jGen.writeNumberField("priority", flowMod.getPriority());
jGen.writeNumberField("idleTimeoutSec", flowMod.getIdleTimeout());
jGen.writeNumberField("hardTimeoutSec", flowMod.getHardTimeout());
jGen.writeStringField("outGroup", flowMod.getOutGroup().toString());
jGen.writeStringField("outPort", flowMod.getOutPort().toString());
switch (flowMod.getVersion()) {
......@@ -72,15 +69,26 @@ public class OFFlowModSerializer extends JsonSerializer<OFFlowMod> {
break;
case OF_11:
jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer11.toWireValue(flowMod.getFlags()));
jGen.writeNumberField("cookieMask", flowMod.getCookieMask().getValue());
jGen.writeStringField("outGroup", flowMod.getOutGroup().toString());
jGen.writeStringField("tableId", flowMod.getTableId().toString());
break;
case OF_12:
jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer12.toWireValue(flowMod.getFlags()));
jGen.writeNumberField("cookieMask", flowMod.getCookieMask().getValue());
jGen.writeStringField("outGroup", flowMod.getOutGroup().toString());
jGen.writeStringField("tableId", flowMod.getTableId().toString());
break;
case OF_13:
jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer13.toWireValue(flowMod.getFlags()));
jGen.writeNumberField("cookieMask", flowMod.getCookieMask().getValue());
jGen.writeStringField("outGroup", flowMod.getOutGroup().toString());
break;
case OF_14:
jGen.writeNumberField("flags", OFFlowModFlagsSerializerVer14.toWireValue(flowMod.getFlags()));
jGen.writeNumberField("cookieMask", flowMod.getCookieMask().getValue());
jGen.writeStringField("outGroup", flowMod.getOutGroup().toString());
jGen.writeStringField("tableId", flowMod.getTableId().toString());
break;
default:
logger.error("Could not decode OFVersion {}", flowMod.getVersion());
......
......@@ -74,7 +74,7 @@ public class OFInstructionListSerializer extends JsonSerializer<List<OFInstructi
} // end switch on instruction
jGen.writeEndObject(); // end specific instruction
} // end for instructions
jGen.writeEndObject();
} // end process instructions (OF1.1+ only)
jGen.writeEndObject(); // end object (either has instructions or a "none":"drop" key:value as specified above)
} // end not-empty instructions (else)
}
......@@ -431,7 +431,8 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
try {
fmb.setMatch(MatchUtils.fromString(match, fmb.getVersion()));
} catch (IllegalArgumentException e) {
log.debug("Ignoring flow entry {} on switch {} with illegal OFMatch() key: " + match, entryName, switchName);
log.error(e.toString());
log.error("Ignoring flow entry {} on switch {} with illegal OFMatch() key: " + match, entryName, switchName);
return;
} catch (Exception e) {
log.error("OF version incompatible for the match: " + match);
......@@ -510,7 +511,8 @@ implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
/* MODIFY_STRICT b/c the match is still the same */
if (oldFlowMod.getMatch().equals(newFlowMod.getMatch())
&& oldFlowMod.getCookie().equals(newFlowMod.getCookie())
&& oldFlowMod.getPriority() == newFlowMod.getPriority()) {
&& oldFlowMod.getPriority() == newFlowMod.getPriority()
&& dpidOldFlowMod.equalsIgnoreCase(dpid)) {
log.debug("ModifyStrict SFP Flow");
entriesFromStorage.get(dpid).put(entry, newFlowMod);
entry2dpid.put(entry, dpid);
......
......@@ -359,7 +359,7 @@ public class ActionUtils {
recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
public static void fromString(OFFlowMod.Builder fmb, String bigString, Logger log) {
List<OFAction> actions = new LinkedList<OFAction>();
if (bigString != null) {
if (bigString != null && !bigString.trim().isEmpty()) {
bigString = bigString.toLowerCase();
String[] bigStringSplit = bigString.split(","); // split into separate action=value or action=key@value pairs
......@@ -410,7 +410,7 @@ public class ActionUtils {
if (actionData.length != 2) {
throw new IllegalArgumentException("[Action, Data] " + keyPair + " does not have form 'action=data'" + actionData);
}
switch (actionData[0]) {
case MatchUtils.STR_ARP_OPCODE:
if (actionData[1].startsWith("0x")) {
......@@ -857,10 +857,11 @@ public class ActionUtils {
actions.add(a);
}
}
}
log.debug("action {}", actions);
fmb.setActions(actions);
log.debug("actions: {}", actions);
fmb.setActions(actions);
} else {
log.debug("actions not found --> drop");
}
return;
}
......
......@@ -24,6 +24,7 @@ import org.projectfloodlight.openflow.types.OFPort;
import org.projectfloodlight.openflow.types.OFVlanVidMatch;
import org.projectfloodlight.openflow.types.OFVlanVidMatchWithMask;
import org.projectfloodlight.openflow.types.TransportPort;
import org.projectfloodlight.openflow.types.U16;
import org.projectfloodlight.openflow.types.U32;
import org.projectfloodlight.openflow.types.U64;
import org.projectfloodlight.openflow.types.U8;
......@@ -387,10 +388,10 @@ public class MatchUtils {
switch (key_value[0]) {
case STR_IN_PORT:
if (dataMask.length == 1) {
mb.setExact(MatchField.IN_PORT, OFPort.of(dataMask[0].contains("0x") ? Integer.valueOf(dataMask[0].replaceFirst("0x", ""), 16) : Integer.valueOf(dataMask[0])));
mb.setExact(MatchField.IN_PORT, OFPort.ofShort(dataMask[0].contains("0x") ? U16.of(Integer.valueOf(dataMask[0].replaceFirst("0x", ""), 16)).getRaw() : U16.of(Integer.valueOf(dataMask[0])).getRaw()));
} else {
mb.setMasked(MatchField.IN_PORT, OFPort.of(dataMask[0].contains("0x") ? Integer.valueOf(dataMask[0].replaceFirst("0x", ""), 16) : Integer.valueOf(dataMask[0])),
OFPort.of(dataMask[1].contains("0x") ? Integer.valueOf(dataMask[1].replaceFirst("0x", ""), 16) : Integer.valueOf(dataMask[1])));
mb.setMasked(MatchField.IN_PORT, OFPort.ofShort(dataMask[0].contains("0x") ? U16.of(Integer.valueOf(dataMask[0].replaceFirst("0x", ""), 16)).getRaw() : U16.of(Integer.valueOf(dataMask[0])).getRaw()),
OFPort.ofShort(dataMask[1].contains("0x") ? U16.of(Integer.valueOf(dataMask[1].replaceFirst("0x", ""), 16)).getRaw() : U16.of(Integer.valueOf(dataMask[1])).getRaw()));
}
break;
case STR_DL_DST: /* Only accept hex-string for MAC addresses */
......
......@@ -14,6 +14,7 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import java.util.concurrent.LinkedTransferQueue;
import net.floodlightcontroller.core.annotations.LogMessageCategory;
import net.floodlightcontroller.core.annotations.LogMessageDoc;
......@@ -31,7 +32,6 @@ import org.jboss.netty.channel.group.ChannelGroup;
import org.jboss.netty.channel.group.DefaultChannelGroup;
import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
import org.jboss.netty.util.internal.LinkedTransferQueue;
import org.sdnplatform.sync.internal.SyncManager;
import org.sdnplatform.sync.internal.config.Node;
import org.sdnplatform.sync.internal.util.Pair;
......
......@@ -21,3 +21,6 @@ org.sdnplatform.sync.internal.SyncManager.dbPath=/var/lib/floodlight/
org.sdnplatform.sync.internal.SyncManager.port=6642
net.floodlightcontroller.core.internal.FloodlightProvider.openflowPort=6653
net.floodlightcontroller.core.internal.FloodlightProvider.role=ACTIVE
net.floodlightcontroller.core.internal.OFSwitchManager.keyStorePath=/path/to/your/keystore-file.jks
net.floodlightcontroller.core.internal.OFSwitchManager.keyStorePassword=your-keystore-password
net.floodlightcontroller.core.internal.OFSwitchManager.useSsl=NO
\ No newline at end of file
......@@ -19,6 +19,6 @@
<logger name="net.floodlightcontroller.forwarding" level="INFO"></logger>
<logger name="net.floodlightcontroller.routing" level="INFO"></logger>
<logger name="net.floodlightcontroller.core.internal" level="INFO"></logger>
<logger level="DEBUG" name="net.floodlightcontroller.firewall"></logger>
<logger level="INFO" name="net.floodlightcontroller.firewall"></logger>
<logger level="INFO" name="net.floodlightcontroller.staticflowentry"></logger>
</configuration>
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