blob: 43cc24a9bdbf06850c1eeb46167c74be3c4bc4aa [file] [log] [blame]
Vignesh Ethirajd1957c92019-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
Esin Karaman305908c2020-02-24 14:42:52 +000018import com.google.common.collect.ImmutableSet;
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000019import org.onlab.packet.Ethernet;
20import org.onlab.packet.Ip4Address;
21import org.onlab.packet.IpAddress;
Esin Karaman305908c2020-02-24 14:42:52 +000022import org.onlab.packet.MacAddress;
Vignesh Ethirajd1957c92019-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;
Vignesh Ethirajd1957c92019-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;
Esin Karaman305908c2020-02-24 14:42:52 +000034import org.onosproject.net.DefaultPort;
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000035import org.onosproject.net.Device;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.HostId;
38import org.onosproject.net.Port;
39import org.onosproject.net.PortNumber;
40import org.onosproject.net.SparseAnnotations;
41import org.onosproject.net.config.Config;
Esin Karaman305908c2020-02-24 14:42:52 +000042import org.onosproject.net.config.ConfigFactory;
43import org.onosproject.net.config.NetworkConfigRegistryAdapter;
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000044import org.onosproject.net.config.basics.McastConfig;
45import org.onosproject.net.config.basics.SubjectFactories;
46import org.onosproject.net.device.DeviceServiceAdapter;
47import org.onosproject.net.packet.DefaultInboundPacket;
48import org.onosproject.net.packet.DefaultPacketContext;
49import org.onosproject.net.packet.InboundPacket;
50import org.onosproject.net.packet.OutboundPacket;
51import org.onosproject.net.packet.PacketContext;
52import org.onosproject.net.packet.PacketProcessor;
53import org.onosproject.net.packet.PacketServiceAdapter;
Esin Karaman305908c2020-02-24 14:42:52 +000054import org.opencord.sadis.BandwidthProfileInformation;
55import org.opencord.sadis.BaseInformationService;
56import org.opencord.sadis.SadisService;
57import org.opencord.sadis.SubscriberAndDeviceInformation;
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000058import org.slf4j.Logger;
59import org.slf4j.LoggerFactory;
60
Esin Karaman305908c2020-02-24 14:42:52 +000061import java.nio.ByteBuffer;
62import java.util.ArrayList;
63import java.util.LinkedList;
64import java.util.List;
65import java.util.Set;
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000066
67public class IgmpManagerBase {
68
69 // Device configuration
70 protected static final DeviceId DEVICE_ID_OF_A = DeviceId.deviceId("of:1");
71 protected static final DeviceId DEVICE_ID_OF_B = DeviceId.deviceId("of:2");
72
73 //Multicast ip address
74 protected static final Ip4Address GROUP_IP = Ip4Address.valueOf("224.0.0.0");
75 // Source ip address of two different device.
76 protected static final Ip4Address SOURCE_IP_OF_A = Ip4Address.valueOf("10.177.125.4");
77 protected static final Ip4Address SOURCE_IP_OF_B = Ip4Address.valueOf("10.177.125.5");
78
79 // Common connect point of aggregation switch used by all devices.
80 protected static final ConnectPoint COMMON_CONNECT_POINT =
81 ConnectPoint.deviceConnectPoint("of:00000000000000003/3");
82 // Uplink ports for two olts A and B
83 protected static final PortNumber PORT_A = PortNumber.portNumber(1);
84 protected static final PortNumber PORT_B = PortNumber.portNumber(2);
Esin Karaman305908c2020-02-24 14:42:52 +000085 protected static final PortNumber PORT_NNI = PortNumber.portNumber(65536);
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000086
87 // Connect Point mode for two olts
88 protected static final ConnectPoint CONNECT_POINT_A = new ConnectPoint(DEVICE_ID_OF_A, PORT_A);
89 protected static final ConnectPoint CONNECT_POINT_B = new ConnectPoint(DEVICE_ID_OF_B, PORT_B);
90
Esin Karaman305908c2020-02-24 14:42:52 +000091 protected static final String CLIENT_NAS_PORT_ID = "PON 1/1";
92 protected static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
93 protected String dsBpId = "HSIA-DS";
94
95 private static final String NNI_PREFIX = "nni";
96
Vignesh Ethirajd1957c92019-11-18 11:52:49 +000097 protected List<Port> lsPorts = new ArrayList<Port>();
98 // Flag for adding two different devices in oltData
99 protected boolean flagForDevice = true;
100 PacketContext context;
101 // Flag for sending two different packets
102 protected boolean flagForPacket = true;
103 // List to store the packets emitted
104 protected List<OutboundPacket> savedPackets;
105 protected PacketProcessor packetProcessor;
106 private Logger log = LoggerFactory.getLogger(getClass());
107
108 class MockDeviceService extends DeviceServiceAdapter {
109
110 @Override
111 public Device getDevice(DeviceId deviceId) {
112 if (flagForDevice) {
113 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
114 .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_A.toString());
115 SparseAnnotations annotations = annotationsBuilder.build();
116 Annotations[] da = {annotations };
117 Device deviceA = new DefaultDevice(null, DEVICE_ID_OF_A, Device.Type.OTHER, "", "", "", "", null, da);
118 flagForDevice = false;
119 return deviceA;
120 } else {
121 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
122 .set(AnnotationKeys.MANAGEMENT_ADDRESS, SOURCE_IP_OF_B.toString());
123 SparseAnnotations annotations = annotationsBuilder.build();
124 Annotations[] da = {annotations };
125 Device deviceB = new DefaultDevice(null, DEVICE_ID_OF_B, Device.Type.OTHER, "", "", "", "", null, da);
126 return deviceB;
127 }
128 }
129 @Override
130 public List<Port> getPorts(DeviceId deviceId) {
131 return lsPorts;
132 }
Esin Karaman305908c2020-02-24 14:42:52 +0000133
134 @Override
135 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
136 if (portNumber.equals(PORT_NNI)) {
137 DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder()
138 .set(AnnotationKeys.PORT_NAME, NNI_PREFIX);
139 Port nni = new DefaultPort(null, portNumber, true, annotationsBuilder.build());
140 return nni;
141 }
142 return super.getPort(deviceId, portNumber);
143 }
Vignesh Ethirajd1957c92019-11-18 11:52:49 +0000144 }
145
Vignesh Ethirajd1957c92019-11-18 11:52:49 +0000146 static final Class<IgmpproxyConfig> IGMPPROXY_CONFIG_CLASS = IgmpproxyConfig.class;
147 static final Class<IgmpproxySsmTranslateConfig> IGMPPROXY_SSM_CONFIG_CLASS = IgmpproxySsmTranslateConfig.class;
148 static final Class<McastConfig> MCAST_CONFIG_CLASS = McastConfig.class;
149 ConfigFactory<ApplicationId, IgmpproxyConfig> igmpproxyConfigFactory =
150 new ConfigFactory<ApplicationId, IgmpproxyConfig>(
151 SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_CONFIG_CLASS, "igmpproxy") {
152 @Override
153 public IgmpproxyConfig createConfig() {
154 return new IgmpproxyConfig();
155 }
156 };
157
158 ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig> igmpproxySsmConfigFactory =
159 new ConfigFactory<ApplicationId, IgmpproxySsmTranslateConfig>(
160 SubjectFactories.APP_SUBJECT_FACTORY, IGMPPROXY_SSM_CONFIG_CLASS, "ssmTranslate", true) {
161
162 @Override
163 public IgmpproxySsmTranslateConfig createConfig() {
164 return new IgmpproxySsmTranslateConfig();
165 }
166 };
167
168
169 class MockIgmpProxyConfig extends IgmpproxyConfig {
170 boolean igmpOnPodBasis = true;
171
172 MockIgmpProxyConfig(boolean igmpFlagValue) {
173 igmpOnPodBasis = igmpFlagValue;
174 }
175 @Override
176 public boolean igmpOnPodBasis() {
177 return igmpOnPodBasis;
178 }
179
180 @Override
181 public ConnectPoint getSourceDeviceAndPort() {
182 return COMMON_CONNECT_POINT;
183 }
184
185 @Override
186 public ConnectPoint connectPoint() {
187 return COMMON_CONNECT_POINT;
188 }
189 }
190
191
Vignesh Ethirajd1957c92019-11-18 11:52:49 +0000192 class TestNetworkConfigRegistry extends NetworkConfigRegistryAdapter {
193 Boolean igmpOnPodFlag = false;
194 TestNetworkConfigRegistry(Boolean igmpFlag) {
195 igmpOnPodFlag = igmpFlag;
196 }
197 @SuppressWarnings("unchecked")
198 @Override
Esin Karaman305908c2020-02-24 14:42:52 +0000199 public <S> Set<S> getSubjects(Class<S> subjectClass) {
200 if (subjectClass.getName().equalsIgnoreCase("org.onosproject.net.DeviceId")) {
201 return (Set<S>) ImmutableSet.of(DEVICE_ID_OF_A, DEVICE_ID_OF_B);
Vignesh Ethirajd1957c92019-11-18 11:52:49 +0000202 }
203 return null;
204 }
205
Esin Karaman305908c2020-02-24 14:42:52 +0000206 @SuppressWarnings("unchecked")
207 @Override
208 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
209 if (configClass.getName().equalsIgnoreCase("org.opencord.igmpproxy.IgmpproxyConfig")) {
210 IgmpproxyConfig igmpproxyConfig = new MockIgmpProxyConfig(igmpOnPodFlag);
211 return (C) igmpproxyConfig;
212 } else {
213 super.getConfig(subject, configClass);
214 }
215 return null;
216 }
Vignesh Ethirajd1957c92019-11-18 11:52:49 +0000217 }
218
219
220 /**
221 * Keeps a reference to the PacketProcessor and saves the OutboundPackets. Adds
222 * the emitted packet in savedPackets list
223 */
224 class MockPacketService extends PacketServiceAdapter {
225
226 public MockPacketService() {
227 savedPackets = new LinkedList<>();
228 }
229
230 @Override
231 public void addProcessor(PacketProcessor processor, int priority) {
232 packetProcessor = processor;
233 }
234
235 @Override
236 public void emit(OutboundPacket packet) {
237 synchronized (savedPackets) {
238 savedPackets.add(packet);
239 savedPackets.notify();
240 }
241 }
242 }
243
244
245 class MockMastershipService extends MastershipServiceAdapter {
246 @Override
247 public boolean isLocalMaster(DeviceId deviceId) {
248 return true;
249 }
250 }
251
252 final class TestMulticastRouteService implements MulticastRouteService {
253 @Override
254 public void addListener(McastListener listener) {
255 }
256
257 @Override
258 public void removeListener(McastListener listener) {
259 }
260
261 @Override
262 public void add(McastRoute route) {
263 }
264
265 @Override
266 public void remove(McastRoute route) {
267 }
268
269 @Override
270 public Set<McastRoute> getRoutes() {
271 return null;
272 }
273
274 @Override
275 public Set<McastRoute> getRoute(IpAddress groupIp, IpAddress sourceIp) {
276 return null;
277 }
278
279 @Override
280 public void addSource(McastRoute route, HostId source) {
281 }
282
283 @Override
284 public void addSources(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
285 }
286
287 @Override
288 public void addSources(McastRoute route, Set<ConnectPoint> sources) {
289
290 }
291
292 @Override
293 public void removeSources(McastRoute route) {
294
295 }
296
297 @Override
298 public void removeSource(McastRoute route, HostId source) {
299
300 }
301
302 @Override
303 public void addSink(McastRoute route, HostId hostId) {
304
305 }
306
307 @Override
308 public void addSinks(McastRoute route, HostId hostId, Set<ConnectPoint> connectPoints) {
309
310 }
311
312 @Override
313 public void addSinks(McastRoute route, Set<ConnectPoint> sinks) {
314
315 }
316
317 @Override
318 public void removeSinks(McastRoute route) {
319
320 }
321
322 @Override
323 public void removeSink(McastRoute route, HostId hostId) {
324
325 }
326
327 @Override
328 public void removeSinks(McastRoute route, Set<ConnectPoint> sink) {
329
330 }
331
332 @Override
333 public McastRouteData routeData(McastRoute route) {
334 return null;
335 }
336
337 @Override
338 public Set<ConnectPoint> sources(McastRoute route) {
339 return null;
340 }
341
342 @Override
343 public Set<ConnectPoint> sources(McastRoute route, HostId hostId) {
344 return null;
345 }
346
347 @Override
348 public Set<ConnectPoint> sinks(McastRoute route) {
349 return null;
350 }
351
352 @Override
353 public Set<ConnectPoint> sinks(McastRoute route, HostId hostId) {
354 return null;
355 }
356
357 @Override
358 public Set<ConnectPoint> nonHostSinks(McastRoute route) {
359 return null;
360 }
361
362 }
363
364
365 /**
366 * Mocks the DefaultPacketContext.
367 */
368 final class TestPacketContext extends DefaultPacketContext {
369 TestPacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
370 super(time, inPkt, outPkt, block);
371 }
372
373 @Override
374 public void send() {
375 // We don't send anything out.
376 }
377 }
378
379 /**
380 * Sends an Ethernet packet to the process method of the Packet Processor.
381 *
382 * @param reply Ethernet packet
383 * @throws InterruptedException
384 */
385 void sendPacket(Ethernet reply) {
386
387 final ByteBuffer byteBuffer = ByteBuffer.wrap(reply.serialize());
388
389 if (flagForPacket) {
390 InboundPacket inPacket = new DefaultInboundPacket(CONNECT_POINT_A, reply, byteBuffer);
391 context = new TestPacketContext(127L, inPacket, null, false);
392 flagForPacket = false;
393
394 packetProcessor.process(context);
395 } else {
396 InboundPacket inBoundPacket = new DefaultInboundPacket(CONNECT_POINT_B, reply, byteBuffer);
397 context = new TestPacketContext(127L, inBoundPacket, null, false);
398 flagForPacket = true;
399
400 packetProcessor.process(context);
401 }
402 }
403
Esin Karaman305908c2020-02-24 14:42:52 +0000404 protected class MockSadisService implements SadisService {
405
406 @Override
407 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
408 return new MockSubService();
409 }
410
411 @Override
412 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
413 return new MockBpService();
414 }
415 }
416
417 private class MockBpService implements BaseInformationService<BandwidthProfileInformation> {
418
419 @Override
420 public void invalidateAll() {
421
422 }
423
424 @Override
425 public void invalidateId(String id) {
426
427 }
428
429 @Override
430 public BandwidthProfileInformation get(String id) {
431 if (id.equals(dsBpId)) {
432 BandwidthProfileInformation bpInfo = new BandwidthProfileInformation();
433 bpInfo.setAssuredInformationRate(0);
434 bpInfo.setCommittedInformationRate(10000);
435 bpInfo.setCommittedBurstSize(1000L);
436 bpInfo.setExceededBurstSize(2000L);
437 bpInfo.setExceededInformationRate(20000);
438 return bpInfo;
439 }
440 return null;
441 }
442
443 @Override
444 public BandwidthProfileInformation getfromCache(String id) {
445 return null;
446 }
447 }
448
449 private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
450 MockSubscriberAndDeviceInformation sub =
451 new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID,
452 CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
453
454 @Override
455 public SubscriberAndDeviceInformation get(String id) {
456 return sub;
457 }
458
459 @Override
460 public void invalidateAll() {
461 }
462
463 @Override
464 public void invalidateId(String id) {
465 }
466
467 @Override
468 public SubscriberAndDeviceInformation getfromCache(String id) {
469 return null;
470 }
471 }
472
473 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
474
475 MockSubscriberAndDeviceInformation(String id, String nasPortId,
476 String circuitId, MacAddress hardId,
477 Ip4Address ipAddress) {
478 this.setHardwareIdentifier(hardId);
479 this.setId(id);
480 this.setIPAddress(ipAddress);
481 this.setNasPortId(nasPortId);
482 this.setCircuitId(circuitId);
483 this.setUplinkPort((int) PORT_NNI.toLong());
484 }
485 }
486
Vignesh Ethirajd1957c92019-11-18 11:52:49 +0000487}