Freeze upstream versions
[genius.git] / mdsalutil / mdsalutil-api / src / main / java / org / opendaylight / genius / mdsalutil / MetaDataUtil.java
1 /*
2  * Copyright (c) 2016 Ericsson India Global Services Pvt Ltd. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.genius.mdsalutil;
9
10 import org.opendaylight.yangtools.yang.common.Uint64;
11
12 public final class MetaDataUtil {
13     public static final Uint64 METADATA_MASK_LPORT_TAG = Uint64.valueOf("0FFFFF0000000000", 16).intern();
14     public static final Uint64 METADATA_MASK_SERVICE = Uint64.valueOf("000000FFFF000000", 16).intern();
15     public static final Uint64 METADATA_MASK_SERVICE_INDEX = Uint64.valueOf("F000000000000000", 16).intern();
16     public static final Uint64 METADATA_MASK_VRFID = Uint64.valueOf("0000000000FFFFFE", 16).intern();
17     public static final Uint64 METADATA_MASK_REMOTE_ACL_TAG = Uint64.valueOf("0000000000FFFFF0", 16).intern();
18     public static final Uint64 METADATA_MASK_POLICY_CLASSIFER_ID = Uint64.valueOf("0000000000FFFFFE", 16).intern();
19     public static final Uint64 METADA_MASK_VALID_TUNNEL_ID_BIT_AND_TUNNEL_ID = Uint64.valueOf("08000000FFFFFF00", 16)
20             .intern();
21     public static final Uint64 METADATA_MASK_LABEL_ITM = Uint64.valueOf("40FFFFFF000000FF", 16).intern();
22     public static final Uint64 METADA_MASK_TUNNEL_ID = Uint64.valueOf("00000000FFFFFF00", 16).intern();
23     public static final Uint64 METADATA_MASK_SERVICE_SH_FLAG = Uint64.valueOf("000000FFFF000001", 16).intern();
24     public static final Uint64 METADATA_MASK_LPORT_TAG_SH_FLAG = Uint64.valueOf("0FFFFF0000000001", 16).intern();
25     public static final Uint64 METADATA_MASK_SH_FLAG = Uint64.valueOf("0000000000000001", 16).intern();
26     public static final Uint64 METADATA_MASK_ELAN_SUBNET_ROUTE = Uint64.valueOf("000000FFFF000000", 16).intern();
27     public static final Uint64 METADATA_MASK_SUBNET_ROUTE = Uint64.valueOf("000000FFFFFFFFFE", 16).intern();
28     public static final Uint64 METADATA_MASK_ACL_CONNTRACK_CLASSIFIER_TYPE = Uint64.valueOf("0000000000000002", 16)
29             .intern();
30     public static final Uint64 METADATA_MASK_ACL_DROP = Uint64.valueOf("0000000000000004", 16).intern();
31     public static final Uint64 REG6_MASK_REMOTE_DPN = Uint64.valueOf("0FFFFF0000000000", 16).intern();
32
33     public static final int METADATA_LPORT_TAG_OFFSET = 40;
34     public static final int METADATA_LPORT_TAG_BITLEN = 20;
35     public static final int METADATA_ELAN_TAG_OFFSET = 24;
36     public static final int METADATA_ELAN_TAG_BITLEN = 16;
37     public static final int METADATA_VPN_ID_OFFSET = 1;
38     public static final int METADATA_VPN_ID_BITLEN = 23;
39
40     public static final int REG6_START_INDEX = 0;
41     public static final int REG6_END_INDEX = 31;
42
43     private static final Uint64 MASK_FOR_DISPATCHER = Uint64.valueOf("FFFFFFFFFFFFFFFE", 16).intern();
44
45     private MetaDataUtil() {
46
47     }
48
49     public static Uint64 getMetaDataForLPortDispatcher(int lportTag, short serviceIndex) {
50         // FIXME: this can be done more efficiently
51         return Uint64.valueOf(getServiceIndexMetaData(serviceIndex).toJava().or(
52             getLportTagMetaData(lportTag).toJava()));
53     }
54
55     public static Uint64 getMetaDataForLPortDispatcher(int lportTag, short serviceIndex, Uint64 serviceMetaData) {
56         return getMetaDataForLPortDispatcher(lportTag, serviceIndex, serviceMetaData, false);
57     }
58
59     public static Uint64 getMetaDataForLPortDispatcher(int lportTag, short serviceIndex,
60                                                        Uint64 serviceMetaData, boolean isSHFlagSet) {
61         return Uint64.fromLongBits(getServiceIndexMetaData(serviceIndex).longValue()
62             | getLportTagMetaData(lportTag).longValue()
63             | serviceMetaData.longValue()
64             | (isSHFlagSet ? 1 : 0));
65     }
66
67     public static Uint64 getPolicyClassifierMetaData(long classifier) {
68         return Uint64.valueOf((METADATA_MASK_POLICY_CLASSIFER_ID.longValue() & classifier) << 1);
69     }
70
71     public static Uint64 getServiceIndexMetaData(int serviceIndex) {
72         return Uint64.fromLongBits((serviceIndex & 0xFL) << 60);
73     }
74
75     public static Uint64 getLportTagMetaData(int lportTag) {
76         return Uint64.fromLongBits((lportTag & 0xFFFFFL) << METADATA_LPORT_TAG_OFFSET);
77     }
78
79     public static Uint64 getMetaDataMaskForLPortDispatcher() {
80         return getMetaDataMaskForLPortDispatcher(METADATA_MASK_LPORT_TAG);
81     }
82
83     public static Uint64 getMetaDataMaskForLPortDispatcher(Uint64 metadataMaskForLPortTag) {
84         return Uint64.fromLongBits(METADATA_MASK_SERVICE_INDEX.longValue() | metadataMaskForLPortTag.longValue());
85     }
86
87     public static Uint64 getMetaDataMaskForLPortDispatcher(Uint64 metadataMaskForServiceIndex,
88             Uint64 metadataMaskForLPortTag, Uint64 metadataMaskForService) {
89         return Uint64.fromLongBits(metadataMaskForServiceIndex.longValue() | metadataMaskForLPortTag.longValue()
90             | metadataMaskForService.longValue());
91     }
92
93     public static Uint64 getMetadataLPort(int portTag) {
94         return Uint64.valueOf((portTag & 0xFFFFL) << METADATA_LPORT_TAG_OFFSET);
95     }
96
97     public static Uint64 getLportFromMetadata(Uint64 metadata) {
98         // FIXME: this can be done more efficiently
99         return Uint64.valueOf(metadata.toJava().and(METADATA_MASK_LPORT_TAG.toJava())
100             .shiftRight(METADATA_LPORT_TAG_OFFSET));
101     }
102
103     public static int getElanTagFromMetadata(Uint64 metadata) {
104         // FIXME: this can be done more efficiently
105         return metadata.toJava().and(MetaDataUtil.METADATA_MASK_SERVICE.toJava()).shiftRight(24).intValue();
106     }
107
108     public static long getPolicyClassifierFromMetadata(Uint64 metadata) {
109         // FIXME: this can be done more efficiently
110         return metadata.toJava().and(METADATA_MASK_POLICY_CLASSIFER_ID.toJava()).shiftRight(1).longValue();
111     }
112
113     public static Uint64 getElanTagMetadata(long elanTag) {
114         return Uint64.fromLongBits(elanTag << 24);
115     }
116
117     public static int getServiceTagFromMetadata(Uint64 metadata) {
118         // FIXME: this can be done more efficiently
119         return metadata.toJava().and(MetaDataUtil.METADATA_MASK_SERVICE_INDEX.toJava())
120                 .shiftRight(60).intValue();
121     }
122
123     /**
124      * For the tunnel id with VNI and valid-vni-flag set, the most significant byte
125      * should have 08. So, shifting 08 to 7 bytes (56 bits) and the result is OR-ed with
126      * VNI being shifted to 1 byte.
127      * @param vni virtual network id
128      * @return TunnelId
129      */
130     public static Uint64 getTunnelIdWithValidVniBitAndVniSet(int vni) {
131         return Uint64.valueOf(8L << 56 | vni << 8);
132     }
133
134     public static long getNatRouterIdFromMetadata(Uint64 metadata) {
135         return getVpnIdFromMetadata(metadata);
136     }
137
138     /**
139      * Gets the ACL conntrack classifier type from meta data.<br>
140      * Second bit in metadata is used for this purpose.<br>
141      *
142      * <p>
143      * Conntrack supported traffic is identified by value 0 (0000 in binary)
144      * i.e., 0x0/0x2<br>
145      * Non-conntrack supported traffic is identified by value 2 (0010 in binary)
146      * i.e., 0x2/0x2
147      *
148      * @param conntrackClassifierType the conntrack classifier flag
149      * @return the acl conntrack classifier flag from meta data
150      */
151     public static Uint64 getAclConntrackClassifierTypeFromMetaData(Uint64 conntrackClassifierType) {
152         // FIXME: this can be done more efficiently
153         return Uint64.valueOf(METADATA_MASK_ACL_CONNTRACK_CLASSIFIER_TYPE.toJava().and(conntrackClassifierType.toJava()
154             .shiftLeft(1)));
155     }
156
157     public static Uint64 getAclDropMetaData(Uint64 dropFlag) {
158         // FIXME: this can be done more efficiently
159         return Uint64.valueOf(METADATA_MASK_ACL_DROP.toJava().and(dropFlag.toJava().shiftLeft(2)));
160     }
161
162     public static Uint64 getVpnIdMetadata(long vrfId) {
163         return Uint64.valueOf(METADATA_MASK_VRFID.longValue() & vrfId << 1);
164     }
165
166     public static long getVpnIdFromMetadata(Uint64 metadata) {
167         // FIXME: this can be done more efficiently
168         return metadata.toJava().and(METADATA_MASK_VRFID.toJava()).shiftRight(1).longValue();
169     }
170
171     public static Uint64 getWriteMetaDataMaskForDispatcherTable() {
172         return MASK_FOR_DISPATCHER;
173     }
174
175     public static Uint64 getWriteMetaDataMaskForEgressDispatcherTable() {
176         // FIXME: make this an interned constant
177         return Uint64.valueOf("000000FFFFFFFFFE", 16);
178     }
179
180     public static Uint64 getLportTagForReg6(int lportTag) {
181         return Uint64.valueOf((lportTag & 0xFFFFF) << 8);
182     }
183
184     public static Uint64 getServiceIndexForReg6(int serviceIndex) {
185         return Uint64.valueOf((0xFL & serviceIndex) << 28);
186     }
187
188     public static Uint64 getInterfaceTypeForReg6(int tunnelType) {
189         return Uint64.valueOf((0xF & tunnelType) << 4);
190     }
191
192     public static long getReg6ValueForLPortDispatcher(int lportTag, short serviceIndex) {
193         // FIXME: this can be done more efficiently
194         return getServiceIndexForReg6(serviceIndex).toJava().or(getLportTagForReg6(lportTag).toJava()).longValue();
195     }
196
197     /** Utility to fetch the register value for lport dispatcher table.
198      * Register6 used for service binding will have first 4 bits of service-index, next 20 bits for lportTag,
199      * and next 4 bits for interface-type
200      * @param lportTag lport tag of interface
201      * @param serviceIndex serviceIndex of interface
202      * @param interfaceType type of interface
203      * @return reg6 value of lport dispatcher
204      */
205     public static long getReg6ValueForLPortDispatcher(int lportTag, short serviceIndex, short interfaceType) {
206         // FIXME: this can be done more efficiently
207         return getServiceIndexForReg6(serviceIndex).toJava().or(getLportTagForReg6(lportTag).toJava()
208             .or(getInterfaceTypeForReg6(interfaceType).toJava())).longValue();
209     }
210
211     public static long getRemoteDpnMetadatForEgressTunnelTable(long remoteDpnId) {
212         return (remoteDpnId & 0xFFFFFF) << 8;
213     }
214
215     public static long getRemoteDpnMaskForEgressTunnelTable() {
216         // FIXME: this can be done more efficiently
217         return REG6_MASK_REMOTE_DPN.toJava().shiftRight(32).longValue();
218     }
219
220     public static long getLportTagMaskForReg6() {
221         // FIXME: this can be done more efficiently
222         return METADATA_MASK_LPORT_TAG.toJava().shiftRight(32).longValue();
223     }
224
225     public static long getElanMaskForReg() {
226         // FIXME: this can be done more efficiently
227         return METADATA_MASK_SERVICE.toJava().shiftRight(24).longValue();
228     }
229
230     public static long getVpnIdMaskForReg() {
231         // FIXME: this can be done more efficiently
232         return METADATA_MASK_VRFID.toJava().shiftRight(1).longValue();
233     }
234
235     public static Uint64 mergeMetadataValues(Uint64 metadata, Uint64 metadata2) {
236         // FIXME: this can be done more efficiently
237         return Uint64.valueOf(metadata.toJava().or(metadata2.toJava()));
238     }
239
240     public static Uint64 mergeMetadataMask(Uint64 mask, Uint64 mask2) {
241         // FIXME: this can be done more efficiently
242         return Uint64.valueOf(mask.toJava().or(mask2.toJava()));
243     }
244 }