Пример #1
0
  protected void advanceInitializers(IOFSwitchExt sw) {
    CopyOnWriteArrayList<IOFInitializerListener> initializers = initializerMap.get(sw);

    // Remove first initializer if it exists
    Iterator<IOFInitializerListener> it = initializers.iterator();
    if (it.hasNext()) {
      IOFInitializerListener initializer = it.next();
      initializers.remove(initializer);
      log.debug("Remaining initializers for switch {}: {}", sw, initializers);
    }

    if (it.hasNext()) {
      IOFInitializerListener initializer = it.next();
      queueInitializer(sw, initializer);
    } else {
      /**
       * Must synchronize here to ensure we don't transition into active while simultaneously being
       * disconnected.
       */
      synchronized (sw) {
        if (!OFSwitchState.DISCONNECTED.equals(sw.getState())) {
          sw.transitionToState(OFSwitchState.ACTIVE);
          // Add switch to active list
          addActiveSwitch(sw);
        }
        initializerMap.remove(sw);
      }
    }
  }
Пример #2
0
 /**
  * Removes a disconnected switch and calls all related listeners
  *
  * @param sw the switch that has disconnected
  */
 protected void removeSwitch(IOFSwitchExt sw) {
   this.allSwitches.remove(sw);
   // If active remove from DPID indexed map
   if (OFSwitchState.ACTIVE == sw.getState()) {
     if (!this.activeSwitches.remove(sw.getId(), sw)) {
       log.warn("Removing switch {} has already been replaced", sw);
     }
     Update update = new Update(sw, false);
     try {
       this.updates.put(update);
     } catch (InterruptedException e) {
       log.error("Failure adding update to queue", e);
     }
   }
 }
Пример #3
0
 /** Disconnect the switch from Beacon */
 protected void disconnectSwitch(SelectionKey key, IOFSwitchExt sw) {
   /**
    * Must synchronize here to ensure we don't transition into active while simultaneously being
    * disconnected.
    */
   synchronized (sw) {
     key.cancel();
     OFStream stream = (OFStream) sw.getInputStream();
     stream.getIOLoop().removeStream(stream);
     removeSwitch(sw);
     try {
       sw.getSocketChannel().socket().close();
     } catch (IOException e1) {
     }
     this.initializerMap.remove(sw);
     if (!OFSwitchState.DISCONNECTED.equals(sw.getState())) {
       sw.transitionToState(OFSwitchState.DISCONNECTED);
     }
     log.info("Switch disconnected {}", sw);
   }
 }
Пример #4
0
  /**
   * 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())
    }
  }