blob: 878078a790bc793de3093a4cac53d5d8df2d9b1c [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;
116 OltFlowService.InternalFlowListener internalFlowListener;
117 private final ApplicationId testAppId = new DefaultApplicationId(1, "org.opencord.olt.test");
118 private final short eapolDefaultVlan = 4091;
119
120 private final DeviceId deviceId = DeviceId.deviceId("test-device");
121 private final Device testDevice = new DefaultDevice(ProviderId.NONE, deviceId, Device.Type.OLT,
122 "testManufacturer", "1.0", "1.0", "SN", new ChassisId(1));
123 Port nniPort = new OltPort(testDevice, true, PortNumber.portNumber(1048576),
124 DefaultAnnotations.builder().set(PORT_NAME, "nni-1").build());
125 Port nniPortDisabled = new OltPort(testDevice, false, PortNumber.portNumber(1048576),
126 DefaultAnnotations.builder().set(PORT_NAME, "nni-1").build());
127 Port uniUpdateEnabled = new OltPort(testDevice, true, PortNumber.portNumber(16),
128 DefaultAnnotations.builder().set(PORT_NAME, "uni-1").build());
129
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530130 private final UniTagInformation dpuMgmtUti = new UniTagInformation.Builder()
131 .setPonCTag(VlanId.vlanId("6"))
132 .setPonSTag(VlanId.vlanId("60"))
133 .setUsPonCTagPriority(1)
134 .setUsPonSTagPriority(2)
135 .setTechnologyProfileId(64)
136 .setUpstreamBandwidthProfile("usBp")
137 .setUpstreamOltBandwidthProfile("usOltBp")
138 .setServiceName(FttbUtils.FTTB_SERVICE_DPU_MGMT_TRAFFIC)
139 .setIsDhcpRequired(true)
140 .setEnableMacLearning(true)
141 .build();
142
143 private final UniTagInformation ancpUti = new UniTagInformation.Builder()
144 .setPonCTag(VlanId.vlanId("4"))
145 .setPonSTag(VlanId.vlanId("40"))
146 .setUsPonCTagPriority(3)
147 .setUsPonSTagPriority(4)
148 .setTechnologyProfileId(64)
149 .setUpstreamBandwidthProfile("usBp")
150 .setUpstreamOltBandwidthProfile("usOltBp")
151 .setServiceName(FttbUtils.FTTB_SERVICE_DPU_ANCP_TRAFFIC)
152 .setIsDhcpRequired(false)
153 .build();
154
155 private final UniTagInformation fttbSubscriberUti = new UniTagInformation.Builder()
156 .setPonCTag(VlanId.vlanId("8"))
157 .setPonSTag(VlanId.vlanId("80"))
158 .setTechnologyProfileId(64)
159 .setUpstreamBandwidthProfile("usBp")
160 .setUpstreamOltBandwidthProfile("usOltBp")
161 .setServiceName(FttbUtils.FTTB_SERVICE_SUBSCRIBER_TRAFFIC)
162 .setIsDhcpRequired(false)
163 .build();
164
165
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700166 @Before
167 public void setUp() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800168 component = new OltFlowService();
169 component.cfgService = new ComponentConfigAdapter();
170 component.sadisService = Mockito.mock(SadisService.class);
171 component.coreService = Mockito.spy(new CoreServiceAdapter());
172 component.oltMeterService = Mockito.mock(OltMeterService.class);
173 component.flowObjectiveService = Mockito.mock(FlowObjectiveService.class);
174 component.hostService = Mockito.mock(HostService.class);
175 component.flowRuleService = Mockito.mock(FlowRuleService.class);
176 component.storageService = new TestStorageService();
177 component.oltDeviceService = Mockito.mock(OltDeviceService.class);
178 component.appId = testAppId;
179 component.deviceService = Mockito.mock(DeviceService.class);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700180
181 doReturn(Mockito.mock(BaseInformationService.class))
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800182 .when(component.sadisService).getSubscriberInfoService();
183 doReturn(testAppId).when(component.coreService).registerApplication("org.opencord.olt");
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530184 doReturn(testDevice).when(component.deviceService).getDevice(testDevice.id());
185 when(component.sadisService.getSubscriberInfoService().get(testDevice.serialNumber())).
186 thenReturn(Mockito.mock(SubscriberAndDeviceInformation.class));
187 when(component.oltDeviceService.getNniPort(testDevice)).thenReturn(Optional.of(nniPort));
188
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800189 component.activate(null);
190 component.bindSadisService(component.sadisService);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700191
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800192 internalFlowListener = spy(component.internalFlowListener);
193
194 oltFlowService = spy(component);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700195 }
196
197 @After
198 public void tearDown() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800199 component.deactivate(null);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700200 }
201
202 @Test
203 public void testUpdateConnectPointStatus() {
204
205 DeviceId deviceId = DeviceId.deviceId("test-device");
206 ProviderId pid = new ProviderId("of", "foo");
207 Device device =
208 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
209 Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100210 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700211 Port port2 = new DefaultPort(device, PortNumber.portNumber(2), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100212 DefaultAnnotations.builder().set(PORT_NAME, PORT_2).build());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700213 Port port3 = new DefaultPort(device, PortNumber.portNumber(3), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100214 DefaultAnnotations.builder().set(PORT_NAME, PORT_3).build());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700215
216 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), new UniTagInformation());
217 ServiceKey sk2 = new ServiceKey(new AccessDevicePort(port2), new UniTagInformation());
218 ServiceKey sk3 = new ServiceKey(new AccessDevicePort(port3), new UniTagInformation());
219
220 // cpStatus map for the test
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800221 component.cpStatus = component.storageService.
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700222 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
Andrea Campanella87241ae2022-03-11 11:20:24 +0100223 OltPortStatus cp1Status = new OltPortStatus(PENDING_ADD, NONE, NONE, NONE, NONE);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800224 component.cpStatus.put(sk1, cp1Status);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700225
226 //check that we only update the provided value
Andrea Campanella87241ae2022-03-11 11:20:24 +0100227 component.updateConnectPointStatus(sk1, ADDED, null, null, null, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800228 OltPortStatus updated = component.cpStatus.get(sk1);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700229 Assert.assertEquals(ADDED, updated.defaultEapolStatus);
230 Assert.assertEquals(NONE, updated.subscriberFlowsStatus);
231 Assert.assertEquals(NONE, updated.dhcpStatus);
232
233 // check that it creates an entry if it does not exist
Andrea Campanella87241ae2022-03-11 11:20:24 +0100234 component.updateConnectPointStatus(sk2, PENDING_ADD, NONE, NONE, NONE, NONE);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800235 Assert.assertNotNull(component.cpStatus.get(sk2));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700236
237 // check that if we create a new entry with null values they're converted to NONE
Andrea Campanella87241ae2022-03-11 11:20:24 +0100238 component.updateConnectPointStatus(sk3, null, null, null, null, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800239 updated = component.cpStatus.get(sk3);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700240 Assert.assertEquals(NONE, updated.defaultEapolStatus);
241 Assert.assertEquals(NONE, updated.subscriberFlowsStatus);
242 Assert.assertEquals(NONE, updated.dhcpStatus);
243 }
244
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800245 /**
246 * If the flow status is PENDING_REMOVE or ERROR and there is no
247 * previous state in the map that don't update it.
248 * In case of a device disconnection we immediately wipe out the status,
249 * but then flows might update the cpStatus map. That result
250 */
251 @Test
252 public void doNotUpdateConnectPointStatus() {
253 DeviceId deviceId = DeviceId.deviceId("test-device");
254 ProviderId pid = new ProviderId("of", "foo");
255 Device device =
256 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
257 Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100258 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800259
260 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), new UniTagInformation());
261
262 // cpStatus map for the test
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800263 component.cpStatus = component.storageService.
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800264 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
265
266 // check that an entry is not created if the only status is pending remove
Andrea Campanella87241ae2022-03-11 11:20:24 +0100267 component.updateConnectPointStatus(sk1, null, null, null, PENDING_REMOVE, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800268 OltPortStatus entry = component.cpStatus.get(sk1);
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800269 Assert.assertNull(entry);
270
271 // check that an entry is not created if the only status is ERROR
Andrea Campanella87241ae2022-03-11 11:20:24 +0100272 component.updateConnectPointStatus(sk1, null, null, null, ERROR, null);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800273 entry = component.cpStatus.get(sk1);
Matteo Scandolo2542e5d2021-12-01 16:53:41 -0800274 Assert.assertNull(entry);
275 }
276
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700277 @Test
278 public void testHasDefaultEapol() {
279 DeviceId deviceId = DeviceId.deviceId("test-device");
280 ProviderId pid = new ProviderId("of", "foo");
281
282 Device device =
283 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
284
285 Port port = new DefaultPort(device, PortNumber.portNumber(16), true,
286 DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
287 ServiceKey skWithStatus = new ServiceKey(new AccessDevicePort(port),
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800288 component.defaultEapolUniTag);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700289
290 Port port17 = new DefaultPort(device, PortNumber.portNumber(17), true,
291 DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
292
293 OltPortStatus portStatusAdded = new OltPortStatus(
294 OltFlowService.OltFlowsStatus.ADDED,
295 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000296 null,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100297 null,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700298 null
299 );
300
301 OltPortStatus portStatusRemoved = new OltPortStatus(
302 REMOVED,
303 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000304 null,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100305 null,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700306 null
307 );
308
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800309 component.cpStatus.put(skWithStatus, portStatusAdded);
310 Assert.assertTrue(component.hasDefaultEapol(port));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700311
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800312 component.cpStatus.put(skWithStatus, portStatusRemoved);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700313
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800314 Assert.assertFalse(component.hasDefaultEapol(port17));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700315 }
316
317 @Test
318 public void testHasSubscriberFlows() {
319 // TODO test with multiple services
320 DeviceId deviceId = DeviceId.deviceId("test-device");
321 ProviderId pid = new ProviderId("of", "foo");
322
323 Device device =
324 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
325
326 Port port = new DefaultPort(device, PortNumber.portNumber(16), true,
327 DefaultAnnotations.builder().set(PORT_NAME, "name-1").build());
328
329 UniTagInformation uti = new UniTagInformation.Builder().setServiceName("test").build();
330 ServiceKey skWithStatus = new ServiceKey(new AccessDevicePort(port),
331 uti);
332
333 OltPortStatus withDefaultEapol = new OltPortStatus(
334 ADDED,
335 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000336 NONE,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100337 NONE,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700338 NONE
339 );
340
341 OltPortStatus withDhcp = new OltPortStatus(
342 REMOVED,
343 NONE,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100344 NONE,
yasin sapli0823c932022-01-26 11:26:09 +0000345 ADDED,
346 NONE
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700347 );
348
349 OltPortStatus withSubFlow = new OltPortStatus(
350 REMOVED,
351 ADDED,
yasin sapli0823c932022-01-26 11:26:09 +0000352 ADDED,
Andrea Campanella87241ae2022-03-11 11:20:24 +0100353 ADDED,
yasin sapli0823c932022-01-26 11:26:09 +0000354 NONE
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700355 );
356
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800357 component.cpStatus.put(skWithStatus, withDefaultEapol);
358 Assert.assertFalse(component.hasSubscriberFlows(port, uti));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700359
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800360 component.cpStatus.put(skWithStatus, withDhcp);
361 Assert.assertTrue(component.hasDhcpFlows(port, uti));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700362
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800363 component.cpStatus.put(skWithStatus, withSubFlow);
364 Assert.assertTrue(component.hasSubscriberFlows(port, uti));
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700365 }
366
367 @Test
368 public void testHandleBasicPortFlowsNoEapol() throws Exception {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800369 component.enableEapol = false;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700370 // create empty service for testing
371 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
372 UniTagInformation empty = new UniTagInformation.Builder().build();
373 uniTagInformationList.add(empty);
374
375 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
376 si.setUniTagList(uniTagInformationList);
377
378 final DiscoveredSubscriber addedSub =
379 new DiscoveredSubscriber(testDevice,
380 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
381 false, si);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800382 component.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700383 // if eapol is not enabled there's nothing we need to do,
384 // so make sure we don't even call sadis
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800385 verify(component.subsService, never()).get(any());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700386 }
387
388 @Test
389 public void testHandleBasicPortFlowsWithEapolNoMeter() throws Exception {
390 // create empty service for testing
391 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
392 UniTagInformation empty = new UniTagInformation.Builder().build();
393 uniTagInformationList.add(empty);
394 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
395 si.setUniTagList(uniTagInformationList);
396 final DiscoveredSubscriber addedSub =
397 new DiscoveredSubscriber(testDevice,
398 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
399 false, si);
400 // whether the meter is pending or not is up to the createMeter method to handle
401 // we just don't proceed with the subscriber till it's ready
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800402 doReturn(false).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700403 .createMeter(addedSub.device.id(), DEFAULT_BP_ID_DEFAULT);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800404 boolean res = component.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700405
406 Assert.assertFalse(res);
407
408 // we do not create flows
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800409 verify(component.flowObjectiveService, never())
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700410 .filter(eq(addedSub.device.id()), any());
411 }
412
413 @Test
414 public void testHandleBasicPortFlowsWithEapolAddedMeter() throws Exception {
415 // create empty service for testing
416 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
417 UniTagInformation empty = new UniTagInformation.Builder().build();
418 uniTagInformationList.add(empty);
419 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
420 si.setUniTagList(uniTagInformationList);
421 final DiscoveredSubscriber addedSub =
422 new DiscoveredSubscriber(testDevice,
423 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
424 false, si);
425 // this is the happy case, we have the meter so we check that the default EAPOL flow
426 // is installed
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800427 doReturn(true).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700428 .createMeter(deviceId, DEFAULT_BP_ID_DEFAULT);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800429 doReturn(true).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700430 .hasMeterByBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800431 doReturn(MeterId.meterId(1)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700432 .getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
433
434 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
435 .permit()
436 .withKey(Criteria.matchInPort(uniUpdateEnabled.number()))
437 .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
438 .fromApp(testAppId)
439 .withPriority(10000)
440 .withMeta(
441 DefaultTrafficTreatment.builder()
442 .meter(MeterId.meterId(1))
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530443 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700444 VlanId.vlanId(eapolDefaultVlan),
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800445 component.defaultTechProfileId, MeterId.meterId(1)), 0)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700446 .setOutput(PortNumber.CONTROLLER)
447 .pushVlan()
448 .setVlanId(VlanId.vlanId(eapolDefaultVlan)).build()
449 )
450 .add();
451
452
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800453 component.handleBasicPortFlows(addedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700454
455 // we check for an existing meter (present)
456 // FIXME understand why the above test invokes this call and this one doesn't
457// verify(oltFlowService.oltMeterService, times(1))
458// .hasMeterByBandwidthProfile(eq(addedSub.device.id()), eq(DEFAULT_BP_ID_DEFAULT));
459
460 // the meter exist, no need to check for PENDING or to create it
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800461 verify(component.oltMeterService, never())
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700462 .hasPendingMeterByBandwidthProfile(eq(deviceId), eq(DEFAULT_BP_ID_DEFAULT));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800463 verify(component.oltMeterService, never())
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700464 .createMeterForBp(eq(deviceId), eq(DEFAULT_BP_ID_DEFAULT));
465
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800466 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700467 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
468 }
469
470 @Test
471 public void testHandleBasicPortFlowsRemovedSub() throws Exception {
472 // create empty service for testing
473 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
474 UniTagInformation empty = new UniTagInformation.Builder().build();
475 uniTagInformationList.add(empty);
476 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
477 si.setUniTagList(uniTagInformationList);
478 final DiscoveredSubscriber removedSub =
479 new DiscoveredSubscriber(testDevice,
480 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
481 false, si);
482 // we are testing that when a port goes down we remove the default EAPOL flow
483
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800484 doReturn(MeterId.meterId(1)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700485 .getMeterIdForBandwidthProfile(deviceId, DEFAULT_BP_ID_DEFAULT);
486
487 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
488 .deny()
489 .withKey(Criteria.matchInPort(uniUpdateEnabled.number()))
490 .addCondition(Criteria.matchEthType(EthType.EtherType.EAPOL.ethType()))
491 .fromApp(testAppId)
492 .withPriority(10000)
493 .withMeta(
494 DefaultTrafficTreatment.builder()
495 .meter(MeterId.meterId(1))
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530496 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700497 VlanId.vlanId(eapolDefaultVlan),
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800498 component.defaultTechProfileId, MeterId.meterId(1)), 0)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700499 .setOutput(PortNumber.CONTROLLER)
500 .pushVlan()
501 .setVlanId(VlanId.vlanId(eapolDefaultVlan)).build()
502 )
503 .add();
504
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800505 component.handleBasicPortFlows(removedSub, DEFAULT_BP_ID_DEFAULT, DEFAULT_BP_ID_DEFAULT);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700506
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800507 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700508 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
509 }
510
511 @Test
512 public void testHandleNniFlowsOnlyLldp() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800513 component.enableDhcpOnNni = false;
514 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700515
516 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
517 .permit()
518 .withKey(Criteria.matchInPort(nniPort.number()))
519 .addCondition(Criteria.matchEthType(EthType.EtherType.LLDP.ethType()))
520 .fromApp(testAppId)
521 .withPriority(10000)
522 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
523 .add();
524
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800525 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700526 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800527 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700528 .filter(eq(deviceId), any());
529 }
530
531 @Test
532 public void testHandleNniFlowsDhcpV4() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800533 component.enableDhcpOnNni = true;
534 component.enableDhcpV4 = true;
535 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700536
537 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
538 .permit()
539 .withKey(Criteria.matchInPort(nniPort.number()))
540 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
541 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
542 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
543 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
544 .fromApp(testAppId)
545 .withPriority(10000)
546 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
547 .add();
548
549 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800550 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700551 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
552 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800553 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700554 .filter(eq(deviceId), any());
555 }
556
557 @Test
558 public void testRemoveNniFlowsDhcpV4() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800559 component.enableDhcpOnNni = true;
560 component.enableDhcpV4 = true;
561 component.handleNniFlows(testDevice, nniPortDisabled, OltFlowService.FlowOperation.REMOVE);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700562
563 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
564 .deny()
565 .withKey(Criteria.matchInPort(nniPort.number()))
566 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
567 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
568 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
569 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
570 .fromApp(testAppId)
571 .withPriority(10000)
572 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
573 .add();
574
575 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800576 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700577 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
578 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800579 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700580 .filter(eq(deviceId), any());
581 }
582
583 @Test
584 public void testHandleNniFlowsDhcpV6() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800585 component.enableDhcpOnNni = true;
586 component.enableDhcpV4 = false;
587 component.enableDhcpV6 = true;
588 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700589
590 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
591 .permit()
592 .withKey(Criteria.matchInPort(nniPort.number()))
593 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV6.ethType()))
594 .addCondition(Criteria.matchIPProtocol(IPv6.PROTOCOL_UDP))
595 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(546)))
596 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(547)))
597 .fromApp(testAppId)
598 .withPriority(10000)
599 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
600 .add();
601
602 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800603 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700604 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
605 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800606 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700607 .filter(eq(deviceId), any());
608 }
609
610 @Test
611 public void testHandleNniFlowsIgmp() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800612 component.enableDhcpOnNni = false;
613 component.enableIgmpOnNni = true;
614 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700615
616 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
617 .permit()
618 .withKey(Criteria.matchInPort(nniPort.number()))
619 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
620 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_IGMP))
621 .fromApp(testAppId)
622 .withPriority(10000)
623 .add();
624
625 // invoked with the correct DHCP filtering objective
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800626 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700627 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
628 // invoked only twice, LLDP and DHCP
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800629 verify(component.flowObjectiveService, times(2))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700630 .filter(eq(deviceId), any());
631 }
632
633 @Test
yasin sapli0823c932022-01-26 11:26:09 +0000634 public void testHandleNniFlowsPppoe() {
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530635 component.enableDhcpOnNni = false;
yasin sapli0823c932022-01-26 11:26:09 +0000636 component.enablePppoeOnNni = true;
637 component.enablePppoe = true;
638 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
639
640 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
641 .permit()
642 .withKey(Criteria.matchInPort(nniPort.number()))
643 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
644 .fromApp(testAppId)
645 .withPriority(10000)
646 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
647 .add();
648
649 // invoked with the correct Pppoe filtering objective
650 verify(component.flowObjectiveService, times(1))
651 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
652 // invoked only twice, LLDP and DHCP
653 verify(component.flowObjectiveService, times(2))
654 .filter(eq(deviceId), any());
655 }
656
657 @Test
658 public void testRemoveNniFlowsPppoe() {
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530659 component.enableDhcpOnNni = false;
yasin sapli0823c932022-01-26 11:26:09 +0000660 component.enablePppoeOnNni = true;
661 component.enablePppoe = true;
662 component.handleNniFlows(testDevice, nniPortDisabled, OltFlowService.FlowOperation.REMOVE);
663
664 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
665 .deny()
666 .withKey(Criteria.matchInPort(nniPort.number()))
667 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
668 .fromApp(testAppId)
669 .withPriority(10000)
670 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
671 .add();
672
673 // invoked with the correct Pppoe filtering objective
674 verify(component.flowObjectiveService, times(1))
675 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
676 // invoked only twice, LLDP and DHCP
677 verify(component.flowObjectiveService, times(2))
678 .filter(eq(deviceId), any());
679 }
680
681 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700682 public void testMacAddressNotRequired() {
683 // create a single service that doesn't require mac address
684 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
685 UniTagInformation hsia = new UniTagInformation.Builder()
686 .setEnableMacLearning(false)
687 .build();
688 uniTagInformationList.add(hsia);
689 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
690 si.setUniTagList(uniTagInformationList);
691
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800692 boolean isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700693 // we return true as we don't care wether it's available or not
694 Assert.assertTrue(isMacAvailable);
695 }
696
697 @Test
698 public void testIsMacAddressAvailableViaMacLearning() {
699
700 // create a single service that requires macLearning to be enabled
701 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
702 VlanId hsiaCtag = VlanId.vlanId((short) 11);
703 UniTagInformation hsia = new UniTagInformation.Builder()
704 .setPonCTag(hsiaCtag)
705 .setEnableMacLearning(true).build();
706 uniTagInformationList.add(hsia);
707
708 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
709 si.setUniTagList(uniTagInformationList);
710
711 // with no hosts discovered, return false
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800712 boolean isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700713 Assert.assertFalse(isMacAvailable);
714
715 // with a discovered host, return true
716 Host fakeHost = new DefaultHost(ProviderId.NONE, HostId.hostId(MacAddress.NONE), MacAddress.ZERO,
717 hsiaCtag, HostLocation.NONE, new HashSet<>(), DefaultAnnotations.builder().build());
718 Set<Host> hosts = new HashSet<>(Arrays.asList(fakeHost));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800719 doReturn(hosts).when(component.hostService).getConnectedHosts((ConnectPoint) any());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700720
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800721 isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700722 Assert.assertTrue(isMacAvailable);
723 }
724
725 @Test
726 public void testIsMacAddressAvailableViaConfiguration() {
727 // create a single service that has a macAddress configured
728 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
729 UniTagInformation hsia = new UniTagInformation.Builder()
730 .setConfiguredMacAddress("2e:0a:00:01:00:00")
731 .build();
732 uniTagInformationList.add(hsia);
733 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
734 si.setUniTagList(uniTagInformationList);
735
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800736 boolean isMacAvailable = component.isMacAddressAvailable(testDevice.id(), uniUpdateEnabled, si);
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700737 Assert.assertTrue(isMacAvailable);
738 }
739
740 @Test
741 public void testHandleSubscriberDhcpFlowsAdd() {
742
743 String usBp = "usBp";
744 String usOltBp = "usOltBp";
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800745 component.enableDhcpV4 = true;
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700746
747 // create two services, one requires DHCP the other doesn't
748 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
749 VlanId hsiaCtag = VlanId.vlanId((short) 11);
750 UniTagInformation hsia = new UniTagInformation.Builder()
751 .setPonCTag(hsiaCtag)
752 .setTechnologyProfileId(64)
753 .setUniTagMatch(VlanId.vlanId(VlanId.NO_VID))
754 .setUpstreamBandwidthProfile(usBp)
755 .setUpstreamOltBandwidthProfile(usOltBp)
756 .setIsDhcpRequired(true).build();
757 UniTagInformation mc = new UniTagInformation.Builder()
758 .setIsDhcpRequired(false).build();
759 uniTagInformationList.add(hsia);
760 uniTagInformationList.add(mc);
761
762 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
763 si.setUniTagList(uniTagInformationList);
764
765 final DiscoveredSubscriber addedSub =
766 new DiscoveredSubscriber(testDevice,
767 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
768 false, si);
769
770 // return meter IDs
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800771 doReturn(MeterId.meterId(2)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700772 .getMeterIdForBandwidthProfile(addedSub.device.id(), usBp);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800773 doReturn(MeterId.meterId(3)).when(component.oltMeterService)
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700774 .getMeterIdForBandwidthProfile(addedSub.device.id(), usOltBp);
775
776 // TODO improve the matches on the filter
777 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
778 .permit()
779 .withKey(Criteria.matchInPort(addedSub.port.number()))
780 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
781 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
782 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
783 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
784 .fromApp(testAppId)
785 .withPriority(10000)
786 .add();
787
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800788 component.handleSubscriberDhcpFlows(addedSub.device.id(), addedSub.port,
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700789 OltFlowService.FlowOperation.ADD, si);
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800790 verify(component.flowObjectiveService, times(1))
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700791 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
792 }
793
794 @Test
yasin sapli0823c932022-01-26 11:26:09 +0000795 public void testHandleSubscriberPppoeFlowsAdd() {
796
797 String usBp = "usBp";
798 String usOltBp = "usOltBp";
799 component.enablePppoe = true;
800
801 // create two services, one requires Pppoe the other doesn't
802 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
803 VlanId hsiaCtag = VlanId.vlanId((short) 11);
804 UniTagInformation hsia = new UniTagInformation.Builder()
805 .setPonCTag(hsiaCtag)
806 .setTechnologyProfileId(64)
807 .setUniTagMatch(VlanId.vlanId(VlanId.NO_VID))
808 .setUpstreamBandwidthProfile(usBp)
809 .setUpstreamOltBandwidthProfile(usOltBp)
810 .setIsPppoeRequired(true).build();
811 UniTagInformation mc = new UniTagInformation.Builder()
812 .setIsPppoeRequired(false).build();
813 uniTagInformationList.add(hsia);
814 uniTagInformationList.add(mc);
815
816 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
817 si.setUniTagList(uniTagInformationList);
818
819 final DiscoveredSubscriber addedSub =
820 new DiscoveredSubscriber(testDevice,
821 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
822 false, si);
823
824 // return meter IDs
825 doReturn(MeterId.meterId(2)).when(component.oltMeterService)
826 .getMeterIdForBandwidthProfile(addedSub.device.id(), usBp);
827 doReturn(MeterId.meterId(3)).when(component.oltMeterService)
828 .getMeterIdForBandwidthProfile(addedSub.device.id(), usOltBp);
829
830 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
831 .permit()
832 .withKey(Criteria.matchInPort(addedSub.port.number()))
833 .addCondition(Criteria.matchEthType(EthType.EtherType.PPPoED.ethType()))
834 .fromApp(testAppId)
835 .withPriority(10000)
836 .add();
837
838 component.handleSubscriberPppoeFlows(addedSub.device.id(), addedSub.port,
839 OltFlowService.FlowOperation.ADD, si);
840 verify(component.flowObjectiveService, times(1))
841 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
842 }
843
844 @Test
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700845 public void testInternalFlowListenerNotMaster() {
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800846 doReturn(false).when(component.oltDeviceService).isLocalLeader(any());
Matteo Scandoloaa2adde2021-09-13 12:45:32 -0700847
848 FlowRule flowRule = DefaultFlowRule.builder()
849 .forDevice(DeviceId.deviceId("foo"))
850 .fromApp(testAppId)
851 .makePermanent()
852 .withPriority(1000)
853 .build();
854 FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED,
855 flowRule);
856
857 internalFlowListener.event(event);
858
859 // if we're not master of the device, we should not update
860 verify(internalFlowListener, never()).updateCpStatus(any(), any(), any());
861 }
862
863 @Test
864 public void testInternalFlowListenerDifferentApp() {
865 ApplicationId someAppId = new DefaultApplicationId(1, "org.opencord.olt.not-test");
866 FlowRule flowRule = DefaultFlowRule.builder()
867 .forDevice(DeviceId.deviceId("foo"))
868 .fromApp(someAppId)
869 .makePermanent()
870 .withPriority(1000)
871 .build();
872 FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_ADDED,
873 flowRule);
874
875 internalFlowListener.event(event);
876
877 // if we're not master of the device, we should not update
878 verify(internalFlowListener, never()).updateCpStatus(any(), any(), any());
879 }
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800880
881 @Test
882 public void testRemoveSubscriberFlows() {
883 // test that if we have EAPOL we wait till the tagged flow is removed
884 // before installing the default one
885
886 // setup
887 component.enableEapol = true;
888
889 // mock data
890 DeviceId deviceId = DeviceId.deviceId("test-device");
891 ProviderId pid = new ProviderId("of", "foo");
892 Device device =
893 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
894 Port port = new DefaultPort(device, PortNumber.portNumber(1), true,
Andrea Campanella40d2b342022-02-04 18:13:37 +0100895 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800896
897 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
898 UniTagInformation hsia = new UniTagInformation.Builder()
899 .setUpstreamBandwidthProfile("usbp")
900 .setDownstreamBandwidthProfile("dsbp")
901 .setPonCTag(VlanId.vlanId((short) 900)).build();
902 uniTagInformationList.add(hsia);
903 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
904 si.setUniTagList(uniTagInformationList);
905
906 DiscoveredSubscriber sub = new DiscoveredSubscriber(
907 device, port, DiscoveredSubscriber.Status.REMOVED, true, si);
908
909 // first test that when we remove the EAPOL flow we return false so that the
910 // subscriber is not removed from the queue
Andrea Campanella87241ae2022-03-11 11:20:24 +0100911 doReturn(true).when(oltFlowService).areSubscriberFlowsPendingRemoval(any(), any(), eq(true));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800912 boolean res = oltFlowService.removeSubscriberFlows(sub, DEFAULT_BP_ID_DEFAULT, DEFAULT_MCAST_SERVICE_NAME);
913 verify(oltFlowService, times(1))
914 .handleSubscriberDhcpFlows(deviceId, port, OltFlowService.FlowOperation.REMOVE, si);
915 verify(oltFlowService, times(1))
916 .handleSubscriberEapolFlows(sub, OltFlowService.FlowOperation.REMOVE, si);
917 verify(oltFlowService, times(1))
918 .handleSubscriberDataFlows(device, port, OltFlowService.FlowOperation.REMOVE,
919 si, DEFAULT_MCAST_SERVICE_NAME);
920 verify(oltFlowService, times(1))
921 .handleSubscriberIgmpFlows(sub, OltFlowService.FlowOperation.REMOVE);
922 verify(oltFlowService, never())
923 .handleEapolFlow(any(), any(), any(),
924 eq(OltFlowService.FlowOperation.ADD), eq(VlanId.vlanId(OltFlowService.EAPOL_DEFAULT_VLAN)));
925 Assert.assertFalse(res);
926
927 // then test that if the tagged EAPOL is not there we install the default EAPOL
928 // and return true so we remove the subscriber from the queue
Andrea Campanella87241ae2022-03-11 11:20:24 +0100929 doReturn(false).when(oltFlowService).areSubscriberFlowsPendingRemoval(any(), any(), eq(true));
Matteo Scandolo97449bb2021-12-09 15:33:46 -0800930 doReturn(port).when(oltFlowService.deviceService).getPort(deviceId, port.number());
931 res = oltFlowService.removeSubscriberFlows(sub, DEFAULT_BP_ID_DEFAULT, DEFAULT_MCAST_SERVICE_NAME);
932 verify(oltFlowService, times(1))
933 .handleEapolFlow(any(), any(), any(),
934 eq(OltFlowService.FlowOperation.ADD), eq(VlanId.vlanId(OltFlowService.EAPOL_DEFAULT_VLAN)));
935 Assert.assertTrue(res);
936 }
Andrea Campanella40d2b342022-02-04 18:13:37 +0100937
938 @Test
939 public void testRemovedFlowEvent() throws InterruptedException {
940 // test that we update the status in case of REMOVED flow even with non
941 // existing port in the onos device manager
942
943 DeviceId deviceId = DeviceId.deviceId("test-device");
944 ProviderId pid = new ProviderId("of", "foo");
945 Device device =
946 new DefaultDevice(pid, deviceId, Device.Type.OLT, "", "", "", "", null);
947
948 Port port1 = new DefaultPort(device, PortNumber.portNumber(1), true,
949 DefaultAnnotations.builder().set(PORT_NAME, PORT_1).build());
950 // create empty service for testing
951 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
952 UniTagInformation vlanUniTag = new UniTagInformation.Builder().setPonCTag(VlanId.vlanId((short) 60))
953 .build();
954 uniTagInformationList.add(vlanUniTag);
955 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
956 si.setUniTagList(uniTagInformationList);
957 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(port1), vlanUniTag);
958
959 TrafficSelector selector = DefaultTrafficSelector.builder()
960 .matchInPort(port1.number())
961 .matchVlanId(VlanId.vlanId((short) 60))
962 .build();
963
964 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
965 .immediate()
966 .setOutput(port1.number())
967 .build();
968
969 FlowRule flowRule = DefaultFlowRule.builder()
970 .makePermanent()
971 .withPriority(1000)
972 .forTable(0)
973 .forDevice(deviceId)
974 .fromApp(testAppId)
975 .withSelector(selector)
976 .withTreatment(treatment)
977 .build();
978
979 // cpStatus map for the test
980 component.cpStatus = component.storageService.
981 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
Andrea Campanella87241ae2022-03-11 11:20:24 +0100982 OltPortStatus cp1Status = new OltPortStatus(NONE, NONE, PENDING_REMOVE, NONE, NONE);
Andrea Campanella40d2b342022-02-04 18:13:37 +0100983 component.cpStatus.put(sk1, cp1Status);
984
985 FlowRuleEvent event = new FlowRuleEvent(FlowRuleEvent.Type.RULE_REMOVED, flowRule);
986 doReturn(true).when(component.oltDeviceService).isLocalLeader(any());
987 doReturn(device).when(component.deviceService).getDevice(deviceId);
988 doReturn(si).when(component.subsService).get(PORT_1);
989
990 oltFlowService.internalFlowListener.event(event);
991
992 //Some time to finish the operation
993 TimeUnit.MILLISECONDS.sleep(200);
994
995 OltPortStatus status = component.cpStatus.get(sk1);
996 Assert.assertEquals(REMOVED, status.subscriberFlowsStatus);
997 }
Harsh Awasthic1e4bf52022-02-09 14:14:14 +0530998
999 @Test
1000 public void testHandleNniFlowsDhcpV4WithNniDhcpTrapVid() {
1001 component.enableDhcpOnNni = true;
1002 component.enableDhcpV4 = true;
1003
1004 SubscriberAndDeviceInformation testOltFttbSadis = new SubscriberAndDeviceInformation();
1005 testOltFttbSadis.setNniDhcpTrapVid(VlanId.vlanId("60"));
1006
1007 when(component.sadisService.getSubscriberInfoService().get(testDevice.serialNumber())).
1008 thenReturn(testOltFttbSadis);
1009
1010 component.handleNniFlows(testDevice, nniPort, OltFlowService.FlowOperation.ADD);
1011
1012 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1013 .permit()
1014 .withKey(Criteria.matchInPort(nniPort.number()))
1015 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1016 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1017 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(67)))
1018 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(68)))
1019 .addCondition(Criteria.matchVlanId(testOltFttbSadis.nniDhcpTrapVid()))
1020 .fromApp(testAppId)
1021 .withPriority(10000)
1022 .withMeta(DefaultTrafficTreatment.builder().setOutput(PortNumber.CONTROLLER).build())
1023 .add();
1024
1025 // invoked with the correct DHCP filtering objective
1026 verify(component.flowObjectiveService, times(1))
1027 .filter(eq(deviceId), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1028 // invoked only twice, LLDP and DHCP
1029 verify(component.flowObjectiveService, times(2))
1030 .filter(eq(deviceId), any());
1031 }
1032
1033 @Test
1034 public void testHandleFttbSubscriberDhcpFlowsAdd() {
1035 component.enableDhcpV4 = true;
1036
1037 // add two services, one requires DHCP the other doesn't
1038 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1039
1040 UniTagInformation mc = new UniTagInformation.Builder()
1041 .setIsDhcpRequired(false).build();
1042 uniTagInformationList.add(dpuMgmtUti);
1043 uniTagInformationList.add(mc);
1044
1045 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1046 si.setUniTagList(uniTagInformationList);
1047
1048 final DiscoveredSubscriber addedSub =
1049 new DiscoveredSubscriber(testDevice,
1050 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1051 false, si);
1052
1053 // return meter IDs
1054 MeterId usBpMeterId = MeterId.meterId(2);
1055 MeterId usOltBpMeterId = MeterId.meterId(3);
1056
1057 doReturn(usBpMeterId).when(component.oltMeterService)
1058 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1059 doReturn(usOltBpMeterId).when(component.oltMeterService)
1060 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1061
1062 TrafficTreatment expectedTreatment = DefaultTrafficTreatment.builder()
1063 .setVlanId(dpuMgmtUti.getPonSTag())
1064 .setVlanPcp((byte) dpuMgmtUti.getUsPonSTagPriority())
1065 .setOutput(PortNumber.CONTROLLER)
1066 .meter(usBpMeterId)
1067 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(VlanId.NONE,
1068 dpuMgmtUti.getTechnologyProfileId(), usOltBpMeterId), 0L).build();
1069
1070 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1071 .permit()
1072 .withKey(Criteria.matchInPort(addedSub.port.number()))
1073 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1074 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1075 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
1076 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
1077 .addCondition(Criteria.matchVlanId(dpuMgmtUti.getPonCTag()))
1078 .addCondition(Criteria.matchVlanPcp((byte) dpuMgmtUti.getUsPonCTagPriority()))
1079 .fromApp(testAppId)
1080 .withPriority(10000)
1081 .withMeta(expectedTreatment)
1082 .add();
1083
1084 component.handleSubscriberDhcpFlows(addedSub.device.id(), addedSub.port,
1085 OltFlowService.FlowOperation.ADD, si);
1086 verify(component.flowObjectiveService, times(1))
1087 .filter(eq(addedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1088 }
1089
1090 @Test
1091 public void testRemoveFttbSubscriberDhcpFlows() {
1092 component.enableDhcpV4 = true;
1093
1094 // Mocking the get call, to mark the SubscriberKey as already added.
1095 component.cpStatus = Mockito.mock(Map.class);
1096 doReturn(new OltPortStatus(null, null, null, ADDED, null))
1097 .when(component.cpStatus).get(Mockito.any());
1098
1099 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1100 uniTagInformationList.add(dpuMgmtUti);
1101
1102 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1103 si.setUniTagList(uniTagInformationList);
1104
1105 final DiscoveredSubscriber removedSub =
1106 new DiscoveredSubscriber(testDevice,
1107 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1108 false, si);
1109
1110 // return meter IDs
1111 MeterId usBpMeterId = MeterId.meterId(2);
1112 MeterId usOltBpMeterId = MeterId.meterId(3);
1113
1114 doReturn(usBpMeterId).when(component.oltMeterService)
1115 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1116 doReturn(usOltBpMeterId).when(component.oltMeterService)
1117 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1118
1119 TrafficTreatment expectedTreatment = DefaultTrafficTreatment.builder()
1120 .setVlanId(dpuMgmtUti.getPonSTag())
1121 .setVlanPcp((byte) dpuMgmtUti.getUsPonSTagPriority())
1122 .setOutput(PortNumber.CONTROLLER)
1123 .meter(usBpMeterId)
1124 .writeMetadata(OltFlowServiceUtils.createTechProfValueForWriteMetadata(VlanId.NONE,
1125 dpuMgmtUti.getTechnologyProfileId(), usOltBpMeterId), 0L).build();
1126
1127 FilteringObjective expectedFilter = DefaultFilteringObjective.builder()
1128 .deny()
1129 .withKey(Criteria.matchInPort(removedSub.port.number()))
1130 .addCondition(Criteria.matchEthType(EthType.EtherType.IPV4.ethType()))
1131 .addCondition(Criteria.matchIPProtocol(IPv4.PROTOCOL_UDP))
1132 .addCondition(Criteria.matchUdpSrc(TpPort.tpPort(68)))
1133 .addCondition(Criteria.matchUdpDst(TpPort.tpPort(67)))
1134 .addCondition(Criteria.matchVlanId(dpuMgmtUti.getPonCTag()))
1135 .addCondition(Criteria.matchVlanPcp((byte) dpuMgmtUti.getUsPonCTagPriority()))
1136 .fromApp(testAppId)
1137 .withPriority(10000)
1138 .withMeta(expectedTreatment)
1139 .add();
1140
1141 component.handleSubscriberDhcpFlows(removedSub.device.id(), removedSub.port,
1142 OltFlowService.FlowOperation.REMOVE, si);
1143 verify(component.flowObjectiveService, times(1))
1144 .filter(eq(removedSub.device.id()), argThat(new FilteringObjectiveMatcher(expectedFilter)));
1145 }
1146
1147 @Test
1148 public void testHandleFttbMacSwitchingFlowsAdd() {
1149 component.enableDhcpV4 = true;
1150
1151 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1152
1153 uniTagInformationList.add(dpuMgmtUti);
1154 uniTagInformationList.add(ancpUti);
1155
1156 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1157 si.setUniTagList(uniTagInformationList);
1158
1159 final DiscoveredSubscriber addedSub =
1160 new DiscoveredSubscriber(testDevice,
1161 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1162 false, si);
1163
1164 // return meter IDs
1165 MeterId usBpMeterId = MeterId.meterId(1);
1166 MeterId usOltBpMeterId = MeterId.meterId(1);
1167
1168 MeterId dsBpMeterId = MeterId.meterId(2);
1169 MeterId dsOltBpMeterId = MeterId.meterId(2);
1170
1171 MacAddress mac = MacAddress.valueOf("0A:00:27:00:00:09");
1172 Host host = Mockito.mock(Host.class);
1173 doReturn(mac).when(host).mac();
1174 doReturn(dpuMgmtUti.getPonSTag()).when(host).vlan();
1175
1176 doReturn(new HashSet<>(Arrays.asList(host))).when(component.hostService)
1177 .getConnectedHosts(new ConnectPoint(addedSub.device.id(), addedSub.port.number()));
1178
1179 doReturn(usBpMeterId).when(component.oltMeterService)
1180 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1181 doReturn(usOltBpMeterId).when(component.oltMeterService)
1182 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1183
1184 doReturn(dsBpMeterId).when(component.oltMeterService)
1185 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1186 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1187 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1188
1189 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1190 for (UniTagInformation uti : uniTagInformationList) {
1191 for (String direction : directions) {
1192 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1193 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1194
1195 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1196 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1197 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1198
1199 switch (direction) {
1200 case FTTB_FLOW_UPSTREAM:
1201 expectedSelectorBuilder
1202 .matchInPort(addedSub.port.number())
1203 .matchVlanId(uti.getPonCTag())
1204 .matchVlanPcp((byte) uti.getUsPonCTagPriority())
1205 .matchEthSrc(mac);
1206
1207 expectedTreatment.setVlanId(uti.getPonSTag())
1208 .setVlanPcp((byte) uti.getUsPonSTagPriority())
1209 .setOutput(nniPort.number())
1210 .meter(usBpMeterId)
1211 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1212 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1213
1214 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1215 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1216 break;
1217
1218 case FTTB_FLOW_DOWNSTREAM:
1219 expectedSelectorBuilder
1220 .matchInPort(nniPort.number())
1221 .matchVlanId(uti.getPonSTag())
1222 .matchEthDst(mac);
1223
1224 expectedTreatment.setVlanId(uti.getPonCTag())
1225 .setOutput(addedSub.port.number())
1226 .meter(dsBpMeterId)
1227 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1228 uti.getTechnologyProfileId(), addedSub.port.number()), 0L).build();
1229
1230 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1231 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1232 break;
1233
1234 default:
1235 return;
1236 }
1237
1238 ForwardingObjective expected = DefaultForwardingObjective.builder()
1239 .withFlag(ForwardingObjective.Flag.VERSATILE)
1240 .withPriority(1000)
1241 .makePermanent()
1242 .withSelector(expectedSelectorBuilder.build())
1243 .withAnnotations(annotationBuilder.build())
1244 .fromApp(testAppId)
1245 .withTreatment(expectedTreatment.build())
1246 .add();
1247
1248 component.handleSubscriberDataFlows(addedSub.device, addedSub.port,
1249 OltFlowService.FlowOperation.ADD, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1250 verify(component.flowObjectiveService, times(1))
1251 .forward(eq(addedSub.device.id()), eq(expected));
1252 }
1253 }
1254 }
1255
1256 @Test
1257 public void testRemoveFttbMacSwitchingFlows() {
1258 component.enableDhcpV4 = true;
1259 component.cpStatus = Mockito.mock(Map.class);
1260 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1261
1262 uniTagInformationList.add(dpuMgmtUti);
1263 uniTagInformationList.add(ancpUti);
1264
1265 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1266 si.setUniTagList(uniTagInformationList);
1267
1268 final DiscoveredSubscriber removedSub =
1269 new DiscoveredSubscriber(testDevice,
1270 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1271 false, si);
1272
1273
1274 ServiceKey sk1 = new ServiceKey(new AccessDevicePort(removedSub.port), dpuMgmtUti);
1275 ServiceKey sk2 = new ServiceKey(new AccessDevicePort(removedSub.port), ancpUti);
1276
1277 component.cpStatus = component.storageService.
1278 <ServiceKey, OltPortStatus>consistentMapBuilder().build().asJavaMap();
1279 OltPortStatus cp1Status = new OltPortStatus(NONE, NONE, PENDING_ADD, NONE, NONE);
1280 OltPortStatus cp2Status = new OltPortStatus(NONE, NONE, PENDING_ADD, NONE, NONE);
1281 component.cpStatus.put(sk1, cp1Status);
1282 component.cpStatus.put(sk2, cp2Status);
1283
1284 // return meter IDs
1285 MeterId usBpMeterId = MeterId.meterId(1);
1286 MeterId usOltBpMeterId = MeterId.meterId(1);
1287
1288 MeterId dsBpMeterId = MeterId.meterId(2);
1289 MeterId dsOltBpMeterId = MeterId.meterId(2);
1290
1291 MacAddress mac = MacAddress.valueOf("0A:00:27:00:00:09");
1292 Host host = Mockito.mock(Host.class);
1293 doReturn(mac).when(host).mac();
1294 doReturn(dpuMgmtUti.getPonSTag()).when(host).vlan();
1295
1296 doReturn(new HashSet<>(Arrays.asList(host))).when(component.hostService)
1297 .getConnectedHosts(new ConnectPoint(removedSub.device.id(), removedSub.port.number()));
1298
1299 doReturn(usBpMeterId).when(component.oltMeterService)
1300 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1301 doReturn(usOltBpMeterId).when(component.oltMeterService)
1302 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1303
1304 doReturn(dsBpMeterId).when(component.oltMeterService)
1305 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1306 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1307 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1308
1309 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1310 for (UniTagInformation uti : uniTagInformationList) {
1311 for (String direction : directions) {
1312 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1313 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1314
1315 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1316 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1317 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1318
1319 switch (direction) {
1320 case FTTB_FLOW_UPSTREAM:
1321 expectedSelectorBuilder
1322 .matchInPort(removedSub.port.number())
1323 .matchVlanId(uti.getPonCTag())
1324 .matchVlanPcp((byte) uti.getUsPonCTagPriority())
1325 .matchEthSrc(mac);
1326
1327 expectedTreatment.setVlanId(uti.getPonSTag())
1328 .setVlanPcp((byte) uti.getUsPonSTagPriority())
1329 .setOutput(nniPort.number())
1330 .meter(usBpMeterId)
1331 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1332 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1333
1334 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1335 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1336 break;
1337
1338 case FTTB_FLOW_DOWNSTREAM:
1339 expectedSelectorBuilder
1340 .matchInPort(nniPort.number())
1341 .matchVlanId(uti.getPonSTag())
1342 .matchEthDst(mac);
1343
1344 expectedTreatment.setVlanId(uti.getPonCTag())
1345 .setOutput(removedSub.port.number())
1346 .meter(dsBpMeterId)
1347 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.NONE,
1348 uti.getTechnologyProfileId(), removedSub.port.number()), 0L).build();
1349
1350 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1351 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1352 break;
1353
1354 default:
1355 return;
1356 }
1357
1358 ForwardingObjective expected = DefaultForwardingObjective.builder()
1359 .withFlag(ForwardingObjective.Flag.VERSATILE)
1360 .withPriority(1000)
1361 .makePermanent()
1362 .withSelector(expectedSelectorBuilder.build())
1363 .withAnnotations(annotationBuilder.build())
1364 .fromApp(testAppId)
1365 .withTreatment(expectedTreatment.build())
1366 .remove();
1367
1368 component.handleSubscriberDataFlows(removedSub.device, removedSub.port,
1369 OltFlowService.FlowOperation.REMOVE, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1370 verify(component.flowObjectiveService, times(1))
1371 .forward(eq(removedSub.device.id()), eq(expected));
1372 }
1373 }
1374 }
1375
1376 @Test
1377 public void testHandleFttbSubscriberFlowsAdd() {
1378 component.enableDhcpV4 = true;
1379
1380 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1381 uniTagInformationList.add(fttbSubscriberUti);
1382
1383 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1384 si.setUniTagList(uniTagInformationList);
1385
1386 final DiscoveredSubscriber addedSub =
1387 new DiscoveredSubscriber(testDevice,
1388 uniUpdateEnabled, DiscoveredSubscriber.Status.ADDED,
1389 false, si);
1390
1391 // return meter IDs
1392 MeterId usBpMeterId = MeterId.meterId(1);
1393 MeterId usOltBpMeterId = MeterId.meterId(1);
1394
1395 MeterId dsBpMeterId = MeterId.meterId(2);
1396 MeterId dsOltBpMeterId = MeterId.meterId(2);
1397
1398 doReturn(usBpMeterId).when(component.oltMeterService)
1399 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1400 doReturn(usOltBpMeterId).when(component.oltMeterService)
1401 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1402
1403 doReturn(dsBpMeterId).when(component.oltMeterService)
1404 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1405 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1406 .getMeterIdForBandwidthProfile(addedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1407
1408 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1409 for (UniTagInformation uti : uniTagInformationList) {
1410 for (String direction : directions) {
1411 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1412 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1413
1414 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1415 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1416 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1417
1418 switch (direction) {
1419 case FTTB_FLOW_UPSTREAM:
1420 expectedSelectorBuilder
1421 .matchInPort(addedSub.port.number())
1422 .matchVlanId(uti.getPonCTag());
1423
1424 expectedTreatment.setVlanId(uti.getPonSTag())
1425 .setOutput(nniPort.number())
1426 .meter(usBpMeterId)
1427 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1428 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1429
1430 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1431 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1432 break;
1433
1434 case FTTB_FLOW_DOWNSTREAM:
1435 expectedSelectorBuilder
1436 .matchInPort(nniPort.number())
1437 .matchMetadata(uti.getPonSTag().toShort())
1438 .matchVlanId(uti.getPonSTag());
1439
1440 expectedTreatment.setVlanId(uti.getPonCTag())
1441 .setOutput(addedSub.port.number())
1442 .meter(dsBpMeterId)
1443 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1444 uti.getTechnologyProfileId(), addedSub.port.number()), 0L).build();
1445
1446 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1447 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1448 break;
1449
1450 default:
1451 return;
1452 }
1453
1454 ForwardingObjective expected = DefaultForwardingObjective.builder()
1455 .withFlag(ForwardingObjective.Flag.VERSATILE)
1456 .withPriority(1000)
1457 .makePermanent()
1458 .withSelector(expectedSelectorBuilder.build())
1459 .withAnnotations(annotationBuilder.build())
1460 .fromApp(testAppId)
1461 .withTreatment(expectedTreatment.build())
1462 .add();
1463
1464 component.handleSubscriberDataFlows(addedSub.device, addedSub.port,
1465 OltFlowService.FlowOperation.ADD, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1466 verify(component.flowObjectiveService, times(1))
1467 .forward(eq(addedSub.device.id()), eq(expected));
1468 }
1469 }
1470 }
1471
1472 @Test
1473 public void testRemoveFttbSubscriberFlows() {
1474 component.enableDhcpV4 = true;
1475
1476 OltPortStatus oltPortStatus1 = new OltPortStatus(null, null, ADDED,
1477 null, null);
1478 // Mocking the get call, to mark the SubscriberKey as already added.
1479 component.cpStatus = Mockito.mock(Map.class);
1480 when(component.cpStatus.get(Mockito.any())).thenReturn(oltPortStatus1);
1481
1482 List<UniTagInformation> uniTagInformationList = new LinkedList<>();
1483
1484 uniTagInformationList.add(fttbSubscriberUti);
1485
1486 SubscriberAndDeviceInformation si = new SubscriberAndDeviceInformation();
1487 si.setUniTagList(uniTagInformationList);
1488
1489 final DiscoveredSubscriber removedSub =
1490 new DiscoveredSubscriber(testDevice,
1491 uniUpdateEnabled, DiscoveredSubscriber.Status.REMOVED,
1492 false, si);
1493
1494 // return meter IDs
1495 MeterId usBpMeterId = MeterId.meterId(1);
1496 MeterId usOltBpMeterId = MeterId.meterId(1);
1497
1498 MeterId dsBpMeterId = MeterId.meterId(2);
1499 MeterId dsOltBpMeterId = MeterId.meterId(2);
1500
1501 doReturn(usBpMeterId).when(component.oltMeterService)
1502 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamBandwidthProfile());
1503 doReturn(usOltBpMeterId).when(component.oltMeterService)
1504 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getUpstreamOltBandwidthProfile());
1505
1506 doReturn(dsBpMeterId).when(component.oltMeterService)
1507 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamBandwidthProfile());
1508 doReturn(dsOltBpMeterId).when(component.oltMeterService)
1509 .getMeterIdForBandwidthProfile(removedSub.device.id(), dpuMgmtUti.getDownstreamOltBandwidthProfile());
1510
1511 String[] directions = {FTTB_FLOW_UPSTREAM, FTTB_FLOW_DOWNSTREAM};
1512 for (UniTagInformation uti : uniTagInformationList) {
1513 for (String direction : directions) {
1514 TrafficTreatment.Builder expectedTreatment = DefaultTrafficTreatment.builder();
1515 TrafficSelector.Builder expectedSelectorBuilder = DefaultTrafficSelector.builder();
1516
1517 DefaultAnnotations.Builder annotationBuilder = DefaultAnnotations.builder();
1518 annotationBuilder.set(FTTB_FLOW_DIRECTION, direction);
1519 annotationBuilder.set(FTTB_SERVICE_NAME, uti.getServiceName());
1520
1521 switch (direction) {
1522 case FTTB_FLOW_UPSTREAM:
1523 expectedSelectorBuilder
1524 .matchInPort(removedSub.port.number())
1525 .matchVlanId(uti.getPonCTag());
1526
1527 expectedTreatment.setVlanId(uti.getPonSTag())
1528 .setOutput(nniPort.number())
1529 .meter(usBpMeterId)
1530 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1531 uti.getTechnologyProfileId(), nniPort.number()), 0L).build();
1532
1533 annotationBuilder.set(UPSTREAM_ONU, usBpMeterId.toString());
1534 annotationBuilder.set(UPSTREAM_OLT, usOltBpMeterId.toString());
1535 break;
1536
1537 case FTTB_FLOW_DOWNSTREAM:
1538 expectedSelectorBuilder
1539 .matchInPort(nniPort.number())
1540 .matchMetadata(uti.getPonSTag().toShort())
1541 .matchVlanId(uti.getPonSTag());
1542
1543 expectedTreatment.setVlanId(uti.getPonCTag())
1544 .setOutput(removedSub.port.number())
1545 .meter(dsBpMeterId)
1546 .writeMetadata(OltFlowServiceUtils.createMetadata(VlanId.ANY,
1547 uti.getTechnologyProfileId(), removedSub.port.number()), 0L).build();
1548
1549 annotationBuilder.set(DOWNSTREAM_ONU, dsBpMeterId.toString());
1550 annotationBuilder.set(DOWNSTREAM_OLT, dsOltBpMeterId.toString());
1551 break;
1552
1553 default:
1554 return;
1555 }
1556
1557 ForwardingObjective expected = DefaultForwardingObjective.builder()
1558 .withFlag(ForwardingObjective.Flag.VERSATILE)
1559 .withPriority(1000)
1560 .makePermanent()
1561 .withSelector(expectedSelectorBuilder.build())
1562 .withAnnotations(annotationBuilder.build())
1563 .fromApp(testAppId)
1564 .withTreatment(expectedTreatment.build())
1565 .remove();
1566
1567 component.handleSubscriberDataFlows(removedSub.device, removedSub.port,
1568 OltFlowService.FlowOperation.REMOVE, si, DEFAULT_MCAST_SERVICE_NAME_DEFAULT);
1569 verify(component.flowObjectiveService, times(1))
1570 .forward(eq(removedSub.device.id()), eq(expected));
1571 }
1572 }
1573 }
Matteo Scandoloaa2adde2021-09-13 12:45:32 -07001574}