blob: 35474b7b16a03be9bf22affb9fcf1ba79571af25 [file] [log] [blame]
Matteo Scandoloaa2adde2021-09-13 12:45:32 -07001/*
2 * Copyright 2021-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.opencord.olt.impl;
18
19import org.junit.After;
20import org.junit.Assert;
21import org.junit.Before;
22import org.junit.Test;
23import org.mockito.Mockito;
24import org.onlab.packet.ChassisId;
25import org.onlab.packet.EthType;
26import org.onlab.packet.IPv4;
27import org.onlab.packet.IPv6;
28import org.onlab.packet.MacAddress;
29import org.onlab.packet.TpPort;
30import org.onlab.packet.VlanId;
31import org.onosproject.cfg.ComponentConfigAdapter;
32import org.onosproject.core.ApplicationId;
33import org.onosproject.core.CoreServiceAdapter;
34import org.onosproject.core.DefaultApplicationId;
35import org.onosproject.net.ConnectPoint;
36import org.onosproject.net.DefaultAnnotations;
37import org.onosproject.net.DefaultDevice;
38import org.onosproject.net.DefaultHost;
39import org.onosproject.net.DefaultPort;
40import org.onosproject.net.Device;
41import org.onosproject.net.DeviceId;
42import org.onosproject.net.Host;
43import org.onosproject.net.HostId;
44import org.onosproject.net.HostLocation;
45import org.onosproject.net.Port;
46import org.onosproject.net.PortNumber;
Matteo Scandolo97449bb2021-12-09 15:33:46 -080047import org.onosproject.net.device.DeviceService;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070048import org.onosproject.net.flow.DefaultFlowRule;
Andrea Campanella40d2b342022-02-04 18:13:37 +010049import org.onosproject.net.flow.DefaultTrafficSelector;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070050import org.onosproject.net.flow.DefaultTrafficTreatment;
51import org.onosproject.net.flow.FlowRule;
52import org.onosproject.net.flow.FlowRuleEvent;
53import org.onosproject.net.flow.FlowRuleService;
Andrea Campanella40d2b342022-02-04 18:13:37 +010054import org.onosproject.net.flow.TrafficSelector;
55import org.onosproject.net.flow.TrafficTreatment;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070056import org.onosproject.net.flow.criteria.Criteria;
57import org.onosproject.net.flowobjective.DefaultFilteringObjective;
Harsh Awasthic1e4bf52022-02-09 14:14:14 +053058import org.onosproject.net.flowobjective.DefaultForwardingObjective;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070059import org.onosproject.net.flowobjective.FilteringObjective;
60import org.onosproject.net.flowobjective.FlowObjectiveService;
Harsh Awasthic1e4bf52022-02-09 14:14:14 +053061import org.onosproject.net.flowobjective.ForwardingObjective;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070062import org.onosproject.net.host.HostService;
63import org.onosproject.net.meter.MeterId;
64import org.onosproject.net.provider.ProviderId;
65import org.onosproject.store.service.TestStorageService;
Harsh Awasthic1e4bf52022-02-09 14:14:14 +053066import org.opencord.olt.impl.fttb.FttbUtils;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070067import org.opencord.sadis.BaseInformationService;
68import org.opencord.sadis.SadisService;
69import org.opencord.sadis.SubscriberAndDeviceInformation;
70import org.opencord.sadis.UniTagInformation;
71
72import java.util.Arrays;
73import java.util.HashSet;
74import java.util.LinkedList;
75import java.util.List;
Harsh Awasthic1e4bf52022-02-09 14:14:14 +053076import java.util.Map;
77import java.util.Optional;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070078import java.util.Set;
Andrea Campanella40d2b342022-02-04 18:13:37 +010079import java.util.concurrent.TimeUnit;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070080
81import static org.mockito.Matchers.any;
82import static org.mockito.Matchers.argThat;
83import static org.mockito.Matchers.eq;
84import static org.mockito.Mockito.doReturn;
85import static org.mockito.Mockito.never;
86import static org.mockito.Mockito.spy;
87import static org.mockito.Mockito.times;
88import static org.mockito.Mockito.verify;
Harsh Awasthic1e4bf52022-02-09 14:14:14 +053089import static org.mockito.Mockito.when;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070090import static org.onosproject.net.AnnotationKeys.PORT_NAME;
Matteo Scandolo2542e5d2021-12-01 16:53:41 -080091import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.ERROR;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070092import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.NONE;
93import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.ADDED;
94import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.PENDING_ADD;
Matteo Scandolo2542e5d2021-12-01 16:53:41 -080095import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.PENDING_REMOVE;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -070096import static org.opencord.olt.impl.OltFlowService.OltFlowsStatus.REMOVED;
97import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_BP_ID_DEFAULT;
Matteo Scandolo97449bb2021-12-09 15:33:46 -080098import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_MCAST_SERVICE_NAME;
Harsh Awasthic1e4bf52022-02-09 14:14:14 +053099import static org.opencord.olt.impl.OsgiPropertyConstants.DEFAULT_MCAST_SERVICE_NAME_DEFAULT;
100import static org.opencord.olt.impl.OsgiPropertyConstants.DOWNSTREAM_OLT;
101import static org.opencord.olt.impl.OsgiPropertyConstants.DOWNSTREAM_ONU;
102import static org.opencord.olt.impl.OsgiPropertyConstants.UPSTREAM_OLT;
103import static org.opencord.olt.impl.OsgiPropertyConstants.UPSTREAM_ONU;
104import static org.opencord.olt.impl.fttb.FttbUtils.FTTB_FLOW_DIRECTION;
105import static org.opencord.olt.impl.fttb.FttbUtils.FTTB_FLOW_DOWNSTREAM;
106import static org.opencord.olt.impl.fttb.FttbUtils.FTTB_FLOW_UPSTREAM;
107import static org.opencord.olt.impl.fttb.FttbUtils.FTTB_SERVICE_NAME;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700108
109public class OltFlowServiceTest extends OltTestHelpers {
110
Andrea Campanella40d2b342022-02-04 18:13:37 +0100111 public static final String PORT_1 = "port-1";
112 public static final String PORT_2 = "port-2";
113 public static final String PORT_3 = "port-3";
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800114 private OltFlowService component;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700115 private OltFlowService oltFlowService;
Andrea Campanella34ce61a2022-04-28 18:55:46 +0200116
117 private DeviceService deviceService;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700118 OltFlowService.InternalFlowListener internalFlowListener;
119 private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
120 private final short eapolDefaultVlan = 4091;
121
122 private final DeviceId deviceId = DeviceId.deviceId("test-device");
123 private final Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
124 "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
125 Port nniPort = new OltPort(testDevice, true, PortNumber.portNumber(1048576),
126 DefaultAnnotations.builder().set(PORT_NAME, "nni-1").build());
127 Port nniPortDisabled = new OltPort(testDevice, false, PortNumber.portNumber(1048576),
128 DefaultAnnotations.builder().set(PORT_NAME, "nni-1").build());
129 Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
130 DefaultAnnotations.builder().set(PORT_NAME, "uni-1").build());
131
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530132 private final UniTagInformation dpuMgmtUti = new UniTagInformation.Builder()
133 .setPonCTag(VlanId.vlanId("6"))
134 .setPonSTag(VlanId.vlanId("60"))
135 .setUsPonCTagPriority(1)
136 .setUsPonSTagPriority(2)
137 .setTechnologyProfileId(64)
138 .setUpstreamBandwidthProfile("usBp")
139 .setUpstreamOltBandwidthProfile("usOltBp")
140 .setServiceName(FttbUtils.FTTB_SERVICE_DPU_MGMT_TRAFFIC)
141 .setIsDhcpRequired(true)
142 .setEnableMacLearning(true)
143 .build();
144
145 private final UniTagInformation ancpUti = new UniTagInformation.Builder()
146 .setPonCTag(VlanId.vlanId("4"))
147 .setPonSTag(VlanId.vlanId("40"))
148 .setUsPonCTagPriority(3)
149 .setUsPonSTagPriority(4)
150 .setTechnologyProfileId(64)
151 .setUpstreamBandwidthProfile("usBp")
152 .setUpstreamOltBandwidthProfile("usOltBp")
153 .setServiceName(FttbUtils.FTTB_SERVICE_DPU_ANCP_TRAFFIC)
154 .setIsDhcpRequired(false)
155 .build();
156
157 private final UniTagInformation fttbSubscriberUti = new UniTagInformation.Builder()
158 .setPonCTag(VlanId.vlanId("8"))
159 .setPonSTag(VlanId.vlanId("80"))
160 .setTechnologyProfileId(64)
161 .setUpstreamBandwidthProfile("usBp")
162 .setUpstreamOltBandwidthProfile("usOltBp")
163 .setServiceName(FttbUtils.FTTB_SERVICE_SUBSCRIBER_TRAFFIC)
164 .setIsDhcpRequired(false)
165 .build();
166
167
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700168 @Before
169 public void setUp() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800170 component = new OltFlowService();
171 component.cfgService = new ComponentConfigAdapter();
172 component.sadisService = Mockito.mock(SadisService.class);
173 component.coreService = Mockito.spy(new CoreServiceAdapter());
174 component.oltMeterService = Mockito.mock(OltMeterService.class);
175 component.flowObjectiveService = Mockito.mock(FlowObjectiveService.class);
176 component.hostService = Mockito.mock(HostService.class);
177 component.flowRuleService = Mockito.mock(FlowRuleService.class);
178 component.storageService = new TestStorageService();
179 component.oltDeviceService = Mockito.mock(OltDeviceService.class);
180 component.appId = testAppId;
181 component.deviceService = Mockito.mock(DeviceService.class);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700182
183 doReturn(Mockito.mock(BaseInformationService.class))
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800184 .when(component.sadisService).getSubscriberInfoService();
185 doReturn(testAppId).when(component.coreService).registerApplication("org.opencord.olt");
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530186 doReturn(testDevice).when(component.deviceService).getDevice(testDevice.id());
187 when(component.sadisService.getSubscriberInfoService().get(testDevice.serialNumber())).
188 thenReturn(Mockito.mock(SubscriberAndDeviceInformation.class));
189 when(component.oltDeviceService.getNniPort(testDevice)).thenReturn(Optional.of(nniPort));
190
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800191 component.activate(null);
192 component.bindSadisService(component.sadisService);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700193
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800194 internalFlowListener = spy(component.internalFlowListener);
195
196 oltFlowService = spy(component);
Andrea Campanella34ce61a2022-04-28 18:55:46 +0200197 deviceService = Mockito.mock(DeviceService.class);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700198 }
199
200 @After
201 public void tearDown() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800202 component.deactivate(null);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700203 }
204
205 @Test
206 public void testUpdateConnectPointStatus() {
207
208 DeviceId deviceId = DeviceId.deviceId("test-device");
209 ProviderId pid = new ProviderId("of", "foo");
210 Device device =
211 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
212 Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100213 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700214 Port port2 = new DefaultPort(device, PortNumber.portNumber(2), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100215 DefaultAnnotations.builder().set(PORT_NAME, PORT_2).build());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700216 Port port3 = new DefaultPort(device, PortNumber.portNumber(3), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100217 DefaultAnnotations.builder().set(PORT_NAME, PORT_3).build());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700218
219 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), new UniTagInformation());
220 ServiceKey sk2 = new ServiceKey(new AccessDevicePort(port2), new UniTagInformation());
221 ServiceKey sk3 = new ServiceKey(new AccessDevicePort(port3), new UniTagInformation());
222
223 // cpStatus map for the test
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800224 component.cpStatus = component.storageService.
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700225 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
Andrea Campanella87241ae2022-03-11 11:20:24 +0100226 OltPortStatus cp1Status = new OltPortStatus(PENDING_ADD, NONE, NONE, NONE, NONE);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800227 component.cpStatus.put(sk1, cp1Status);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700228
229 //check that we only update the provided value
Andrea Campanella87241ae2022-03-11 11:20:24 +0100230 component.updateConnectPointStatus(sk1, ADDED, null, null, null, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800231 OltPortStatus updated = component.cpStatus.get(sk1);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700232 Assert.assertEquals(ADDED, updated.defaultEapolStatus);
233 Assert.assertEquals(NONE, updated.subscriberFlowsStatus);
234 Assert.assertEquals(NONE, updated.dhcpStatus);
235
236 // check that it creates an entry if it does not exist
Andrea Campanella87241ae2022-03-11 11:20:24 +0100237 component.updateConnectPointStatus(sk2, PENDING_ADD, NONE, NONE, NONE, NONE);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800238 Assert.assertNotNull(component.cpStatus.get(sk2));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700239
240 // check that if we create a new entry with null values they're converted to NONE
Andrea Campanella87241ae2022-03-11 11:20:24 +0100241 component.updateConnectPointStatus(sk3, null, null, null, null, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800242 updated = component.cpStatus.get(sk3);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700243 Assert.assertEquals(NONE, updated.defaultEapolStatus);
244 Assert.assertEquals(NONE, updated.subscriberFlowsStatus);
245 Assert.assertEquals(NONE, updated.dhcpStatus);
246 }
247
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800248 /**
249 * If the flow status is PENDING_REMOVE or ERROR and there is no
250 * previous state in the map that don't update it.
251 * In case of a device disconnection we immediately wipe out the status,
252 * but then flows might update the cpStatus map. That result
253 */
254 @Test
255 public void doNotUpdateConnectPointStatus() {
256 DeviceId deviceId = DeviceId.deviceId("test-device");
257 ProviderId pid = new ProviderId("of", "foo");
258 Device device =
259 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
260 Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100261 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800262
263 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), new UniTagInformation());
264
265 // cpStatus map for the test
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800266 component.cpStatus = component.storageService.
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800267 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
268
269 // check that an entry is not created if the only status is pending remove
Andrea Campanella87241ae2022-03-11 11:20:24 +0100270 component.updateConnectPointStatus(sk1, null, null, null, PENDING_REMOVE, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800271 OltPortStatus entry = component.cpStatus.get(sk1);
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800272 Assert.assertNull(entry);
273
274 // check that an entry is not created if the only status is ERROR
Andrea Campanella87241ae2022-03-11 11:20:24 +0100275 component.updateConnectPointStatus(sk1, null, null, null, ERROR, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800276 entry = component.cpStatus.get(sk1);
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800277 Assert.assertNull(entry);
278 }
279
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700280 @Test
281 public void testHasDefaultEapol() {
282 DeviceId deviceId = DeviceId.deviceId("test-device");
283 ProviderId pid = new ProviderId("of", "foo");
284
285 Device device =
286 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
287
288 Port port = new DefaultPort(device, PortNumber.portNumber(16), true,
289 DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
290 ServiceKey skWithStatus = new ServiceKey(new AccessDevicePort(port),
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800291 component.defaultEapolUniTag);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700292
293 Port port17 = new DefaultPort(device, PortNumber.portNumber(17), true,
294 DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
295
296 OltPortStatus portStatusAdded = new OltPortStatus(
297 OltFlowService.OltFlowsStatus.ADDED,
298 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000299 null,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100300 null,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700301 null
302 );
303
304 OltPortStatus portStatusRemoved = new OltPortStatus(
305 REMOVED,
306 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000307 null,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100308 null,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700309 null
310 );
311
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800312 component.cpStatus.put(skWithStatus, portStatusAdded);
313 Assert.assertTrue(component.hasDefaultEapol(port));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700314
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800315 component.cpStatus.put(skWithStatus, portStatusRemoved);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700316
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800317 Assert.assertFalse(component.hasDefaultEapol(port17));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700318 }
319
320 @Test
321 public void testHasSubscriberFlows() {
322 // TODO test with multiple services
323 DeviceId deviceId = DeviceId.deviceId("test-device");
324 ProviderId pid = new ProviderId("of", "foo");
325
326 Device device =
327 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
328
329 Port port = new DefaultPort(device, PortNumber.portNumber(16), true,
330 DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
331
332 UniTagInformation uti = new UniTagInformation.Builder().setServiceName("test").build();
333 ServiceKey skWithStatus = new ServiceKey(new AccessDevicePort(port),
334 uti);
335
336 OltPortStatus withDefaultEapol = new OltPortStatus(
337 ADDED,
338 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000339 NONE,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100340 NONE,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700341 NONE
342 );
343
344 OltPortStatus withDhcp = new OltPortStatus(
345 REMOVED,
346 NONE,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100347 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000348 ADDED,
349 NONE
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700350 );
351
352 OltPortStatus withSubFlow = new OltPortStatus(
353 REMOVED,
354 ADDED,
yasin sapli0823c932022-01-26 11:26:09 +0000355 ADDED,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100356 ADDED,
yasin sapli0823c932022-01-26 11:26:09 +0000357 NONE
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700358 );
359
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800360 component.cpStatus.put(skWithStatus, withDefaultEapol);
361 Assert.assertFalse(component.hasSubscriberFlows(port, uti));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700362
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800363 component.cpStatus.put(skWithStatus, withDhcp);
364 Assert.assertTrue(component.hasDhcpFlows(port, uti));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700365
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800366 component.cpStatus.put(skWithStatus, withSubFlow);
367 Assert.assertTrue(component.hasSubscriberFlows(port, uti));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700368 }
369
370 @Test
371 public void testHandleBasicPortFlowsNoEapol() throws Exception {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800372 component.enableEapol = false;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700373 // create empty service for testing
374 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
375 UniTagInformation empty = new UniTagInformation.Builder().build();
376 uniTagInformationList.add(empty);
377
378 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
379 si.setUniTagList(uniTagInformationList);
380
381 final DiscoveredSubscriber addedSub =
382 new DiscoveredSubscriber(testDevice,
383 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
384 false, si);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800385 component.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700386 // if eapol is not enabled there's nothing we need to do,
387 // so make sure we don't even call sadis
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800388 verify(component.subsService, never()).get(any());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700389 }
390
391 @Test
392 public void testHandleBasicPortFlowsWithEapolNoMeter() throws Exception {
393 // create empty service for testing
394 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
395 UniTagInformation empty = new UniTagInformation.Builder().build();
396 uniTagInformationList.add(empty);
397 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
398 si.setUniTagList(uniTagInformationList);
399 final DiscoveredSubscriber addedSub =
400 new DiscoveredSubscriber(testDevice,
401 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
402 false, si);
403 // whether the meter is pending or not is up to the createMeter method to handle
404 // we just don't proceed with the subscriber till it's ready
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800405 doReturn(false).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700406 .createMeter(addedSub.device.id(), DEFAULT_BP_ID_DEFAULT);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800407 boolean res = component.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700408
409 Assert.assertFalse(res);
410
411 // we do not create flows
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800412 verify(component.flowObjectiveService, never())
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700413 .filter(eq(addedSub.device.id()), any());
414 }
415
416 @Test
417 public void testHandleBasicPortFlowsWithEapolAddedMeter() throws Exception {
418 // create empty service for testing
419 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
420 UniTagInformation empty = new UniTagInformation.Builder().build();
421 uniTagInformationList.add(empty);
422 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
423 si.setUniTagList(uniTagInformationList);
424 final DiscoveredSubscriber addedSub =
425 new DiscoveredSubscriber(testDevice,
426 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
427 false, si);
428 // this is the happy case, we have the meter so we check that the default EAPOL flow
429 // is installed
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800430 doReturn(true).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700431 .createMeter(deviceId, DEFAULT_BP_ID_DEFAULT);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800432 doReturn(true).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700433 .hasMeterByBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800434 doReturn(MeterId.meterId(1)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700435 .getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
436
437 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
438 .permit()
439 .withKey(Criteria.matchInPort(uniUpdateEnabled.number()))
440 .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
441 .fromApp(testAppId)
442 .withPriority(10000)
443 .withMeta(
444 DefaultTrafficTreatment.builder()
445 .meter(MeterId.meterId(1))
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530446 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(
Harsh Awasthi498b5c62022-03-21 23:19:46 +0530447 VlanId.NONE,
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800448 component.defaultTechProfileId, MeterId.meterId(1)), 0)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700449 .setOutput(PortNumber.CONTROLLER)
450 .pushVlan()
451 .setVlanId(VlanId.vlanId(eapolDefaultVlan)).build()
452 )
453 .add();
454
455
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800456 component.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700457
458 // we check for an existing meter (present)
459 // FIXME understand why the above test invokes this call and this one doesn't
460// verify(oltFlowService.oltMeterService, times(1))
461// .hasMeterByBandwidthProfile(eq(addedSub.device.id()), eq(DEFAULT_BP_ID_DEFAULT));
462
463 // the meter exist, no need to check for PENDING or to create it
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800464 verify(component.oltMeterService, never())
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700465 .hasPendingMeterByBandwidthProfile(eq(deviceId), eq(DEFAULT_BP_ID_DEFAULT));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800466 verify(component.oltMeterService, never())
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700467 .createMeterForBp(eq(deviceId), eq(DEFAULT_BP_ID_DEFAULT));
468
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800469 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700470 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
471 }
472
473 @Test
474 public void testHandleBasicPortFlowsRemovedSub() throws Exception {
475 // create empty service for testing
476 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
477 UniTagInformation empty = new UniTagInformation.Builder().build();
478 uniTagInformationList.add(empty);
479 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
480 si.setUniTagList(uniTagInformationList);
481 final DiscoveredSubscriber removedSub =
482 new DiscoveredSubscriber(testDevice,
483 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
484 false, si);
485 // we are testing that when a port goes down we remove the default EAPOL flow
486
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800487 doReturn(MeterId.meterId(1)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700488 .getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
489
490 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
491 .deny()
492 .withKey(Criteria.matchInPort(uniUpdateEnabled.number()))
493 .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
494 .fromApp(testAppId)
495 .withPriority(10000)
496 .withMeta(
497 DefaultTrafficTreatment.builder()
498 .meter(MeterId.meterId(1))
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530499 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(
Harsh Awasthi498b5c62022-03-21 23:19:46 +0530500 VlanId.NONE,
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800501 component.defaultTechProfileId, MeterId.meterId(1)), 0)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700502 .setOutput(PortNumber.CONTROLLER)
503 .pushVlan()
504 .setVlanId(VlanId.vlanId(eapolDefaultVlan)).build()
505 )
506 .add();
507
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800508 component.handleBasicPortFlows(removedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700509
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800510 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700511 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
512 }
513
514 @Test
515 public void testHandleNniFlowsOnlyLldp() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800516 component.enableDhcpOnNni = false;
517 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700518
519 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
520 .permit()
521 .withKey(Criteria.matchInPort(nniPort.number()))
522 .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
523 .fromApp(testAppId)
524 .withPriority(10000)
525 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
526 .add();
527
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800528 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700529 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800530 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700531 .filter(eq(deviceId), any());
532 }
533
534 @Test
535 public void testHandleNniFlowsDhcpV4() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800536 component.enableDhcpOnNni = true;
537 component.enableDhcpV4 = true;
538 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700539
540 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
541 .permit()
542 .withKey(Criteria.matchInPort(nniPort.number()))
543 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
544 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
545 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
546 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
547 .fromApp(testAppId)
548 .withPriority(10000)
549 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
550 .add();
551
552 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800553 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700554 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
555 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800556 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700557 .filter(eq(deviceId), any());
558 }
559
560 @Test
561 public void testRemoveNniFlowsDhcpV4() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800562 component.enableDhcpOnNni = true;
563 component.enableDhcpV4 = true;
564 component.handleNniFlows(testDevice, nniPortDisabled, OltFlowService.FlowOperation.REMOVE);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700565
566 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
567 .deny()
568 .withKey(Criteria.matchInPort(nniPort.number()))
569 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
570 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
571 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
572 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
573 .fromApp(testAppId)
574 .withPriority(10000)
575 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
576 .add();
577
578 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800579 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700580 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
581 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800582 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700583 .filter(eq(deviceId), any());
584 }
585
586 @Test
587 public void testHandleNniFlowsDhcpV6() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800588 component.enableDhcpOnNni = true;
589 component.enableDhcpV4 = false;
590 component.enableDhcpV6 = true;
591 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700592
593 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
594 .permit()
595 .withKey(Criteria.matchInPort(nniPort.number()))
596 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV6.ethType()))
597 .addCondition(Criteria.matchIPProtocol(IPv6.PROTOCOL_UDP))
598 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(546)))
599 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(547)))
600 .fromApp(testAppId)
601 .withPriority(10000)
602 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
603 .add();
604
605 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800606 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700607 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
608 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800609 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700610 .filter(eq(deviceId), any());
611 }
612
613 @Test
614 public void testHandleNniFlowsIgmp() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800615 component.enableDhcpOnNni = false;
616 component.enableIgmpOnNni = true;
617 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700618
619 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
620 .permit()
621 .withKey(Criteria.matchInPort(nniPort.number()))
622 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
623 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
624 .fromApp(testAppId)
625 .withPriority(10000)
626 .add();
627
628 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800629 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700630 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
631 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800632 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700633 .filter(eq(deviceId), any());
634 }
635
636 @Test
yasin sapli0823c932022-01-26 11:26:09 +0000637 public void testHandleNniFlowsPppoe() {
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530638 component.enableDhcpOnNni = false;
yasin sapli0823c932022-01-26 11:26:09 +0000639 component.enablePppoeOnNni = true;
640 component.enablePppoe = true;
641 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
642
643 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
644 .permit()
645 .withKey(Criteria.matchInPort(nniPort.number()))
646 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
647 .fromApp(testAppId)
648 .withPriority(10000)
649 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
650 .add();
651
652 // invoked with the correct Pppoe filtering objective
653 verify(component.flowObjectiveService, times(1))
654 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
655 // invoked only twice, LLDP and DHCP
656 verify(component.flowObjectiveService, times(2))
657 .filter(eq(deviceId), any());
658 }
659
660 @Test
661 public void testRemoveNniFlowsPppoe() {
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530662 component.enableDhcpOnNni = false;
yasin sapli0823c932022-01-26 11:26:09 +0000663 component.enablePppoeOnNni = true;
664 component.enablePppoe = true;
665 component.handleNniFlows(testDevice, nniPortDisabled, OltFlowService.FlowOperation.REMOVE);
666
667 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
668 .deny()
669 .withKey(Criteria.matchInPort(nniPort.number()))
670 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
671 .fromApp(testAppId)
672 .withPriority(10000)
673 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
674 .add();
675
676 // invoked with the correct Pppoe filtering objective
677 verify(component.flowObjectiveService, times(1))
678 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
679 // invoked only twice, LLDP and DHCP
680 verify(component.flowObjectiveService, times(2))
681 .filter(eq(deviceId), any());
682 }
683
684 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700685 public void testMacAddressNotRequired() {
686 // create a single service that doesn't require mac address
687 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
688 UniTagInformation hsia = new UniTagInformation.Builder()
689 .setEnableMacLearning(false)
690 .build();
691 uniTagInformationList.add(hsia);
692 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
693 si.setUniTagList(uniTagInformationList);
694
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800695 boolean isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700696 // we return true as we don't care wether it's available or not
697 Assert.assertTrue(isMacAvailable);
698 }
699
700 @Test
701 public void testIsMacAddressAvailableViaMacLearning() {
702
703 // create a single service that requires macLearning to be enabled
704 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
705 VlanId hsiaCtag = VlanId.vlanId((short) 11);
706 UniTagInformation hsia = new UniTagInformation.Builder()
707 .setPonCTag(hsiaCtag)
708 .setEnableMacLearning(true).build();
709 uniTagInformationList.add(hsia);
710
711 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
712 si.setUniTagList(uniTagInformationList);
713
714 // with no hosts discovered, return false
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800715 boolean isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700716 Assert.assertFalse(isMacAvailable);
717
718 // with a discovered host, return true
719 Host fakeHost = new DefaultHost(ProviderId.NONE, HostId.hostId(MacAddress.NONE), MacAddress.ZERO,
720 hsiaCtag, HostLocation.NONE, new HashSet<>(), DefaultAnnotations.builder().build());
721 Set<Host> hosts = new HashSet<>(Arrays.asList(fakeHost));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800722 doReturn(hosts).when(component.hostService).getConnectedHosts((ConnectPoint) any());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700723
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800724 isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700725 Assert.assertTrue(isMacAvailable);
726 }
727
728 @Test
729 public void testIsMacAddressAvailableViaConfiguration() {
730 // create a single service that has a macAddress configured
731 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
732 UniTagInformation hsia = new UniTagInformation.Builder()
733 .setConfiguredMacAddress("2e:0a:00:01:00:00")
734 .build();
735 uniTagInformationList.add(hsia);
736 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
737 si.setUniTagList(uniTagInformationList);
738
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800739 boolean isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700740 Assert.assertTrue(isMacAvailable);
741 }
742
743 @Test
744 public void testHandleSubscriberDhcpFlowsAdd() {
745
746 String usBp = "usBp";
747 String usOltBp = "usOltBp";
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800748 component.enableDhcpV4 = true;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700749
750 // create two services, one requires DHCP the other doesn't
751 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
752 VlanId hsiaCtag = VlanId.vlanId((short) 11);
753 UniTagInformation hsia = new UniTagInformation.Builder()
754 .setPonCTag(hsiaCtag)
755 .setTechnologyProfileId(64)
756 .setUniTagMatch(VlanId.vlanId(VlanId.NO_VID))
757 .setUpstreamBandwidthProfile(usBp)
758 .setUpstreamOltBandwidthProfile(usOltBp)
759 .setIsDhcpRequired(true).build();
760 UniTagInformation mc = new UniTagInformation.Builder()
761 .setIsDhcpRequired(false).build();
762 uniTagInformationList.add(hsia);
763 uniTagInformationList.add(mc);
764
765 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
766 si.setUniTagList(uniTagInformationList);
767
768 final DiscoveredSubscriber addedSub =
769 new DiscoveredSubscriber(testDevice,
770 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
771 false, si);
772
773 // return meter IDs
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800774 doReturn(MeterId.meterId(2)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700775 .getMeterIdForBandwidthProfile(addedSub.device.id(), usBp);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800776 doReturn(MeterId.meterId(3)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700777 .getMeterIdForBandwidthProfile(addedSub.device.id(), usOltBp);
778
779 // TODO improve the matches on the filter
780 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
781 .permit()
782 .withKey(Criteria.matchInPort(addedSub.port.number()))
783 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
784 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
785 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
786 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
787 .fromApp(testAppId)
788 .withPriority(10000)
789 .add();
790
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800791 component.handleSubscriberDhcpFlows(addedSub.device.id(), addedSub.port,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700792 OltFlowService.FlowOperation.ADD, si);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800793 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700794 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
795 }
796
797 @Test
yasin sapli0823c932022-01-26 11:26:09 +0000798 public void testHandleSubscriberPppoeFlowsAdd() {
799
800 String usBp = "usBp";
801 String usOltBp = "usOltBp";
802 component.enablePppoe = true;
803
804 // create two services, one requires Pppoe the other doesn't
805 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
806 VlanId hsiaCtag = VlanId.vlanId((short) 11);
807 UniTagInformation hsia = new UniTagInformation.Builder()
808 .setPonCTag(hsiaCtag)
809 .setTechnologyProfileId(64)
810 .setUniTagMatch(VlanId.vlanId(VlanId.NO_VID))
811 .setUpstreamBandwidthProfile(usBp)
812 .setUpstreamOltBandwidthProfile(usOltBp)
813 .setIsPppoeRequired(true).build();
814 UniTagInformation mc = new UniTagInformation.Builder()
815 .setIsPppoeRequired(false).build();
816 uniTagInformationList.add(hsia);
817 uniTagInformationList.add(mc);
818
819 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
820 si.setUniTagList(uniTagInformationList);
821
822 final DiscoveredSubscriber addedSub =
823 new DiscoveredSubscriber(testDevice,
824 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
825 false, si);
826
827 // return meter IDs
828 doReturn(MeterId.meterId(2)).when(component.oltMeterService)
829 .getMeterIdForBandwidthProfile(addedSub.device.id(), usBp);
830 doReturn(MeterId.meterId(3)).when(component.oltMeterService)
831 .getMeterIdForBandwidthProfile(addedSub.device.id(), usOltBp);
832
833 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
834 .permit()
835 .withKey(Criteria.matchInPort(addedSub.port.number()))
836 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
837 .fromApp(testAppId)
838 .withPriority(10000)
839 .add();
840
841 component.handleSubscriberPppoeFlows(addedSub.device.id(), addedSub.port,
842 OltFlowService.FlowOperation.ADD, si);
843 verify(component.flowObjectiveService, times(1))
844 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
845 }
846
847 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700848 public void testInternalFlowListenerNotMaster() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800849 doReturn(false).when(component.oltDeviceService).isLocalLeader(any());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700850
851 FlowRule flowRule = DefaultFlowRule.builder()
852 .forDevice(DeviceId.deviceId("foo"))
853 .fromApp(testAppId)
854 .makePermanent()
855 .withPriority(1000)
856 .build();
857 FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED,
858 flowRule);
859
860 internalFlowListener.event(event);
861
862 // if we're not master of the device, we should not update
863 verify(internalFlowListener, never()).updateCpStatus(any(), any(), any());
864 }
865
866 @Test
867 public void testInternalFlowListenerDifferentApp() {
868 ApplicationId someAppId = new DefaultApplicationId(1, "org.opencord.olt.not-test");
869 FlowRule flowRule = DefaultFlowRule.builder()
870 .forDevice(DeviceId.deviceId("foo"))
871 .fromApp(someAppId)
872 .makePermanent()
873 .withPriority(1000)
874 .build();
875 FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED,
876 flowRule);
877
878 internalFlowListener.event(event);
879
880 // if we're not master of the device, we should not update
881 verify(internalFlowListener, never()).updateCpStatus(any(), any(), any());
882 }
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800883
884 @Test
885 public void testRemoveSubscriberFlows() {
886 // test that if we have EAPOL we wait till the tagged flow is removed
887 // before installing the default one
888
889 // setup
890 component.enableEapol = true;
891
892 // mock data
893 DeviceId deviceId = DeviceId.deviceId("test-device");
894 ProviderId pid = new ProviderId("of", "foo");
895 Device device =
896 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
897 Port port = new DefaultPort(device, PortNumber.portNumber(1), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100898 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800899
900 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
901 UniTagInformation hsia = new UniTagInformation.Builder()
902 .setUpstreamBandwidthProfile("usbp")
903 .setDownstreamBandwidthProfile("dsbp")
904 .setPonCTag(VlanId.vlanId((short) 900)).build();
905 uniTagInformationList.add(hsia);
906 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
907 si.setUniTagList(uniTagInformationList);
908
909 DiscoveredSubscriber sub = new DiscoveredSubscriber(
910 device, port, DiscoveredSubscriber.Status.REMOVED, true, si);
911
912 // first test that when we remove the EAPOL flow we return false so that the
913 // subscriber is not removed from the queue
Andrea Campanella34ce61a2022-04-28 18:55:46 +0200914 doReturn(null).when(deviceService).getPort(any());
Andrea Campanella87241ae2022-03-11 11:20:24 +0100915 doReturn(true).when(oltFlowService).areSubscriberFlowsPendingRemoval(any(), any(), eq(true));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800916 boolean res = oltFlowService.removeSubscriberFlows(sub, DEFAULT_BP_ID_DEFAULT, DEFAULT_MCAST_SERVICE_NAME);
917 verify(oltFlowService, times(1))
918 .handleSubscriberDhcpFlows(deviceId, port, OltFlowService.FlowOperation.REMOVE, si);
919 verify(oltFlowService, times(1))
920 .handleSubscriberEapolFlows(sub, OltFlowService.FlowOperation.REMOVE, si);
921 verify(oltFlowService, times(1))
922 .handleSubscriberDataFlows(device, port, OltFlowService.FlowOperation.REMOVE,
923 si, DEFAULT_MCAST_SERVICE_NAME);
924 verify(oltFlowService, times(1))
925 .handleSubscriberIgmpFlows(sub, OltFlowService.FlowOperation.REMOVE);
926 verify(oltFlowService, never())
927 .handleEapolFlow(any(), any(), any(),
928 eq(OltFlowService.FlowOperation.ADD), eq(VlanId.vlanId(OltFlowService.EAPOL_DEFAULT_VLAN)));
929 Assert.assertFalse(res);
930
931 // then test that if the tagged EAPOL is not there we install the default EAPOL
932 // and return true so we remove the subscriber from the queue
Andrea Campanella87241ae2022-03-11 11:20:24 +0100933 doReturn(false).when(oltFlowService).areSubscriberFlowsPendingRemoval(any(), any(), eq(true));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800934 doReturn(port).when(oltFlowService.deviceService).getPort(deviceId, port.number());
935 res = oltFlowService.removeSubscriberFlows(sub, DEFAULT_BP_ID_DEFAULT, DEFAULT_MCAST_SERVICE_NAME);
936 verify(oltFlowService, times(1))
937 .handleEapolFlow(any(), any(), any(),
938 eq(OltFlowService.FlowOperation.ADD), eq(VlanId.vlanId(OltFlowService.EAPOL_DEFAULT_VLAN)));
939 Assert.assertTrue(res);
940 }
Andrea Campanella40d2b342022-02-04 18:13:37 +0100941
942 @Test
943 public void testRemovedFlowEvent() throws InterruptedException {
944 // test that we update the status in case of REMOVED flow even with non
945 // existing port in the onos device manager
946
947 DeviceId deviceId = DeviceId.deviceId("test-device");
948 ProviderId pid = new ProviderId("of", "foo");
949 Device device =
950 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
951
952 Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
953 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
954 // create empty service for testing
955 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
956 UniTagInformation vlanUniTag = new UniTagInformation.Builder().setPonCTag(VlanId.vlanId((short) 60))
957 .build();
958 uniTagInformationList.add(vlanUniTag);
959 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
960 si.setUniTagList(uniTagInformationList);
961 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), vlanUniTag);
962
963 TrafficSelector selector = DefaultTrafficSelector.builder()
964 .matchInPort(port1.number())
965 .matchVlanId(VlanId.vlanId((short) 60))
966 .build();
967
968 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
969 .immediate()
970 .setOutput(port1.number())
971 .build();
972
973 FlowRule flowRule = DefaultFlowRule.builder()
974 .makePermanent()
975 .withPriority(1000)
976 .forTable(0)
977 .forDevice(deviceId)
978 .fromApp(testAppId)
979 .withSelector(selector)
980 .withTreatment(treatment)
981 .build();
982
983 // cpStatus map for the test
984 component.cpStatus = component.storageService.
985 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
Andrea Campanella87241ae2022-03-11 11:20:24 +0100986 OltPortStatus cp1Status = new OltPortStatus(NONE, NONE, PENDING_REMOVE, NONE, NONE);
Andrea Campanella40d2b342022-02-04 18:13:37 +0100987 component.cpStatus.put(sk1, cp1Status);
988
989 FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVED, flowRule);
990 doReturn(true).when(component.oltDeviceService).isLocalLeader(any());
991 doReturn(device).when(component.deviceService).getDevice(deviceId);
992 doReturn(si).when(component.subsService).get(PORT_1);
993
994 oltFlowService.internalFlowListener.event(event);
995
996 //Some time to finish the operation
997 TimeUnit.MILLISECONDS.sleep(200);
998
999 OltPortStatus status = component.cpStatus.get(sk1);
1000 Assert.assertEquals(REMOVED, status.subscriberFlowsStatus);
1001 }
Harsh Awasthic1e4bf52022-02-09 14:14:14 +05301002
1003 @Test
1004 public void testHandleNniFlowsDhcpV4WithNniDhcpTrapVid() {
1005 component.enableDhcpOnNni = true;
1006 component.enableDhcpV4 = true;
1007
1008 SubscriberAndDeviceInformation testOltFttbSadis = new SubscriberAndDeviceInformation();
1009 testOltFttbSadis.setNniDhcpTrapVid(VlanId.vlanId("60"));
1010
1011 when(component.sadisService.getSubscriberInfoService().get(testDevice.serialNumber())).
1012 thenReturn(testOltFttbSadis);
1013
1014 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
1015
1016 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1017 .permit()
1018 .withKey(Criteria.matchInPort(nniPort.number()))
1019 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1020 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1021 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
1022 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
1023 .addCondition(Criteria.matchVlanId(testOltFttbSadis.nniDhcpTrapVid()))
1024 .fromApp(testAppId)
1025 .withPriority(10000)
1026 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
1027 .add();
1028
1029 // invoked with the correct DHCP filtering objective
1030 verify(component.flowObjectiveService, times(1))
1031 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1032 // invoked only twice, LLDP and DHCP
1033 verify(component.flowObjectiveService, times(2))
1034 .filter(eq(deviceId), any());
1035 }
1036
1037 @Test
1038 public void testHandleFttbSubscriberDhcpFlowsAdd() {
1039 component.enableDhcpV4 = true;
1040
1041 // add two services, one requires DHCP the other doesn't
1042 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1043
1044 UniTagInformation mc = new UniTagInformation.Builder()
1045 .setIsDhcpRequired(false).build();
1046 uniTagInformationList.add(dpuMgmtUti);
1047 uniTagInformationList.add(mc);
1048
1049 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1050 si.setUniTagList(uniTagInformationList);
1051
1052 final DiscoveredSubscriber addedSub =
1053 new DiscoveredSubscriber(testDevice,
1054 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1055 false, si);
1056
1057 // return meter IDs
1058 MeterId usBpMeterId = MeterId.meterId(2);
1059 MeterId usOltBpMeterId = MeterId.meterId(3);
1060
1061 doReturn(usBpMeterId).when(component.oltMeterService)
1062 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1063 doReturn(usOltBpMeterId).when(component.oltMeterService)
1064 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1065
1066 TrafficTreatment expectedTreatment = DefaultTrafficTreatment.builder()
1067 .setVlanId(dpuMgmtUti.getPonSTag())
1068 .setVlanPcp((byte) dpuMgmtUti.getUsPonSTagPriority())
1069 .setOutput(PortNumber.CONTROLLER)
1070 .meter(usBpMeterId)
Andrea Campanella7ef88992022-05-17 12:38:00 +02001071 //TODO why tests use this one and not the other method ?
Harsh Awasthic1e4bf52022-02-09 14:14:14 +05301072 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(VlanId.NONE,
1073 dpuMgmtUti.getTechnologyProfileId(), usOltBpMeterId), 0L).build();
1074
1075 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1076 .permit()
1077 .withKey(Criteria.matchInPort(addedSub.port.number()))
1078 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1079 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1080 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
1081 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
1082 .addCondition(Criteria.matchVlanId(dpuMgmtUti.getPonCTag()))
1083 .addCondition(Criteria.matchVlanPcp((byte) dpuMgmtUti.getUsPonCTagPriority()))
1084 .fromApp(testAppId)
1085 .withPriority(10000)
1086 .withMeta(expectedTreatment)
1087 .add();
1088
1089 component.handleSubscriberDhcpFlows(addedSub.device.id(), addedSub.port,
1090 OltFlowService.FlowOperation.ADD, si);
1091 verify(component.flowObjectiveService, times(1))
1092 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1093 }
1094
1095 @Test
1096 public void testRemoveFttbSubscriberDhcpFlows() {
1097 component.enableDhcpV4 = true;
1098
1099 // Mocking the get call, to mark the SubscriberKey as already added.
1100 component.cpStatus = Mockito.mock(Map.class);
1101 doReturn(new OltPortStatus(null, null, null, ADDED, null))
1102 .when(component.cpStatus).get(Mockito.any());
1103
1104 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1105 uniTagInformationList.add(dpuMgmtUti);
1106
1107 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1108 si.setUniTagList(uniTagInformationList);
1109
1110 final DiscoveredSubscriber removedSub =
1111 new DiscoveredSubscriber(testDevice,
1112 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1113 false, si);
1114
1115 // return meter IDs
1116 MeterId usBpMeterId = MeterId.meterId(2);
1117 MeterId usOltBpMeterId = MeterId.meterId(3);
1118
1119 doReturn(usBpMeterId).when(component.oltMeterService)
1120 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1121 doReturn(usOltBpMeterId).when(component.oltMeterService)
1122 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1123
1124 TrafficTreatment expectedTreatment = DefaultTrafficTreatment.builder()
1125 .setVlanId(dpuMgmtUti.getPonSTag())
1126 .setVlanPcp((byte) dpuMgmtUti.getUsPonSTagPriority())
1127 .setOutput(PortNumber.CONTROLLER)
1128 .meter(usBpMeterId)
1129 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(VlanId.NONE,
1130 dpuMgmtUti.getTechnologyProfileId(), usOltBpMeterId), 0L).build();
1131
1132 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1133 .deny()
1134 .withKey(Criteria.matchInPort(removedSub.port.number()))
1135 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1136 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1137 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
1138 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
1139 .addCondition(Criteria.matchVlanId(dpuMgmtUti.getPonCTag()))
1140 .addCondition(Criteria.matchVlanPcp((byte) dpuMgmtUti.getUsPonCTagPriority()))
1141 .fromApp(testAppId)
1142 .withPriority(10000)
1143 .withMeta(expectedTreatment)
1144 .add();
1145
1146 component.handleSubscriberDhcpFlows(removedSub.device.id(), removedSub.port,
1147 OltFlowService.FlowOperation.REMOVE, si);
1148 verify(component.flowObjectiveService, times(1))
1149 .filter(eq(removedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1150 }
1151
1152 @Test
1153 public void testHandleFttbMacSwitchingFlowsAdd() {
1154 component.enableDhcpV4 = true;
1155
1156 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1157
1158 uniTagInformationList.add(dpuMgmtUti);
1159 uniTagInformationList.add(ancpUti);
1160
1161 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1162 si.setUniTagList(uniTagInformationList);
1163
1164 final DiscoveredSubscriber addedSub =
1165 new DiscoveredSubscriber(testDevice,
1166 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1167 false, si);
1168
1169 // return meter IDs
1170 MeterId usBpMeterId = MeterId.meterId(1);
1171 MeterId usOltBpMeterId = MeterId.meterId(1);
1172
1173 MeterId dsBpMeterId = MeterId.meterId(2);
1174 MeterId dsOltBpMeterId = MeterId.meterId(2);
1175
1176 MacAddress mac = MacAddress.valueOf("0A:00:27:00:00:09");
1177 Host host = Mockito.mock(Host.class);
1178 doReturn(mac).when(host).mac();
1179 doReturn(dpuMgmtUti.getPonSTag()).when(host).vlan();
1180
1181 doReturn(new HashSet<>(Arrays.asList(host))).when(component.hostService)
1182 .getConnectedHosts(new ConnectPoint(addedSub.device.id(), addedSub.port.number()));
1183
1184 doReturn(usBpMeterId).when(component.oltMeterService)
1185 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1186 doReturn(usOltBpMeterId).when(component.oltMeterService)
1187 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1188
1189 doReturn(dsBpMeterId).when(component.oltMeterService)
1190 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1191 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1192 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1193
1194 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1195 for (UniTagInformation uti : uniTagInformationList) {
1196 for (String direction : directions) {
1197 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1198 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1199
1200 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1201 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1202 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1203
1204 switch (direction) {
1205 case FTTB_FLOW_UPSTREAM:
1206 expectedSelectorBuilder
1207 .matchInPort(addedSub.port.number())
1208 .matchVlanId(uti.getPonCTag())
1209 .matchVlanPcp((byte) uti.getUsPonCTagPriority())
1210 .matchEthSrc(mac);
1211
1212 expectedTreatment.setVlanId(uti.getPonSTag())
1213 .setVlanPcp((byte) uti.getUsPonSTagPriority())
1214 .setOutput(nniPort.number())
1215 .meter(usBpMeterId)
1216 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1217 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1218
1219 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1220 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1221 break;
1222
1223 case FTTB_FLOW_DOWNSTREAM:
1224 expectedSelectorBuilder
1225 .matchInPort(nniPort.number())
1226 .matchVlanId(uti.getPonSTag())
1227 .matchEthDst(mac);
1228
1229 expectedTreatment.setVlanId(uti.getPonCTag())
1230 .setOutput(addedSub.port.number())
1231 .meter(dsBpMeterId)
1232 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1233 uti.getTechnologyProfileId(), addedSub.port.number()), 0L).build();
1234
1235 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1236 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1237 break;
1238
1239 default:
1240 return;
1241 }
1242
1243 ForwardingObjective expected = DefaultForwardingObjective.builder()
1244 .withFlag(ForwardingObjective.Flag.VERSATILE)
1245 .withPriority(1000)
1246 .makePermanent()
1247 .withSelector(expectedSelectorBuilder.build())
1248 .withAnnotations(annotationBuilder.build())
1249 .fromApp(testAppId)
1250 .withTreatment(expectedTreatment.build())
1251 .add();
1252
1253 component.handleSubscriberDataFlows(addedSub.device, addedSub.port,
1254 OltFlowService.FlowOperation.ADD, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1255 verify(component.flowObjectiveService, times(1))
1256 .forward(eq(addedSub.device.id()), eq(expected));
1257 }
1258 }
1259 }
1260
1261 @Test
1262 public void testRemoveFttbMacSwitchingFlows() {
1263 component.enableDhcpV4 = true;
1264 component.cpStatus = Mockito.mock(Map.class);
1265 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1266
1267 uniTagInformationList.add(dpuMgmtUti);
1268 uniTagInformationList.add(ancpUti);
1269
1270 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1271 si.setUniTagList(uniTagInformationList);
1272
1273 final DiscoveredSubscriber removedSub =
1274 new DiscoveredSubscriber(testDevice,
1275 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1276 false, si);
1277
1278
1279 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(removedSub.port), dpuMgmtUti);
1280 ServiceKey sk2 = new ServiceKey(new AccessDevicePort(removedSub.port), ancpUti);
1281
1282 component.cpStatus = component.storageService.
1283 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
1284 OltPortStatus cp1Status = new OltPortStatus(NONE, NONE, PENDING_ADD, NONE, NONE);
1285 OltPortStatus cp2Status = new OltPortStatus(NONE, NONE, PENDING_ADD, NONE, NONE);
1286 component.cpStatus.put(sk1, cp1Status);
1287 component.cpStatus.put(sk2, cp2Status);
1288
1289 // return meter IDs
1290 MeterId usBpMeterId = MeterId.meterId(1);
1291 MeterId usOltBpMeterId = MeterId.meterId(1);
1292
1293 MeterId dsBpMeterId = MeterId.meterId(2);
1294 MeterId dsOltBpMeterId = MeterId.meterId(2);
1295
1296 MacAddress mac = MacAddress.valueOf("0A:00:27:00:00:09");
1297 Host host = Mockito.mock(Host.class);
1298 doReturn(mac).when(host).mac();
1299 doReturn(dpuMgmtUti.getPonSTag()).when(host).vlan();
1300
1301 doReturn(new HashSet<>(Arrays.asList(host))).when(component.hostService)
1302 .getConnectedHosts(new ConnectPoint(removedSub.device.id(), removedSub.port.number()));
1303
1304 doReturn(usBpMeterId).when(component.oltMeterService)
1305 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1306 doReturn(usOltBpMeterId).when(component.oltMeterService)
1307 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1308
1309 doReturn(dsBpMeterId).when(component.oltMeterService)
1310 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1311 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1312 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1313
1314 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1315 for (UniTagInformation uti : uniTagInformationList) {
1316 for (String direction : directions) {
1317 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1318 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1319
1320 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1321 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1322 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1323
1324 switch (direction) {
1325 case FTTB_FLOW_UPSTREAM:
1326 expectedSelectorBuilder
1327 .matchInPort(removedSub.port.number())
1328 .matchVlanId(uti.getPonCTag())
1329 .matchVlanPcp((byte) uti.getUsPonCTagPriority())
1330 .matchEthSrc(mac);
1331
1332 expectedTreatment.setVlanId(uti.getPonSTag())
1333 .setVlanPcp((byte) uti.getUsPonSTagPriority())
1334 .setOutput(nniPort.number())
1335 .meter(usBpMeterId)
1336 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1337 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1338
1339 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1340 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1341 break;
1342
1343 case FTTB_FLOW_DOWNSTREAM:
1344 expectedSelectorBuilder
1345 .matchInPort(nniPort.number())
1346 .matchVlanId(uti.getPonSTag())
1347 .matchEthDst(mac);
1348
1349 expectedTreatment.setVlanId(uti.getPonCTag())
1350 .setOutput(removedSub.port.number())
1351 .meter(dsBpMeterId)
1352 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1353 uti.getTechnologyProfileId(), removedSub.port.number()), 0L).build();
1354
1355 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1356 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1357 break;
1358
1359 default:
1360 return;
1361 }
1362
1363 ForwardingObjective expected = DefaultForwardingObjective.builder()
1364 .withFlag(ForwardingObjective.Flag.VERSATILE)
1365 .withPriority(1000)
1366 .makePermanent()
1367 .withSelector(expectedSelectorBuilder.build())
1368 .withAnnotations(annotationBuilder.build())
1369 .fromApp(testAppId)
1370 .withTreatment(expectedTreatment.build())
1371 .remove();
1372
1373 component.handleSubscriberDataFlows(removedSub.device, removedSub.port,
1374 OltFlowService.FlowOperation.REMOVE, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1375 verify(component.flowObjectiveService, times(1))
1376 .forward(eq(removedSub.device.id()), eq(expected));
1377 }
1378 }
1379 }
1380
1381 @Test
1382 public void testHandleFttbSubscriberFlowsAdd() {
1383 component.enableDhcpV4 = true;
1384
1385 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1386 uniTagInformationList.add(fttbSubscriberUti);
1387
1388 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1389 si.setUniTagList(uniTagInformationList);
1390
1391 final DiscoveredSubscriber addedSub =
1392 new DiscoveredSubscriber(testDevice,
1393 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1394 false, si);
1395
1396 // return meter IDs
1397 MeterId usBpMeterId = MeterId.meterId(1);
1398 MeterId usOltBpMeterId = MeterId.meterId(1);
1399
1400 MeterId dsBpMeterId = MeterId.meterId(2);
1401 MeterId dsOltBpMeterId = MeterId.meterId(2);
1402
1403 doReturn(usBpMeterId).when(component.oltMeterService)
1404 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1405 doReturn(usOltBpMeterId).when(component.oltMeterService)
1406 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1407
1408 doReturn(dsBpMeterId).when(component.oltMeterService)
1409 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1410 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1411 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1412
1413 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1414 for (UniTagInformation uti : uniTagInformationList) {
1415 for (String direction : directions) {
1416 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1417 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1418
1419 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1420 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1421 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1422
1423 switch (direction) {
1424 case FTTB_FLOW_UPSTREAM:
1425 expectedSelectorBuilder
1426 .matchInPort(addedSub.port.number())
1427 .matchVlanId(uti.getPonCTag());
1428
1429 expectedTreatment.setVlanId(uti.getPonSTag())
1430 .setOutput(nniPort.number())
1431 .meter(usBpMeterId)
1432 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1433 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1434
1435 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1436 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1437 break;
1438
1439 case FTTB_FLOW_DOWNSTREAM:
1440 expectedSelectorBuilder
1441 .matchInPort(nniPort.number())
Andrea Campanella7ef88992022-05-17 12:38:00 +02001442 .matchMetadata(uti.getPonCTag().toShort())
Harsh Awasthic1e4bf52022-02-09 14:14:14 +05301443 .matchVlanId(uti.getPonSTag());
1444
1445 expectedTreatment.setVlanId(uti.getPonCTag())
1446 .setOutput(addedSub.port.number())
1447 .meter(dsBpMeterId)
1448 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1449 uti.getTechnologyProfileId(), addedSub.port.number()), 0L).build();
1450
1451 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1452 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1453 break;
1454
1455 default:
1456 return;
1457 }
1458
1459 ForwardingObjective expected = DefaultForwardingObjective.builder()
1460 .withFlag(ForwardingObjective.Flag.VERSATILE)
1461 .withPriority(1000)
1462 .makePermanent()
1463 .withSelector(expectedSelectorBuilder.build())
1464 .withAnnotations(annotationBuilder.build())
1465 .fromApp(testAppId)
1466 .withTreatment(expectedTreatment.build())
1467 .add();
1468
1469 component.handleSubscriberDataFlows(addedSub.device, addedSub.port,
1470 OltFlowService.FlowOperation.ADD, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1471 verify(component.flowObjectiveService, times(1))
1472 .forward(eq(addedSub.device.id()), eq(expected));
1473 }
1474 }
1475 }
1476
1477 @Test
1478 public void testRemoveFttbSubscriberFlows() {
1479 component.enableDhcpV4 = true;
1480
1481 OltPortStatus oltPortStatus1 = new OltPortStatus(null, null, ADDED,
1482 null, null);
1483 // Mocking the get call, to mark the SubscriberKey as already added.
1484 component.cpStatus = Mockito.mock(Map.class);
1485 when(component.cpStatus.get(Mockito.any())).thenReturn(oltPortStatus1);
1486
1487 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1488
1489 uniTagInformationList.add(fttbSubscriberUti);
1490
1491 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1492 si.setUniTagList(uniTagInformationList);
1493
1494 final DiscoveredSubscriber removedSub =
1495 new DiscoveredSubscriber(testDevice,
1496 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1497 false, si);
1498
1499 // return meter IDs
1500 MeterId usBpMeterId = MeterId.meterId(1);
1501 MeterId usOltBpMeterId = MeterId.meterId(1);
1502
1503 MeterId dsBpMeterId = MeterId.meterId(2);
1504 MeterId dsOltBpMeterId = MeterId.meterId(2);
1505
1506 doReturn(usBpMeterId).when(component.oltMeterService)
1507 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1508 doReturn(usOltBpMeterId).when(component.oltMeterService)
1509 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1510
1511 doReturn(dsBpMeterId).when(component.oltMeterService)
1512 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1513 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1514 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1515
1516 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1517 for (UniTagInformation uti : uniTagInformationList) {
1518 for (String direction : directions) {
1519 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1520 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1521
1522 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1523 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1524 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1525
1526 switch (direction) {
1527 case FTTB_FLOW_UPSTREAM:
1528 expectedSelectorBuilder
1529 .matchInPort(removedSub.port.number())
1530 .matchVlanId(uti.getPonCTag());
1531
1532 expectedTreatment.setVlanId(uti.getPonSTag())
1533 .setOutput(nniPort.number())
1534 .meter(usBpMeterId)
1535 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1536 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1537
1538 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1539 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1540 break;
1541
1542 case FTTB_FLOW_DOWNSTREAM:
1543 expectedSelectorBuilder
1544 .matchInPort(nniPort.number())
Andrea Campanella7ef88992022-05-17 12:38:00 +02001545 .matchMetadata(uti.getPonCTag().toShort())
Harsh Awasthic1e4bf52022-02-09 14:14:14 +05301546 .matchVlanId(uti.getPonSTag());
1547
1548 expectedTreatment.setVlanId(uti.getPonCTag())
1549 .setOutput(removedSub.port.number())
1550 .meter(dsBpMeterId)
1551 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1552 uti.getTechnologyProfileId(), removedSub.port.number()), 0L).build();
1553
1554 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1555 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1556 break;
1557
1558 default:
1559 return;
1560 }
1561
1562 ForwardingObjective expected = DefaultForwardingObjective.builder()
1563 .withFlag(ForwardingObjective.Flag.VERSATILE)
1564 .withPriority(1000)
1565 .makePermanent()
1566 .withSelector(expectedSelectorBuilder.build())
1567 .withAnnotations(annotationBuilder.build())
1568 .fromApp(testAppId)
1569 .withTreatment(expectedTreatment.build())
1570 .remove();
1571
1572 component.handleSubscriberDataFlows(removedSub.device, removedSub.port,
1573 OltFlowService.FlowOperation.REMOVE, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1574 verify(component.flowObjectiveService, times(1))
1575 .forward(eq(removedSub.device.id()), eq(expected));
1576 }
1577 }
1578 }
Matteo Scandoloaa2adde2021-09-13 12:45:32 -07001579}