Пример #1
0
 @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);
   }
 }
Пример #2
0
 @Override
 @LogMessageDoc(
     level = "WARN",
     message =
         "Sending OF message that modifies switch " + "state while in the slave role: {switch}",
     explanation =
         "An application has sent a message to a switch "
             + "that is not valid when the switch is in a slave role",
     recommendation = LogMessageDoc.REPORT_CONTROLLER_BUG)
 public void write(List<OFMessage> msglist, FloodlightContext bc) throws IOException {
   for (OFMessage m : msglist) {
     if (role == Role.SLAVE) {
       switch (m.getType()) {
         case PACKET_OUT:
         case FLOW_MOD:
         case PORT_MOD:
           log.warn(
               "Sending OF message that modifies switch " + "state while in the slave role: {}",
               m.getType().name());
           break;
         default:
           break;
       }
     }
     this.floodlightProvider.handleOutgoingMessage(this, m, bc);
   }
   this.write(msglist);
 }
Пример #3
0
 @Override
 public Future<OFFeaturesReply> querySwitchFeaturesReply() throws IOException {
   OFMessage request =
       floodlightProvider.getOFMessageFactory().getMessage(OFType.FEATURES_REQUEST);
   request.setXid(getNextTransactionId());
   OFFeaturesReplyFuture future = new OFFeaturesReplyFuture(threadPool, this, request.getXid());
   this.featuresFutureMap.put(request.getXid(), future);
   List<OFMessage> msglist = new ArrayList<OFMessage>(1);
   msglist.add(request);
   this.write(msglist);
   return future;
 }
Пример #4
0
 @Override
 public void deliverStatisticsReply(OFMessage reply) {
   OFStatisticsFuture future = this.statsFutureMap.get(reply.getXid());
   if (future != null) {
     future.deliverFuture(this, reply);
     // The future will ultimately unregister itself and call
     // cancelStatisticsReply
     return;
   }
   /* Transaction id was not found in statsFutureMap.check the other map */
   IOFMessageListener caller = this.iofMsgListenersMap.get(reply.getXid());
   if (caller != null) {
     caller.receive(this, reply, null);
   }
 }
Пример #5
0
  @Override
  public net.floodlightcontroller.core.IListener.Command receive(
      IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {

    if (msg.getType() == OFType.PACKET_IN) {
      OFPacketIn pi = (OFPacketIn) msg;
      Ethernet eth =
          IFloodlightProviderService.bcStore.get(
              cntx, IFloodlightProviderService.CONTEXT_PI_PAYLOAD);
      Short type = eth.getEtherType();

      if (type == Ethernet.TYPE_IPv4) {
        IPv4 ippacket = (IPv4) eth.getPayload();
        log.info("New IPv4 message found. \n  {} \n", eth.toString());

        // For debugging purposes in mininet only
        if (ippacket.getProtocol() == IPv4.PROTOCOL_ICMP) {

          // ICMP icmp = (ICMP)ippacket.getPayload();
          log.info("New ICMP message found. \n  {} \n", ippacket.toString());

          // TODO: Call doForwardFlow with the calculated weights
          // change doForwardFlow args...
          // doForwardFlow(sw, pi, cntx);
        }
      }
    }
    return Command.CONTINUE;
  }
Пример #6
0
  protected List<ICounter> getPktRemoteFMCounters(IOFSwitch sw, OFMessage m) {
    /* If possible, find and return counters for this tuple */
    String countersKey = this.getCountersKey(sw, m, null);
    List<ICounter> counters = this.pktremoteCounters.get(countersKey);
    if (counters != null) {
      return counters;
    }

    /*
     *  Create the required counters
     */
    counters = new ArrayList<ICounter>();

    /* String values for names */
    String switchIdHex = sw.getStringId();
    String packetName = m.getType().toClass().getName();
    packetName = packetName.substring(packetName.lastIndexOf('.') + 1);

    String controllerFMCounterName =
        CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName);
    counters.add(createCounter(controllerFMCounterName, CounterValue.CounterType.LONG));

    String switchFMCounterName = CounterStore.createCounterName(switchIdHex, -1, packetName);
    counters.add(createCounter(switchFMCounterName, CounterValue.CounterType.LONG));

    /* Add to map and return */
    this.pktremoteCounters.putIfAbsent(countersKey, counters);
    return this.pktremoteCounters.get(countersKey);
  }
Пример #7
0
  @Override
  public void write(OFMessage m, FloodlightContext bc) throws IOException {
    Map<IOFSwitch, List<OFMessage>> msg_buffer_map = local_msg_buffer.get();
    List<OFMessage> msg_buffer = msg_buffer_map.get(this);
    if (msg_buffer == null) {
      msg_buffer = new ArrayList<OFMessage>();
      msg_buffer_map.put(this, msg_buffer);
    }

    this.floodlightProvider.handleOutgoingMessage(this, m, bc);
    msg_buffer.add(m);

    if ((msg_buffer.size() >= Controller.BATCH_MAX_SIZE)
        || ((m.getType() != OFType.PACKET_OUT) && (m.getType() != OFType.FLOW_MOD))) {
      this.write(msg_buffer);
      msg_buffer.clear();
    }
  }
    @Override
    public void run() {

      while (true) {
        try {
          SwitchEvent ev = switchEvents.take();
          SwitchEvent.SwitchEventType eType = ev.getEventType();
          ISwitch sw = ev.getSwitch();
          switch (eType) {
            case SWITCH_ADD:
              Long sid = sw.getId();
              ISwitch existingSwitch = switches.get(sid);
              if (existingSwitch != null) {
                logger.info("Replacing existing {} with New {}", existingSwitch, sw);
                disconnectSwitch(existingSwitch);
              }
              switches.put(sid, sw);
              notifySwitchAdded(sw);
              break;
            case SWITCH_DELETE:
              disconnectSwitch(sw);
              break;
            case SWITCH_ERROR:
              disconnectSwitch(sw);
              break;
            case SWITCH_MESSAGE:
              OFMessage msg = ev.getMsg();
              if (msg != null) {
                IMessageListener listener = messageListeners.get(msg.getType());
                if (listener != null) {
                  listener.receive(sw, msg);
                }
              }
              break;
            default:
              logger.error("Unknown switch event {}", eType.ordinal());
          }
        } catch (InterruptedException e) {
          switchEvents.clear();
          return;
        }
      }
    }
  @Override
  public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
    switch (msg.getType()) {
      case PACKET_IN:
        return this.processPacketInMessage(sw, (OFPacketIn) msg, cntx);
      default:
        break;
    }

    return Command.CONTINUE;
  }
Пример #10
0
 @Override
 public void deliverOFFeaturesReply(OFMessage reply) {
   OFFeaturesReplyFuture future = this.featuresFutureMap.get(reply.getXid());
   if (future != null) {
     future.deliverFuture(this, reply);
     // The future will ultimately unregister itself and call
     // cancelFeaturesReply
     return;
   }
   log.error("Switch {}: received unexpected featureReply", this);
 }
Пример #11
0
  @Override
  public Command receive(IOFSwitch sw, OFMessage msg, FloodlightContext cntx) {
    switch (msg.getType()) {
      case PACKET_IN:
        IRoutingDecision decision = null;
        if (cntx != null)
          decision = IRoutingDecision.rtStore.get(cntx, IRoutingDecision.CONTEXT_DECISION);

        return this.processPacketInMessage(sw, (OFPacketIn) msg, decision, cntx);
      default:
        break;
    }
    return Command.CONTINUE;
  }
Пример #12
0
  protected String getCountersKey(IOFSwitch sw, OFMessage m, Ethernet eth) {
    byte mtype = m.getType().getTypeValue();
    // long swid = sw.getId();
    String swsid = sw.getStringId();
    short port = 0;
    short l3type = 0;
    byte l4type = 0;

    if (eth != null) {
      // Packet in counters
      // Need port and protocol level differentiation
      OFPacketIn packet = (OFPacketIn) m;
      port = packet.getInPort();
      l3type = eth.getEtherType();
      if (l3type == (short) 0x0800) {
        IPv4 ipV4 = (IPv4) eth.getPayload();
        l4type = ipV4.getProtocol();
      }
    }

    /* If possible, find and return counters for this tuple
     *
     * NOTE: this can be converted to a tuple for better performance,
     * for now we are using a string representation as a the key
     */
    String countersKey =
        Byte.toString(mtype)
            + "-"
            + swsid
            + "-"
            + Short.toString(port)
            + "-"
            + Short.toString(l3type)
            + "-"
            + Byte.toString(l4type);
    return countersKey;
  }
Пример #13
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())
    }
  }
Пример #14
0
  private void handleIOEvent(FVIOEvent e) {
    if (!this.isConnected) {
      try {
        if (!this.sock.finishConnect()) return; // not done yet

      } catch (IOException e1) {
        FVLog.log(
            LogLevel.DEBUG,
            this,
            "retrying connection in ",
            this.reconnectSeconds,
            " seconds; got: ",
            e1);
        this.reconnectLater();
        return;
      }
      FVLog.log(LogLevel.DEBUG, this, "connected");
      this.isConnected = true;
      this.connectCount++;
      HashMap<String, Object> info = this.getStatusInfo();
      TopologyController tc = TopologyController.getRunningInstance();
      if (tc != null)
        tc.sliceConnectionJustChanged(info, TopologyCallback.EventType.SLICE_CONNECTED);
      this.reconnectSeconds = 0;
      try {
        msgStream = new FVMessageAsyncStream(this.sock, new FVMessageFactory(), this, this.stats);
      } catch (IOException e1) {
        FVLog.log(
            LogLevel.WARN,
            this,
            "Trying again later; while creating OFMessageAsyncStream, got: ",
            e1);
        this.reconnectLater();
        return;
      }
      sendMsg(new OFHello(), this); // send initial handshake
    }
    try {
      if (msgStream.needsFlush()) // flush any pending messages
      msgStream.flush();
      List<OFMessage> msgs = this.msgStream.read();
      // .read(FVSlicer.MessagesPerRead); // read any new
      // messages
      if (msgs == null) throw new IOException("got null from read()");
      for (OFMessage msg : msgs) {
        FVLog.log(LogLevel.DEBUG, this, "recv from controller: ", msg);
        this.stats.increment(FVStatsType.SEND, this, msg);
        if ((msg instanceof SanityCheckable) && (!((SanityCheckable) msg).isSane())) {
          FVLog.log(LogLevel.CRIT, this, "msg failed sanity check; dropping: " + msg);
          continue;
        }
        if (msg instanceof Slicable) {
          // mark this channel as still alive
          this.keepAlive.registerPong();
          if (msg.getType() != OFType.HELLO && !fvClassifier.isRateLimited(this.getSliceName())) {
            FVLog.log(
                LogLevel.WARN,
                this,
                "dropping msg because slice",
                this.getSliceName(),
                " is rate limited: ",
                msg);
            this.sendMsg(FVMessageUtil.makeErrorMsg(OFBadRequestCode.OFPBRC_EPERM, msg), this);

            continue;
          }
          ((Slicable) msg).sliceFromController(fvClassifier, this);

        } else
          FVLog.log(LogLevel.CRIT, this, "dropping msg that doesn't implement classify: ", msg);
      }
    } catch (IOException e1) {
      FVLog.log(LogLevel.WARN, this, "got i/o error; tearing down and reconnecting: ", e1);
      reconnect();
    } catch (Exception e2) {
      e2.printStackTrace();
      FVLog.log(LogLevel.ALERT, this, "got unknown error; tearing down and reconnecting: ", e2);

      reconnect();
    }
    // no need to setup for next select; done in eventloop
  }
 public void takeSwitchEventMsg(ISwitch sw, OFMessage msg) {
   if (messageListeners.get(msg.getType()) != null) {
     SwitchEvent ev = new SwitchEvent(SwitchEvent.SwitchEventType.SWITCH_MESSAGE, sw, msg);
     addSwitchEvent(ev);
   }
 }
Пример #16
0
  protected List<ICounter> getPacketInCounters(IOFSwitch sw, OFMessage m, Ethernet eth) {
    /* If possible, find and return counters for this tuple */
    String countersKey = this.getCountersKey(sw, m, eth);
    List<ICounter> counters = this.pktinCounters.get(countersKey);
    if (counters != null) {
      return counters;
    }

    /*
     *  Create the required counters
     */
    counters = new ArrayList<ICounter>();

    /* values for names */
    short port = ((OFPacketIn) m).getInPort();
    short l3type = eth.getEtherType();
    String switchIdHex = sw.getStringId();
    String etherType = String.format("%04x", eth.getEtherType());
    String packetName = m.getType().toClass().getName();
    packetName = packetName.substring(packetName.lastIndexOf('.') + 1);

    // L2 Type
    String l2Type = null;
    if (eth.isBroadcast()) {
      l2Type = BROADCAST;
    } else if (eth.isMulticast()) {
      l2Type = MULTICAST;
    } else {
      l2Type = UNICAST;
    }

    /*
     * Use alias for L3 type
     * Valid EtherType must be greater than or equal to 0x0600
     * It is V1 Ethernet Frame if EtherType < 0x0600
     */
    if (l3type < 0x0600) {
      etherType = "0599";
    }
    if (TypeAliases.l3TypeAliasMap != null && TypeAliases.l3TypeAliasMap.containsKey(etherType)) {
      etherType = TypeAliases.l3TypeAliasMap.get(etherType);
    } else {
      etherType = "L3_" + etherType;
    }

    // overall controller packet counter names
    String controllerCounterName = CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName);
    counters.add(createCounter(controllerCounterName, CounterType.LONG));

    String switchCounterName = CounterStore.createCounterName(switchIdHex, -1, packetName);
    counters.add(createCounter(switchCounterName, CounterType.LONG));

    String portCounterName = CounterStore.createCounterName(switchIdHex, port, packetName);
    counters.add(createCounter(portCounterName, CounterType.LONG));

    // L2 counter names
    String controllerL2CategoryCounterName =
        CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName, l2Type, NetworkLayer.L2);
    counters.add(createCounter(controllerL2CategoryCounterName, CounterType.LONG));

    String switchL2CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, -1, packetName, l2Type, NetworkLayer.L2);
    counters.add(createCounter(switchL2CategoryCounterName, CounterType.LONG));

    String portL2CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, port, packetName, l2Type, NetworkLayer.L2);
    counters.add(createCounter(portL2CategoryCounterName, CounterType.LONG));

    // L3 counter names
    String controllerL3CategoryCounterName =
        CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName, etherType, NetworkLayer.L3);
    counters.add(createCounter(controllerL3CategoryCounterName, CounterType.LONG));

    String switchL3CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, -1, packetName, etherType, NetworkLayer.L3);
    counters.add(createCounter(switchL3CategoryCounterName, CounterType.LONG));

    String portL3CategoryCounterName =
        CounterStore.createCounterName(switchIdHex, port, packetName, etherType, NetworkLayer.L3);
    counters.add(createCounter(portL3CategoryCounterName, CounterType.LONG));

    // L4 counters
    if (l3type == (short) 0x0800) {

      // resolve protocol alias
      IPv4 ipV4 = (IPv4) eth.getPayload();
      String l4name = String.format("%02x", ipV4.getProtocol());
      if (TypeAliases.l4TypeAliasMap != null && TypeAliases.l4TypeAliasMap.containsKey(l4name)) {
        l4name = TypeAliases.l4TypeAliasMap.get(l4name);
      } else {
        l4name = "L4_" + l4name;
      }

      // create counters
      String controllerL4CategoryCounterName =
          CounterStore.createCounterName(CONTROLLER_NAME, -1, packetName, l4name, NetworkLayer.L4);
      counters.add(createCounter(controllerL4CategoryCounterName, CounterType.LONG));

      String switchL4CategoryCounterName =
          CounterStore.createCounterName(switchIdHex, -1, packetName, l4name, NetworkLayer.L4);
      counters.add(createCounter(switchL4CategoryCounterName, CounterType.LONG));

      String portL4CategoryCounterName =
          CounterStore.createCounterName(switchIdHex, port, packetName, l4name, NetworkLayer.L4);
      counters.add(createCounter(portL4CategoryCounterName, CounterType.LONG));
    }

    /* Add to map and return */
    this.pktinCounters.putIfAbsent(countersKey, counters);
    return this.pktinCounters.get(countersKey);
  }