Removed Floodlight's static flow pusher
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java b/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
deleted file mode 100644
index 66e02dd..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/IStaticFlowEntryPusherService.java
+++ /dev/null
@@ -1,44 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-import java.util.Map;
-
-import org.openflow.protocol.OFFlowMod;
-
-import net.floodlightcontroller.core.module.IFloodlightService;
-
-public interface IStaticFlowEntryPusherService extends IFloodlightService {
- /**
- * Adds a static flow.
- * @param name Name of the flow mod. Must be unique.
- * @param fm The flow to push.
- * @param swDpid The switch DPID to push it to, in 00:00:00:00:00:00:00:01 notation.
- */
- public void addFlow(String name, OFFlowMod fm, String swDpid);
-
- /**
- * Deletes a static flow
- * @param name The name of the static flow to delete.
- */
- 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.
- */
- public void deleteAllFlows();
-
- /**
- * Gets all list of all flows
- */
- public Map<String, Map<String, OFFlowMod>> getFlows();
-
- /**
- * Gets a list of flows by switch
- */
- public Map<String, OFFlowMod> getFlows(String dpid);
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
deleted file mode 100644
index e733843..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntries.java
+++ /dev/null
@@ -1,831 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.regex.Matcher;
-import java.util.regex.Pattern;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.packet.IPv4;
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-
-import org.codehaus.jackson.JsonParseException;
-import org.codehaus.jackson.JsonParser;
-import org.codehaus.jackson.JsonToken;
-import org.codehaus.jackson.map.MappingJsonFactory;
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFPacketOut;
-import org.openflow.protocol.OFPort;
-import org.openflow.protocol.action.OFAction;
-import org.openflow.protocol.action.OFActionDataLayerDestination;
-import org.openflow.protocol.action.OFActionDataLayerSource;
-import org.openflow.protocol.action.OFActionEnqueue;
-import org.openflow.protocol.action.OFActionNetworkLayerDestination;
-import org.openflow.protocol.action.OFActionNetworkLayerSource;
-import org.openflow.protocol.action.OFActionNetworkTypeOfService;
-import org.openflow.protocol.action.OFActionOutput;
-import org.openflow.protocol.action.OFActionStripVirtualLan;
-import org.openflow.protocol.action.OFActionTransportLayerDestination;
-import org.openflow.protocol.action.OFActionTransportLayerSource;
-import org.openflow.protocol.action.OFActionVirtualLanIdentifier;
-import org.openflow.protocol.action.OFActionVirtualLanPriorityCodePoint;
-import org.openflow.util.HexString;
-
-/**
- * Represents static flow entries to be maintained by the controller on the
- * switches.
- */
-@LogMessageCategory("Static Flow Pusher")
-public class StaticFlowEntries {
- protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntries.class);
-
- private static class SubActionStruct {
- OFAction action;
- int len;
- }
-
- private static byte[] zeroMac = new byte[] {0x0, 0x0, 0x0, 0x0, 0x0, 0x0};
-
- /**
- * This function generates a random hash for the bottom half of the cookie
- *
- * @param fm
- * @param userCookie
- * @param name
- * @return A cookie that encodes the application ID and a hash
- */
- public static long computeEntryCookie(OFFlowMod fm, int userCookie, String name) {
- // flow-specific hash is next 20 bits LOOK! who knows if this
- int prime = 211;
- int flowHash = 2311;
- for (int i=0; i < name.length(); i++)
- flowHash = flowHash * prime + (int)name.charAt(i);
-
- return AppCookie.makeCookie(StaticFlowEntryPusher.STATIC_FLOW_APP_ID, flowHash);
- }
-
- /**
- * Sets defaults for an OFFlowMod
- * @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.setIdleTimeout((short) 0); // infinite
- fm.setHardTimeout((short) 0); // infinite
- fm.setBufferId(OFPacketOut.BUFFER_ID_NONE);
- fm.setCommand((short) 0);
- fm.setFlags((short) 0);
- fm.setOutPort(OFPort.OFPP_NONE.getValue());
- fm.setCookie(computeEntryCookie(fm, 0, entryName));
- fm.setPriority(Short.MAX_VALUE);
- }
-
- /**
- * Gets the entry name of a flow mod
- * @param fmJson The OFFlowMod in a JSON representation
- * @return The name of the OFFlowMod, null if not found
- * @throws IOException If there was an error parsing the JSON
- */
- public static String getEntryNameFromJson(String fmJson) throws IOException{
- MappingJsonFactory f = new MappingJsonFactory();
- JsonParser jp;
-
- try {
- jp = f.createJsonParser(fmJson);
- } catch (JsonParseException e) {
- throw new IOException(e);
- }
-
- jp.nextToken();
- if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected START_OBJECT");
- }
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
- throw new IOException("Expected FIELD_NAME");
- }
-
- String n = jp.getCurrentName();
- jp.nextToken();
- if (jp.getText().equals(""))
- continue;
-
- if (n == "name")
- return jp.getText();
- }
-
- return null;
- }
-
- /**
- * Parses an OFFlowMod (and it's inner OFMatch) to the storage entry format.
- * @param fm The FlowMod to parse
- * @param sw The switch the FlowMod is going to be installed on
- * @param name The name of this static flow entry
- * @return A Map representation of the storage entry
- */
- public static Map<String, Object> flowModToStorageEntry(OFFlowMod fm, String sw, String name) {
- Map<String, Object> entry = new HashMap<String, Object>();
- OFMatch match = fm.getMatch();
- entry.put(StaticFlowEntryPusher.COLUMN_NAME, name);
- entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, sw);
- entry.put(StaticFlowEntryPusher.COLUMN_ACTIVE, Boolean.toString(true));
- entry.put(StaticFlowEntryPusher.COLUMN_PRIORITY, Short.toString(fm.getPriority()));
- entry.put(StaticFlowEntryPusher.COLUMN_WILDCARD, Integer.toString(match.getWildcards()));
-
- if ((fm.getActions() != null) && (fm.getActions().size() > 0))
- entry.put(StaticFlowEntryPusher.COLUMN_ACTIONS, StaticFlowEntries.flowModActionsToString(fm.getActions()));
-
- if (match.getInputPort() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, Short.toString(match.getInputPort()));
-
- if (!Arrays.equals(match.getDataLayerSource(), zeroMac))
- entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, HexString.toHexString(match.getDataLayerSource()));
-
- if (!Arrays.equals(match.getDataLayerDestination(), zeroMac))
- entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, HexString.toHexString(match.getDataLayerDestination()));
-
- if (match.getDataLayerVirtualLan() != -1)
- entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, Short.toString(match.getDataLayerVirtualLan()));
-
- if (match.getDataLayerVirtualLanPriorityCodePoint() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, Short.toString(match.getDataLayerVirtualLanPriorityCodePoint()));
-
- if (match.getDataLayerType() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, Short.toString(match.getDataLayerType()));
-
- if (match.getNetworkTypeOfService() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, Short.toString(match.getNetworkTypeOfService()));
-
- if (match.getNetworkProtocol() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, Short.toString(match.getNetworkProtocol()));
-
- if (match.getNetworkSource() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, IPv4.fromIPv4Address(match.getNetworkSource()));
-
- if (match.getNetworkDestination() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, IPv4.fromIPv4Address(match.getNetworkDestination()));
-
- if (match.getTransportSource() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_TP_SRC, Short.toString(match.getTransportSource()));
-
- if (match.getTransportDestination() != 0)
- entry.put(StaticFlowEntryPusher.COLUMN_TP_DST, Short.toString(match.getTransportDestination()));
-
- return entry;
- }
-
- /**
- * Returns a String representation of all the openflow actions.
- * @param fmActions A list of OFActions to encode into one string
- * @return A string of the actions encoded for our database
- */
- @LogMessageDoc(level="ERROR",
- message="Could not decode action {action}",
- explanation="A static flow entry contained an invalid action",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- private static String flowModActionsToString(List<OFAction> fmActions) {
- StringBuilder sb = new StringBuilder();
- for (OFAction a : fmActions) {
- if (sb.length() > 0) {
- sb.append(',');
- }
- switch(a.getType()) {
- case OUTPUT:
- sb.append("output=" + Short.toString(((OFActionOutput)a).getPort()));
- break;
- case OPAQUE_ENQUEUE:
- int queue = ((OFActionEnqueue)a).getQueueId();
- short port = ((OFActionEnqueue)a).getPort();
- sb.append("enqueue=" + Short.toString(port) + ":0x" + String.format("%02x", queue));
- break;
- case STRIP_VLAN:
- sb.append("strip-vlan");
- break;
- case SET_VLAN_ID:
- sb.append("set-vlan-id=" +
- Short.toString(((OFActionVirtualLanIdentifier)a).getVirtualLanIdentifier()));
- break;
- case SET_VLAN_PCP:
- sb.append("set-vlan-priority=" +
- Byte.toString(((OFActionVirtualLanPriorityCodePoint)a).getVirtualLanPriorityCodePoint()));
- break;
- case SET_DL_SRC:
- sb.append("set-src-mac=" +
- HexString.toHexString(((OFActionDataLayerSource)a).getDataLayerAddress()));
- break;
- case SET_DL_DST:
- sb.append("set-dst-mac=" +
- HexString.toHexString(((OFActionDataLayerDestination)a).getDataLayerAddress()));
- break;
- case SET_NW_TOS:
- sb.append("set-tos-bits=" +
- Byte.toString(((OFActionNetworkTypeOfService)a).getNetworkTypeOfService()));
- break;
- case SET_NW_SRC:
- sb.append("set-src-ip=" +
- IPv4.fromIPv4Address(((OFActionNetworkLayerSource)a).getNetworkAddress()));
- break;
- case SET_NW_DST:
- sb.append("set-dst-ip=" +
- IPv4.fromIPv4Address(((OFActionNetworkLayerDestination)a).getNetworkAddress()));
- break;
- case SET_TP_SRC:
- sb.append("set-src-port=" +
- Short.toString(((OFActionTransportLayerSource)a).getTransportPort()));
- break;
- case SET_TP_DST:
- sb.append("set-dst-port=" +
- Short.toString(((OFActionTransportLayerDestination)a).getTransportPort()));
- break;
- default:
- log.error("Could not decode action: {}", a);
- break;
- }
-
- }
- return sb.toString();
- }
-
- /**
- * Turns a JSON formatted Static Flow Pusher string into a storage entry
- * Expects a string in JSON along the lines of:
- * {
- * "switch": "AA:BB:CC:DD:EE:FF:00:11",
- * "name": "flow-mod-1",
- * "cookie": "0",
- * "priority": "32768",
- * "ingress-port": "1",
- * "actions": "output=2",
- * }
- * @param fmJson The JSON formatted static flow pusher entry
- * @return The map of the storage entry
- * @throws IOException If there was an error parsing the JSON
- */
- public static Map<String, Object> jsonToStorageEntry(String fmJson) throws IOException {
- Map<String, Object> entry = new HashMap<String, Object>();
- MappingJsonFactory f = new MappingJsonFactory();
- JsonParser jp;
-
- try {
- jp = f.createJsonParser(fmJson);
- } catch (JsonParseException e) {
- throw new IOException(e);
- }
-
- jp.nextToken();
- if (jp.getCurrentToken() != JsonToken.START_OBJECT) {
- throw new IOException("Expected START_OBJECT");
- }
-
- while (jp.nextToken() != JsonToken.END_OBJECT) {
- if (jp.getCurrentToken() != JsonToken.FIELD_NAME) {
- throw new IOException("Expected FIELD_NAME");
- }
-
- String n = jp.getCurrentName();
- jp.nextToken();
- if (jp.getText().equals(""))
- continue;
-
- if (n == "name")
- entry.put(StaticFlowEntryPusher.COLUMN_NAME, jp.getText());
- else if (n == "switch")
- entry.put(StaticFlowEntryPusher.COLUMN_SWITCH, jp.getText());
- else if (n == "actions")
- entry.put(StaticFlowEntryPusher.COLUMN_ACTIONS, jp.getText());
- else if (n == "priority")
- entry.put(StaticFlowEntryPusher.COLUMN_PRIORITY, jp.getText());
- else if (n == "active")
- entry.put(StaticFlowEntryPusher.COLUMN_ACTIVE, jp.getText());
- else if (n == "wildcards")
- entry.put(StaticFlowEntryPusher.COLUMN_WILDCARD, jp.getText());
- else if (n == "ingress-port")
- entry.put(StaticFlowEntryPusher.COLUMN_IN_PORT, jp.getText());
- else if (n == "src-mac")
- entry.put(StaticFlowEntryPusher.COLUMN_DL_SRC, jp.getText());
- else if (n == "dst-mac")
- entry.put(StaticFlowEntryPusher.COLUMN_DL_DST, jp.getText());
- else if (n == "vlan-id")
- entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN, jp.getText());
- else if (n == "vlan-priority")
- entry.put(StaticFlowEntryPusher.COLUMN_DL_VLAN_PCP, jp.getText());
- else if (n == "ether-type")
- entry.put(StaticFlowEntryPusher.COLUMN_DL_TYPE, jp.getText());
- else if (n == "tos-bits")
- entry.put(StaticFlowEntryPusher.COLUMN_NW_TOS, jp.getText());
- else if (n == "protocol")
- entry.put(StaticFlowEntryPusher.COLUMN_NW_PROTO, jp.getText());
- else if (n == "src-ip")
- entry.put(StaticFlowEntryPusher.COLUMN_NW_SRC, jp.getText());
- else if (n == "dst-ip")
- entry.put(StaticFlowEntryPusher.COLUMN_NW_DST, jp.getText());
- else if (n == "src-port")
- entry.put(StaticFlowEntryPusher.COLUMN_TP_SRC, jp.getText());
- else if (n == "dst-port")
- entry.put(StaticFlowEntryPusher.COLUMN_TP_DST, jp.getText());
- }
-
- return entry;
- }
-
- /**
- * Parses OFFlowMod actions from strings.
- * @param flowMod The OFFlowMod to set the actions for
- * @param actionstr The string containing all the actions
- * @param log A logger to log for errors.
- */
- @LogMessageDoc(level="ERROR",
- 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) {
- List<OFAction> actions = new LinkedList<OFAction>();
- int actionsLength = 0;
- if (actionstr != null) {
- actionstr = actionstr.toLowerCase();
- for (String subaction : actionstr.split(",")) {
- String action = subaction.split("[=:]")[0];
- SubActionStruct subaction_struct = null;
-
- if (action.equals("output")) {
- subaction_struct = StaticFlowEntries.decode_output(subaction, log);
- }
- else if (action.equals("enqueue")) {
- subaction_struct = decode_enqueue(subaction, log);
- }
- else if (action.equals("strip-vlan")) {
- subaction_struct = decode_strip_vlan(subaction, log);
- }
- else if (action.equals("set-vlan-id")) {
- subaction_struct = decode_set_vlan_id(subaction, log);
- }
- else if (action.equals("set-vlan-priority")) {
- subaction_struct = decode_set_vlan_priority(subaction, log);
- }
- else if (action.equals("set-src-mac")) {
- subaction_struct = decode_set_src_mac(subaction, log);
- }
- else if (action.equals("set-dst-mac")) {
- subaction_struct = decode_set_dst_mac(subaction, log);
- }
- else if (action.equals("set-tos-bits")) {
- subaction_struct = decode_set_tos_bits(subaction, log);
- }
- else if (action.equals("set-src-ip")) {
- subaction_struct = decode_set_src_ip(subaction, log);
- }
- else if (action.equals("set-dst-ip")) {
- subaction_struct = decode_set_dst_ip(subaction, log);
- }
- else if (action.equals("set-src-port")) {
- subaction_struct = decode_set_src_port(subaction, log);
- }
- else if (action.equals("set-dst-port")) {
- subaction_struct = decode_set_dst_port(subaction, log);
- }
- else {
- log.error("Unexpected action '{}', '{}'", action, subaction);
- }
-
- if (subaction_struct != null) {
- actions.add(subaction_struct.action);
- actionsLength += subaction_struct.len;
- }
- }
- }
- log.debug("action {}", actions);
-
- flowMod.setActions(actions);
- flowMod.setLengthU(OFFlowMod.MINIMUM_LENGTH + actionsLength);
- }
-
- @LogMessageDoc(level="ERROR",
- message="Invalid subaction: '{subaction}'",
- explanation="A static flow entry contained an invalid subaction",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- private static SubActionStruct decode_output(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n;
-
- n = Pattern.compile("output=(?:((?:0x)?\\d+)|(all)|(controller)|(local)|(ingress-port)|(normal)|(flood))").matcher(subaction);
- if (n.matches()) {
- OFActionOutput action = new OFActionOutput();
- action.setMaxLength((short) Short.MAX_VALUE);
- short port = OFPort.OFPP_NONE.getValue();
- if (n.group(1) != null) {
- try {
- port = get_short(n.group(1));
- }
- catch (NumberFormatException e) {
- log.debug("Invalid port in: '{}' (error ignored)", subaction);
- return null;
- }
- }
- else if (n.group(2) != null)
- port = OFPort.OFPP_ALL.getValue();
- else if (n.group(3) != null)
- port = OFPort.OFPP_CONTROLLER.getValue();
- else if (n.group(4) != null)
- port = OFPort.OFPP_LOCAL.getValue();
- else if (n.group(5) != null)
- port = OFPort.OFPP_IN_PORT.getValue();
- else if (n.group(6) != null)
- port = OFPort.OFPP_NORMAL.getValue();
- else if (n.group(7) != null)
- port = OFPort.OFPP_FLOOD.getValue();
- action.setPort(port);
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionOutput.MINIMUM_LENGTH;
- }
- else {
- log.error("Invalid subaction: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_enqueue(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n;
-
- n = Pattern.compile("enqueue=(?:((?:0x)?\\d+)\\:((?:0x)?\\d+))").matcher(subaction);
- if (n.matches()) {
- short portnum = 0;
- if (n.group(1) != null) {
- try {
- portnum = get_short(n.group(1));
- }
- catch (NumberFormatException e) {
- log.debug("Invalid port-num in: '{}' (error ignored)", subaction);
- return null;
- }
- }
-
- int queueid = 0;
- if (n.group(2) != null) {
- try {
- queueid = get_int(n.group(2));
- }
- catch (NumberFormatException e) {
- log.debug("Invalid queue-id in: '{}' (error ignored)", subaction);
- return null;
- }
- }
-
- OFActionEnqueue action = new OFActionEnqueue();
- action.setPort(portnum);
- action.setQueueId(queueid);
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionEnqueue.MINIMUM_LENGTH;
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_strip_vlan(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("strip-vlan").matcher(subaction);
-
- if (n.matches()) {
- OFActionStripVirtualLan action = new OFActionStripVirtualLan();
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionStripVirtualLan.MINIMUM_LENGTH;
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_vlan_id(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-vlan-id=((?:0x)?\\d+)").matcher(subaction);
-
- if (n.matches()) {
- if (n.group(1) != null) {
- try {
- short vlanid = get_short(n.group(1));
- OFActionVirtualLanIdentifier action = new OFActionVirtualLanIdentifier();
- action.setVirtualLanIdentifier(vlanid);
- log.debug(" action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionVirtualLanIdentifier.MINIMUM_LENGTH;
- }
- catch (NumberFormatException e) {
- log.debug("Invalid VLAN in: {} (error ignored)", subaction);
- return null;
- }
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_vlan_priority(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-vlan-priority=((?:0x)?\\d+)").matcher(subaction);
-
- if (n.matches()) {
- if (n.group(1) != null) {
- try {
- byte prior = get_byte(n.group(1));
- OFActionVirtualLanPriorityCodePoint action = new OFActionVirtualLanPriorityCodePoint();
- action.setVirtualLanPriorityCodePoint(prior);
- log.debug(" action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionVirtualLanPriorityCodePoint.MINIMUM_LENGTH;
- }
- catch (NumberFormatException e) {
- log.debug("Invalid VLAN priority in: {} (error ignored)", subaction);
- return null;
- }
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_src_mac(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-src-mac=(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(subaction);
-
- if (n.matches()) {
- byte[] macaddr = get_mac_addr(n, subaction, log);
- if (macaddr != null) {
- OFActionDataLayerSource action = new OFActionDataLayerSource();
- action.setDataLayerAddress(macaddr);
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionDataLayerSource.MINIMUM_LENGTH;
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_dst_mac(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-dst-mac=(?:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+)\\:(\\p{XDigit}+))").matcher(subaction);
-
- if (n.matches()) {
- byte[] macaddr = get_mac_addr(n, subaction, log);
- if (macaddr != null) {
- OFActionDataLayerDestination action = new OFActionDataLayerDestination();
- action.setDataLayerAddress(macaddr);
- log.debug(" action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionDataLayerDestination.MINIMUM_LENGTH;
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_tos_bits(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-tos-bits=((?:0x)?\\d+)").matcher(subaction);
-
- if (n.matches()) {
- if (n.group(1) != null) {
- try {
- byte tosbits = get_byte(n.group(1));
- OFActionNetworkTypeOfService action = new OFActionNetworkTypeOfService();
- action.setNetworkTypeOfService(tosbits);
- log.debug(" action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionNetworkTypeOfService.MINIMUM_LENGTH;
- }
- catch (NumberFormatException e) {
- log.debug("Invalid dst-port in: {} (error ignored)", subaction);
- return null;
- }
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_src_ip(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-src-ip=(?:(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))").matcher(subaction);
-
- if (n.matches()) {
- int ipaddr = get_ip_addr(n, subaction, log);
- OFActionNetworkLayerSource action = new OFActionNetworkLayerSource();
- action.setNetworkAddress(ipaddr);
- log.debug(" action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionNetworkLayerSource.MINIMUM_LENGTH;
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_dst_ip(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-dst-ip=(?:(\\d+)\\.(\\d+)\\.(\\d+)\\.(\\d+))").matcher(subaction);
-
- if (n.matches()) {
- int ipaddr = get_ip_addr(n, subaction, log);
- OFActionNetworkLayerDestination action = new OFActionNetworkLayerDestination();
- action.setNetworkAddress(ipaddr);
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionNetworkLayerDestination.MINIMUM_LENGTH;
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_src_port(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-src-port=((?:0x)?\\d+)").matcher(subaction);
-
- if (n.matches()) {
- if (n.group(1) != null) {
- try {
- short portnum = get_short(n.group(1));
- OFActionTransportLayerSource action = new OFActionTransportLayerSource();
- action.setTransportPort(portnum);
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionTransportLayerSource.MINIMUM_LENGTH;;
- }
- catch (NumberFormatException e) {
- log.debug("Invalid src-port in: {} (error ignored)", subaction);
- return null;
- }
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static SubActionStruct decode_set_dst_port(String subaction, Logger log) {
- SubActionStruct sa = null;
- Matcher n = Pattern.compile("set-dst-port=((?:0x)?\\d+)").matcher(subaction);
-
- if (n.matches()) {
- if (n.group(1) != null) {
- try {
- short portnum = get_short(n.group(1));
- OFActionTransportLayerDestination action = new OFActionTransportLayerDestination();
- action.setTransportPort(portnum);
- log.debug("action {}", action);
-
- sa = new SubActionStruct();
- sa.action = action;
- sa.len = OFActionTransportLayerDestination.MINIMUM_LENGTH;;
- }
- catch (NumberFormatException e) {
- log.debug("Invalid dst-port in: {} (error ignored)", subaction);
- return null;
- }
- }
- }
- else {
- log.debug("Invalid action: '{}'", subaction);
- return null;
- }
-
- return sa;
- }
-
- private static byte[] get_mac_addr(Matcher n, String subaction, Logger log) {
- byte[] macaddr = new byte[6];
-
- for (int i=0; i<6; i++) {
- if (n.group(i+1) != null) {
- try {
- macaddr[i] = get_byte("0x" + n.group(i+1));
- }
- catch (NumberFormatException e) {
- log.debug("Invalid src-mac in: '{}' (error ignored)", subaction);
- return null;
- }
- }
- else {
- log.debug("Invalid src-mac in: '{}' (null, error ignored)", subaction);
- return null;
- }
- }
-
- return macaddr;
- }
-
- private static int get_ip_addr(Matcher n, String subaction, Logger log) {
- int ipaddr = 0;
-
- for (int i=0; i<4; i++) {
- if (n.group(i+1) != null) {
- try {
- ipaddr = ipaddr<<8;
- ipaddr = ipaddr | get_int(n.group(i+1));
- }
- catch (NumberFormatException e) {
- log.debug("Invalid src-ip in: '{}' (error ignored)", subaction);
- return 0;
- }
- }
- else {
- log.debug("Invalid src-ip in: '{}' (null, error ignored)", subaction);
- return 0;
- }
- }
-
- return ipaddr;
- }
-
- // Parse int as decimal, hex (start with 0x or #) or octal (starts with 0)
- private static int get_int(String str) {
- return (int)Integer.decode(str);
- }
-
- // Parse short as decimal, hex (start with 0x or #) or octal (starts with 0)
- private static short get_short(String str) {
- return (short)(int)Integer.decode(str);
- }
-
- // Parse byte as decimal, hex (start with 0x or #) or octal (starts with 0)
- private static byte get_byte(String str) {
- return Integer.decode(str).byteValue();
- }
-
-}
-
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java b/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
deleted file mode 100644
index 89664a4..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/StaticFlowEntryPusher.java
+++ /dev/null
@@ -1,676 +0,0 @@
-package net.floodlightcontroller.staticflowentry;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.Comparator;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import net.floodlightcontroller.core.FloodlightContext;
-import net.floodlightcontroller.core.IFloodlightProviderService;
-import net.floodlightcontroller.core.IFloodlightProviderService.Role;
-import net.floodlightcontroller.core.IHAListener;
-import net.floodlightcontroller.core.IOFMessageListener;
-import net.floodlightcontroller.core.IOFSwitch;
-import net.floodlightcontroller.core.IOFSwitchListener;
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.core.annotations.LogMessageDoc;
-import net.floodlightcontroller.core.module.FloodlightModuleContext;
-import net.floodlightcontroller.core.module.FloodlightModuleException;
-import net.floodlightcontroller.core.module.IFloodlightModule;
-import net.floodlightcontroller.core.module.IFloodlightService;
-import net.floodlightcontroller.core.util.AppCookie;
-import net.floodlightcontroller.restserver.IRestApiService;
-import net.floodlightcontroller.staticflowentry.web.StaticFlowEntryWebRoutable;
-
-import org.openflow.protocol.OFFlowMod;
-import org.openflow.protocol.OFFlowRemoved;
-import org.openflow.protocol.OFMatch;
-import org.openflow.protocol.OFMessage;
-import org.openflow.protocol.OFType;
-import org.openflow.protocol.factory.BasicFactory;
-import org.openflow.util.HexString;
-import org.openflow.util.U16;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-@LogMessageCategory("Static Flow Pusher")
-/**
- * This module is responsible for maintaining a set of static flows on
- * switches. This is just a big 'ol dumb list of flows and something external
- * is responsible for ensuring they make sense for the network.
- */
-public class StaticFlowEntryPusher
- implements IOFSwitchListener, IFloodlightModule, IStaticFlowEntryPusherService,
- /*IStorageSourceListener,*/ IOFMessageListener, IHAListener {
- protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusher.class);
- public static final String StaticFlowName = "staticflowentry";
-
- public static final int STATIC_FLOW_APP_ID = 10;
-
- public static final String TABLE_NAME = "controller_staticflowtableentry";
- public static final String COLUMN_NAME = "name";
- public static final String COLUMN_SWITCH = "switch_id";
- public static final String COLUMN_ACTIVE = "active";
- public static final String COLUMN_IDLE_TIMEOUT = "idle_timeout";
- public static final String COLUMN_HARD_TIMEOUT = "hard_timeout";
- public static final String COLUMN_PRIORITY = "priority";
- public static final String COLUMN_COOKIE = "cookie";
- public static final String COLUMN_WILDCARD = "wildcards";
- public static final String COLUMN_IN_PORT = "in_port";
- public static final String COLUMN_DL_SRC = "dl_src";
- public static final String COLUMN_DL_DST = "dl_dst";
- public static final String COLUMN_DL_VLAN = "dl_vlan";
- public static final String COLUMN_DL_VLAN_PCP = "dl_vlan_pcp";
- public static final String COLUMN_DL_TYPE = "dl_type";
- public static final String COLUMN_NW_TOS = "nw_tos";
- public static final String COLUMN_NW_PROTO = "nw_proto";
- public static final String COLUMN_NW_SRC = "nw_src"; // includes CIDR-style
- // netmask, e.g.
- // "128.8.128.0/24"
- public static final String COLUMN_NW_DST = "nw_dst";
- public static final String COLUMN_TP_DST = "tp_dst";
- public static final String COLUMN_TP_SRC = "tp_src";
- public static final String COLUMN_ACTIONS = "actions";
- public static String ColumnNames[] = { COLUMN_NAME, COLUMN_SWITCH,
- COLUMN_ACTIVE, COLUMN_IDLE_TIMEOUT, COLUMN_HARD_TIMEOUT,
- COLUMN_PRIORITY, COLUMN_COOKIE, COLUMN_WILDCARD, COLUMN_IN_PORT,
- COLUMN_DL_SRC, COLUMN_DL_DST, COLUMN_DL_VLAN, COLUMN_DL_VLAN_PCP,
- COLUMN_DL_TYPE, COLUMN_NW_TOS, COLUMN_NW_PROTO, COLUMN_NW_SRC,
- COLUMN_NW_DST, COLUMN_TP_DST, COLUMN_TP_SRC, COLUMN_ACTIONS };
-
-
- protected IFloodlightProviderService floodlightProvider;
- //protected IStorageSourceService storageSource;
- protected IRestApiService restApi;
-
- // Map<DPID, Map<Name, FlowMod>> ; FlowMod can be null to indicate non-active
- protected Map<String, Map<String, OFFlowMod>> entriesFromStorage;
- // Entry Name -> DPID of Switch it's on
- protected Map<String, String> entry2dpid;
-
- private BasicFactory ofMessageFactory;
-
- // Class to sort FlowMod's by priority, from lowest to highest
- class FlowModSorter implements Comparator<String> {
- private String dpid;
- public FlowModSorter(String dpid) {
- this.dpid = dpid;
- }
- @Override
- public int compare(String o1, String o2) {
- OFFlowMod f1 = entriesFromStorage.get(dpid).get(o1);
- OFFlowMod f2 = entriesFromStorage.get(dpid).get(o2);
- if (f1 == null || f2 == null) // sort active=false flows by key
- return o1.compareTo(o2);
- return U16.f(f1.getPriority()) - U16.f(f2.getPriority());
- }
- };
-
- /**
- * used for debugging and unittests
- * @return the number of static flow entries as cached from storage
- */
- public int countEntries() {
- int size = 0;
- if (entriesFromStorage == null)
- return 0;
- for (String ofswitch : entriesFromStorage.keySet())
- size += entriesFromStorage.get(ofswitch).size();
- return size;
- }
-
- public IFloodlightProviderService getFloodlightProvider() {
- return floodlightProvider;
- }
-
- public void setFloodlightProvider(IFloodlightProviderService floodlightProvider) {
- this.floodlightProvider = floodlightProvider;
- }
-
- /*
- public void setStorageSource(IStorageSourceService storageSource) {
- this.storageSource = storageSource;
- }
- */
-
- /**
- * Reads from our entriesFromStorage for the specified switch and
- * sends the FlowMods down to the controller in <b>sorted</b> order.
- *
- * Sorted is important to maintain correctness of the switch:
- * if a packet would match both a lower and a higher priority
- * rule, then we want it to match the higher priority or nothing,
- * but never just the lower priority one. Inserting from high to
- * low priority fixes this.
- *
- * TODO consider adding a "block all" flow mod and then removing it
- * while starting up.
- *
- * @param sw The switch to send entries to
- */
- protected void sendEntriesToSwitch(IOFSwitch sw) {
- String dpid = sw.getStringId();
-
- if ((entriesFromStorage != null) && (entriesFromStorage.containsKey(dpid))) {
- Map<String, OFFlowMod> entries = entriesFromStorage.get(dpid);
- List<String> sortedList = new ArrayList<String>(entries.keySet());
- // weird that Collections.sort() returns void
- Collections.sort( sortedList, new FlowModSorter(dpid));
- for (String entryName : sortedList) {
- OFFlowMod flowMod = entries.get(entryName);
- if (flowMod != null) {
- if (log.isDebugEnabled()) {
- log.debug("Pushing static entry {} for {}", dpid, entryName);
- }
- writeFlowModToSwitch(sw, flowMod);
- }
- }
- }
- }
-
- /**
- * Used only for bundle-local indexing
- *
- * @param map
- * @return
- */
-
- protected Map<String, String> computeEntry2DpidMap(
- Map<String, Map<String, OFFlowMod>> map) {
- Map<String, String> ret = new HashMap<String, String>();
- for(String dpid : map.keySet()) {
- for( String entry: map.get(dpid).keySet())
- ret.put(entry, dpid);
- }
- return ret;
- }
-
- /**
- * Read entries from storageSource, and store them in a hash
- *
- * @return
- */
- /*
- @LogMessageDoc(level="ERROR",
- message="failed to access storage: {reason}",
- explanation="Could not retrieve static flows from the system " +
- "database",
- recommendation=LogMessageDoc.CHECK_CONTROLLER)
- private Map<String, Map<String, OFFlowMod>> readEntriesFromStorage() {
- Map<String, Map<String, OFFlowMod>> entries = new ConcurrentHashMap<String, Map<String, OFFlowMod>>();
- try {
- Map<String, Object> row;
- // null1=no predicate, null2=no ordering
- IResultSet resultSet = storageSource.executeQuery(TABLE_NAME,
- ColumnNames, null, null);
- for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
- row = it.next().getRow();
- parseRow(row, entries);
- }
- } catch (StorageException e) {
- log.error("failed to access storage: {}", e.getMessage());
- // if the table doesn't exist, then wait to populate later via
- // setStorageSource()
- }
- return entries;
- }
- */
-
- /**
- * Take a single row, turn it into a flowMod, and add it to the
- * entries{$dpid}.{$entryName}=FlowMod
- *
- * IF an entry is in active, mark it with FlowMod = null
- *
- * @param row
- * @param entries
- */
-
- void parseRow(Map<String, Object> row,
- Map<String, Map<String, OFFlowMod>> entries) {
- String switchName = null;
- String entryName = null;
-
- StringBuffer matchString = new StringBuffer();
- if (ofMessageFactory == null) // lazy init
- ofMessageFactory = new BasicFactory();
-
- OFFlowMod flowMod = (OFFlowMod) ofMessageFactory
- .getMessage(OFType.FLOW_MOD);
-
- if (!row.containsKey(COLUMN_SWITCH) || !row.containsKey(COLUMN_NAME)) {
- log.debug(
- "skipping entry with missing required 'switch' or 'name' entry: {}",
- row);
- return;
- }
- // most error checking done with ClassCastException
- try {
- // first, snag the required entries, for debugging info
- switchName = (String) row.get(COLUMN_SWITCH);
- entryName = (String) row.get(COLUMN_NAME);
- if (!entries.containsKey(switchName))
- entries.put(switchName, new HashMap<String, OFFlowMod>());
- StaticFlowEntries.initDefaultFlowMod(flowMod, entryName);
-
- for (String key : row.keySet()) {
- if (row.get(key) == null)
- continue;
- if ( key.equals(COLUMN_SWITCH) || key.equals(COLUMN_NAME)
- || key.equals("id"))
- continue; // already handled
- // explicitly ignore timeouts and wildcards
- if ( key.equals(COLUMN_HARD_TIMEOUT) || key.equals(COLUMN_IDLE_TIMEOUT) ||
- key.equals(COLUMN_WILDCARD))
- continue;
- if ( key.equals(COLUMN_ACTIVE)) {
- if (! Boolean.valueOf((String) row.get(COLUMN_ACTIVE))) {
- log.debug("skipping inactive entry {} for switch {}",
- entryName, switchName);
- entries.get(switchName).put(entryName, null); // mark this an inactive
- return;
- }
- } else if ( key.equals(COLUMN_ACTIONS)){
- StaticFlowEntries.parseActionString(flowMod, (String) row.get(COLUMN_ACTIONS), log);
- } else if ( key.equals(COLUMN_COOKIE)) {
- flowMod.setCookie(
- StaticFlowEntries.computeEntryCookie(flowMod,
- Integer.valueOf((String) row.get(COLUMN_COOKIE)),
- entryName)
- );
- } else if ( key.equals(COLUMN_PRIORITY)) {
- flowMod.setPriority(U16.t(Integer.valueOf((String) row.get(COLUMN_PRIORITY))));
- } else { // the rest of the keys are for OFMatch().fromString()
- if (matchString.length() > 0)
- matchString.append(",");
- matchString.append(key + "=" + row.get(key).toString());
- }
- }
- } catch (ClassCastException e) {
- if (entryName != null && switchName != null)
- log.debug(
- "skipping entry {} on switch {} with bad data : "
- + e.getMessage(), entryName, switchName);
- else
- log.debug("skipping entry with bad data: {} :: {} ",
- e.getMessage(), e.getStackTrace());
- }
-
- OFMatch ofMatch = new OFMatch();
- String match = matchString.toString();
- try {
- ofMatch.fromString(match);
- } catch (IllegalArgumentException e) {
- log.debug(
- "ignoring flow entry {} on switch {} with illegal OFMatch() key: "
- + match, entryName, switchName);
- return;
- }
- flowMod.setMatch(ofMatch);
-
- entries.get(switchName).put(entryName, flowMod);
- }
-
- @Override
- public void addedSwitch(IOFSwitch sw) {
- log.debug("addedSwitch {}; processing its static entries", sw);
- sendEntriesToSwitch(sw);
- }
-
- @Override
- public void removedSwitch(IOFSwitch sw) {
- log.debug("removedSwitch {}", sw);
- // do NOT delete from our internal state; we're tracking the rules,
- // not the switches
- }
-
- @Override
- public void switchPortChanged(Long switchId) {
- // no-op
- }
-
- /**
- * This handles both rowInsert() and rowUpdate()
- */
- /*
- @Override
- public void rowsModified(String tableName, Set<Object> rowKeys) {
- log.debug("Modifying Table {}", tableName);
-
- HashMap<String, Map<String, OFFlowMod>> entriesToAdd =
- new HashMap<String, Map<String, OFFlowMod>>();
- // build up list of what was added
- for(Object key: rowKeys) {
- IResultSet resultSet = storageSource.getRow(tableName, key);
- for (Iterator<IResultSet> it = resultSet.iterator(); it.hasNext();) {
- Map<String, Object> row = it.next().getRow();
- parseRow(row, entriesToAdd);
- }
- }
- // batch updates by switch and blast them out
- for (String dpid : entriesToAdd.keySet()) {
- if (!entriesFromStorage.containsKey(dpid))
- entriesFromStorage.put(dpid, new HashMap<String, OFFlowMod>());
- List<OFMessage> outQueue = new ArrayList<OFMessage>();
- for(String entry : entriesToAdd.get(dpid).keySet()) {
- OFFlowMod newFlowMod = entriesToAdd.get(dpid).get(entry);
- OFFlowMod oldFlowMod = entriesFromStorage.get(dpid).get(entry);
- if (oldFlowMod != null) { // remove any pre-existing rule
- oldFlowMod.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
- outQueue.add(oldFlowMod);
- }
- if (newFlowMod != null) {
- entriesFromStorage.get(dpid).put(entry, newFlowMod);
- outQueue.add(newFlowMod);
- entry2dpid.put(entry, dpid);
- } else {
- entriesFromStorage.get(dpid).remove(entry);
- entry2dpid.remove(entry);
- }
- }
-
- writeOFMessagesToSwitch(HexString.toLong(dpid), outQueue);
- }
- }
-
- @Override
- public void rowsDeleted(String tableName, Set<Object> rowKeys) {
- if (log.isDebugEnabled()) {
- log.debug("deleting from Table {}", tableName);
- }
-
- for(Object obj : rowKeys) {
- if (!(obj instanceof String)) {
- log.debug("tried to delete non-string key {}; ignoring", obj);
- continue;
- }
- deleteStaticFlowEntry((String) obj);
- }
- }
- */
-
- @LogMessageDoc(level="ERROR",
- message="inconsistent internal state: no switch has rule {rule}",
- explanation="Inconsistent internat state discovered while " +
- "deleting a static flow rule",
- recommendation=LogMessageDoc.REPORT_CONTROLLER_BUG)
- private boolean deleteStaticFlowEntry(String entryName) {
- String dpid = entry2dpid.get(entryName);
- if (log.isDebugEnabled()) {
- log.debug("Deleting flow {} for switch {}", entryName, dpid);
- }
- if (dpid == null) {
- log.error("inconsistent internal state: no switch has rule {}",
- entryName);
- return false;
- }
-
- // send flow_mod delete
- OFFlowMod flowMod = entriesFromStorage.get(dpid).get(entryName);
- flowMod.setCommand(OFFlowMod.OFPFC_DELETE_STRICT);
-
- if (entriesFromStorage.containsKey(dpid) &&
- entriesFromStorage.get(dpid).containsKey(entryName)) {
- entriesFromStorage.get(dpid).remove(entryName);
- } else {
- log.debug("Tried to delete non-existent entry {} for switch {}",
- entryName, dpid);
- return false;
- }
-
- writeFlowModToSwitch(HexString.toLong(dpid), flowMod);
- return true;
- }
-
- /**
- * Writes a list of OFMessages to a switch
- * @param dpid The datapath ID of the switch to write to
- * @param messages The list of OFMessages to write.
- */
- @LogMessageDoc(level="ERROR",
- message="Tried to write to switch {switch} but got {error}",
- explanation="An I/O error occured while trying to write a " +
- "static flow to a switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- private void writeOFMessagesToSwitch(long dpid, List<OFMessage> messages) {
- IOFSwitch ofswitch = floodlightProvider.getSwitches().get(dpid);
- if (ofswitch != null) { // is the switch connected
- try {
- if (log.isDebugEnabled()) {
- log.debug("Sending {} new entries to {}", messages.size(), dpid);
- }
- ofswitch.write(messages, null);
- ofswitch.flush();
- } catch (IOException e) {
- log.error("Tried to write to switch {} but got {}", dpid, e.getMessage());
- }
- }
- }
-
- /**
- * Writes an OFFlowMod to a switch. It checks to make sure the switch
- * exists before it sends
- * @param dpid The data to write the flow mod to
- * @param flowMod The OFFlowMod to write
- */
- private void writeFlowModToSwitch(long dpid, OFFlowMod flowMod) {
- Map<Long,IOFSwitch> switches = floodlightProvider.getSwitches();
- IOFSwitch ofSwitch = switches.get(dpid);
- if (ofSwitch == null) {
- if (log.isDebugEnabled()) {
- log.debug("Not deleting key {} :: switch {} not connected",
- dpid);
- }
- return;
- }
- writeFlowModToSwitch(ofSwitch, flowMod);
- }
-
- /**
- * Writes an OFFlowMod to a switch
- * @param sw The IOFSwitch to write to
- * @param flowMod The OFFlowMod to write
- */
- @LogMessageDoc(level="ERROR",
- message="Tried to write OFFlowMod to {switch} but got {error}",
- explanation="An I/O error occured while trying to write a " +
- "static flow to a switch",
- recommendation=LogMessageDoc.CHECK_SWITCH)
- private void writeFlowModToSwitch(IOFSwitch sw, OFFlowMod flowMod) {
- try {
- sw.write(flowMod, null);
- sw.flush();
- } catch (IOException e) {
- log.error("Tried to write OFFlowMod to {} but failed: {}",
- HexString.toHexString(sw.getId()), e.getMessage());
- }
- }
-
- @Override
- public String getName() {
- return StaticFlowName;
- }
-
- @Override
- @LogMessageDoc(level="ERROR",
- message="Got a FlowRemove message for a infinite " +
- "timeout flow: {flow} from switch {switch}",
- explanation="Flows with infinite timeouts should not expire. " +
- "The switch has expired the flow anyway.",
- recommendation=LogMessageDoc.REPORT_SWITCH_BUG)
- public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
- switch (msg.getType()) {
- case FLOW_REMOVED:
- break;
- default:
- return Command.CONTINUE;
- }
- OFFlowRemoved flowRemoved = (OFFlowRemoved) msg;
- long cookie = flowRemoved.getCookie();
- /**
- * This is just to sanity check our assumption that static flows
- * never expire.
- */
- if( AppCookie.extractApp(cookie) == STATIC_FLOW_APP_ID) {
- if (flowRemoved.getReason() !=
- OFFlowRemoved.OFFlowRemovedReason.OFPRR_DELETE)
- log.error("Got a FlowRemove message for a infinite " +
- "timeout flow: {} from switch {}", msg, sw);
- return Command.STOP; // only for us
- } else
- return Command.CONTINUE;
- }
-
- @Override
- public boolean isCallbackOrderingPrereq(OFType type, String name) {
- return false; // no dependency for non-packet in
- }
-
- @Override
- public boolean isCallbackOrderingPostreq(OFType type, String name) {
- return false; // no dependency for non-packet in
- }
-
- // IFloodlightModule
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleServices() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IStaticFlowEntryPusherService.class);
- return l;
- }
-
- @Override
- public Map<Class<? extends IFloodlightService>, IFloodlightService> getServiceImpls() {
- Map<Class<? extends IFloodlightService>,
- IFloodlightService> m =
- new HashMap<Class<? extends IFloodlightService>,
- IFloodlightService>();
- m.put(IStaticFlowEntryPusherService.class, this);
- return m;
- }
-
- @Override
- public Collection<Class<? extends IFloodlightService>> getModuleDependencies() {
- Collection<Class<? extends IFloodlightService>> l =
- new ArrayList<Class<? extends IFloodlightService>>();
- l.add(IFloodlightProviderService.class);
- //l.add(IStorageSourceService.class);
- l.add(IRestApiService.class);
- return l;
- }
-
- @Override
- public void init(FloodlightModuleContext context)
- throws FloodlightModuleException {
- floodlightProvider =
- context.getServiceImpl(IFloodlightProviderService.class);
- //storageSource =
- //context.getServiceImpl(IStorageSourceService.class);
- restApi =
- context.getServiceImpl(IRestApiService.class);
- }
-
- @Override
- public void startUp(FloodlightModuleContext context) {
- floodlightProvider.addOFMessageListener(OFType.FLOW_REMOVED, this);
- floodlightProvider.addOFSwitchListener(this);
- floodlightProvider.addHAListener(this);
-
- // assumes no switches connected at startup()
- //storageSource.createTable(TABLE_NAME, null);
- //storageSource.setTablePrimaryKeyName(TABLE_NAME, COLUMN_NAME);
- //storageSource.addListener(TABLE_NAME, this);
- //entriesFromStorage = readEntriesFromStorage();
- //entry2dpid = computeEntry2DpidMap(entriesFromStorage);
- restApi.addRestletRoutable(new StaticFlowEntryWebRoutable());
- }
-
- // IStaticFlowEntryPusherService methods
-
- @Override
- public void addFlow(String name, OFFlowMod fm, String swDpid) {
- Map<String, Object> fmMap = StaticFlowEntries.flowModToStorageEntry(fm, swDpid, name);
- entry2dpid.put(name, swDpid);
- Map<String, OFFlowMod> switchEntries = entriesFromStorage.get(swDpid);
- if (switchEntries == null) {
- switchEntries = new HashMap<String, OFFlowMod>();
- entriesFromStorage.put(swDpid, switchEntries);
- }
- switchEntries.put(name, fm);
- //storageSource.insertRowAsync(TABLE_NAME, fmMap);
- }
-
- @Override
- public void deleteFlow(String name) {
- //storageSource.deleteRowAsync(TABLE_NAME, name);
- // TODO - What if there is a delay in storage?
- }
-
- @Override
- public void deleteAllFlows() {
- for (String entry : entry2dpid.keySet()) {
- 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());
- }
- }
-
- @Override
- public Map<String, Map<String, OFFlowMod>> getFlows() {
- return entriesFromStorage;
- }
-
- @Override
- public Map<String, OFFlowMod> getFlows(String dpid) {
- return entriesFromStorage.get(dpid);
- }
-
-
- // IHAListener
-
- @Override
- public void roleChanged(Role oldRole, Role newRole) {
- switch(newRole) {
- case MASTER:
- if (oldRole == Role.SLAVE) {
- log.debug("Re-reading static flows from storage due " +
- "to HA change from SLAVE->MASTER");
- //entriesFromStorage = readEntriesFromStorage();
- entry2dpid = computeEntry2DpidMap(entriesFromStorage);
- }
- break;
- case SLAVE:
- log.debug("Clearing in-memory flows due to " +
- "HA change to SLAVE");
- entry2dpid.clear();
- entriesFromStorage.clear();
- break;
- default:
- break;
- }
- }
-
- @Override
- public void controllerNodeIPsChanged(
- Map<String, String> curControllerNodeIPs,
- Map<String, String> addedControllerNodeIPs,
- Map<String, String> removedControllerNodeIPs) {
- // ignore
- }
-
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java
deleted file mode 100644
index f103e99..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/ClearStaticFlowEntriesResource.java
+++ /dev/null
@@ -1,38 +0,0 @@
-package net.floodlightcontroller.staticflowentry.web;
-
-import net.floodlightcontroller.core.web.ControllerSwitchesResource;
-import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
-
-import org.openflow.util.HexString;
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ClearStaticFlowEntriesResource extends ServerResource {
- protected final static Logger log = LoggerFactory.getLogger(ClearStaticFlowEntriesResource.class);
-
- @Get
- public void ClearStaticFlowEntries() {
- IStaticFlowEntryPusherService sfpService =
- (IStaticFlowEntryPusherService)getContext().getAttributes().
- get(IStaticFlowEntryPusherService.class.getCanonicalName());
-
- 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){
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST,
- ControllerSwitchesResource.DPID_ERROR);
- return;
- }
- }
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/ListStaticFlowEntriesResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/ListStaticFlowEntriesResource.java
deleted file mode 100644
index 2bb53ba..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/ListStaticFlowEntriesResource.java
+++ /dev/null
@@ -1,45 +0,0 @@
-package net.floodlightcontroller.staticflowentry.web;
-
-import java.util.HashMap;
-import java.util.Map;
-
-import net.floodlightcontroller.core.web.ControllerSwitchesResource;
-import net.floodlightcontroller.staticflowentry.IStaticFlowEntryPusherService;
-
-import org.openflow.protocol.OFFlowMod;
-import org.restlet.data.Status;
-import org.restlet.resource.Get;
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-public class ListStaticFlowEntriesResource extends ServerResource {
- protected final static Logger log = LoggerFactory.getLogger(ListStaticFlowEntriesResource.class);
-
- @Get
- public Map<String, Map<String, OFFlowMod>> ListStaticFlowEntries() {
- IStaticFlowEntryPusherService sfpService =
- (IStaticFlowEntryPusherService)getContext().getAttributes().
- get(IStaticFlowEntryPusherService.class.getCanonicalName());
-
- String param = (String) getRequestAttributes().get("switch");
- if (log.isDebugEnabled())
- log.debug("Listing all static flow entires for switch: " + param);
-
- if (param.toLowerCase().equals("all")) {
- return sfpService.getFlows();
- } else {
- try {
- Map<String, Map<String, OFFlowMod>> retMap =
- new HashMap<String, Map<String, OFFlowMod>>();
- retMap.put(param, sfpService.getFlows(param));
- return retMap;
-
- } catch (NumberFormatException e){
- setStatus(Status.CLIENT_ERROR_BAD_REQUEST,
- ControllerSwitchesResource.DPID_ERROR);
- }
- }
- return null;
- }
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
deleted file mode 100644
index 1db262d..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java
+++ /dev/null
@@ -1,137 +0,0 @@
-/**
-* 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.staticflowentry.web;
-
-import java.util.Map;
-
-import net.floodlightcontroller.core.annotations.LogMessageCategory;
-import net.floodlightcontroller.staticflowentry.StaticFlowEntryPusher;
-
-import org.restlet.resource.ServerResource;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-/**
- * Pushes a static flow entry to the storage source
- * @author alexreimers
- *
- */
-@LogMessageCategory("Static Flow Pusher")
-public class StaticFlowEntryPusherResource extends ServerResource {
- protected final static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class);
-
- /**
- * Checks to see if the user matches IP information without
- * checking for the correct ether-type (2048).
- * @param rows The Map that is a string representation of
- * the static flow.
- * @reutrn True if they checked the ether-type, false otherwise
- */
- private boolean checkMatchIp(Map<String, Object> rows) {
- boolean matchEther = false;
- String val = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE);
- if (val != null) {
- int type = 0;
- // check both hex and decimal
- if (val.startsWith("0x")) {
- type = Integer.parseInt(val.substring(2), 16);
- } else {
- try {
- type = Integer.parseInt(val);
- } catch (NumberFormatException e) { /* fail silently */}
- }
- if (type == 2048) matchEther = true;
- }
-
- if ((rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) ||
- rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC) ||
- rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO) ||
- rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_TOS)) &&
- (matchEther == false))
- return false;
-
- return true;
- }
-
- /**
- * Takes a Static Flow Pusher string in JSON format and parses it into
- * our database schema then pushes it to the database.
- * @param fmJson The Static Flow Pusher entry in JSON format.
- * @return A string status message
- */
- /*
- @Post
- @LogMessageDoc(level="ERROR",
- message="Error parsing push flow mod request: {request}",
- explanation="An invalid request was sent to static flow pusher",
- recommendation="Fix the format of the static flow mod request")
- public String store(String fmJson) {
- IStorageSourceService storageSource =
- (IStorageSourceService)getContext().getAttributes().
- get(IStorageSourceService.class.getCanonicalName());
-
- Map<String, Object> rowValues;
- try {
- rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson);
- String status = null;
- if (!checkMatchIp(rowValues)) {
- status = "Warning! Pushing a static flow entry that matches IP " +
- "fields without matching for IP payload (ether-type 2048) will cause " +
- "the switch to wildcard higher level fields.";
- log.error(status);
- } else {
- status = "Entry pushed";
- }
- storageSource.insertRowAsync(StaticFlowEntryPusher.TABLE_NAME, rowValues);
- return ("{\"status\" : \"" + status + "\"}");
- } catch (IOException e) {
- log.error("Error parsing push flow mod request: " + fmJson, e);
- e.printStackTrace();
- return "{\"status\" : \"Error! Could not parse flod mod, see log for details.\"}";
- }
- }
-
- @Delete
- @LogMessageDoc(level="ERROR",
- message="Error deleting flow mod request: {request}",
- explanation="An invalid delete request was sent to static flow pusher",
- recommendation="Fix the format of the static flow mod request")
- public String del(String fmJson) {
- IStorageSourceService storageSource =
- (IStorageSourceService)getContext().getAttributes().
- get(IStorageSourceService.class.getCanonicalName());
- String fmName = null;
- if (fmJson == null) {
- return "{\"status\" : \"Error! No data posted.\"}";
- }
- try {
- fmName = StaticFlowEntries.getEntryNameFromJson(fmJson);
- if (fmName == null) {
- return "{\"status\" : \"Error deleting entry, no name provided\"}";
- }
- } catch (IOException e) {
- log.error("Error deleting flow mod request: " + fmJson, e);
- e.printStackTrace();
- return "{\"status\" : \"Error deleting entry, see log for details\"}";
- }
-
- storageSource.deleteRowAsync(StaticFlowEntryPusher.TABLE_NAME, fmName);
- return "{\"status\" : \"Entry " + fmName + " deleted\"}";
- }
- */
-}
diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java
deleted file mode 100644
index b5a6fe1..0000000
--- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryWebRoutable.java
+++ /dev/null
@@ -1,29 +0,0 @@
-package net.floodlightcontroller.staticflowentry.web;
-
-import net.floodlightcontroller.restserver.RestletRoutable;
-
-import org.restlet.Context;
-import org.restlet.Restlet;
-import org.restlet.routing.Router;
-
-public class StaticFlowEntryWebRoutable implements RestletRoutable {
- /**
- * Create the Restlet router and bind to the proper resources.
- */
- @Override
- public Restlet getRestlet(Context context) {
- Router router = new Router(context);
- router.attach("/json", StaticFlowEntryPusherResource.class);
- router.attach("/clear/{switch}/json", ClearStaticFlowEntriesResource.class);
- router.attach("/list/{switch}/json", ListStaticFlowEntriesResource.class);
- return router;
- }
-
- /**
- * Set the base path for the Topology
- */
- @Override
- public String basePath() {
- return "/wm/staticflowentrypusher";
- }
-}