Saurav Das
Committed by Gerrit Code Review

Adding eth masking in match

Change-Id: I95e0ee66b1c6c139de7672f9bc04871fd0ead6d7
......@@ -174,11 +174,21 @@ public final class DefaultTrafficSelector implements TrafficSelector {
}
@Override
public Builder matchEthDstMasked(MacAddress addr, MacAddress mask) {
return add(Criteria.matchEthDstMasked(addr, mask));
}
@Override
public Builder matchEthSrc(MacAddress addr) {
return add(Criteria.matchEthSrc(addr));
}
@Override
public Builder matchEthSrcMasked(MacAddress addr, MacAddress mask) {
return add(Criteria.matchEthSrcMasked(addr, mask));
}
@Override
public Builder matchEthType(short ethType) {
return add(Criteria.matchEthType(ethType));
}
......
......@@ -97,6 +97,15 @@ public interface TrafficSelector {
Builder matchEthDst(MacAddress addr);
/**
* Matches a l2 dst address with mask.
*
* @param addr a l2 address
* @param mask a mask for an l2 address
* @return a selection builder
*/
Builder matchEthDstMasked(MacAddress addr, MacAddress mask);
/**
* Matches a l2 src address.
*
* @param addr a l2 address
......@@ -105,6 +114,15 @@ public interface TrafficSelector {
Builder matchEthSrc(MacAddress addr);
/**
* Matches a l2 src address with mask.
*
* @param addr a l2 address
* @param mask a mask for an l2 address
* @return a selection builder
*/
Builder matchEthSrcMasked(MacAddress addr, MacAddress mask);
/**
* Matches the ethernet type.
*
* @param ethType an ethernet type
......
......@@ -86,6 +86,17 @@ public final class Criteria {
}
/**
* Creates a masked match on ETH_DST field using the specified value and mask.
*
* @param mac MAC address value
* @param mask MAC address masking
* @return match criterion
*/
public static Criterion matchEthDstMasked(MacAddress mac, MacAddress mask) {
return new EthCriterion(mac, mask, Type.ETH_DST_MASKED);
}
/**
* Creates a match on ETH_SRC field using the specified value. This value
* may be a wildcard mask.
*
......@@ -97,6 +108,17 @@ public final class Criteria {
}
/**
* Creates a masked match on ETH_SRC field using the specified value and mask.
*
* @param mac MAC address value
* @param mask MAC address masking
* @return match criterion
*/
public static Criterion matchEthSrcMasked(MacAddress mac, MacAddress mask) {
return new EthCriterion(mac, mask, Type.ETH_SRC_MASKED);
}
/**
* Creates a match on ETH_TYPE field using the specified value.
*
* @param ethType eth type value (16 bits unsigned integer)
......
......@@ -40,9 +40,15 @@ public interface Criterion {
/** Ethernet destination address. */
ETH_DST,
/** Ethernet destination address with masking. */
ETH_DST_MASKED,
/** Ethernet source address. */
ETH_SRC,
/** Ethernet source address with masking. */
ETH_SRC_MASKED,
/** Ethernet frame type. */
ETH_TYPE,
......
......@@ -24,20 +24,34 @@ import java.util.Objects;
*/
public final class EthCriterion implements Criterion {
private final MacAddress mac;
private final MacAddress mask;
private final Type type;
/**
* Constructor.
*
* @param mac the source or destination MAC address to match
* @param type the match type. Should be either Type.ETH_DST or
* Type.ETH_SRC
* @param mask the mask for the address
* @param type the match type. Should be either Type.ETH_DST_MASKED or
* Type.ETH_SRC_MASKED
*/
EthCriterion(MacAddress mac, Type type) {
EthCriterion(MacAddress mac, MacAddress mask, Type type) {
this.mac = mac;
this.mask = mask;
this.type = type;
}
/**
* Constructor.
*
* @param mac the source or destination MAC address to match
* @param type the match type. Should be either Type.ETH_DST or
* Type.ETH_SRC
*/
EthCriterion(MacAddress mac, Type type) {
this(mac, null, type);
}
@Override
public Type type() {
return this.type;
......@@ -52,14 +66,23 @@ public final class EthCriterion implements Criterion {
return this.mac;
}
/**
* Gets the mask for the MAC address to match.
*
* @return the MAC address to match
*/
public MacAddress mask() {
return this.mask;
}
@Override
public String toString() {
return type().toString() + SEPARATOR + mac;
return type().toString() + SEPARATOR + mac + "/" + mask;
}
@Override
public int hashCode() {
return Objects.hash(type.ordinal(), mac);
return Objects.hash(type.ordinal(), mac, mask);
}
@Override
......@@ -70,6 +93,7 @@ public final class EthCriterion implements Criterion {
if (obj instanceof EthCriterion) {
EthCriterion that = (EthCriterion) obj;
return Objects.equals(mac, that.mac) &&
Objects.equals(mask, that.mask) &&
Objects.equals(type, that.type);
}
return false;
......
......@@ -130,6 +130,9 @@ public final class EncodeCriterionCodecHelper {
formatMap.put(Criterion.Type.ACTSET_OUTPUT, new FormatUnknown());
formatMap.put(Criterion.Type.PACKET_TYPE, new FormatUnknown());
formatMap.put(Criterion.Type.EXTENSION, new FormatUnknown());
formatMap.put(Criterion.Type.ETH_DST_MASKED, new FormatUnknown());
formatMap.put(Criterion.Type.ETH_SRC_MASKED, new FormatUnknown());
}
private interface CriterionTypeFormatter {
......
......@@ -615,12 +615,26 @@ public class FlowEntryBuilder {
builder.matchMetadata(metadata);
break;
case ETH_DST:
mac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
builder.matchEthDst(mac);
if (match.isPartiallyMasked(MatchField.ETH_DST)) {
Masked<org.projectfloodlight.openflow.types.MacAddress> maskedMac =
match.getMasked(MatchField.ETH_DST);
builder.matchEthDstMasked(MacAddress.valueOf(maskedMac.getValue().getLong()),
MacAddress.valueOf(maskedMac.getMask().getLong()));
} else {
mac = MacAddress.valueOf(match.get(MatchField.ETH_DST).getLong());
builder.matchEthDst(mac);
}
break;
case ETH_SRC:
mac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
builder.matchEthSrc(mac);
if (match.isPartiallyMasked(MatchField.ETH_SRC)) {
Masked<org.projectfloodlight.openflow.types.MacAddress> maskedMac =
match.getMasked(MatchField.ETH_SRC);
builder.matchEthSrcMasked(MacAddress.valueOf(maskedMac.getValue().getLong()),
MacAddress.valueOf(maskedMac.getMask().getLong()));
} else {
mac = MacAddress.valueOf(match.get(MatchField.ETH_SRC).getLong());
builder.matchEthSrc(mac);
}
break;
case ETH_TYPE:
int ethType = match.get(MatchField.ETH_TYPE).getValue();
......
......@@ -219,11 +219,23 @@ public abstract class FlowModBuilder {
mBuilder.setExact(MatchField.ETH_DST,
MacAddress.of(ethCriterion.mac().toLong()));
break;
case ETH_DST_MASKED:
ethCriterion = (EthCriterion) c;
mBuilder.setMasked(MatchField.ETH_DST,
MacAddress.of(ethCriterion.mac().toLong()),
MacAddress.of(ethCriterion.mask().toLong()));
break;
case ETH_SRC:
ethCriterion = (EthCriterion) c;
mBuilder.setExact(MatchField.ETH_SRC,
MacAddress.of(ethCriterion.mac().toLong()));
break;
case ETH_SRC_MASKED:
ethCriterion = (EthCriterion) c;
mBuilder.setMasked(MatchField.ETH_SRC,
MacAddress.of(ethCriterion.mac().toLong()),
MacAddress.of(ethCriterion.mask().toLong()));
break;
case ETH_TYPE:
EthTypeCriterion ethType = (EthTypeCriterion) c;
mBuilder.setExact(MatchField.ETH_TYPE, EthType.of(ethType.ethType().toShort()));
......