blob: 4196f57d449311331cc92ad21cd28281f2c6719f [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)
1071 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(VlanId.NONE,
1072 dpuMgmtUti.getTechnologyProfileId(), usOltBpMeterId), 0L).build();
1073
1074 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1075 .permit()
1076 .withKey(Criteria.matchInPort(addedSub.port.number()))
1077 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1078 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1079 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
1080 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
1081 .addCondition(Criteria.matchVlanId(dpuMgmtUti.getPonCTag()))
1082 .addCondition(Criteria.matchVlanPcp((byte) dpuMgmtUti.getUsPonCTagPriority()))
1083 .fromApp(testAppId)
1084 .withPriority(10000)
1085 .withMeta(expectedTreatment)
1086 .add();
1087
1088 component.handleSubscriberDhcpFlows(addedSub.device.id(), addedSub.port,
1089 OltFlowService.FlowOperation.ADD, si);
1090 verify(component.flowObjectiveService, times(1))
1091 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1092 }
1093
1094 @Test
1095 public void testRemoveFttbSubscriberDhcpFlows() {
1096 component.enableDhcpV4 = true;
1097
1098 // Mocking the get call, to mark the SubscriberKey as already added.
1099 component.cpStatus = Mockito.mock(Map.class);
1100 doReturn(new OltPortStatus(null, null, null, ADDED, null))
1101 .when(component.cpStatus).get(Mockito.any());
1102
1103 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1104 uniTagInformationList.add(dpuMgmtUti);
1105
1106 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1107 si.setUniTagList(uniTagInformationList);
1108
1109 final DiscoveredSubscriber removedSub =
1110 new DiscoveredSubscriber(testDevice,
1111 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1112 false, si);
1113
1114 // return meter IDs
1115 MeterId usBpMeterId = MeterId.meterId(2);
1116 MeterId usOltBpMeterId = MeterId.meterId(3);
1117
1118 doReturn(usBpMeterId).when(component.oltMeterService)
1119 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1120 doReturn(usOltBpMeterId).when(component.oltMeterService)
1121 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1122
1123 TrafficTreatment expectedTreatment = DefaultTrafficTreatment.builder()
1124 .setVlanId(dpuMgmtUti.getPonSTag())
1125 .setVlanPcp((byte) dpuMgmtUti.getUsPonSTagPriority())
1126 .setOutput(PortNumber.CONTROLLER)
1127 .meter(usBpMeterId)
1128 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(VlanId.NONE,
1129 dpuMgmtUti.getTechnologyProfileId(), usOltBpMeterId), 0L).build();
1130
1131 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1132 .deny()
1133 .withKey(Criteria.matchInPort(removedSub.port.number()))
1134 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1135 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1136 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
1137 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
1138 .addCondition(Criteria.matchVlanId(dpuMgmtUti.getPonCTag()))
1139 .addCondition(Criteria.matchVlanPcp((byte) dpuMgmtUti.getUsPonCTagPriority()))
1140 .fromApp(testAppId)
1141 .withPriority(10000)
1142 .withMeta(expectedTreatment)
1143 .add();
1144
1145 component.handleSubscriberDhcpFlows(removedSub.device.id(), removedSub.port,
1146 OltFlowService.FlowOperation.REMOVE, si);
1147 verify(component.flowObjectiveService, times(1))
1148 .filter(eq(removedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1149 }
1150
1151 @Test
1152 public void testHandleFttbMacSwitchingFlowsAdd() {
1153 component.enableDhcpV4 = true;
1154
1155 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1156
1157 uniTagInformationList.add(dpuMgmtUti);
1158 uniTagInformationList.add(ancpUti);
1159
1160 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1161 si.setUniTagList(uniTagInformationList);
1162
1163 final DiscoveredSubscriber addedSub =
1164 new DiscoveredSubscriber(testDevice,
1165 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1166 false, si);
1167
1168 // return meter IDs
1169 MeterId usBpMeterId = MeterId.meterId(1);
1170 MeterId usOltBpMeterId = MeterId.meterId(1);
1171
1172 MeterId dsBpMeterId = MeterId.meterId(2);
1173 MeterId dsOltBpMeterId = MeterId.meterId(2);
1174
1175 MacAddress mac = MacAddress.valueOf("0A:00:27:00:00:09");
1176 Host host = Mockito.mock(Host.class);
1177 doReturn(mac).when(host).mac();
1178 doReturn(dpuMgmtUti.getPonSTag()).when(host).vlan();
1179
1180 doReturn(new HashSet<>(Arrays.asList(host))).when(component.hostService)
1181 .getConnectedHosts(new ConnectPoint(addedSub.device.id(), addedSub.port.number()));
1182
1183 doReturn(usBpMeterId).when(component.oltMeterService)
1184 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1185 doReturn(usOltBpMeterId).when(component.oltMeterService)
1186 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1187
1188 doReturn(dsBpMeterId).when(component.oltMeterService)
1189 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1190 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1191 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1192
1193 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1194 for (UniTagInformation uti : uniTagInformationList) {
1195 for (String direction : directions) {
1196 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1197 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1198
1199 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1200 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1201 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1202
1203 switch (direction) {
1204 case FTTB_FLOW_UPSTREAM:
1205 expectedSelectorBuilder
1206 .matchInPort(addedSub.port.number())
1207 .matchVlanId(uti.getPonCTag())
1208 .matchVlanPcp((byte) uti.getUsPonCTagPriority())
1209 .matchEthSrc(mac);
1210
1211 expectedTreatment.setVlanId(uti.getPonSTag())
1212 .setVlanPcp((byte) uti.getUsPonSTagPriority())
1213 .setOutput(nniPort.number())
1214 .meter(usBpMeterId)
1215 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1216 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1217
1218 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1219 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1220 break;
1221
1222 case FTTB_FLOW_DOWNSTREAM:
1223 expectedSelectorBuilder
1224 .matchInPort(nniPort.number())
1225 .matchVlanId(uti.getPonSTag())
1226 .matchEthDst(mac);
1227
1228 expectedTreatment.setVlanId(uti.getPonCTag())
1229 .setOutput(addedSub.port.number())
1230 .meter(dsBpMeterId)
1231 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1232 uti.getTechnologyProfileId(), addedSub.port.number()), 0L).build();
1233
1234 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1235 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1236 break;
1237
1238 default:
1239 return;
1240 }
1241
1242 ForwardingObjective expected = DefaultForwardingObjective.builder()
1243 .withFlag(ForwardingObjective.Flag.VERSATILE)
1244 .withPriority(1000)
1245 .makePermanent()
1246 .withSelector(expectedSelectorBuilder.build())
1247 .withAnnotations(annotationBuilder.build())
1248 .fromApp(testAppId)
1249 .withTreatment(expectedTreatment.build())
1250 .add();
1251
1252 component.handleSubscriberDataFlows(addedSub.device, addedSub.port,
1253 OltFlowService.FlowOperation.ADD, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1254 verify(component.flowObjectiveService, times(1))
1255 .forward(eq(addedSub.device.id()), eq(expected));
1256 }
1257 }
1258 }
1259
1260 @Test
1261 public void testRemoveFttbMacSwitchingFlows() {
1262 component.enableDhcpV4 = true;
1263 component.cpStatus = Mockito.mock(Map.class);
1264 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1265
1266 uniTagInformationList.add(dpuMgmtUti);
1267 uniTagInformationList.add(ancpUti);
1268
1269 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1270 si.setUniTagList(uniTagInformationList);
1271
1272 final DiscoveredSubscriber removedSub =
1273 new DiscoveredSubscriber(testDevice,
1274 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1275 false, si);
1276
1277
1278 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(removedSub.port), dpuMgmtUti);
1279 ServiceKey sk2 = new ServiceKey(new AccessDevicePort(removedSub.port), ancpUti);
1280
1281 component.cpStatus = component.storageService.
1282 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
1283 OltPortStatus cp1Status = new OltPortStatus(NONE, NONE, PENDING_ADD, NONE, NONE);
1284 OltPortStatus cp2Status = new OltPortStatus(NONE, NONE, PENDING_ADD, NONE, NONE);
1285 component.cpStatus.put(sk1, cp1Status);
1286 component.cpStatus.put(sk2, cp2Status);
1287
1288 // return meter IDs
1289 MeterId usBpMeterId = MeterId.meterId(1);
1290 MeterId usOltBpMeterId = MeterId.meterId(1);
1291
1292 MeterId dsBpMeterId = MeterId.meterId(2);
1293 MeterId dsOltBpMeterId = MeterId.meterId(2);
1294
1295 MacAddress mac = MacAddress.valueOf("0A:00:27:00:00:09");
1296 Host host = Mockito.mock(Host.class);
1297 doReturn(mac).when(host).mac();
1298 doReturn(dpuMgmtUti.getPonSTag()).when(host).vlan();
1299
1300 doReturn(new HashSet<>(Arrays.asList(host))).when(component.hostService)
1301 .getConnectedHosts(new ConnectPoint(removedSub.device.id(), removedSub.port.number()));
1302
1303 doReturn(usBpMeterId).when(component.oltMeterService)
1304 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1305 doReturn(usOltBpMeterId).when(component.oltMeterService)
1306 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1307
1308 doReturn(dsBpMeterId).when(component.oltMeterService)
1309 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1310 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1311 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1312
1313 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1314 for (UniTagInformation uti : uniTagInformationList) {
1315 for (String direction : directions) {
1316 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1317 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1318
1319 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1320 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1321 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1322
1323 switch (direction) {
1324 case FTTB_FLOW_UPSTREAM:
1325 expectedSelectorBuilder
1326 .matchInPort(removedSub.port.number())
1327 .matchVlanId(uti.getPonCTag())
1328 .matchVlanPcp((byte) uti.getUsPonCTagPriority())
1329 .matchEthSrc(mac);
1330
1331 expectedTreatment.setVlanId(uti.getPonSTag())
1332 .setVlanPcp((byte) uti.getUsPonSTagPriority())
1333 .setOutput(nniPort.number())
1334 .meter(usBpMeterId)
1335 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1336 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1337
1338 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1339 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1340 break;
1341
1342 case FTTB_FLOW_DOWNSTREAM:
1343 expectedSelectorBuilder
1344 .matchInPort(nniPort.number())
1345 .matchVlanId(uti.getPonSTag())
1346 .matchEthDst(mac);
1347
1348 expectedTreatment.setVlanId(uti.getPonCTag())
1349 .setOutput(removedSub.port.number())
1350 .meter(dsBpMeterId)
1351 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1352 uti.getTechnologyProfileId(), removedSub.port.number()), 0L).build();
1353
1354 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1355 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1356 break;
1357
1358 default:
1359 return;
1360 }
1361
1362 ForwardingObjective expected = DefaultForwardingObjective.builder()
1363 .withFlag(ForwardingObjective.Flag.VERSATILE)
1364 .withPriority(1000)
1365 .makePermanent()
1366 .withSelector(expectedSelectorBuilder.build())
1367 .withAnnotations(annotationBuilder.build())
1368 .fromApp(testAppId)
1369 .withTreatment(expectedTreatment.build())
1370 .remove();
1371
1372 component.handleSubscriberDataFlows(removedSub.device, removedSub.port,
1373 OltFlowService.FlowOperation.REMOVE, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1374 verify(component.flowObjectiveService, times(1))
1375 .forward(eq(removedSub.device.id()), eq(expected));
1376 }
1377 }
1378 }
1379
1380 @Test
1381 public void testHandleFttbSubscriberFlowsAdd() {
1382 component.enableDhcpV4 = true;
1383
1384 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1385 uniTagInformationList.add(fttbSubscriberUti);
1386
1387 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1388 si.setUniTagList(uniTagInformationList);
1389
1390 final DiscoveredSubscriber addedSub =
1391 new DiscoveredSubscriber(testDevice,
1392 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1393 false, si);
1394
1395 // return meter IDs
1396 MeterId usBpMeterId = MeterId.meterId(1);
1397 MeterId usOltBpMeterId = MeterId.meterId(1);
1398
1399 MeterId dsBpMeterId = MeterId.meterId(2);
1400 MeterId dsOltBpMeterId = MeterId.meterId(2);
1401
1402 doReturn(usBpMeterId).when(component.oltMeterService)
1403 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1404 doReturn(usOltBpMeterId).when(component.oltMeterService)
1405 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1406
1407 doReturn(dsBpMeterId).when(component.oltMeterService)
1408 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1409 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1410 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1411
1412 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1413 for (UniTagInformation uti : uniTagInformationList) {
1414 for (String direction : directions) {
1415 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1416 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1417
1418 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1419 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1420 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1421
1422 switch (direction) {
1423 case FTTB_FLOW_UPSTREAM:
1424 expectedSelectorBuilder
1425 .matchInPort(addedSub.port.number())
1426 .matchVlanId(uti.getPonCTag());
1427
1428 expectedTreatment.setVlanId(uti.getPonSTag())
1429 .setOutput(nniPort.number())
1430 .meter(usBpMeterId)
1431 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1432 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1433
1434 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1435 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1436 break;
1437
1438 case FTTB_FLOW_DOWNSTREAM:
1439 expectedSelectorBuilder
1440 .matchInPort(nniPort.number())
1441 .matchMetadata(uti.getPonSTag().toShort())
1442 .matchVlanId(uti.getPonSTag());
1443
1444 expectedTreatment.setVlanId(uti.getPonCTag())
1445 .setOutput(addedSub.port.number())
1446 .meter(dsBpMeterId)
1447 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1448 uti.getTechnologyProfileId(), addedSub.port.number()), 0L).build();
1449
1450 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1451 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1452 break;
1453
1454 default:
1455 return;
1456 }
1457
1458 ForwardingObjective expected = DefaultForwardingObjective.builder()
1459 .withFlag(ForwardingObjective.Flag.VERSATILE)
1460 .withPriority(1000)
1461 .makePermanent()
1462 .withSelector(expectedSelectorBuilder.build())
1463 .withAnnotations(annotationBuilder.build())
1464 .fromApp(testAppId)
1465 .withTreatment(expectedTreatment.build())
1466 .add();
1467
1468 component.handleSubscriberDataFlows(addedSub.device, addedSub.port,
1469 OltFlowService.FlowOperation.ADD, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1470 verify(component.flowObjectiveService, times(1))
1471 .forward(eq(addedSub.device.id()), eq(expected));
1472 }
1473 }
1474 }
1475
1476 @Test
1477 public void testRemoveFttbSubscriberFlows() {
1478 component.enableDhcpV4 = true;
1479
1480 OltPortStatus oltPortStatus1 = new OltPortStatus(null, null, ADDED,
1481 null, null);
1482 // Mocking the get call, to mark the SubscriberKey as already added.
1483 component.cpStatus = Mockito.mock(Map.class);
1484 when(component.cpStatus.get(Mockito.any())).thenReturn(oltPortStatus1);
1485
1486 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1487
1488 uniTagInformationList.add(fttbSubscriberUti);
1489
1490 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1491 si.setUniTagList(uniTagInformationList);
1492
1493 final DiscoveredSubscriber removedSub =
1494 new DiscoveredSubscriber(testDevice,
1495 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1496 false, si);
1497
1498 // return meter IDs
1499 MeterId usBpMeterId = MeterId.meterId(1);
1500 MeterId usOltBpMeterId = MeterId.meterId(1);
1501
1502 MeterId dsBpMeterId = MeterId.meterId(2);
1503 MeterId dsOltBpMeterId = MeterId.meterId(2);
1504
1505 doReturn(usBpMeterId).when(component.oltMeterService)
1506 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1507 doReturn(usOltBpMeterId).when(component.oltMeterService)
1508 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1509
1510 doReturn(dsBpMeterId).when(component.oltMeterService)
1511 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1512 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1513 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1514
1515 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1516 for (UniTagInformation uti : uniTagInformationList) {
1517 for (String direction : directions) {
1518 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1519 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1520
1521 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1522 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1523 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1524
1525 switch (direction) {
1526 case FTTB_FLOW_UPSTREAM:
1527 expectedSelectorBuilder
1528 .matchInPort(removedSub.port.number())
1529 .matchVlanId(uti.getPonCTag());
1530
1531 expectedTreatment.setVlanId(uti.getPonSTag())
1532 .setOutput(nniPort.number())
1533 .meter(usBpMeterId)
1534 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1535 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1536
1537 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1538 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1539 break;
1540
1541 case FTTB_FLOW_DOWNSTREAM:
1542 expectedSelectorBuilder
1543 .matchInPort(nniPort.number())
1544 .matchMetadata(uti.getPonSTag().toShort())
1545 .matchVlanId(uti.getPonSTag());
1546
1547 expectedTreatment.setVlanId(uti.getPonCTag())
1548 .setOutput(removedSub.port.number())
1549 .meter(dsBpMeterId)
1550 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1551 uti.getTechnologyProfileId(), removedSub.port.number()), 0L).build();
1552
1553 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1554 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1555 break;
1556
1557 default:
1558 return;
1559 }
1560
1561 ForwardingObjective expected = DefaultForwardingObjective.builder()
1562 .withFlag(ForwardingObjective.Flag.VERSATILE)
1563 .withPriority(1000)
1564 .makePermanent()
1565 .withSelector(expectedSelectorBuilder.build())
1566 .withAnnotations(annotationBuilder.build())
1567 .fromApp(testAppId)
1568 .withTreatment(expectedTreatment.build())
1569 .remove();
1570
1571 component.handleSubscriberDataFlows(removedSub.device, removedSub.port,
1572 OltFlowService.FlowOperation.REMOVE, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1573 verify(component.flowObjectiveService, times(1))
1574 .forward(eq(removedSub.device.id()), eq(expected));
1575 }
1576 }
1577 }
Matteo Scandoloaa2adde2021-09-13 12:45:32 -07001578}