package org.opendaylight.controller.sal.match;
+import java.net.Inet4Address;
import java.net.InetAddress;
import java.util.Arrays;
* Represents the binding between the id, the value and mask type and the range
* values of the elements type that can be matched on the network
* frame/packet/message
- *
- *
- *
*/
public enum MatchType {
IN_PORT("inPort", 1 << 0, NodeConnector.class, 1, 0),
DL_SRC("dlSrc", 1 << 1, Byte[].class, 0, 0xffffffffffffL),
DL_DST("dlDst", 1 << 2, Byte[].class, 0, 0xffffffffffffL),
- DL_VLAN("dlVlan", 1 << 3, Short.class, 1, 0xfff), // 2 bytes
+ DL_VLAN("dlVlan", 1 << 3, Short.class, 0, 0xfff), // 2 bytes
DL_VLAN_PR("dlVlanPriority", 1 << 4, Byte.class, 0, 0x7), // 3 bits
DL_OUTER_VLAN("dlOuterVlan", 1 << 5, Short.class, 1, 0xfff),
DL_OUTER_VLAN_PR("dlOuterVlanPriority", 1 << 6, Short.class, 0, 0x7),
NW_PROTO("nwProto", 1 << 9, Byte.class, 0, 0xff), // 1 byte
NW_SRC("nwSrc", 1 << 10, InetAddress.class, 0, 0),
NW_DST("nwDst", 1 << 11, InetAddress.class, 0, 0),
- TP_SRC("tpSrc", 1 << 12, Short.class, 1, 0xffff), // 2 bytes
- TP_DST("tpDst", 1 << 13, Short.class, 1, 0xffff); // 2 bytes
+ TP_SRC("tpSrc", 1 << 12, Short.class, 0, 0xffff), // 2 bytes
+ TP_DST("tpDst", 1 << 13, Short.class, 0, 0xffff); // 2 bytes
+
+ // Used to indicate that no VLAN ID is set.
+ public static final short DL_VLAN_NONE = (short) 0;
private String id;
private int index;
private long minValue;
private long maxValue;
- private MatchType(String id, int index, Class<?> dataType, long minValue,
- long maxValue) {
+ private MatchType(String id, int index, Class<?> dataType, long minValue, long maxValue) {
this.id = id;
this.index = index;
this.dataType = dataType;
}
public String getRange() {
- return "[0x" + Long.toHexString(minValue) + "-0x"
- + Long.toHexString(maxValue) + "]";
+ return "[0x" + Long.toHexString(minValue) + "-0x" + Long.toHexString(maxValue) + "]";
}
/**
val = ((Integer) value).intValue();
msk = (mask != null) ? ((Integer) mask).intValue() : 0;
- } else if (value.getClass() == Short.class
- || value.getClass() == short.class) {
+ } else if (value.getClass() == Short.class || value.getClass() == short.class) {
val = ((Short) value).intValue() & 0xffff;
msk = (mask != null) ? ((Short) mask).intValue() & 0xffff : 0;
- } else if (value.getClass() == Byte.class
- || value.getClass() == byte.class) {
+ } else if (value.getClass() == Byte.class || value.getClass() == byte.class) {
val = ((Byte) value).intValue() & 0xff;
msk = (mask != null) ? ((Byte) mask).intValue() & 0xff : 0;
}
byte mac[] = (byte[]) mask;
long bitmask = 0;
for (short i = 0; i < 6; i++) {
- bitmask |= (((long) mac[i] & 0xffL) << ((5 - i) * 8));
+ bitmask |= ((mac[i] & 0xffL) << ((5 - i) * 8));
}
return bitmask;
}
if (this.dataType == Integer.class || this.dataType == int.class) {
- return (mask == null) ? this.maxValue : ((Integer) mask)
- .longValue();
+ return (mask == null) ? this.maxValue : ((Integer) mask).longValue();
}
if (this.dataType == Short.class || this.dataType == short.class) {
return HexEncode.bytesToHexStringFormat((byte[]) value);
case DL_TYPE:
case DL_VLAN:
- return ((Integer) NetUtils.getUnsignedShort((Short) value))
- .toString();
+ return ((Integer) NetUtils.getUnsignedShort((Short) value)).toString();
case NW_SRC:
case NW_DST:
return ((InetAddress) value).getHostAddress();
case NW_TOS:
- return ((Integer) NetUtils.getUnsignedByte((Byte) value))
- .toString();
+ return ((Integer) NetUtils.getUnsignedByte((Byte) value)).toString();
case TP_SRC:
case TP_DST:
- return ((Integer) NetUtils.getUnsignedShort((Short) value))
- .toString();
+ return ((Integer) NetUtils.getUnsignedShort((Short) value)).toString();
default:
break;
}
return value.toString();
}
+ public int valueHashCode(Object o) {
+ if (o == null) {
+ return 0;
+ }
+ switch (this) {
+ case DL_SRC:
+ case DL_DST:
+ return NetUtils.byteArray4ToInt((byte[])o);
+ default:
+ return o.hashCode();
+ }
+ }
+
+ public int hashCode(Object v, Object m) {
+ final int prime = 31;
+ int result = 1;
+ result = prime * result + this.hashCode();
+
+ switch (this) {
+ case DL_SRC:
+ case DL_DST:
+ result = prime * result + ((v == null)? 0 : NetUtils.byteArray4ToInt((byte[])v));
+ result = prime * result + ((m == null)? 0 : NetUtils.byteArray4ToInt((byte[])m));
+ break;
+ case NW_SRC:
+ case NW_DST:
+ // Hash code has to take into account only prefix address
+ InetAddress ip = (InetAddress) v;
+ int maskLen = (m == null) ? ((ip instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength((InetAddress) m);
+ InetAddress prefix = NetUtils.getSubnetPrefix(ip, maskLen);
+ result = prime * result + ((v == null)? 0 : prefix.hashCode());
+ break;
+ default:
+ result = prime * result + ((v == null)? 0 : v.hashCode());
+ result = prime * result + ((m == null)? 0 : m.hashCode());
+ }
+ return result;
+ }
public boolean equalValues(Object a, Object b) {
if (a == b) {
return true;
* For network address mask, network node may return full mask for
* flows the controller generated with a null mask object
*/
- byte maskBytes[] = null;
- if (a == null) {
- maskBytes = ((InetAddress) b).getAddress();
- } else if (b == null) {
- maskBytes = ((InetAddress) a).getAddress();
- }
- if (maskBytes != null) {
- return (NetUtils.getSubnetMaskLength(maskBytes) == 0);
+ if (a == null || b == null) {
+ InetAddress mask = (a == null) ? (InetAddress) b : (InetAddress) a;
+ int maxLength = (mask instanceof Inet4Address) ? 32 : 128;
+ return (NetUtils.getSubnetMaskLength(mask) == maxLength);
}
default:
if (a == null) {
return a.equals(b);
}
}
+
+ public boolean equals(Object value1, Object value2, Object mask1, Object mask2) {
+ switch (this) {
+ case NW_SRC:
+ case NW_DST:
+ // Equality to be checked against prefix addresses
+ InetAddress thisIP = (InetAddress) value1;
+ int thisMaskLen = (mask1 == null) ? ((thisIP instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength((InetAddress) mask1);
+ InetAddress otherIP = (InetAddress) value2;
+ int otherMaskLen = (mask2 == null) ? ((otherIP instanceof Inet4Address) ? 32 : 128) : NetUtils
+ .getSubnetMaskLength((InetAddress) mask2);
+
+ return NetUtils.getSubnetPrefix(thisIP, thisMaskLen)
+ .equals(NetUtils.getSubnetPrefix(otherIP, otherMaskLen));
+ default:
+ return (this.equalValues(value1, value2) && this.equalMasks(mask1, mask2));
+ }
+ }
}