diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java index 10e65678aceaf267ade0411ca69d5de0818f6fd0..b646880b74032d5d6e754e8518629b351f1be2ed 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java @@ -19,6 +19,12 @@ public interface IStaticFlowEntryPusherService extends IFloodlightService { */ public void deleteFlow(String name); + /** + * Deletes all static flows for a practicular switch + * @param dpid The DPID of the switch to delete flows for. + */ + public void deleteFlowsForSwitch(long dpid); + /** * Deletes all flows. */ diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java index 7359ff0a98b03fccc828bd6bc3f8f9b80817c941..b8ebc7552c103882d5ecc4306169bc094e81a545 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java @@ -156,59 +156,61 @@ public class StaticFlowEntries { * @return A string of the actions encoded for our database */ private static String flowModActionsToString(List<OFAction> fmActions) { - // TODO commas?, make a string array then join with commas in between - // TODO - some values may be in hex....i.e. ethertype - String actions = ""; + StringBuilder sb = new StringBuilder(); for (OFAction a : fmActions) { + if (sb.length() > 0) { + sb.append(','); + } switch(a.getType()) { case OUTPUT: - actions += "output=" + Short.toString(((OFActionOutput)a).getPort()); + sb.append("output=" + Short.toString(((OFActionOutput)a).getPort())); break; case OPAQUE_ENQUEUE: - actions += "enqueue=" + Integer.toString(((OFActionEnqueue)a).getQueueId()); + sb.append("enqueue=" + Integer.toString(((OFActionEnqueue)a).getQueueId())); break; case SET_VLAN_ID: - actions += "set-vlan-id=" + - Short.toString(((OFActionVirtualLanIdentifier)a).getVirtualLanIdentifier()); + sb.append("set-vlan-id=" + + Short.toString(((OFActionVirtualLanIdentifier)a).getVirtualLanIdentifier())); break; case SET_VLAN_PCP: - actions += "set-vlan-priority=" + - Byte.toString(((OFActionVirtualLanPriorityCodePoint)a).getVirtualLanPriorityCodePoint()); + sb.append("set-vlan-priority=" + + Byte.toString(((OFActionVirtualLanPriorityCodePoint)a).getVirtualLanPriorityCodePoint())); break; case SET_DL_SRC: - actions += "set-src-mac=" + - HexString.toHexString(((OFActionDataLayerSource)a).getDataLayerAddress()); + sb.append("set-src-mac=" + + HexString.toHexString(((OFActionDataLayerSource)a).getDataLayerAddress())); break; case SET_DL_DST: - actions += "set-dst-mac=" + - HexString.toHexString(((OFActionDataLayerDestination)a).getDataLayerAddress()); + sb.append("set-dst-mac=" + + HexString.toHexString(((OFActionDataLayerDestination)a).getDataLayerAddress())); break; case SET_NW_TOS: - actions += "set-tos-bits=" + - Byte.toString(((OFActionNetworkTypeOfService)a).getNetworkTypeOfService()); + sb.append("set-tos-bits=" + + Byte.toString(((OFActionNetworkTypeOfService)a).getNetworkTypeOfService())); break; case SET_NW_SRC: - actions += "set-nw-src=" + - IPv4.fromIPv4Address(((OFActionNetworkLayerSource)a).getNetworkAddress()); + sb.append("set-nw-src=" + + IPv4.fromIPv4Address(((OFActionNetworkLayerSource)a).getNetworkAddress())); break; case SET_NW_DST: - actions += "set-nw-dst=" + - IPv4.fromIPv4Address(((OFActionNetworkLayerDestination)a).getNetworkAddress()); + sb.append("set-nw-dst=" + + IPv4.fromIPv4Address(((OFActionNetworkLayerDestination)a).getNetworkAddress())); break; case SET_TP_SRC: - actions += "set-src-port=" + - Short.toString(((OFActionTransportLayerSource)a).getTransportPort()); + sb.append("set-src-port=" + + Short.toString(((OFActionTransportLayerSource)a).getTransportPort())); break; case SET_TP_DST: - actions += "set-dst-port=" + - Short.toString(((OFActionTransportLayerDestination)a).getTransportPort()); + sb.append("set-dst-port=" + + Short.toString(((OFActionTransportLayerDestination)a).getTransportPort())); break; default: - + log.error("Could not decode action " + a); + break; } } - return actions; + return sb.toString(); } /** diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java index 6e83f5a491110c694c0da8c7cfcf80ac645e8cab..4746c7e3ffa55e559a1050afc46a30c219b10041 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java @@ -9,6 +9,7 @@ import java.util.Iterator; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import net.floodlightcontroller.core.FloodlightContext; @@ -579,4 +580,14 @@ public class StaticFlowEntryPusher deleteFlow(entry); } } + + @Override + public void deleteFlowsForSwitch(long dpid) { + String sDpid = HexString.toHexString(dpid); + + for (Entry<String, String> e : entry2dpid.entrySet()) { + if (e.getValue().equals(sDpid)) + deleteFlow(e.getKey()); + } + } } diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java index 43474c5a296ea1204f58c422b56b156a3dae47d6..b9b00bca88d356c20de567e6096e9d0f14ff7069 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java @@ -2,6 +2,7 @@ package net.floodlightcontroller.staticflowentry.web; import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService; +import org.openflow.util.HexString; import org.restlet.resource.Get; import org.restlet.resource.ServerResource; import org.slf4j.Logger; @@ -15,7 +16,19 @@ public class ClearStaticFlowEntriesResource extends ServerResource { IStaticFlowEntryPusherService sfpService = (IStaticFlowEntryPusherService)getContext().getAttributes(). get(IStaticFlowEntryPusherService.class.getCanonicalName()); - log.debug("Clearing all static flow entires"); - sfpService.deleteAllFlows(); + + String param = (String) getRequestAttributes().get("switch"); + if (log.isDebugEnabled()) + log.debug("Clearing all static flow entires for switch: " + param); + + if (param.toLowerCase().equals("all")) { + sfpService.deleteAllFlows(); + } else { + try { + sfpService.deleteFlowsForSwitch(HexString.toLong(param)); + } catch (NumberFormatException e){ + log.error("Could not parse switch DPID: " + e.getMessage()); + } + } } } diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java index d8eb0537a7d2710e17ee34a8cd052e296f8ba295..b61516f1c41aadeae63fa7ef7e3fb13d80dc7121 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java @@ -14,7 +14,7 @@ public class StaticFlowEntryWebRoutable implements RestletRoutable { public Restlet getRestlet(Context context) { Router router = new Router(context); router.attach("/json", StaticFlowEntryPusherResource.class); - router.attach("/clear/json", ClearStaticFlowEntriesResource.class); + router.attach("/clear/{switch}/json", ClearStaticFlowEntriesResource.class); return router; } diff --git a/src/main/java/org/openflow/util/HexString.java b/src/main/java/org/openflow/util/HexString.java index 46525e1d95b36fdb7a39852c568ba2abb5dab04c..c61723474d91bbbe8e1f55629e15b4a7fe4962f1 100644 --- a/src/main/java/org/openflow/util/HexString.java +++ b/src/main/java/org/openflow/util/HexString.java @@ -75,7 +75,7 @@ public class HexString { return ret; } - public static long toLong(String values) { + public static long toLong(String values) throws NumberFormatException { return Long.parseLong(values.replaceAll(":", ""),16); }