3 * Copyright (c) 2013 Cisco Systems, Inc. and others. All rights reserved.
5 * This program and the accompanying materials are made available under the
6 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
7 * and is available at http://www.eclipse.org/legal/epl-v10.html
10 package org.opendaylight.controller.sal.match;
12 import java.net.InetAddress;
14 import org.opendaylight.controller.sal.core.NodeConnector;
17 * Represents the binding between the id, the value and mask type and the range values
18 * of the elements type that can be matched on the network frame/packet/message
23 public enum MatchType {
24 IN_PORT("inPort", 1 << 0, NodeConnector.class, 1, 0), DL_SRC("dlSrc",
25 1 << 1, Byte[].class, 0, 0xffffffffffffL), DL_DST("dlDst", 1 << 2,
26 Byte[].class, 0, 0xffffffffffffL), DL_VLAN("dlVlan", 1 << 3,
27 Short.class, 2, 0xfff), // 2 bytes
28 DL_VLAN_PR("dlVlanPriority", 1 << 4, Byte.class, 0, 0x7), // 3 bits
29 DL_OUTER_VLAN("dlOuterVlan", 1 << 5, Short.class, 2, 0xfff), DL_OUTER_VLAN_PR(
30 "dlOuterVlanPriority", 1 << 6, Short.class, 0, 0x7), DL_TYPE(
31 "dlType", 1 << 7, Short.class, 0, 0xffff), // 2 bytes
32 NW_TOS("nwTOS", 1 << 8, Byte.class, 0, 0xff), // 1 byte
33 NW_PROTO("nwProto", 1 << 9, Byte.class, 0, 0xff), // 1 byte
34 NW_SRC("nwSrc", 1 << 10, InetAddress.class, 0, 0), NW_DST("nwDst", 1 << 11,
35 InetAddress.class, 0, 0), TP_SRC("tpSrc", 1 << 12, Short.class, 1,
37 TP_DST("tpDst", 1 << 13, Short.class, 1, 0xffff); // 2 bytes
41 private Class<?> dataType;
42 private long minValue;
43 private long maxValue;
45 private MatchType(String id, int index, Class<?> dataType, long minValue,
49 this.dataType = dataType;
50 this.minValue = minValue;
51 this.maxValue = maxValue;
58 public int getIndex() {
62 public Class<?> dataType() {
66 public String getRange() {
67 return "[0x" + Long.toHexString(minValue) + "-0x"
68 + Long.toHexString(maxValue) + "]";
72 * Perform the assignment type validation
77 public boolean isCongruentType(Object value, Object mask) {
78 // Mask type has to match value type
79 if (mask != null && (mask.getClass() != value.getClass())) {
83 Class<?> e = this.dataType();
84 Class<?> g = value.getClass();
86 // This is all what we need, if value type is same of match required type
91 // This is for the numeric class vs primitive congruence
92 // For what concerns here, for instance, Integer is congruent to int
93 if (e == Short.class) {
94 return g.equals(short.class);
97 if (e == Integer.class) {
98 return g.equals(int.class);
101 if (e == Byte.class) {
102 return g.equals(byte.class);
105 if (e == Byte[].class) {
106 return g.equals(byte[].class);
109 if (e == InetAddress.class) {
110 return g.getSuperclass().equals(InetAddress.class);
116 * Perform the value and mask range validation
121 public boolean isValid(Object value, Object mask) {
122 // Skip if main error
123 if (mask != null && (mask.getClass() != value.getClass())) {
126 // For the complex below types let's skip the value range check for now
127 if (this.dataType == InetAddress.class) {
130 if (this.dataType() == Byte[].class) {
133 if (this.dataType() == NodeConnector.class) {
139 if (value.getClass() == Integer.class || value.getClass() == int.class) {
140 val = ((Integer) value).intValue();
141 msk = (mask != null) ? ((Integer) mask).intValue() : 0;
143 } else if (value.getClass() == Short.class
144 || value.getClass() == short.class) {
145 val = ((Short) value).intValue() & 0xffff;
146 msk = (mask != null) ? ((Short) mask).intValue() & 0xffff : 0;
148 } else if (value.getClass() == Byte.class
149 || value.getClass() == byte.class) {
150 val = ((Byte) value).intValue() & 0xff;
151 msk = (mask != null) ? ((Byte) mask).intValue() & 0xff : 0;
153 return ((val >= minValue && val <= maxValue) && (mask == null || (msk >= minValue && msk <= maxValue)));
158 * Return the mask value in 64 bits bitmask form
162 public long getBitMask(Object mask) {
163 if (this.dataType == InetAddress.class) {
164 //TODO handle Inet v4 and v6 v6 will have a second upper mask
167 if (this.dataType() == Byte[].class) {
169 return 0xffffffffffffL;
171 byte mac[] = (byte[]) mask;
173 for (short i = 0; i < 6; i++) {
174 // bitmask |= (((long)mac[i] & 0xffL) << (long)((5-i)*8));
175 bitmask |= (((long) mac[i] & 0xffL) << ((5 - i) * 8));
179 if (this.dataType == Integer.class || this.dataType == int.class) {
180 return (mask == null) ? this.maxValue : ((Integer) mask)
184 if (this.dataType == Short.class || this.dataType == short.class) {
185 return (mask == null) ? this.maxValue : ((Short) mask).longValue();
187 if (this.dataType == Byte.class || this.dataType == byte.class) {
188 return (mask == null) ? this.maxValue : ((Byte) mask).longValue();