/**
   * match is called when a switch sends a packet in to the controller. The goal is to find all flow
   * space rules which match the fields of the packet in.
   *
   * @param dpid - the datapath id of the switch which sent the packet in.
   * @param match - the packet in information
   * @return a list, sorted by priority, of flow space rules which match.
   */
  public List<FlowEntry> match(long dpid, FVMatch match) {
    BitSet set = new BitSet();
    LinkedList<FlowEntry> flowrules = new LinkedList<FlowEntry>();
    int wildcards = match.getWildcards();
    FVLog.log(LogLevel.DEBUG, null, "dpid: ", dpid, "match: ", match.toString());

    set.or(allRules);
    FVLog.log(LogLevel.DEBUG, null, "allRules: ", set.toString());

    try {

      testEmpty(set, dpids, dpid, FlowEntry.ALL_DPIDS, wildcards, 0);
      /*
       * Test every field and intersect the resulting bitset. If the bit
       * set is empty an exception is thrown to stop the search.
       */
      testEmpty(set, port, match.getInputPort(), ANY_IN_PORT, wildcards, FVMatch.OFPFW_IN_PORT);
      if (match.getDataLayerVirtualLan() != ANY_VLAN_ID) {
        testEmpty(
            set,
            vlan,
            (int) match.getDataLayerVirtualLan(),
            (int) ANY_VLAN_ID,
            wildcards,
            FVMatch.OFPFW_DL_VLAN);
        testEmpty(
            set,
            vlan,
            match.getDataLayerVirtualLanPriorityCodePoint() << 16,
            ANY_VLAN_PCP << 16,
            wildcards,
            FVMatch.OFPFW_DL_VLAN_PCP);
      } else {

        set.andNot(vlan_ignore);
      }

      testEmpty(
          set, dl_type, match.getDataLayerType(), ANY_ETHER, wildcards, FVMatch.OFPFW_DL_TYPE);

      testEmpty(
          set,
          nw,
          (short) match.getNetworkProtocol(),
          (short) ANY_NW_PROTO_TOS,
          wildcards,
          FVMatch.OFPFW_NW_PROTO);

      testEmpty(
          set,
          nw,
          (short) (match.getNetworkTypeOfService() << 8),
          (short) (ANY_NW_PROTO_TOS << 8),
          wildcards,
          FVMatch.OFPFW_NW_TOS);

      testEmpty(
          set, tp, (int) match.getTransportSource(), (int) ANY_TP, wildcards, FVMatch.OFPFW_TP_SRC);

      testEmpty(
          set,
          tp,
          match.getTransportDestination() << 16,
          ANY_TP << 16,
          wildcards,
          FVMatch.OFPFW_TP_DST);

      testEmpty(
          set,
          dl_src,
          FVMatch.toLong(match.getDataLayerSource()),
          ANY_MAC,
          wildcards,
          FVMatch.OFPFW_DL_SRC);

      testEmpty(
          set,
          dl_dst,
          FVMatch.toLong(match.getDataLayerDestination()),
          ANY_MAC,
          wildcards,
          FVMatch.OFPFW_DL_DST);

      for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) {
        FlowEntry fe = rules.get(i);
        FVMatch ruleMatch = fe.getRuleMatch();
        FlowIntersect inter;
        inter = new FlowIntersect(fe.clone());

        FVMatch interMatch = inter.getMatch();
        interMatch.setNetworkDestination(
            testIP(
                inter,
                FVMatch.OFPFW_NW_DST_SHIFT,
                match.getNetworkDestinationMaskLen(),
                ruleMatch.getNetworkDestinationMaskLen(),
                match.getNetworkDestination(),
                ruleMatch.getNetworkDestination()));
        if (inter.getMatchType() == MatchType.NONE) {
          set.clear(i);
          continue;
        }

        // test ip_src
        interMatch.setNetworkSource(
            testIP(
                inter,
                FVMatch.OFPFW_NW_SRC_SHIFT,
                match.getNetworkSourceMaskLen(),
                ruleMatch.getNetworkSourceMaskLen(),
                match.getNetworkSource(),
                ruleMatch.getNetworkSource()));
        if (inter.getMatchType() == MatchType.NONE) {
          set.clear(i);
          continue;
        }
      }

    } catch (NoMatch e) {
      FVLog.log(LogLevel.INFO, null, "No match for: ", match);
      return flowrules;
    }

    /*
     * If we got here we have a match. Now return a prioritized list of
     * matches.
     *
     * Higher numbers have higher priorities.
     */

    TreeSet<FlowEntry> entries = new TreeSet<FlowEntry>();
    for (int i = set.nextSetBit(0); i >= 0; i = set.nextSetBit(i + 1)) {
      entries.add(rules.get(i));
    }
    flowrules.addAll(entries);
    return flowrules;
  }
示例#2
0
 /*
  * (non-Javadoc)
  *
  * @see java.lang.Object#clone()
  */
 @Override
 public FlowMap clone() {
   LinearFlowMap flowMap = new LinearFlowMap();
   for (FlowEntry flowEntry : this.rules) flowMap.addRule(flowEntry.clone());
   return flowMap;
 }