private PortNumber getOutput(FlowRule rule) {
   for (Instruction i : rule.treatment().allInstructions()) {
     if (i.type() == Instruction.Type.OUTPUT) {
       Instructions.OutputInstruction out = (Instructions.OutputInstruction) i;
       return out.port();
     }
   }
   return null;
 }
예제 #2
0
  @Override
  public void filter(FilteringObjective filter) {
    Instructions.OutputInstruction output;

    if (filter.meta() != null && !filter.meta().immediate().isEmpty()) {
      output =
          (Instructions.OutputInstruction)
              filter
                  .meta()
                  .immediate()
                  .stream()
                  .filter(t -> t.type().equals(Instruction.Type.OUTPUT))
                  .limit(1)
                  .findFirst()
                  .get();

      if (output == null || !output.port().equals(PortNumber.CONTROLLER)) {
        log.error("OLT can only filter packet to controller");
        fail(filter, ObjectiveError.UNSUPPORTED);
        return;
      }
    } else {
      fail(filter, ObjectiveError.BADPARAMS);
      return;
    }

    if (filter.key().type() != Criterion.Type.IN_PORT) {
      fail(filter, ObjectiveError.BADPARAMS);
      return;
    }

    EthTypeCriterion ethType =
        (EthTypeCriterion) filterForCriterion(filter.conditions(), Criterion.Type.ETH_TYPE);

    if (ethType == null) {
      fail(filter, ObjectiveError.BADPARAMS);
      return;
    }

    if (ethType.ethType().equals(EthType.EtherType.EAPOL.ethType())) {
      provisionEapol(filter, ethType, output);
    } else if (ethType.ethType().equals(EthType.EtherType.IPV4.ethType())) {
      IPProtocolCriterion ipProto =
          (IPProtocolCriterion) filterForCriterion(filter.conditions(), Criterion.Type.IP_PROTO);
      if (ipProto.protocol() == IPv4.PROTOCOL_IGMP) {
        provisionIgmp(filter, ethType, ipProto, output);
      } else {
        log.error("OLT can only filter igmp");
        fail(filter, ObjectiveError.UNSUPPORTED);
      }
    } else {
      log.error("OLT can only filter eapol and igmp");
      fail(filter, ObjectiveError.UNSUPPORTED);
    }
  }
  // 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);
    }
  }