diff --git a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java index d0c4687cc40f4a6c267404d90682a1abce19790d..158655840043340f0271a34eabe01cb339447cb7 100644 --- a/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java +++ b/src/main/java/net/floodlightcontroller/staticflowentry/web/StaticFlowEntryPusherResource.java @@ -1,19 +1,19 @@ /** -* 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.staticflowentry.web; @@ -40,248 +40,248 @@ import net.floodlightcontroller.util.MatchUtils; */ @LogMessageCategory("Static Flow Pusher") public class StaticFlowEntryPusherResource extends ServerResource { - protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class); - + protected static Logger log = LoggerFactory.getLogger(StaticFlowEntryPusherResource.class); -/** -* Validates if all the mandatory fields are set properly while adding an IPv6 flow -* @param Map containing the fields of the flow -* @return state indicating whether a flow is valid or not -*/ - private int checkFlow(Map<String, Object> rows) { - //Declaring & Initializing flags - int state = 0; - boolean dl_type = false; - boolean nw_proto = false; - boolean nw_layer = false; - boolean icmp6_type = false; - boolean icmp6_code = false; - boolean nd_target = false; - boolean nd_sll = false; - boolean nd_tll = false; - boolean ip6 = false; - boolean ip4 = false; + /** + * Validates if all the mandatory fields are set properly while adding an IPv6 flow + * @param Map containing the fields of the flow + * @return state indicating whether a flow is valid or not + */ + private int checkFlow(Map<String, Object> rows) { + //Declaring & Initializing flags + int state = 0; + boolean dl_type = false; + boolean nw_proto = false; + boolean nw_layer = false; + boolean icmp6_type = false; + boolean icmp6_code = false; + boolean nd_target = false; + boolean nd_sll = false; + boolean nd_tll = false; + boolean ip6 = false; + boolean ip4 = false; + + String eth_type = null; + String nw_protocol = null; + int icmp_type = -1; - String eth_type = null; - String nw_protocol = null; - int icmp_type = -1; - - //Determine the dl_type if set - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_DL_TYPE)) { - dl_type = true; - eth_type = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE); - if (eth_type.equalsIgnoreCase("0x86dd") || eth_type.equals("34525")) { - ip6 = true; + //Determine the dl_type if set + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_DL_TYPE)) { + dl_type = true; + eth_type = (String) rows.get(StaticFlowEntryPusher.COLUMN_DL_TYPE); + if (eth_type.equalsIgnoreCase("0x86dd") || eth_type.equals("34525")) { + ip6 = true; + } + else if (eth_type.equalsIgnoreCase("0x800") || eth_type.equals("2048") || + eth_type.equalsIgnoreCase("0x806") || eth_type.equals("2054") || + eth_type.equalsIgnoreCase("0x8035") || eth_type.equals("32821")) { + ip4 = true; + } + //else { + // state = 2; + // return state; + //} } - else if (eth_type.equalsIgnoreCase("0x800") || eth_type.equals("2048")|| - eth_type.equalsIgnoreCase("0x806") || eth_type.equals("2054")) { + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC)) { + nw_layer = true; ip4 = true; - } - //else { - // state = 2; - // return state; - //} - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_DST) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_SRC)) { - nw_layer = true; - ip4 = true; - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_CODE) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_TYPE) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DHA) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SHA) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SPA) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DPA) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_OPCODE)) { - ip4 = true; - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_SRC) || - rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_DST)) { - nw_layer = true; - ip6 = true; - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO)) { - nw_proto = true; - nw_protocol = (String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO); - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_CODE)) { - icmp6_code = true; - ip6 = true; - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)) { - icmp6_type = true; - ip6 = true; - icmp_type = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)); - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_SLL)) { - nd_sll = true; - ip6 = true; - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TLL)) { - nd_tll = true; - ip6 = true; - } - if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TARGET)) { - nd_target = true; - ip6 = true; - } - - if (nw_layer == true || nw_proto == true) { - if (dl_type == true) { - if (!(ip4 == true || ip6 == true)) { - //invalid dl_type - state = 2; - return state; - } } - else { - //dl_type not set - state = 1; - return state; + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_CODE) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP_TYPE) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DHA) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SHA) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_SPA) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_DPA) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_ARP_OPCODE)) { + ip4 = true; } - } - if (icmp6_type == true || icmp6_code == true ) { - if (nw_proto == true) { - if (!(nw_protocol.equals("58") || nw_protocol.equalsIgnoreCase("0x3A"))) { - //invalid nw_proto - state = 4; - return state; - } + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_IPV6_FLOW_LABEL) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_SRC) || + rows.containsKey(StaticFlowEntryPusher.COLUMN_NW6_DST)) { + nw_layer = true; + ip6 = true; } - else { - //nw_proto not set - state = 3; - return state; + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_NW_PROTO)) { + nw_proto = true; + nw_protocol = (String) rows.get(StaticFlowEntryPusher.COLUMN_NW_PROTO); } - } - - if (nd_sll == true || nd_tll == true || nd_target == true) { - if (icmp6_type == true) { - //icmp_type must be set to 135/136 to set ipv6_nd_target - if (nd_target == true) { - if (!(icmp_type == 135 || icmp_type == 136)) { - //invalid icmp6_type - state = 6; + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_CODE)) { + icmp6_code = true; + ip6 = true; + } + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)) { + icmp6_type = true; + ip6 = true; + icmp_type = Integer.parseInt((String) rows.get(StaticFlowEntryPusher.COLUMN_ICMP6_TYPE)); + } + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_SLL)) { + nd_sll = true; + ip6 = true; + } + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TLL)) { + nd_tll = true; + ip6 = true; + } + if (rows.containsKey(StaticFlowEntryPusher.COLUMN_ND_TARGET)) { + nd_target = true; + ip6 = true; + } + + if (nw_layer == true || nw_proto == true) { + if (dl_type == true) { + if (!(ip4 == true || ip6 == true)) { + //invalid dl_type + state = 2; return state; } } - //icmp_type must be set to 136 to set ipv6_nd_tll - else if (nd_tll == true) { - if (!(icmp_type == 136)) { - //invalid icmp6_type - state = 6; + else { + //dl_type not set + state = 1; + return state; + } + } + if (icmp6_type == true || icmp6_code == true ) { + if (nw_proto == true) { + if (!(nw_protocol.equals("58") || nw_protocol.equalsIgnoreCase("0x3A"))) { + //invalid nw_proto + state = 4; return state; } } - //icmp_type must be set to 135 to set ipv6_nd_sll - else if (nd_sll == true) { - if (!(icmp_type == 135)) { - //invalid icmp6_type - state = 6; - return state; + else { + //nw_proto not set + state = 3; + return state; + } + } + + if (nd_sll == true || nd_tll == true || nd_target == true) { + if (icmp6_type == true) { + //icmp_type must be set to 135/136 to set ipv6_nd_target + if (nd_target == true) { + if (!(icmp_type == 135 || icmp_type == 136)) { + //invalid icmp6_type + state = 6; + return state; + } + } + //icmp_type must be set to 136 to set ipv6_nd_tll + else if (nd_tll == true) { + if (!(icmp_type == 136)) { + //invalid icmp6_type + state = 6; + return state; + } + } + //icmp_type must be set to 135 to set ipv6_nd_sll + else if (nd_sll == true) { + if (!(icmp_type == 135)) { + //invalid icmp6_type + state = 6; + return state; + } } } + else { + //icmp6_type not set + state = 5; + return state; + } } - else { - //icmp6_type not set - state = 5; + + int result = checkActions(rows); + + if ((ip4 == true && ip6 == true) || (result == -1) || + (result == 1 && ip6 == true) || (result == 2 && ip4 == true)) { + //ipv4 & ipv6 conflict + state = 7; return state; } - } - - int result = checkActions(rows); - - if ((ip4 == true && ip6 == true) || (result == -1) || - (result == 1 && ip6 == true) || (result == 2 && ip4 == true)) { - //ipv4 & ipv6 conflict - state = 7; + return state; + } - return state; - - } - - /** - * Validates actions/instructions - * - * -1 --> IPv4/IPv6 conflict - * 0 --> no IPv4 or IPv6 actions - * 1 --> IPv4 only actions - * 2 --> IPv6 only actions - * - * @param Map containing the fields of the flow - * @return state indicating whether a flow is valid or not - */ - public static int checkActions(Map<String, Object> entry) { - - boolean ip6 = false; - boolean ip4 = false; - String actions = null; + /** + * Validates actions/instructions + * + * -1 --> IPv4/IPv6 conflict + * 0 --> no IPv4 or IPv6 actions + * 1 --> IPv4 only actions + * 2 --> IPv6 only actions + * + * @param Map containing the fields of the flow + * @return state indicating whether a flow is valid or not + */ + public static int checkActions(Map<String, Object> entry) { - if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS) || - entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS) || - entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) { - if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS)) { - actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_ACTIONS); - } - else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) { - actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS); - } - else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) { - actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS); - } + boolean ip6 = false; + boolean ip4 = false; + String actions = null; - if (actions.contains(MatchUtils.STR_ICMPV6_CODE) || actions.contains(MatchUtils.STR_ICMPV6_TYPE) || - actions.contains(MatchUtils.STR_IPV6_DST) || actions.contains(MatchUtils.STR_IPV6_SRC) || - actions.contains(MatchUtils.STR_IPV6_FLOW_LABEL) || actions.contains(MatchUtils.STR_IPV6_ND_SSL) || - actions.contains(MatchUtils.STR_IPV6_ND_TARGET) || actions.contains(MatchUtils.STR_IPV6_ND_TTL)) { - ip6 = true; + if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS) || + entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS) || + entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) { + if (entry.containsKey(StaticFlowEntryPusher.COLUMN_ACTIONS)) { + actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_ACTIONS); + } + else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS)) { + actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_APPLY_ACTIONS); + } + else if (entry.containsKey(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS)) { + actions = (String) entry.get(StaticFlowEntryPusher.COLUMN_INSTR_WRITE_ACTIONS); + } + + if (actions.contains(MatchUtils.STR_ICMPV6_CODE) || actions.contains(MatchUtils.STR_ICMPV6_TYPE) || + actions.contains(MatchUtils.STR_IPV6_DST) || actions.contains(MatchUtils.STR_IPV6_SRC) || + actions.contains(MatchUtils.STR_IPV6_FLOW_LABEL) || actions.contains(MatchUtils.STR_IPV6_ND_SSL) || + actions.contains(MatchUtils.STR_IPV6_ND_TARGET) || actions.contains(MatchUtils.STR_IPV6_ND_TTL)) { + ip6 = true; + } + if (actions.contains(MatchUtils.STR_NW_SRC) || actions.contains(MatchUtils.STR_NW_DST) || + actions.contains(MatchUtils.STR_ARP_OPCODE) || actions.contains(MatchUtils.STR_ARP_SHA) || + actions.contains(MatchUtils.STR_ARP_DHA) || actions.contains(MatchUtils.STR_ARP_SPA) || + actions.contains(MatchUtils.STR_ARP_DPA) || actions.contains(MatchUtils.STR_ICMP_CODE) || + actions.contains(MatchUtils.STR_ICMP_TYPE)) { + ip4 = true; + } } - if (actions.contains(MatchUtils.STR_NW_SRC) || actions.contains(MatchUtils.STR_NW_DST) || - actions.contains(MatchUtils.STR_ARP_OPCODE) || actions.contains(MatchUtils.STR_ARP_SHA) || - actions.contains(MatchUtils.STR_ARP_DHA) || actions.contains(MatchUtils.STR_ARP_SPA) || - actions.contains(MatchUtils.STR_ARP_DPA) || actions.contains(MatchUtils.STR_ICMP_CODE) || - actions.contains(MatchUtils.STR_ICMP_TYPE)) { - ip4 = true; + + if (ip6 == false && ip4 == false) { + return 0; // no actions involving ipv4 or ipv6 + } else if (ip6 == false && ip4 == true) { + return 1; //ipv4 + } else if (ip6 == true && ip4 == false) { + return 2; //ipv6 + } else { + return -1; // conflict of ipv4 and ipv6 actions } } - - if (ip6 == false && ip4 == false) { - return 0; // no actions involving ipv4 or ipv6 - } else if (ip6 == false && ip4 == true) { - return 1; //ipv4 - } else if (ip6 == true && ip4 == false) { - return 2; //ipv6 - } else { - return -1; // conflict of ipv4 and ipv6 actions - } - } - /** - * 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()); + /** + * 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; - int state = checkFlow(rowValues); + Map<String, Object> rowValues; + try { + rowValues = StaticFlowEntries.jsonToStorageEntry(fmJson); + String status = null; + int state = checkFlow(rowValues); if (state == 1) { status = "Warning! Must specify eth_type of IPv4/IPv6 to " + "match on IPv4/IPv6 fields! The flow has been discarded."; @@ -313,32 +313,32 @@ public class StaticFlowEntryPusherResource extends ServerResource { log.error("Error parsing push flow mod request: " + fmJson, e); 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); - return "{\"status\" : \"Error deleting entry, 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); + return "{\"status\" : \"Error deleting entry, see log for details\"}"; + } - storageSource.deleteRowAsync(StaticFlowEntryPusher.TABLE_NAME, fmName); - return "{\"status\" : \"Entry " + fmName + " deleted\"}"; - } + storageSource.deleteRowAsync(StaticFlowEntryPusher.TABLE_NAME, fmName); + return "{\"status\" : \"Entry " + fmName + " deleted\"}"; + } }