예제 #1
0
 public boolean remove(DeviceId deviceId, FlowEntry rule) {
   try {
     return getFlowEntriesInternal(deviceId, rule.id()).remove(rule);
   } finally {
     lastUpdateTimes.put(deviceId, System.currentTimeMillis());
   }
 }
예제 #2
0
  private FlowRuleEvent addOrUpdateFlowRuleInternal(FlowEntry rule) {
    // check if this new rule is an update to an existing entry
    StoredFlowEntry stored = flowTable.getFlowEntry(rule);
    if (stored != null) {
      stored.setBytes(rule.bytes());
      stored.setLife(rule.life());
      stored.setPackets(rule.packets());
      if (stored.state() == FlowEntryState.PENDING_ADD) {
        stored.setState(FlowEntryState.ADDED);
        return new FlowRuleEvent(Type.RULE_ADDED, rule);
      }
      return new FlowRuleEvent(Type.RULE_UPDATED, rule);
    }

    // TODO: Confirm if this behavior is correct. See SimpleFlowRuleStore
    // TODO: also update backup if the behavior is correct.
    flowTable.add(rule);
    return null;
  }
예제 #3
0
  @Override
  public FlowRuleEvent addOrUpdateFlowRule(FlowEntry rule) {
    NodeId master = mastershipService.getMasterFor(rule.deviceId());
    if (Objects.equal(local, master)) {
      return addOrUpdateFlowRuleInternal(rule);
    }

    log.warn("Tried to update FlowRule {} state," + " while the Node was not the master.", rule);
    return null;
  }
  // send openflow flow stats request message with getting the specific flow entry(fe) to a given
  // switch sw
  private void ofFlowStatsRequestFlowSend(FlowEntry fe) {
    // set find match
    Match match =
        FlowModBuilder.builder(fe, sw.factory(), Optional.empty(), Optional.of(driverService))
            .buildMatch();
    // set find tableId
    TableId tableId = TableId.of(fe.tableId());
    // set output port
    Instruction ins =
        fe.treatment()
            .allInstructions()
            .stream()
            .filter(i -> (i.type() == Instruction.Type.OUTPUT))
            .findFirst()
            .orElse(null);
    OFPort ofPort = OFPort.NO_MASK;
    if (ins != null) {
      Instructions.OutputInstruction out = (Instructions.OutputInstruction) ins;
      ofPort = OFPort.of((int) ((out.port().toLong())));
    }

    OFFlowStatsRequest request =
        sw.factory()
            .buildFlowStatsRequest()
            .setMatch(match)
            .setTableId(tableId)
            .setOutPort(ofPort)
            .build();

    synchronized (this) {
      if (getFlowMissingXid() != NO_FLOW_MISSING_XID) {
        log.debug(
            "ofFlowStatsRequestFlowSend: previous FlowStatsRequestAll does not be processed yet,"
                + " set no flow missing xid anyway, for {}",
            sw.getStringId());
        setFlowMissingXid(NO_FLOW_MISSING_XID);
      }

      sw.sendMsg(request);
    }
  }
예제 #5
0
  /**
   * Creates a new typed flow entry with the given flow entry fe.
   *
   * @param fe flow entry
   */
  public static TypedStoredFlowEntry newTypedStoredFlowEntry(FlowEntry fe) {
    if (fe == null) {
      return null;
    }

    long life = fe.life();

    if (life >= LONG_POLL_INTERVAL) {
      return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.LONG_FLOW);
    } else if (life >= MID_POLL_INTERVAL) {
      return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.MID_FLOW);
    } else if (life >= CAL_AND_POLL_INTERVAL) {
      return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.SHORT_FLOW);
    } else if (life >= 0) {
      return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.IMMEDIATE_FLOW);
    } else { // life < 0
      return new DefaultTypedFlowEntry(fe, TypedStoredFlowEntry.FlowLiveType.UNKNOWN_FLOW);
    }
  }
  /**
   * add or update typed flow entry from flow entry into the internal flow table.
   *
   * @param flowEntries the flow entries
   */
  public synchronized void addOrUpdateFlows(FlowEntry... flowEntries) {
    for (FlowEntry fe : flowEntries) {
      // check if this new rule is an update to an existing entry
      TypedStoredFlowEntry stored = deviceFlowTable.getFlowEntry(fe);

      if (stored != null) {
        // duplicated flow entry is collected!, just skip
        if (fe.bytes() == stored.bytes()
            && fe.packets() == stored.packets()
            && fe.life() == stored.life()) {
          log.debug(
              "addOrUpdateFlows:, FlowId="
                  + Long.toHexString(fe.id().value())
                  + ",is DUPLICATED stats collection, just skip."
                  + " AdaptiveStats collection thread for {}",
              sw.getStringId());

          // FIXME modification of "stored" flow entry outside of store
          stored.setLastSeen();
          continue;
        } else if (fe.life() < stored.life()) {
          // Invalid updates the stats values, i.e., bytes, packets, durations ...
          log.debug(
              "addOrUpdateFlows():"
                  + " Invalid Flow Update! The new life is SMALLER than the previous one, jus skip."
                  + " new flowId="
                  + Long.toHexString(fe.id().value())
                  + ", old flowId="
                  + Long.toHexString(stored.id().value())
                  + ", new bytes="
                  + fe.bytes()
                  + ", old bytes="
                  + stored.bytes()
                  + ", new life="
                  + fe.life()
                  + ", old life="
                  + stored.life()
                  + ", new lastSeen="
                  + fe.lastSeen()
                  + ", old lastSeen="
                  + stored.lastSeen());
          // go next
          // FIXME modification of "stored" flow entry outside of store
          stored.setLastSeen();
          continue;
        }

        // update now
        // FIXME modification of "stored" flow entry outside of store
        stored.setLife(fe.life());
        stored.setPackets(fe.packets());
        stored.setBytes(fe.bytes());
        stored.setLastSeen();
        if (stored.state() == FlowEntry.FlowEntryState.PENDING_ADD) {
          // flow is really RULE_ADDED
          stored.setState(FlowEntry.FlowEntryState.ADDED);
        }
        // flow is RULE_UPDATED, skip adding and just updating flow live table
        // deviceFlowTable.calAndSetFlowLiveType(stored);
        continue;
      }

      // add new flow entry, we suppose IMMEDIATE_FLOW
      TypedStoredFlowEntry newFlowEntry =
          new DefaultTypedFlowEntry(fe, FlowLiveType.IMMEDIATE_FLOW);
      deviceFlowTable.addWithCalAndSetFlowLiveType(newFlowEntry);
    }
  }
예제 #7
0
 public TypedFlowEntryWithLoad(ConnectPoint cp, FlowEntry fe) {
   this.cp = cp;
   this.tfe = newTypedStoredFlowEntry(fe);
   this.load = new DefaultLoad(fe.bytes(), 0, typedPollInterval(this.tfe));
 }
  @Override
  public synchronized void updateFlowStatistic(FlowEntry rule) {
    ConnectPoint cp = buildConnectPoint(rule);
    if (cp == null) {
      return;
    }

    Set<FlowEntry> curr = current.get(cp);
    if (curr == null) {
      addFlowStatistic(rule);
    } else {
      Optional<FlowEntry> f = curr.stream().filter(c -> rule.equals(c)).findAny();
      if (f.isPresent() && rule.bytes() < f.get().bytes()) {
        log.debug(
            "DistributedFlowStatisticStore:updateFlowStatistic():"
                + " Invalid Flow Update! Will be removed!!"
                + " curr flowId="
                + Long.toHexString(rule.id().value())
                + ", prev flowId="
                + Long.toHexString(f.get().id().value())
                + ", curr bytes="
                + rule.bytes()
                + ", prev bytes="
                + f.get().bytes()
                + ", curr life="
                + rule.life()
                + ", prev life="
                + f.get().life()
                + ", curr lastSeen="
                + rule.lastSeen()
                + ", prev lastSeen="
                + f.get().lastSeen());
        // something is wrong! invalid flow entry, so delete it
        removeFlowStatistic(rule);
        return;
      }
      Set<FlowEntry> prev = previous.get(cp);
      if (prev == null) {
        prev = new HashSet<>();
        previous.put(cp, prev);
      }

      // previous one is exist
      if (f.isPresent()) {
        // remove old one and add new one
        prev.remove(rule);
        if (!prev.add(f.get())) {
          log.debug(
              "DistributedFlowStatisticStore:updateFlowStatistic():"
                  + " flowId={}, add failed into previous.",
              Long.toHexString(rule.id().value()));
        }
      }

      // remove old one and add new one
      curr.remove(rule);
      if (!curr.add(rule)) {
        log.debug(
            "DistributedFlowStatisticStore:updateFlowStatistic():"
                + " flowId={}, add failed into current.",
            Long.toHexString(rule.id().value()));
      }
    }
  }
예제 #9
0
 public void add(FlowEntry rule) {
   getFlowEntriesInternal(rule.deviceId(), rule.id()).add((StoredFlowEntry) rule);
   lastUpdateTimes.put(rule.deviceId(), System.currentTimeMillis());
 }
예제 #10
0
 private FlowRuleEvent removeFlowRuleInternal(FlowEntry rule) {
   final DeviceId deviceId = rule.deviceId();
   // This is where one could mark a rule as removed and still keep it in the store.
   final boolean removed = flowTable.remove(deviceId, rule); // flowEntries.remove(deviceId, rule);
   return removed ? new FlowRuleEvent(RULE_REMOVED, rule) : null;
 }
예제 #11
-1
  @Override
  public FlowRuleEvent removeFlowRule(FlowEntry rule) {
    final DeviceId deviceId = rule.deviceId();
    NodeId master = mastershipService.getMasterFor(deviceId);

    if (Objects.equal(local, master)) {
      // bypass and handle it locally
      return removeFlowRuleInternal(rule);
    }

    if (master == null) {
      log.warn("Failed to removeFlowRule: No master for {}", deviceId);
      // TODO: revisit if this should be null (="no-op") or Exception
      return null;
    }

    log.trace(
        "Forwarding removeFlowRule to {}, which is the master for device {}", master, deviceId);

    return Futures.get(
        clusterCommunicator.sendAndReceive(
            rule, REMOVE_FLOW_ENTRY, SERIALIZER::encode, SERIALIZER::decode, master),
        FLOW_RULE_STORE_TIMEOUT_MILLIS,
        TimeUnit.MILLISECONDS,
        RuntimeException.class);
  }