blob: e0bd109e108da312ee0a64ffef1daf60a77fed7c [file] [log] [blame]
Andrea Campanellacbbb7952019-11-25 06:38:41 +00001/*
2 * Copyright 2016-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 */
16package org.opencord.olt.impl;
17
18import com.google.common.collect.ImmutableMap;
19import com.google.common.collect.ImmutableSet;
20import com.google.common.collect.ListMultimap;
21import org.apache.commons.lang3.tuple.Pair;
22import org.junit.Before;
23import org.junit.Test;
24import org.onlab.packet.EthType;
25import org.onlab.packet.VlanId;
26import org.onosproject.cluster.NodeId;
27import org.onosproject.cluster.RoleInfo;
28import org.onosproject.mastership.MastershipInfo;
29import org.onosproject.mastership.MastershipListener;
30import org.onosproject.net.DeviceId;
31import org.onosproject.net.MastershipRole;
32import org.onosproject.net.PortNumber;
33import org.onosproject.net.flow.TrafficSelector;
34import org.onosproject.net.flow.TrafficTreatment;
35import org.onosproject.net.flow.criteria.Criterion;
36import org.onosproject.net.flow.criteria.EthTypeCriterion;
37import org.onosproject.net.flow.criteria.PortCriterion;
38import org.onosproject.net.flow.criteria.VlanIdCriterion;
39import org.onosproject.net.flow.instructions.Instruction;
40import org.onosproject.net.flow.instructions.Instructions;
41import org.onosproject.net.flow.instructions.L2ModificationInstruction;
42import org.onosproject.net.flowobjective.FilteringObjQueueKey;
43import org.onosproject.net.flowobjective.FilteringObjective;
44import org.onosproject.net.flowobjective.ForwardingObjQueueKey;
45import org.onosproject.net.flowobjective.ForwardingObjective;
46import org.onosproject.net.flowobjective.NextObjQueueKey;
47import org.onosproject.net.flowobjective.NextObjective;
48import org.onosproject.net.flowobjective.Objective;
49import org.onosproject.net.meter.MeterId;
50import org.onosproject.net.meter.MeterKey;
51import org.opencord.sadis.BandwidthProfileInformation;
52import org.opencord.sadis.UniTagInformation;
53
54import java.util.Collection;
55import java.util.List;
56import java.util.Map;
57import java.util.Optional;
58import java.util.Set;
59import java.util.concurrent.CompletableFuture;
60
61public class OltFlowTest extends TestBase {
62 private OltFlowService oltFlowService;
63
64 PortNumber uniPortNumber = PortNumber.portNumber(1);
65 PortNumber nniPortNumber = PortNumber.portNumber(65535);
66
67 UniTagInformation.Builder tagInfoBuilder = new UniTagInformation.Builder();
68 UniTagInformation uniTagInfo = tagInfoBuilder.setUniTagMatch(VlanId.vlanId((short) 35))
69 .setPonCTag(VlanId.vlanId((short) 33))
70 .setPonSTag(VlanId.vlanId((short) 7))
71 .setDsPonCTagPriority(0)
72 .setUsPonSTagPriority(0)
73 .setTechnologyProfileId(64)
74 .setDownstreamBandwidthProfile(dsBpId)
75 .setUpstreamBandwidthProfile(usBpId)
76 .build();
77
78 @Before
79 public void setUp() {
80 oltFlowService = new OltFlowService();
81 oltFlowService.oltMeterService = new MockOltMeterService();
82 oltFlowService.flowObjectiveService = new MockOltFlowObjectiveService();
83 oltFlowService.mastershipService = new MockMastershipService();
84 oltFlowService.sadisService = new MockSadisService();
85 oltFlowService.bpService = oltFlowService.sadisService.getBandwidthProfileService();
86 oltFlowService.appId = appId;
87 }
88
89 @Test
90 public void testDhcpFiltering() {
91 oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
92 true, true);
93 oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
94 false, true);
95 oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, dsMeterId, uniTagInfo,
96 true, false);
97 oltFlowService.processDhcpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
98 false, false);
99 }
100
101 @Test
102 public void testIgmpFiltering() {
103 oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
104 true, true);
105 oltFlowService.processIgmpFilteringObjectives(DEVICE_ID_1, uniPortNumber, usMeterId, uniTagInfo,
106 false, true);
107 }
108
109 @Test
110 public void testEapolFiltering() {
111 addBandwidthProfile(uniTagInfo.getUpstreamBandwidthProfile());
112 oltFlowService.enableEapol = true;
113
114 //will install
115 oltFlowService.processEapolFilteringObjectives(DEVICE_ID_1, uniPortNumber,
116 uniTagInfo.getUpstreamBandwidthProfile(), new CompletableFuture<>(),
117 uniTagInfo.getUniTagMatch(), true);
118
119 //bp profile doesn't exist
120 oltFlowService.processEapolFilteringObjectives(DEVICE_ID_1, uniPortNumber,
121 uniTagInfo.getDownstreamBandwidthProfile(), new CompletableFuture<>(),
122 uniTagInfo.getUniTagMatch(), true);
123 }
124
125 @Test
126 public void testLldpFiltering() {
127 oltFlowService.processLldpFilteringObjective(DEVICE_ID_1, nniPortNumber, true);
128 oltFlowService.processLldpFilteringObjective(DEVICE_ID_1, nniPortNumber, false);
129 }
130
131 @Test
132 public void testNniFiltering() {
133 oltFlowService.enableDhcpOnProvisioning = true;
134 oltFlowService.enableIgmpOnProvisioning = true;
135 oltFlowService.processNniFilteringObjectives(DEVICE_ID_1, nniPortNumber, true);
136 oltFlowService.processNniFilteringObjectives(DEVICE_ID_1, nniPortNumber, false);
137 }
138
139 @Test
140 public void testUpBuilder() {
141 ForwardingObjective objective =
142 oltFlowService.createUpBuilder(nniPortNumber, uniPortNumber, usMeterId, uniTagInfo).add();
143 checkObjective(objective, true);
144 }
145
146 @Test
147 public void testDownBuilder() {
148 ForwardingObjective objective =
149 oltFlowService.createDownBuilder(nniPortNumber, uniPortNumber, dsMeterId, uniTagInfo).remove();
150 checkObjective(objective, false);
151 }
152
153 private void checkObjective(ForwardingObjective fwd, boolean upstream) {
154 TrafficTreatment treatment = fwd.treatment();
155
156 //check instructions
157 Set<Instructions.MeterInstruction> meters = treatment.meters();
158 assert !meters.isEmpty();
159
160 Instructions.MetadataInstruction writeMetadata = treatment.writeMetadata();
161 assert writeMetadata != null;
162
163 List<Instruction> immediateInstructions = treatment.immediate();
164 Optional<Instruction> vlanInstruction = immediateInstructions.stream()
165 .filter(i -> i.type() == Instruction.Type.L2MODIFICATION)
166 .filter(i -> ((L2ModificationInstruction) i).subtype() ==
167 L2ModificationInstruction.L2SubType.VLAN_PUSH ||
168 ((L2ModificationInstruction) i).subtype() ==
169 L2ModificationInstruction.L2SubType.VLAN_POP)
170 .findAny();
171
172 assert vlanInstruction.isPresent();
173
174 //check match criteria
175 TrafficSelector selector = fwd.selector();
176 assert selector.getCriterion(Criterion.Type.IN_PORT) != null;
177 assert selector.getCriterion(Criterion.Type.VLAN_VID) != null;
178
179 if (!upstream) {
180 assert selector.getCriterion(Criterion.Type.METADATA) != null;
181 }
182 }
183
184 private class MockOltMeterService implements org.opencord.olt.internalapi.AccessDeviceMeterService {
185 @Override
186 public ImmutableMap<String, Collection<MeterKey>> getBpMeterMappings() {
187 return null;
188 }
189
190 @Override
Andrea Campanellacbbb7952019-11-25 06:38:41 +0000191 public MeterId getMeterIdFromBpMapping(DeviceId deviceId, String bandwidthProfile) {
192 return null;
193 }
194
195
196 @Override
197 public ImmutableSet<MeterKey> getProgMeters() {
198 return null;
199 }
200
201 @Override
202 public MeterId createMeter(DeviceId deviceId, BandwidthProfileInformation bpInfo,
203 CompletableFuture<Object> meterFuture) {
204 return usMeterId;
205 }
Jonathan Hart4f178fa2020-02-03 10:46:01 -0800206
207 @Override
208 public void clearMeters(DeviceId deviceId) {
209 }
Andrea Campanellacbbb7952019-11-25 06:38:41 +0000210 }
211
212 private class MockOltFlowObjectiveService implements org.onosproject.net.flowobjective.FlowObjectiveService {
213 @Override
214 public void filter(DeviceId deviceId, FilteringObjective filteringObjective) {
215
216 EthTypeCriterion ethType = (EthTypeCriterion)
217 filterForCriterion(filteringObjective.conditions(), Criterion.Type.ETH_TYPE);
218
219 Instructions.MeterInstruction meter = filteringObjective.meta().metered();
220 Instruction writeMetadata = filteringObjective.meta().writeMetadata();
221 VlanIdCriterion vlanIdCriterion = (VlanIdCriterion)
222 filterForCriterion(filteringObjective.conditions(), Criterion.Type.VLAN_VID);
223 PortCriterion portCriterion = (PortCriterion) filteringObjective.key();
224
225
226 if (ethType.ethType().equals(EthType.EtherType.LLDP.ethType()) ||
227 portCriterion.port().equals(nniPortNumber)) {
228 assert meter == null;
229 assert writeMetadata == null;
230 assert vlanIdCriterion == null;
231 } else {
232 assert meter.meterId().equals(usMeterId) || meter.meterId().equals(dsMeterId);
233 assert writeMetadata != null;
234 assert vlanIdCriterion.vlanId() == uniTagInfo.getPonCTag();
235 }
236
237 }
238
239 @Override
240 public void forward(DeviceId deviceId, ForwardingObjective forwardingObjective) {
241
242 }
243
244 @Override
245 public void next(DeviceId deviceId, NextObjective nextObjective) {
246
247 }
248
249 @Override
250 public int allocateNextId() {
251 return 0;
252 }
253
254 @Override
255 public void initPolicy(String s) {
256
257 }
258
259 @Override
260 public void apply(DeviceId deviceId, Objective objective) {
261
262 }
263
264 @Override
265 public Map<Pair<Integer, DeviceId>, List<String>> getNextMappingsChain() {
266 return null;
267 }
268
269 @Override
270 public List<String> getNextMappings() {
271 return null;
272 }
273
274 @Override
275 public List<String> getPendingFlowObjectives() {
276 return null;
277 }
278
279 @Override
280 public ListMultimap<FilteringObjQueueKey, Objective> getFilteringObjQueue() {
281 return null;
282 }
283
284 @Override
285 public ListMultimap<ForwardingObjQueueKey, Objective> getForwardingObjQueue() {
286 return null;
287 }
288
289 @Override
290 public ListMultimap<NextObjQueueKey, Objective> getNextObjQueue() {
291 return null;
292 }
293
294 @Override
295 public Map<FilteringObjQueueKey, Objective> getFilteringObjQueueHead() {
296 return null;
297 }
298
299 @Override
300 public Map<ForwardingObjQueueKey, Objective> getForwardingObjQueueHead() {
301 return null;
302 }
303
304 @Override
305 public Map<NextObjQueueKey, Objective> getNextObjQueueHead() {
306 return null;
307 }
308
309 @Override
310 public void clearQueue() {
311
312 }
313
314 private Criterion filterForCriterion(Collection<Criterion> criteria, Criterion.Type type) {
315 return criteria.stream()
316 .filter(c -> c.type().equals(type))
317 .limit(1)
318 .findFirst().orElse(null);
319 }
320 }
321
322 private class MockMastershipService implements org.onosproject.mastership.MastershipService {
323 @Override
324 public MastershipRole getLocalRole(DeviceId deviceId) {
325 return null;
326 }
327
328 @Override
329 public boolean isLocalMaster(DeviceId deviceId) {
330 return true;
331 }
332
333 @Override
334 public CompletableFuture<MastershipRole> requestRoleFor(DeviceId deviceId) {
335 return null;
336 }
337
338 @Override
339 public CompletableFuture<Void> relinquishMastership(DeviceId deviceId) {
340 return null;
341 }
342
343 @Override
344 public NodeId getMasterFor(DeviceId deviceId) {
345 return null;
346 }
347
348 @Override
349 public RoleInfo getNodesFor(DeviceId deviceId) {
350 return null;
351 }
352
353 @Override
354 public MastershipInfo getMastershipFor(DeviceId deviceId) {
355 return null;
356 }
357
358 @Override
359 public Set<DeviceId> getDevicesOf(NodeId nodeId) {
360 return null;
361 }
362
363 @Override
364 public void addListener(MastershipListener mastershipListener) {
365
366 }
367
368 @Override
369 public void removeListener(MastershipListener mastershipListener) {
370
371 }
372 }
373}