918eaa6656859406f920f3febf3b0cdae6e361b5
[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      */
128     public static Uint64 getTunnelIdWithValidVniBitAndVniSet(int vni) {
129         return Uint64.valueOf(8L << 56 | vni << 8);
130     }
131
132     public static long getNatRouterIdFromMetadata(Uint64 metadata) {
133         return getVpnIdFromMetadata(metadata);
134     }
135
136     /**
137      * Gets the ACL conntrack classifier type from meta data.<br>
138      * Second bit in metadata is used for this purpose.<br>
139      *
140      * <p>
141      * Conntrack supported traffic is identified by value 0 (0000 in binary)
142      * i.e., 0x0/0x2<br>
143      * Non-conntrack supported traffic is identified by value 2 (0010 in binary)
144      * i.e., 0x2/0x2
145      *
146      * @param conntrackClassifierType the conntrack classifier flag
147      * @return the acl conntrack classifier flag from meta data
148      */
149     public static Uint64 getAclConntrackClassifierTypeFromMetaData(Uint64 conntrackClassifierType) {
150         // FIXME: this can be done more efficiently
151         return Uint64.valueOf(METADATA_MASK_ACL_CONNTRACK_CLASSIFIER_TYPE.toJava().and(conntrackClassifierType.toJava()
152             .shiftLeft(1)));
153     }
154
155     public static Uint64 getAclDropMetaData(Uint64 dropFlag) {
156         // FIXME: this can be done more efficiently
157         return Uint64.valueOf(METADATA_MASK_ACL_DROP.toJava().and(dropFlag.toJava().shiftLeft(2)));
158     }
159
160     public static Uint64 getVpnIdMetadata(long vrfId) {
161         return Uint64.valueOf(METADATA_MASK_VRFID.longValue() & vrfId << 1);
162     }
163
164     public static long getVpnIdFromMetadata(Uint64 metadata) {
165         // FIXME: this can be done more efficiently
166         return metadata.toJava().and(METADATA_MASK_VRFID.toJava()).shiftRight(1).longValue();
167     }
168
169     public static Uint64 getWriteMetaDataMaskForDispatcherTable() {
170         return MASK_FOR_DISPATCHER;
171     }
172
173     public static Uint64 getWriteMetaDataMaskForEgressDispatcherTable() {
174         // FIXME: make this an interned constant
175         return Uint64.valueOf("000000FFFFFFFFFE", 16);
176     }
177
178     public static Uint64 getLportTagForReg6(int lportTag) {
179         return Uint64.valueOf((lportTag & 0xFFFFF) << 8);
180     }
181
182     public static Uint64 getServiceIndexForReg6(int serviceIndex) {
183         return Uint64.valueOf((0xFL & serviceIndex) << 28);
184     }
185
186     public static Uint64 getInterfaceTypeForReg6(int tunnelType) {
187         return Uint64.valueOf((0xF & tunnelType) << 4);
188     }
189
190     public static long getReg6ValueForLPortDispatcher(int lportTag, short serviceIndex) {
191         // FIXME: this can be done more efficiently
192         return getServiceIndexForReg6(serviceIndex).toJava().or(getLportTagForReg6(lportTag).toJava()).longValue();
193     }
194
195     /** Utility to fetch the register value for lport dispatcher table.
196      * Register6 used for service binding will have first 4 bits of service-index, next 20 bits for lportTag,
197      * and next 4 bits for interface-type
198      */
199     public static long getReg6ValueForLPortDispatcher(int lportTag, short serviceIndex, short interfaceType) {
200         // FIXME: this can be done more efficiently
201         return getServiceIndexForReg6(serviceIndex).toJava().or(getLportTagForReg6(lportTag).toJava()
202             .or(getInterfaceTypeForReg6(interfaceType).toJava())).longValue();
203     }
204
205     public static long getRemoteDpnMetadatForEgressTunnelTable(long remoteDpnId) {
206         return (remoteDpnId & 0xFFFFFF) << 8;
207     }
208
209     public static long getRemoteDpnMaskForEgressTunnelTable() {
210         // FIXME: this can be done more efficiently
211         return REG6_MASK_REMOTE_DPN.toJava().shiftRight(32).longValue();
212     }
213
214     public static long getLportTagMaskForReg6() {
215         // FIXME: this can be done more efficiently
216         return METADATA_MASK_LPORT_TAG.toJava().shiftRight(32).longValue();
217     }
218
219     public static long getElanMaskForReg() {
220         // FIXME: this can be done more efficiently
221         return METADATA_MASK_SERVICE.toJava().shiftRight(24).longValue();
222     }
223
224     public static long getVpnIdMaskForReg() {
225         // FIXME: this can be done more efficiently
226         return METADATA_MASK_VRFID.toJava().shiftRight(1).longValue();
227     }
228
229     public static Uint64 mergeMetadataValues(Uint64 metadata, Uint64 metadata2) {
230         // FIXME: this can be done more efficiently
231         return Uint64.valueOf(metadata.toJava().or(metadata2.toJava()));
232     }
233
234     public static Uint64 mergeMetadataMask(Uint64 mask, Uint64 mask2) {
235         // FIXME: this can be done more efficiently
236         return Uint64.valueOf(mask.toJava().or(mask2.toJava()));
237     }
238 }