예제 #1
0
  /**
   * Returns current typed flow entry's polling interval.
   *
   * @param tfe typed flow entry
   */
  public static long typedPollInterval(TypedStoredFlowEntry tfe) {
    checkNotNull(tfe, "TypedStoredFlowEntry cannot be null");

    switch (tfe.flowLiveType()) {
      case LONG_FLOW:
        return LONG_POLL_INTERVAL;
      case MID_FLOW:
        return MID_POLL_INTERVAL;
      case SHORT_FLOW:
      case IMMEDIATE_FLOW:
      default:
        return CAL_AND_POLL_INTERVAL;
    }
  }
    // In real, calculates and set the flow live type at the first time,
    // and then add it into a corresponding typed flow table
    private void calAndSetFlowLiveTypeInternal(TypedStoredFlowEntry rule) {
      long life = rule.life();
      FlowLiveType prevFlowLiveType = rule.flowLiveType();

      if (life >= longPollInterval) {
        rule.setFlowLiveType(FlowLiveType.LONG_FLOW);
        longFlows.add(rule);
      } else if (life >= midPollInterval) {
        rule.setFlowLiveType(FlowLiveType.MID_FLOW);
        midFlows.add(rule);
      } else if (life >= calAndPollInterval) {
        rule.setFlowLiveType(FlowLiveType.SHORT_FLOW);
        shortFlows.add(rule);
      } else if (life >= 0) {
        rule.setFlowLiveType(FlowLiveType.IMMEDIATE_FLOW);
      } else { // life < 0
        rule.setFlowLiveType(FlowLiveType.UNKNOWN_FLOW);
      }

      if (rule.flowLiveType() != prevFlowLiveType) {
        switch (prevFlowLiveType) {
            // delete it from previous flow table
          case SHORT_FLOW:
            shortFlows.remove(rule);
            break;
          case MID_FLOW:
            midFlows.remove(rule);
            break;
          case LONG_FLOW:
            longFlows.remove(rule);
            break;
          default:
            break;
        }
      }
    }
 // Remove the typed flow entry from corresponding table
 private void removeLiveFlowsInternal(TypedStoredFlowEntry fe) {
   switch (fe.flowLiveType()) {
     case IMMEDIATE_FLOW:
       // do nothing
       break;
     case SHORT_FLOW:
       shortFlows.remove(fe);
       break;
     case MID_FLOW:
       midFlows.remove(fe);
       break;
     case LONG_FLOW:
       longFlows.remove(fe);
       break;
     default: // error in Flow Live Type
       log.error("removeLiveFlowsInternal, Unknown Live Type error!");
       break;
   }
 }
    // check the flow live type based on current time, then set and add it into corresponding table
    private boolean checkAndMoveLiveFlowInternal(TypedStoredFlowEntry fe, long cTime) {
      long curTime = (cTime > 0 ? cTime : System.currentTimeMillis());
      // For latency adjustment(default=500 millisecond) between FlowStatsRequest and Reply
      long fromLastSeen =
          ((curTime - fe.lastSeen() + latencyFlowStatsRequestAndReplyMillis) / 1000);
      // fe.life() unit is SECOND!
      long liveTime = fe.life() + fromLastSeen;

      switch (fe.flowLiveType()) {
        case IMMEDIATE_FLOW:
          if (liveTime >= longPollInterval) {
            fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
            longFlows.add(fe);
          } else if (liveTime >= midPollInterval) {
            fe.setFlowLiveType(FlowLiveType.MID_FLOW);
            midFlows.add(fe);
          } else if (liveTime >= calAndPollInterval) {
            fe.setFlowLiveType(FlowLiveType.SHORT_FLOW);
            shortFlows.add(fe);
          }
          break;
        case SHORT_FLOW:
          if (liveTime >= longPollInterval) {
            fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
            shortFlows.remove(fe);
            longFlows.add(fe);
          } else if (liveTime >= midPollInterval) {
            fe.setFlowLiveType(FlowLiveType.MID_FLOW);
            shortFlows.remove(fe);
            midFlows.add(fe);
          }
          break;
        case MID_FLOW:
          if (liveTime >= longPollInterval) {
            fe.setFlowLiveType(FlowLiveType.LONG_FLOW);
            midFlows.remove(fe);
            longFlows.add(fe);
          }
          break;
        case LONG_FLOW:
          if (fromLastSeen > entirePollInterval) {
            log.trace("checkAndMoveLiveFlowInternal, flow is already removed at switch.");
            return false;
          }
          break;
        case UNKNOWN_FLOW: // Unknown flow is an internal error flow type, just fall through
        default:
          // Error Unknown Live Type
          log.error(
              "checkAndMoveLiveFlowInternal, Unknown Live Type error!"
                  + "AdaptiveStats collection thread for {}",
              sw.getStringId());
          return false;
      }

      log.debug(
          "checkAndMoveLiveFlowInternal, FlowId="
              + Long.toHexString(fe.id().value())
              + ", state="
              + fe.state()
              + ", After liveType="
              + fe.flowLiveType()
              + ", liveTime="
              + liveTime
              + ", life="
              + fe.life()
              + ", bytes="
              + fe.bytes()
              + ", packets="
              + fe.packets()
              + ", fromLastSeen="
              + fromLastSeen
              + ", priority="
              + fe.priority()
              + ", selector="
              + fe.selector().criteria()
              + ", treatment="
              + fe.treatment()
              + " AdaptiveStats collection thread for {}",
          sw.getStringId());

      return true;
    }