blob: 790e34028c1d2333e4c4227d151dae78bebc2a59 [file] [log] [blame]
pier5c817582019-04-17 17:05:08 +02001/*
2 * Copyright 2019-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17package org.onosproject.driver.pipeline.ofdpa;
18
19import org.onlab.packet.Ethernet;
20import org.onlab.packet.IpPrefix;
21import org.onlab.packet.MacAddress;
22import org.onlab.packet.VlanId;
23import org.onosproject.net.driver.Driver;
24import org.onosproject.net.flow.TrafficSelector;
25import org.onosproject.net.flow.TrafficTreatment;
26import org.onosproject.net.flow.criteria.Criterion;
27import org.onosproject.net.flow.criteria.EthCriterion;
28import org.onosproject.net.flow.criteria.EthTypeCriterion;
29import org.onosproject.net.flow.criteria.ExtensionCriterion;
30import org.onosproject.net.flow.criteria.ExtensionSelector;
31import org.onosproject.net.flow.criteria.IPCriterion;
32import org.onosproject.net.flow.criteria.MplsBosCriterion;
33import org.onosproject.net.flow.criteria.VlanIdCriterion;
34import org.onosproject.net.flow.instructions.Instruction;
35import org.onosproject.net.flow.instructions.Instructions;
36import org.onosproject.net.flow.instructions.L2ModificationInstruction;
37import org.onosproject.net.flow.instructions.L2ModificationInstruction.L2SubType;
38import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModTunnelIdInstruction;
39import org.onosproject.net.flowobjective.FilteringObjective;
40import org.onosproject.net.flowobjective.ForwardingObjective;
41import org.onosproject.net.flowobjective.Objective;
42import org.onosproject.net.flowobjective.ObjectiveError;
43
44import static org.onosproject.net.behaviour.Pipeliner.ACCUMULATOR_ENABLED;
45import static org.onosproject.net.flow.criteria.Criterion.Type.ETH_TYPE;
46import static org.onosproject.net.flow.criteria.Criterion.Type.MPLS_BOS;
47import static org.onosproject.net.flow.instructions.Instruction.Type.L2MODIFICATION;
48import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModVlanIdInstruction;
49import org.onosproject.net.flow.instructions.L2ModificationInstruction.ModEtherInstruction;
50
51public final class OfdpaPipelineUtility {
52
53 private OfdpaPipelineUtility() {
54 // Utility classes should not have a public or default constructor.
55 }
56
57 // Ofdpa specific tables number
58 static final int PORT_TABLE = 0;
59 static final int VLAN_TABLE = 10;
60 static final int VLAN_1_TABLE = 11;
61 static final int MPLS_L2_PORT_FLOW_TABLE = 13;
62 static final int MPLS_L2_PORT_PCP_TRUST_FLOW_TABLE = 16;
63 static final int TMAC_TABLE = 20;
64 static final int UNICAST_ROUTING_TABLE = 30;
65 static final int MULTICAST_ROUTING_TABLE = 40;
66 static final int MPLS_TABLE_0 = 23;
67 static final int MPLS_TABLE_1 = 24;
68 static final int MPLS_L3_TYPE_TABLE = 27;
69 static final int MPLS_TYPE_TABLE = 29;
70 static final int BRIDGING_TABLE = 50;
71 public static final int ACL_TABLE = 60;
72 static final int MAC_LEARNING_TABLE = 254;
73
74 // OF max port number
75 static final long OFPP_MAX = 0xffffff00L;
76
77 // Priority values
78 static final int HIGHEST_PRIORITY = 0xffff;
79 static final int DEFAULT_PRIORITY = 0x8000;
80 static final int LOWEST_PRIORITY = 0x0;
81
82 // MPLS L2 table values
83 static final int MPLS_L2_PORT_PRIORITY = 2;
84 static final int MPLS_TUNNEL_ID_BASE = 0x10000;
85 static final int MPLS_TUNNEL_ID_MAX = 0x1FFFF;
86 static final int MPLS_UNI_PORT_MAX = 0x0000FFFF;
87 static final int MPLS_NNI_PORT_BASE = 0x00020000;
88 static final int MPLS_NNI_PORT_MAX = 0x0002FFFF;
89
90 // Flow retry values
91 static final int MAX_RETRY_ATTEMPTS = 10;
92 static final int RETRY_MS = 1000;
93
94 //////////////////////////////
95 // Helper and utility methods
96 //////////////////////////////
97
98 /**
99 * Check whether the accumulator is enabled or not.
100 * @param pipeline the pipeline
101 * @return true if the accumulator is enabled. Otherwise not
102 */
103 static boolean isAccumulatorEnabled(Ofdpa2Pipeline pipeline) {
104 Driver driver = pipeline.data().driver();
105 // we cannot determine the property
106 if (driver == null) {
107 return false;
108 }
109 return Boolean.parseBoolean(driver.getProperty(ACCUMULATOR_ENABLED));
110 }
111
112 static void pass(Objective obj) {
113 obj.context().ifPresent(context -> context.onSuccess(obj));
114 }
115
116 static void fail(Objective obj, ObjectiveError error) {
117 obj.context().ifPresent(context -> context.onError(obj, error));
118 }
119
120 /**
121 * Returns true iff the given selector matches on BOS==true, indicating that
122 * the selector is trying to match on a label that is bottom-of-stack.
123 *
124 * @param selector the given match
125 * @return true iff BoS==true; false if BOS==false, or BOS matching is not
126 * expressed in the given selector
127 */
128 static boolean isMplsBos(TrafficSelector selector) {
129 MplsBosCriterion bosCriterion = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
130 return bosCriterion != null && bosCriterion.mplsBos();
131 }
132
133 /**
134 * Returns true iff the given selector matches on BOS==false, indicating
135 * that the selector is trying to match on a label that is not the
136 * bottom-of-stack label.
137 *
138 * @param selector the given match
139 * @return true iff BoS==false;
140 * false if BOS==true, or BOS matching is not expressed in the given selector
141 */
142 static boolean isNotMplsBos(TrafficSelector selector) {
143 MplsBosCriterion bosCriterion = (MplsBosCriterion) selector.getCriterion(MPLS_BOS);
144 return bosCriterion != null && !bosCriterion.mplsBos();
145 }
146
147 /**
148 * Returns true iff the forwarding objective includes a treatment to pop the
149 * MPLS label.
150 *
151 * @param fwd the given forwarding objective
152 * @return true iff mpls pop treatment exists
153 */
154 static boolean isMplsPop(ForwardingObjective fwd) {
155 if (fwd.treatment() != null) {
156 for (Instruction instr : fwd.treatment().allInstructions()) {
157 if (instr instanceof L2ModificationInstruction
158 && ((L2ModificationInstruction) instr)
159 .subtype() == L2SubType.MPLS_POP) {
160 return true;
161 }
162 }
163 }
164 return false;
165 }
166
167 /**
168 * Returns true iff the given selector matches on ethtype==ipv6, indicating
169 * that the selector is trying to match on ipv6 traffic.
170 *
171 * @param selector the given match
172 * @return true iff ethtype==ipv6; false otherwise
173 */
174 static boolean isIpv6(TrafficSelector selector) {
175 EthTypeCriterion ethTypeCriterion = (EthTypeCriterion) selector.getCriterion(ETH_TYPE);
176 return ethTypeCriterion != null && ethTypeCriterion.ethType().toShort() == Ethernet.TYPE_IPV6;
177 }
178
179 /**
180 * Reads vlan id from selector.
181 *
182 * @param selector the given match
183 * @return the vlan id if found. null otherwise
184 */
185 static VlanId readVlanFromSelector(TrafficSelector selector) {
186 if (selector == null) {
187 return null;
188 }
189 Criterion criterion = selector.getCriterion(Criterion.Type.VLAN_VID);
190 return (criterion == null)
191 ? null : ((VlanIdCriterion) criterion).vlanId();
192 }
193
194 /**
195 * Reads eth dst from selector.
196 *
197 * @param selector the given match
198 * @return the eth dst if found. null otherwise
199 */
200 static MacAddress readEthDstFromSelector(TrafficSelector selector) {
201 if (selector == null) {
202 return null;
203 }
204 Criterion criterion = selector.getCriterion(Criterion.Type.ETH_DST);
205 return (criterion == null)
206 ? null : ((EthCriterion) criterion).mac();
207 }
208
209 /**
210 * Reads ipv4 dst from selector.
211 *
212 * @param selector the given match
213 * @return the ipv4 dst if found. null otherwise
214 */
215 static IpPrefix readIpDstFromSelector(TrafficSelector selector) {
216 if (selector == null) {
217 return null;
218 }
219 Criterion criterion = selector.getCriterion(Criterion.Type.IPV4_DST);
220 return (criterion == null) ? null : ((IPCriterion) criterion).ip();
221 }
222
223 /**
224 * Reads vlan id from treatment.
225 *
226 * @param treatment the given actions
227 * @return the vlan id if found. null otherwise
228 */
229 static VlanId readVlanFromTreatment(TrafficTreatment treatment) {
230 if (treatment == null) {
231 return null;
232 }
233 for (Instruction i : treatment.allInstructions()) {
234 if (i instanceof ModVlanIdInstruction) {
235 return ((ModVlanIdInstruction) i).vlanId();
236 }
237 }
238 return null;
239 }
240
241 /**
242 * Reads eth dst from treatment.
243 *
244 * @param treatment the given actions
245 * @return the eth dst if found. null otherwise
246 */
247 static MacAddress readEthDstFromTreatment(TrafficTreatment treatment) {
248 if (treatment == null) {
249 return null;
250 }
251 for (Instruction i : treatment.allInstructions()) {
252 if (i instanceof ModEtherInstruction) {
253 ModEtherInstruction modEtherInstruction = (ModEtherInstruction) i;
254 if (modEtherInstruction.subtype() == L2SubType.ETH_DST) {
255 return modEtherInstruction.mac();
256 }
257 }
258 }
259 return null;
260 }
261
262 /**
263 * Reads extensions from selector.
264 * @param selector the given match
265 * @return the extensions if found. null otherwise
266 */
267 static ExtensionSelector readExtensionFromSelector(TrafficSelector selector) {
268 if (selector == null) {
269 return null;
270 }
271 ExtensionCriterion criterion = (ExtensionCriterion) selector.getCriterion(Criterion.Type.EXTENSION);
272 return (criterion == null) ? null : criterion.extensionSelector();
273 }
274
275 /**
276 * Determines if the filtering objective will be used for a pseudowire.
277 *
278 * @param filteringObjective the filtering objective
279 * @return True if objective was created for a pseudowire, false otherwise.
280 */
281 static boolean isPseudowire(FilteringObjective filteringObjective) {
282 if (filteringObjective.meta() != null) {
283 TrafficTreatment treatment = filteringObjective.meta();
284 for (Instruction instr : treatment.immediate()) {
285 if (instr.type().equals(Instruction.Type.L2MODIFICATION)) {
286
287 L2ModificationInstruction l2Instr = (L2ModificationInstruction) instr;
288 if (l2Instr.subtype().equals(L2SubType.TUNNEL_ID)) {
289 return true;
290 }
291 }
292 }
293 }
294 return false;
295 }
296
297 /**
298 * Utility function to get the mod tunnel id instruction
299 * if present.
300 *
301 * @param treatment the treatment to analyze
302 * @return the mod tunnel id instruction if present,
303 * otherwise null
304 */
305 static ModTunnelIdInstruction getModTunnelIdInstruction(TrafficTreatment treatment) {
306 if (treatment == null) {
307 return null;
308 }
309 L2ModificationInstruction l2ModificationInstruction;
310 for (Instruction instruction : treatment.allInstructions()) {
311 if (instruction.type() == L2MODIFICATION) {
312 l2ModificationInstruction = (L2ModificationInstruction) instruction;
313 if (l2ModificationInstruction.subtype() == L2SubType.TUNNEL_ID) {
314 return (ModTunnelIdInstruction) l2ModificationInstruction;
315 }
316 }
317 }
318 return null;
319 }
320
321 /**
322 * Utility function to get the output instruction
323 * if present.
324 *
325 * @param treatment the treatment to analyze
326 * @return the output instruction if present,
327 * otherwise null
328 */
329 static Instructions.OutputInstruction getOutputInstruction(TrafficTreatment treatment) {
330 if (treatment == null) {
331 return null;
332 }
333 for (Instruction instruction : treatment.allInstructions()) {
334 if (instruction.type() == Instruction.Type.OUTPUT) {
335 return (Instructions.OutputInstruction) instruction;
336 }
337 }
338 return null;
339 }
340
341}