예제 #1
0
 private void sendPortStatusUpdate(OFPhysicalPort phyPort, boolean added) {
   FVPortStatus portStatus = new FVPortStatus();
   portStatus.setDesc(phyPort);
   portStatus.setReason(
       added
           ? (byte) OFPortReason.OFPPR_ADD.ordinal()
           : (byte) OFPortReason.OFPPR_DELETE.ordinal());
   FVLog.log(
       LogLevel.INFO, this, (added ? "added " : "removed ") + "port " + phyPort.getPortNumber());
   sendMsg(portStatus, this);
 }
예제 #2
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
  }
예제 #3
0
  private void lookupByFlowSpace(FVClassifier fvClassifier) {
    SliceAction sliceAction;
    int perms;
    // grab single matching rule: only one because it's a point in flowspace
    FlowEntry flowEntry =
        fvClassifier
            .getSwitchFlowMap()
            .matches(
                fvClassifier.getSwitchInfo().getDatapathId(),
                this.getInPort(),
                this.getPacketData());
    if (flowEntry == null) {
      FVLog.log(
          LogLevel.DEBUG, fvClassifier, "dropping unclassifiable msg: " + this.toVerboseString());
      return;
    }

    boolean foundHome = false;
    // foreach slice in that rule
    for (OFAction ofAction : flowEntry.getActionsList()) {
      sliceAction = (SliceAction) ofAction;
      perms = sliceAction.getSlicePerms();
      if ((perms & (SliceAction.READ | SliceAction.WRITE)) != 0) {
        // lookup slice and send msg to them
        // TODO record buffer id for later validation
        FVSlicer fvSlicer = fvClassifier.getSlicerByName(sliceAction.getSliceName());
        if (fvSlicer == null) {
          FVLog.log(
              LogLevel.WARN,
              fvClassifier,
              "tried to send msg to non-existant slice: "
                  + sliceAction.getSliceName()
                  + " corrupted flowspace?:: "
                  + this.toVerboseString());
          continue;
        }
        if (fvSlicer.isConnected()) {
          if ((perms & SliceAction.WRITE) != 0) fvSlicer.setBufferIDAllowed(this.getBufferId());
          fvSlicer.sendMsg(this, fvClassifier);
          /**
           * TODO : come back and decide if we should uncomment this i.e., should a rule get
           * squashed if it's only recipient is read only
           *
           * <p>if yes, then tests-readonly.py needs to be changed
           */

          // if ((perms & SliceAction.WRITE) != 0)
          foundHome = true;
        } else {
          sendDropRule(fvClassifier, flowEntry, fvSlicer.getSliceName(), (short) 0, (short) 1);
        }
        foundHome = true;
      }
      /*
       * ash: not sure if this is the intended behavior, but I am guessing
       * that if this packet hasn't gotten handled anywhere we should at least
       * default to adding a drop rule for unless we want to be flooded.
       */
      if (!foundHome) sendDropRule(fvClassifier, flowEntry, "exact", (short) 0, (short) 1);
    }
  }