@Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; OFFlowStatsEntryVer10 other = (OFFlowStatsEntryVer10) obj; if (tableId == null) { if (other.tableId != null) return false; } else if (!tableId.equals(other.tableId)) return false; if (match == null) { if (other.match != null) return false; } else if (!match.equals(other.match)) return false; if (durationSec != other.durationSec) return false; if (durationNsec != other.durationNsec) return false; if (priority != other.priority) return false; if (idleTimeout != other.idleTimeout) return false; if (hardTimeout != other.hardTimeout) return false; if (cookie == null) { if (other.cookie != null) return false; } else if (!cookie.equals(other.cookie)) return false; if (packetCount == null) { if (other.packetCount != null) return false; } else if (!packetCount.equals(other.packetCount)) return false; if (byteCount == null) { if (other.byteCount != null) return false; } else if (!byteCount.equals(other.byteCount)) return false; if (actions == null) { if (other.actions != null) return false; } else if (!actions.equals(other.actions)) return false; return true; }
/** * Checks for "ANY" values that should be wildcards but aren't, such as NW_SRC/DST 0.0.0.0, and * TCP/UDP port 0. * * @param omatch The OFMatch of the FlowMod we are comparing entries against * @param owcard The wildcard field of the FlowMod. * @return the modified wildcard value (a copy). */ private int convertToWcards(Match omatch) { int owcard = 0; for (MatchField<?> mf : omatch.getMatchFields()) { owcard |= 1 << mf.id.ordinal(); } // ASK ABOUT THIS BEHAVIOR, IS IT CORRECT THIS WAY? if (omatch.isFullyWildcarded(MatchField.IPV4_DST)) { // owcard |= Match.OFPFW_NW_DST_ALL | Match.OFPFW_NW_DST_MASK; owcard |= MatchField.IPV4_DST.id.ordinal(); } if (omatch.isFullyWildcarded(MatchField.IPV4_SRC)) { // owcard |= Match.OFPFW_NW_SRC_ALL | Match.OFPFW_NW_SRC_MASK; owcard |= MatchField.IPV4_SRC.id.ordinal(); } if (omatch.isFullyWildcarded(MatchField.IP_PROTO)) { // owcard |= Match.OFPFW_NW_PROTO; owcard |= MatchField.IP_PROTO.id.ordinal(); } if (omatch.isFullyWildcarded(MatchField.TCP_DST)) { // owcard |= Match.OFPFW_TP_DST; owcard |= MatchField.TCP_DST.id.ordinal(); } if (omatch.isFullyWildcarded(MatchField.TCP_SRC)) { // owcard |= Match.OFPFW_TP_SRC; owcard |= MatchField.TCP_SRC.id.ordinal(); } return owcard; }
@Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((tableId == null) ? 0 : tableId.hashCode()); result = prime * result + ((match == null) ? 0 : match.hashCode()); result = prime * (int) (durationSec ^ (durationSec >>> 32)); result = prime * (int) (durationNsec ^ (durationNsec >>> 32)); result = prime * result + priority; result = prime * result + idleTimeout; result = prime * result + hardTimeout; result = prime * result + ((cookie == null) ? 0 : cookie.hashCode()); result = prime * result + ((packetCount == null) ? 0 : packetCount.hashCode()); result = prime * result + ((byteCount == null) ? 0 : byteCount.hashCode()); result = prime * result + ((actions == null) ? 0 : actions.hashCode()); return result; }
/** * Compares this entry against another, and tries to determine if it is a superset, subset, or * equal to it. Required for non-strict matching and overlap checking * * <p>For each field, we first check wildcard equality. If both are equal, they are either 1 or 0. * If 0, we further check for field equality. If the fields are not equal, the flow entries are * considered disjoint and we exit comparison. * * <p>If both wildcards are not equal, we check if one subsumes the other. * * <p>The result is tracked for each field in three ints - equality, superset, and subset. At the * end, either 1) one of the ints are 0x3fffff, or 2) none are. * * @param omatch The other FlowEntry to compare this one against. * @param strict whether FlowMod from which the match came was strict or not. * @return Union enum representing the relationship */ public int compare(Match omatch, boolean strict) { // to allow pass by reference...in order: equal, superset, subset int[] intersect = new int[] {0, 0, 0}; Match tmatch = this.flowmod.getMatch(); int twcard = this.convertToWcards(tmatch); int owcard = this.convertToWcards(omatch); /* inport */ if (tmatch.isFullyWildcarded(MatchField.IN_PORT) == omatch.isFullyWildcarded(MatchField.IN_PORT)) { if (findDisjoint( twcard, MatchField.IN_PORT.id.ordinal(), intersect, tmatch.get(MatchField.IN_PORT).getPortNumber(), omatch.get(MatchField.IN_PORT).getPortNumber())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.IN_PORT.id.ordinal(), intersect); } /* L2 */ if (tmatch.isFullyWildcarded(MatchField.ETH_DST) == omatch.isFullyWildcarded(MatchField.ETH_DST)) { if (findDisjoint( twcard, MatchField.ETH_DST.id.ordinal(), intersect, tmatch.get(MatchField.ETH_DST).getLong(), omatch.get(MatchField.ETH_DST).getLong())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.ETH_DST.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.ETH_SRC) == omatch.isFullyWildcarded(MatchField.ETH_SRC)) { if (findDisjoint( twcard, MatchField.ETH_SRC.id.ordinal(), intersect, tmatch.get(MatchField.ETH_SRC).getLong(), omatch.get(MatchField.ETH_SRC).getLong())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.ETH_SRC.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.ETH_TYPE) == omatch.isFullyWildcarded(MatchField.ETH_TYPE)) { if (findDisjoint( twcard, MatchField.ETH_TYPE.id.ordinal(), intersect, tmatch.get(MatchField.ETH_TYPE).getValue(), omatch.get(MatchField.ETH_TYPE).getValue())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.ETH_TYPE.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.VLAN_VID) == omatch.isFullyWildcarded(MatchField.VLAN_VID)) { if (findDisjoint( twcard, MatchField.VLAN_VID.id.ordinal(), intersect, tmatch.get(MatchField.VLAN_VID).getVlan(), omatch.get(MatchField.VLAN_VID).getVlan())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.VLAN_VID.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.VLAN_PCP) == omatch.isFullyWildcarded(MatchField.VLAN_PCP)) { if (findDisjoint( twcard, MatchField.VLAN_PCP.id.ordinal(), intersect, tmatch.get(MatchField.VLAN_PCP).getValue(), omatch.get(MatchField.VLAN_PCP).getValue())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.VLAN_PCP.id.ordinal(), intersect); } /* L3 */ if (tmatch.isFullyWildcarded(MatchField.IP_PROTO) == omatch.isFullyWildcarded(MatchField.IP_PROTO)) { if (findDisjoint( twcard, MatchField.IP_PROTO.id.ordinal(), intersect, tmatch.get(MatchField.IP_PROTO).getIpProtocolNumber(), omatch.get(MatchField.IP_PROTO).getIpProtocolNumber())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.IP_PROTO.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.IP_DSCP) == omatch.isFullyWildcarded(MatchField.IP_DSCP)) { if (findDisjoint( twcard, MatchField.IP_DSCP.id.ordinal(), intersect, tmatch.get(MatchField.IP_DSCP).getDscpValue(), omatch.get(MatchField.IP_DSCP).getDscpValue())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.IP_DSCP.id.ordinal(), intersect); } // _ALL Flag erased? Normal behavior? if (tmatch.isFullyWildcarded(MatchField.IPV4_SRC) == omatch.isFullyWildcarded(MatchField.IPV4_DST)) { if (findDisjoint( twcard, MatchField.IPV4_SRC.id.ordinal(), intersect, tmatch.get(MatchField.IPV4_SRC).getInt(), omatch.get(MatchField.IPV4_SRC).getInt())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.IPV4_SRC.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.IPV4_DST) == omatch.isFullyWildcarded(MatchField.IPV4_DST)) { if (findDisjoint( twcard, MatchField.IPV4_DST.id.ordinal(), intersect, tmatch.get(MatchField.IPV4_DST).getInt(), omatch.get(MatchField.IPV4_DST).getInt())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.IPV4_DST.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.ARP_SPA) == omatch.isFullyWildcarded(MatchField.ARP_SPA)) { if (findDisjoint( twcard, MatchField.ARP_SPA.id.ordinal(), intersect, tmatch.get(MatchField.ARP_SPA).getInt(), omatch.get(MatchField.ARP_SPA).getInt())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.ARP_SPA.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.ARP_TPA) == omatch.isFullyWildcarded(MatchField.ARP_TPA)) { if (findDisjoint( twcard, MatchField.ARP_TPA.id.ordinal(), intersect, tmatch.get(MatchField.ARP_TPA).getInt(), omatch.get(MatchField.ARP_TPA).getInt())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.ARP_TPA.id.ordinal(), intersect); } /* L4 */ if (tmatch.isFullyWildcarded(MatchField.TCP_SRC) == omatch.isFullyWildcarded(MatchField.TCP_SRC)) { if (findDisjoint( twcard, MatchField.TCP_SRC.id.ordinal(), intersect, tmatch.get(MatchField.TCP_SRC).getPort(), omatch.get(MatchField.TCP_SRC).getPort())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.TCP_SRC.id.ordinal(), intersect); } if (tmatch.isFullyWildcarded(MatchField.TCP_DST) == omatch.isFullyWildcarded(MatchField.TCP_DST)) { if (findDisjoint( twcard, MatchField.TCP_DST.id.ordinal(), intersect, tmatch.get(MatchField.TCP_DST).getPort(), omatch.get(MatchField.TCP_DST).getPort())) { return DISJOINT; } } else { /*check if super or subset*/ findRelation(twcard, owcard, MatchField.TCP_DST.id.ordinal(), intersect); } int equal = intersect[EQUAL]; int superset = intersect[SUPERSET]; int subset = intersect[SUBSET]; if (!strict) { equal |= subset; } // Small hack to find the actual mask int all = 0; for (MatchFields val : MatchFields.values()) { owcard |= 1 << val.ordinal(); } if (equal == all) { return EQUAL; } if (superset == all) { return SUPERSET; } if (subset == all) { return SUBSET; } return INTERSECT; }