@Override @LogMessageDoc( level = "ERROR", message = "Failed to clear all flows on switch {switch}", explanation = "An I/O error occured while trying to clear " + "flows on the switch.", recommendation = LogMessageDoc.CHECK_SWITCH) public void clearAllFlowMods() { // Delete all pre-existing flows OFMatch match = new OFMatch().setWildcards(OFMatch.OFPFW_ALL); OFMessage fm = ((OFFlowMod) floodlightProvider.getOFMessageFactory().getMessage(OFType.FLOW_MOD)) .setMatch(match) .setCommand(OFFlowMod.OFPFC_DELETE) .setOutPort(OFPort.OFPP_NONE) .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH)); fm.setXid(getNextTransactionId()); OFMessage barrierMsg = (OFBarrierRequest) floodlightProvider.getOFMessageFactory().getMessage(OFType.BARRIER_REQUEST); barrierMsg.setXid(getNextTransactionId()); try { List<OFMessage> msglist = new ArrayList<OFMessage>(1); msglist.add(fm); write(msglist); msglist = new ArrayList<OFMessage>(1); msglist.add(barrierMsg); write(msglist); } catch (Exception e) { log.error("Failed to clear all flows on switch " + this, e); } }
/** @param properties the properties to set */ public OFPacketQueue setProperties(List<OFQueueProperty> properties) { this.properties = properties; int l = MINIMUM_LENGTH; if (this.properties != null) { for (OFQueueProperty prop : this.properties) { l += prop.getLengthU(); } } this.length = U16.t(l); return this; }
/** * Handle replies to certain OFMessages, and pass others off to listeners * * @param sw * @param msgs * @throws IOException */ @SuppressWarnings("unchecked") protected void handleMessages(IOFSwitchExt sw, List<OFMessage> msgs) throws IOException { for (OFMessage m : msgs) { // If we detect a write failure, break early so we can disconnect if (((OFStream) sw.getInputStream()).getWriteFailure()) { break; } // Always handle ECHO REQUESTS, regardless of state switch (m.getType()) { case ECHO_REQUEST: OFMessageInStream in = sw.getInputStream(); OFMessageOutStream out = sw.getOutputStream(); OFEchoReply reply = (OFEchoReply) in.getMessageFactory().getMessage(OFType.ECHO_REPLY); reply.setXid(m.getXid()); out.write(reply); break; case ECHO_REPLY: // *Note, ECHO REPLIES need no handling due to last message timestamp break; case ERROR: logError(sw, (OFError) m); // fall through intentionally so error can be listened for default: switch (sw.getState()) { case DISCONNECTED: log.info("Switch {} in state DISCONNECTED, exiting message processing loop", sw); return; case HELLO_SENT: if (m.getType() == OFType.HELLO) { log.debug("HELLO from {}", sw); sw.transitionToState(OFSwitchState.FEATURES_REQUEST_SENT); // Send initial Features Request sw.getOutputStream().write(factory.getMessage(OFType.FEATURES_REQUEST)); } break; case FEATURES_REQUEST_SENT: if (m.getType() == OFType.FEATURES_REPLY) { log.debug("Features Reply from {}", sw); sw.setFeaturesReply((OFFeaturesReply) m); // Send Description Statistics Request OFStatisticsRequest sr = new OFStatisticsRequest(); sr.setStatisticType(OFStatisticsType.DESC); sw.getOutputStream().write(sr); sw.transitionToState(OFSwitchState.DESCRIPTION_STATISTICS_REQUEST_SENT); } break; case DESCRIPTION_STATISTICS_REQUEST_SENT: if (m.getType() == OFType.STATS_REPLY) { OFStatisticsReply sr = (OFStatisticsReply) m; if (sr.getStatisticType() == OFStatisticsType.DESC && sr.getStatistics().size() > 0) { OFDescriptionStatistics desc = (OFDescriptionStatistics) sr.getStatistics().get(0); sw.setDescriptionStatistics(desc); log.debug("Description Statistics Reply from {}: {}", sw, desc); // Set config and request to receive the config OFSetConfig config = (OFSetConfig) factory.getMessage(OFType.SET_CONFIG); config.setMissSendLength((short) 0xffff).setLengthU(OFSetConfig.MINIMUM_LENGTH); sw.getOutputStream().write(config); sw.getOutputStream().write(factory.getMessage(OFType.BARRIER_REQUEST)); sw.getOutputStream().write(factory.getMessage(OFType.GET_CONFIG_REQUEST)); sw.transitionToState(OFSwitchState.GET_CONFIG_REQUEST_SENT); } } break; case GET_CONFIG_REQUEST_SENT: if (m.getType() == OFType.GET_CONFIG_REPLY) { OFGetConfigReply cr = (OFGetConfigReply) m; if (cr.getMissSendLength() == (short) 0xffff) { log.debug("Config Reply from {} confirms miss length set to 0xffff", sw); sw.transitionToState(OFSwitchState.INITIALIZING); CopyOnWriteArrayList<IOFInitializerListener> initializers = (CopyOnWriteArrayList<IOFInitializerListener>) initializerList.clone(); // Add all existing initializers to the list this.initializerMap.put(sw, initializers); log.debug( "Remaining initializers for switch {}: {}", sw, this.initializerMap.get(sw)); // Delete all pre-existing flows if (deletePreExistingFlows) { OFMatch match = new OFMatch().setWildcards(OFMatch.OFPFW_ALL); OFMessage fm = ((OFFlowMod) sw.getInputStream().getMessageFactory().getMessage(OFType.FLOW_MOD)) .setMatch(match) .setCommand(OFFlowMod.OFPFC_DELETE) .setOutPort(OFPort.OFPP_NONE) .setLength(U16.t(OFFlowMod.MINIMUM_LENGTH)); sw.getOutputStream().write(fm); sw.getOutputStream().write(factory.getMessage(OFType.BARRIER_REQUEST)); } if (initializers.size() > 0) queueInitializer(sw, initializers.iterator().next()); else advanceInitializers(sw); } else { log.error( "Switch {} refused to set miss send length to 0xffff, disconnecting", sw); disconnectSwitch(((OFStream) sw.getInputStream()).getKey(), sw); return; } } break; case INITIALIZING: CopyOnWriteArrayList<IOFInitializerListener> initializers = initializerMap.get(sw); Iterator<IOFInitializerListener> it = initializers.iterator(); if (it.hasNext()) { IOFInitializerListener listener = it.next(); try { listener.initializerReceive(sw, m); } catch (Exception e) { log.error( "Error calling initializer listener: {} on switch: {} for message: {}, removing listener", new Object[] {listener, sw, m}); advanceInitializers(sw); } } break; case ACTIVE: List<IOFMessageListener> listeners = messageListeners.get(m.getType()); if (listeners != null) { for (IOFMessageListener listener : listeners) { try { if (listener instanceof IOFSwitchFilter) { if (!((IOFSwitchFilter) listener).isInterested(sw)) { continue; } } if (Command.STOP.equals(listener.receive(sw, m))) { break; } } catch (Exception e) { log.error( "Failure calling listener [" + listener.toString() + "] with message [" + m.toString() + "]", e); } } } else { log.debug("Unhandled OF Message: {} from {}", m, sw); } break; } // end switch(sw.getState()) } // end switch(m.getType()) } }
/** * Set this OFMatch's parameters based on a comma-separated key=value pair dpctl-style string, * e.g., from the output of OFMatch.toString() <br> * * <p>Supported keys/values include <br> * * <p> * * <TABLE border=1> * <TR> * <TD>KEY(s) * <TD>VALUE * </TR> * <TR> * <TD>"in_port","input_port" * <TD>integer * </TR> * <TR> * <TD>"dl_src","eth_src", "dl_dst","eth_dst" * <TD>hex-string * </TR> * <TR> * <TD>"dl_type", "dl_vlan", "dl_vlan_pcp" * <TD>integer * </TR> * <TR> * <TD>"nw_src", "nw_dst", "ip_src", "ip_dst" * <TD>CIDR-style netmask * </TR> * <TR> * <TD>"tp_src","tp_dst" * <TD>integer (max 64k) * </TR> * </TABLE> * * <p>The CIDR-style netmasks assume 32 netmask if none given, so: "128.8.128.118/32" is the same * as "128.8.128.118" * * @param match a key=value comma separated string, e.g. * "in_port=5,ip_dst=192.168.0.0/16,tp_src=80" * @throws IllegalArgumentException on unexpected key or value */ public void fromString(String match) throws IllegalArgumentException { if (match.equals("") || match.equalsIgnoreCase("any") || match.equalsIgnoreCase("all") || match.equals("[]")) match = "OFMatch[]"; String[] tokens = match.split("[\\[,\\]]"); String[] values; int initArg = 0; if (tokens[0].equals("OFMatch")) initArg = 1; this.wildcards = OFPFW_ALL; int i; for (i = initArg; i < tokens.length; i++) { values = tokens[i].split("="); if (values.length != 2) throw new IllegalArgumentException( "Token " + tokens[i] + " does not have form 'key=value' parsing " + match); values[0] = values[0].toLowerCase(); // try to make this case insens if (values[0].equals(STR_IN_PORT) || values[0].equals("input_port")) { this.inputPort = U16.t(Integer.valueOf(values[1])); this.wildcards &= ~OFPFW_IN_PORT; } else if (values[0].equals(STR_DL_DST) || values[0].equals("eth_dst")) { this.dataLayerDestination = HexString.fromHexString(values[1]); this.wildcards &= ~OFPFW_DL_DST; } else if (values[0].equals(STR_DL_SRC) || values[0].equals("eth_src")) { this.dataLayerSource = HexString.fromHexString(values[1]); this.wildcards &= ~OFPFW_DL_SRC; } else if (values[0].equals(STR_DL_TYPE) || values[0].equals("eth_type")) { if (values[1].startsWith("0x")) this.dataLayerType = U16.t(Integer.valueOf(values[1].replaceFirst("0x", ""), 16)); else this.dataLayerType = U16.t(Integer.valueOf(values[1])); this.wildcards &= ~OFPFW_DL_TYPE; } else if (values[0].equals(STR_DL_VLAN)) { if (values[1].startsWith("0x")) this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1].replaceFirst("0x", ""), 16)); else this.dataLayerVirtualLan = U16.t(Integer.valueOf(values[1])); this.wildcards &= ~OFPFW_DL_VLAN; } else if (values[0].equals(STR_DL_VLAN_PCP)) { if (values[1].startsWith("0x")) this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short.valueOf(values[1].replaceFirst("0x", ""), 16)); else this.dataLayerVirtualLanPriorityCodePoint = U8.t(Short.valueOf(values[1])); this.wildcards &= ~OFPFW_DL_VLAN_PCP; } else if (values[0].equals(STR_NW_DST) || values[0].equals("ip_dst")) setFromCIDR(values[1], STR_NW_DST); else if (values[0].equals(STR_NW_SRC) || values[0].equals("ip_src")) setFromCIDR(values[1], STR_NW_SRC); else if (values[0].equals(STR_NW_PROTO)) { this.networkProtocol = U8.t(Short.valueOf(values[1])); this.wildcards &= ~OFPFW_NW_PROTO; } else if (values[0].equals(STR_NW_TOS)) { this.networkTypeOfService = U8.t(Short.valueOf(values[1])); this.wildcards &= ~OFPFW_NW_TOS; } else if (values[0].equals(STR_TP_DST)) { this.transportDestination = U16.t(Integer.valueOf(values[1])); this.wildcards &= ~OFPFW_TP_DST; } else if (values[0].equals(STR_TP_SRC)) { this.transportSource = U16.t(Integer.valueOf(values[1])); this.wildcards &= ~OFPFW_TP_SRC; } else throw new IllegalArgumentException("unknown token " + tokens[i] + " parsing " + match); } }
/** * Set the length of this message, unsigned * * @param length */ public /*OFMessage*/ SNMPMessage setLengthU(int length) { this.length = U16.t(length); return this; }
public OFGroupMod() { super(); this.type = OFType.GROUP_MOD; this.length = U16.t(MINIMUM_LENGTH); }