blob: 82d342c73f96c1def882c613c120ed95c5861b30 [file] [log] [blame]
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +00001/*
2 * Copyright 2017-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16package org.opencord.igmpproxy;
17
Matteo Scandolo7482bbe2020-02-12 14:37:09 -080018import com.google.common.collect.ImmutableSet;
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000019import org.onlab.packet.Ethernet;
20import org.onlab.packet.Ip4Address;
21import org.onlab.packet.IpAddress;
Matteo Scandolo7482bbe2020-02-12 14:37:09 -080022import org.onlab.packet.MacAddress;
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000023import org.onosproject.core.ApplicationId;
24import org.onosproject.mastership.MastershipServiceAdapter;
25import org.onosproject.mcast.api.McastListener;
26import org.onosproject.mcast.api.McastRoute;
27import org.onosproject.mcast.api.McastRouteData;
28import org.onosproject.mcast.api.MulticastRouteService;
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000029import org.onosproject.net.AnnotationKeys;
30import org.onosproject.net.Annotations;
31import org.onosproject.net.ConnectPoint;
32import org.onosproject.net.DefaultAnnotations;
33import org.onosproject.net.DefaultDevice;
34import org.onosproject.net.Device;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.HostId;
37import org.onosproject.net.Port;
38import org.onosproject.net.PortNumber;
39import org.onosproject.net.SparseAnnotations;
40import org.onosproject.net.config.Config;
Matteo Scandolo7482bbe2020-02-12 14:37:09 -080041import org.onosproject.net.config.ConfigFactory;
42import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000043import org.onosproject.net.config.basics.McastConfig;
44import org.onosproject.net.config.basics.SubjectFactories;
45import org.onosproject.net.device.DeviceServiceAdapter;
46import org.onosproject.net.packet.DefaultInboundPacket;
47import org.onosproject.net.packet.DefaultPacketContext;
48import org.onosproject.net.packet.InboundPacket;
49import org.onosproject.net.packet.OutboundPacket;
50import org.onosproject.net.packet.PacketContext;
51import org.onosproject.net.packet.PacketProcessor;
52import org.onosproject.net.packet.PacketServiceAdapter;
Matteo Scandolo7482bbe2020-02-12 14:37:09 -080053import org.opencord.sadis.BandwidthProfileInformation;
54import org.opencord.sadis.BaseInformationService;
55import org.opencord.sadis.SadisService;
56import org.opencord.sadis.SubscriberAndDeviceInformation;
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000057import org.slf4j.Logger;
58import org.slf4j.LoggerFactory;
59
Matteo Scandolo7482bbe2020-02-12 14:37:09 -080060import java.nio.ByteBuffer;
61import java.util.ArrayList;
62import java.util.LinkedList;
63import java.util.List;
64import java.util.Set;
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000065
66public class IgmpManagerBase {
67
68 // Device configuration
69 protected static final DeviceId DEVICE_ID_OF_A = DeviceId.deviceId("of:1");
70 protected static final DeviceId DEVICE_ID_OF_B = DeviceId.deviceId("of:2");
71
72 //Multicast ip address
73 protected static final Ip4Address GROUP_IP = Ip4Address.valueOf("224.0.0.0");
74 // Source ip address of two different device.
75 protected static final Ip4Address SOURCE_IP_OF_A = Ip4Address.valueOf("10.177.125.4");
76 protected static final Ip4Address SOURCE_IP_OF_B = Ip4Address.valueOf("10.177.125.5");
77
78 // Common connect point of aggregation switch used by all devices.
79 protected static final ConnectPoint COMMON_CONNECT_POINT =
80 ConnectPoint.deviceConnectPoint("of:00000000000000003/3");
81 // Uplink ports for two olts A and B
82 protected static final PortNumber PORT_A = PortNumber.portNumber(1);
83 protected static final PortNumber PORT_B = PortNumber.portNumber(2);
84
85 // Connect Point mode for two olts
86 protected static final ConnectPoint CONNECT_POINT_A = new ConnectPoint(DEVICE_ID_OF_A, PORT_A);
87 protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_B, PORT_B);
88
Matteo Scandolo7482bbe2020-02-12 14:37:09 -080089 protected static final String CLIENT_NAS_PORT_ID = "PON 1/1";
90 protected static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
91 protected String dsBpId = "HSIA-DS";
92
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +000093 protected List<Port> lsPorts = new ArrayList<Port>();
94 // Flag for adding two different devices in oltData
95 protected boolean flagForDevice = true;
96 PacketContext context;
97 // Flag for sending two different packets
98 protected boolean flagForPacket = true;
99 // List to store the packets emitted
100 protected List<OutboundPacket> savedPackets;
101 protected PacketProcessor packetProcessor;
102 private Logger log = LoggerFactory.getLogger(getClass());
103
104 class MockDeviceService extends DeviceServiceAdapter {
105
106 @Override
107 public Device getDevice(DeviceId deviceId) {
108 if (flagForDevice) {
109 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
110 .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_A.toString());
111 SparseAnnotations annotations = annotationsBuilder.build();
112 Annotations[] da = {annotations };
113 Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_A, Device.Type.OTHER, "", "", "", "", null, da);
114 flagForDevice = false;
115 return deviceA;
116 } else {
117 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
118 .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_B.toString());
119 SparseAnnotations annotations = annotationsBuilder.build();
120 Annotations[] da = {annotations };
121 Device deviceB = new DefaultDevice(null, DEVICE_ID_OF_B, Device.Type.OTHER, "", "", "", "", null, da);
122 return deviceB;
123 }
124 }
125 @Override
126 public List<Port> getPorts(DeviceId deviceId) {
127 return lsPorts;
128 }
129 }
130
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +0000131 static final Class<IgmpproxyConfig> IGMPPROXY_CONFIG_CLASS = IgmpproxyConfig.class;
132 static final Class<IgmpproxySsmTranslateConfig> IGMPPROXY_SSM_CONFIG_CLASS = IgmpproxySsmTranslateConfig.class;
133 static final Class<McastConfig> MCAST_CONFIG_CLASS = McastConfig.class;
134 ConfigFactory<ApplicationId, IgmpproxyConfig> igmpproxyConfigFactory =
135 new ConfigFactory<ApplicationId, IgmpproxyConfig>(
136 SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_CONFIG_CLASS, "igmpproxy") {
137 @Override
138 public IgmpproxyConfig createConfig() {
139 return new IgmpproxyConfig();
140 }
141 };
142
143 ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig> igmpproxySsmConfigFactory =
144 new ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig>(
145 SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_SSM_CONFIG_CLASS, "ssmTranslate", true) {
146
147 @Override
148 public IgmpproxySsmTranslateConfig createConfig() {
149 return new IgmpproxySsmTranslateConfig();
150 }
151 };
152
153
154 class MockIgmpProxyConfig extends IgmpproxyConfig {
155 boolean igmpOnPodBasis = true;
156
157 MockIgmpProxyConfig(boolean igmpFlagValue) {
158 igmpOnPodBasis = igmpFlagValue;
159 }
160 @Override
161 public boolean igmpOnPodBasis() {
162 return igmpOnPodBasis;
163 }
164
165 @Override
166 public ConnectPoint getSourceDeviceAndPort() {
167 return COMMON_CONNECT_POINT;
168 }
169
170 @Override
171 public ConnectPoint connectPoint() {
172 return COMMON_CONNECT_POINT;
173 }
174 }
175
176
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +0000177 class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
178 Boolean igmpOnPodFlag = false;
179 TestNetworkConfigRegistry(Boolean igmpFlag) {
180 igmpOnPodFlag = igmpFlag;
181 }
182 @SuppressWarnings("unchecked")
183 @Override
Matteo Scandolo7482bbe2020-02-12 14:37:09 -0800184 public <S> Set<S> getSubjects(Class<S> subjectClass) {
185 if (subjectClass.getName().equalsIgnoreCase("org.onosproject.net.DeviceId")) {
186 return (Set<S>) ImmutableSet.of(DEVICE_ID_OF_A, DEVICE_ID_OF_B);
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +0000187 }
188 return null;
189 }
190
Matteo Scandolo7482bbe2020-02-12 14:37:09 -0800191 @SuppressWarnings("unchecked")
192 @Override
193 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
194 if (configClass.getName().equalsIgnoreCase("org.opencord.igmpproxy.IgmpproxyConfig")) {
195 IgmpproxyConfig igmpproxyConfig = new MockIgmpProxyConfig(igmpOnPodFlag);
196 return (C) igmpproxyConfig;
197 } else {
198 super.getConfig(subject, configClass);
199 }
200 return null;
201 }
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +0000202 }
203
204
205 /**
206 * Keeps a reference to the PacketProcessor and saves the OutboundPackets. Adds
207 * the emitted packet in savedPackets list
208 */
209 class MockPacketService extends PacketServiceAdapter {
210
211 public MockPacketService() {
212 savedPackets = new LinkedList<>();
213 }
214
215 @Override
216 public void addProcessor(PacketProcessor processor, int priority) {
217 packetProcessor = processor;
218 }
219
220 @Override
221 public void emit(OutboundPacket packet) {
222 synchronized (savedPackets) {
223 savedPackets.add(packet);
224 savedPackets.notify();
225 }
226 }
227 }
228
229
230 class MockMastershipService extends MastershipServiceAdapter {
231 @Override
232 public boolean isLocalMaster(DeviceId deviceId) {
233 return true;
234 }
235 }
236
237 final class TestMulticastRouteService implements MulticastRouteService {
238 @Override
239 public void addListener(McastListener listener) {
240 }
241
242 @Override
243 public void removeListener(McastListener listener) {
244 }
245
246 @Override
247 public void add(McastRoute route) {
248 }
249
250 @Override
251 public void remove(McastRoute route) {
252 }
253
254 @Override
255 public Set<McastRoute> getRoutes() {
256 return null;
257 }
258
259 @Override
260 public Set<McastRoute> getRoute(IpAddress groupIp, IpAddress sourceIp) {
261 return null;
262 }
263
264 @Override
265 public void addSource(McastRoute route, HostId source) {
266 }
267
268 @Override
269 public void addSources(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
270 }
271
272 @Override
273 public void addSources(McastRoute route, Set<ConnectPoint> sources) {
274
275 }
276
277 @Override
278 public void removeSources(McastRoute route) {
279
280 }
281
282 @Override
283 public void removeSource(McastRoute route, HostId source) {
284
285 }
286
287 @Override
288 public void addSink(McastRoute route, HostId hostId) {
289
290 }
291
292 @Override
293 public void addSinks(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
294
295 }
296
297 @Override
298 public void addSinks(McastRoute route, Set<ConnectPoint> sinks) {
299
300 }
301
302 @Override
303 public void removeSinks(McastRoute route) {
304
305 }
306
307 @Override
308 public void removeSink(McastRoute route, HostId hostId) {
309
310 }
311
312 @Override
313 public void removeSinks(McastRoute route, Set<ConnectPoint> sink) {
314
315 }
316
317 @Override
318 public McastRouteData routeData(McastRoute route) {
319 return null;
320 }
321
322 @Override
323 public Set<ConnectPoint> sources(McastRoute route) {
324 return null;
325 }
326
327 @Override
328 public Set<ConnectPoint> sources(McastRoute route, HostId hostId) {
329 return null;
330 }
331
332 @Override
333 public Set<ConnectPoint> sinks(McastRoute route) {
334 return null;
335 }
336
337 @Override
338 public Set<ConnectPoint> sinks(McastRoute route, HostId hostId) {
339 return null;
340 }
341
342 @Override
343 public Set<ConnectPoint> nonHostSinks(McastRoute route) {
344 return null;
345 }
346
347 }
348
349
350 /**
351 * Mocks the DefaultPacketContext.
352 */
353 final class TestPacketContext extends DefaultPacketContext {
354 TestPacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
355 super(time, inPkt, outPkt, block);
356 }
357
358 @Override
359 public void send() {
360 // We don't send anything out.
361 }
362 }
363
364 /**
365 * Sends an Ethernet packet to the process method of the Packet Processor.
366 *
367 * @param reply Ethernet packet
368 * @throws InterruptedException
369 */
370 void sendPacket(Ethernet reply) {
371
372 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
373
374 if (flagForPacket) {
375 InboundPacket inPacket = new DefaultInboundPacket(CONNECT_POINT_A, reply, byteBuffer);
376 context = new TestPacketContext(127L, inPacket, null, false);
377 flagForPacket = false;
378
379 packetProcessor.process(context);
380 } else {
381 InboundPacket inBoundPacket = new DefaultInboundPacket(CONNECT_POINT_B, reply, byteBuffer);
382 context = new TestPacketContext(127L, inBoundPacket, null, false);
383 flagForPacket = true;
384
385 packetProcessor.process(context);
386 }
387 }
388
Matteo Scandolo7482bbe2020-02-12 14:37:09 -0800389 protected class MockSadisService implements SadisService {
390
391 @Override
392 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
393 return new MockSubService();
394 }
395
396 @Override
397 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
398 return new MockBpService();
399 }
400 }
401
402 private class MockBpService implements BaseInformationService<BandwidthProfileInformation> {
403
404 @Override
405 public void invalidateAll() {
406
407 }
408
409 @Override
410 public void invalidateId(String id) {
411
412 }
413
414 @Override
415 public BandwidthProfileInformation get(String id) {
416 if (id.equals(dsBpId)) {
417 BandwidthProfileInformation bpInfo = new BandwidthProfileInformation();
418 bpInfo.setAssuredInformationRate(0);
419 bpInfo.setCommittedInformationRate(10000);
420 bpInfo.setCommittedBurstSize(1000L);
421 bpInfo.setExceededBurstSize(2000L);
422 bpInfo.setExceededInformationRate(20000);
423 return bpInfo;
424 }
425 return null;
426 }
427
428 @Override
429 public BandwidthProfileInformation getfromCache(String id) {
430 return null;
431 }
432 }
433
434 private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
435 MockSubscriberAndDeviceInformation sub =
436 new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID,
437 CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
438
439 @Override
440 public SubscriberAndDeviceInformation get(String id) {
441 return sub;
442 }
443
444 @Override
445 public void invalidateAll() {
446 }
447
448 @Override
449 public void invalidateId(String id) {
450 }
451
452 @Override
453 public SubscriberAndDeviceInformation getfromCache(String id) {
454 return null;
455 }
456 }
457
458 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
459
460 MockSubscriberAndDeviceInformation(String id, String nasPortId,
461 String circuitId, MacAddress hardId,
462 Ip4Address ipAddress) {
463 this.setHardwareIdentifier(hardId);
464 this.setId(id);
465 this.setIPAddress(ipAddress);
466 this.setNasPortId(nasPortId);
467 this.setCircuitId(circuitId);
468 }
469 }
470
Sonal Kasliwalddc3ff22019-11-18 11:52:49 +0000471}