68711b8c429786f7216ce820833dddb0b2577690
[openflowjava.git] / third-party / openflow-codec / src / main / java / org / openflow / codec / util / MatchUtil.java
1 package org.openflow.codec.util;
2
3 import java.util.Map;
4
5 import org.openflow.codec.protocol.OFBMatchFields;
6 import org.openflow.codec.protocol.OFPMatch;
7 import org.openflow.codec.protocol.OXMField;
8
9 /**
10  * utility class for match field
11  *
12  * @author AnilGujele
13  *
14  */
15
16 public class MatchUtil {
17
18     // ofp_vlan_id constant
19     private static int OFPVID_NONE = 0x0000; /* No VLAN id was set. */
20     private static int OFPVID_PRESENT = 0x1000; /*
21                                                  * Bit that indicate that a VLAN
22                                                  * id is set
23                                                  */
24
25     // Ethernet type constant
26     private static final int ETH_TYPE_IPV4 = 0x0800;
27     private static final int ETH_TYPE_IPV6 = 0x86dd;
28     private static final int ETH_TYPE_MPLS_UNICAST = 0x8847;
29     private static final int ETH_TYPE_MPLS_MULITCAST = 0x8848;
30     private static final int ETH_TYPE_ISID = 0x88E7;
31     private static final int ETH_TYPE_ARP = 0x0806;
32     // protocol type constant
33     private static final short IP_PROTO_TCP = 6;
34     private static final short IP_PROTO_UDP = 17;
35     private static final short IP_PROTO_SCTP = 132;
36     private static final short IP_PROTO_ICMP = 1;
37     private static final short IP_PROTO_ICMPV6 = 58;
38     // ICMPV6 type constant
39     private static final short ICMPV6_TYPE_NDP_NS = 135;
40     private static final short ICMPV6_TYPE_NDP_NA = 136;
41
42     /**
43      * to check if prerequisite is matching for all the field
44      *
45      * @param field
46      * @param map
47      * @return
48      */
49     public static boolean hasPrerequisite(OFPMatch match) {
50         Map<String, OXMField> map = match.getMatchFieldMap();
51         boolean result = true;
52         for (Map.Entry<String, OXMField> entry : map.entrySet()) {
53             OFBMatchFields field = entry.getValue().getMatchField();
54             OXMField value;
55             switch (field.getValue()) {
56             case 1: // OXM_OF_IN_PHY_PORT
57                 result = (null != map.get(OFBMatchFields.IN_PORT.name()));
58                 break;
59             case 7: // OXM_OF_VLAN_PCP
60                 value = map.get(OFBMatchFields.VLAN_VID.name());
61                 result = (null != value) && (U16.f(getShort(value.getData())) != MatchUtil.OFPVID_NONE);
62
63             case 8: // OXM_OF_IP_DSCP
64             case 9: // OXM_OF_IP_ECN
65             case 10: // OXM_OF_IP_PROTO
66                 value = map.get(OFBMatchFields.ETH_TYPE.name());
67                 boolean isMatched = (null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_IPV4);
68                 result = isMatched
69                         || ((null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_IPV6));
70                 break;
71             case 11: // OXM_OF_IPV4_SRC
72             case 12: // OXM_OF_IPV4_DST
73                 value = map.get(OFBMatchFields.ETH_TYPE.name());
74                 result = (null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_IPV4);
75                 break;
76             case 13: // OXM_OF_TCP_SRC
77             case 14: // OXM_OF_TCP_DST
78                 value = map.get(OFBMatchFields.IP_PROTO.name());
79                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.IP_PROTO_TCP);
80                 break;
81             case 15: // OXM_OF_UDP_SRC
82             case 16: // OXM_OF_UDP_DST
83                 value = map.get(OFBMatchFields.IP_PROTO.name());
84                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.IP_PROTO_UDP);
85                 break;
86             case 17: // OXM_OF_SCTP_SRC
87             case 18: // OXM_OF_SCTP_DST
88                 value = map.get(OFBMatchFields.IP_PROTO.name());
89                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.IP_PROTO_SCTP);
90                 break;
91             case 19: // OXM_OF_ICMPV4_TYPE
92             case 20: // OXM_OF_ICMPV4_CODE
93                 value = map.get(OFBMatchFields.IP_PROTO.name());
94                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.IP_PROTO_ICMP);
95                 break;
96             case 21: // OXM_OF_ARP_OP
97             case 22: // OXM_OF_ARP_SPA
98             case 23: // OXM_OF_ARP_TPA
99             case 24: // OXM_OF_ARP_SHA
100             case 25: // OXM_OF_ARP_THA
101                 value = map.get(OFBMatchFields.ETH_TYPE.name());
102                 result = (null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_ARP);
103                 break;
104
105             case 26: // OXM_OF_IPV6_SRC
106             case 27: // OXM_OF_IPV6_DST
107             case 28: // OXM_OF_IPV6_FLABEL
108             case 39: // OXM_OF_IPV6_EXTHDR
109                 value = map.get(OFBMatchFields.ETH_TYPE.name());
110                 result = (null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_IPV6);
111                 break;
112             case 29: // OXM_OF_ICMPV6_TYPE
113             case 30: // OXM_OF_ICMPV6_CODE
114                 value = map.get(OFBMatchFields.IP_PROTO.name());
115                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.IP_PROTO_ICMPV6);
116                 break;
117             case 31: // OXM_OF_IPV6_ND_TARGET
118                 value = map.get(OFBMatchFields.ICMPV6_TYPE.name());
119                 boolean success = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.ICMPV6_TYPE_NDP_NS);
120                 result = success || ((null != value) && (U8.f(value.getData()[0]) == MatchUtil.ICMPV6_TYPE_NDP_NA));
121                 break;
122             case 32: // OXM_OF_IPV6_ND_SLL
123                 value = map.get(OFBMatchFields.ICMPV6_TYPE.name());
124                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.ICMPV6_TYPE_NDP_NS);
125                 break;
126             case 33: // OXM_OF_IPV6_ND_TLL
127                 value = map.get(OFBMatchFields.ICMPV6_TYPE.name());
128                 result = (null != value) && (U8.f(value.getData()[0]) == MatchUtil.ICMPV6_TYPE_NDP_NA);
129                 break;
130             case 34: // OXM_OF_MPLS_LABEL
131             case 35: // OXM_OF_MPLS_TC
132             case 36: // OXM_OF_MPLS_BOS
133                 value = map.get(OFBMatchFields.ETH_TYPE.name());
134                 boolean isSuccess = (null != value)
135                         && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_MPLS_UNICAST);
136                 result = isSuccess
137                         || ((null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_MPLS_MULITCAST));
138                 break;
139             case 37: // OXM_OF_PBB_ISID
140                 value = map.get(OFBMatchFields.ETH_TYPE.name());
141                 result = (null != value) && (U16.f(getShort(value.getData())) == MatchUtil.ETH_TYPE_ISID);
142                 break;
143             default:
144                 result = true;
145                 break;
146
147             }
148             if (!result) {
149                 break; // break for loop
150             }
151         }
152         return result;
153     }
154
155     /**
156      * get short value from byte array
157      *
158      * @param byteArray
159      * @return
160      */
161     public static short getShort(byte[] byteArray) {
162         return (short) ((byteArray[1] << 8) | (byteArray[0] & 0xff));
163     }
164
165 }