blob: 20ac9f5315687da1c58d2eaf2eadba9c2c99e254 [file] [log] [blame]
Amit Ghosh8951f042017-08-10 13:48:10 +01001/*
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 */
16
Matteo Scandolo57af5d12019-04-29 17:11:41 -070017package org.opencord.dhcpl2relay.impl;
Amit Ghosh8951f042017-08-10 13:48:10 +010018
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030019import static com.google.common.base.Preconditions.checkState;
20import static org.junit.Assert.assertEquals;
21import static org.junit.Assert.fail;
22
23import java.nio.ByteBuffer;
24import java.nio.charset.StandardCharsets;
25import java.util.ArrayList;
26import java.util.Collection;
27import java.util.Dictionary;
28import java.util.Hashtable;
29import java.util.LinkedList;
30import java.util.List;
31import java.util.Set;
32import java.util.concurrent.Callable;
33import java.util.concurrent.ExecutionException;
34import java.util.concurrent.Future;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030035import java.util.concurrent.ScheduledExecutorService;
Saurav Dasbd5ce9c2020-09-04 18:46:45 -070036import java.util.concurrent.ScheduledFuture;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030037import java.util.concurrent.TimeUnit;
Saurav Dasbd5ce9c2020-09-04 18:46:45 -070038import java.util.concurrent.TimeoutException;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030039
Amit Ghosh8951f042017-08-10 13:48:10 +010040import org.onlab.packet.BasePacket;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030041import org.onlab.packet.ChassisId;
Amit Ghosh8951f042017-08-10 13:48:10 +010042import org.onlab.packet.DHCP;
Amit Ghosh8951f042017-08-10 13:48:10 +010043import org.onlab.packet.Ethernet;
44import org.onlab.packet.IPv4;
45import org.onlab.packet.Ip4Address;
Saurav Dasbd5ce9c2020-09-04 18:46:45 -070046import org.onlab.packet.IpAddress;
Amit Ghosh8951f042017-08-10 13:48:10 +010047import org.onlab.packet.MacAddress;
48import org.onlab.packet.UDP;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030049import org.onlab.packet.VlanId;
Jonathan Hartedbf6422018-05-02 17:30:05 -070050import org.onlab.packet.dhcp.DhcpOption;
Saurav Dasb4e3e102018-10-02 15:31:17 -070051import org.onosproject.core.ApplicationId;
52import org.onosproject.core.CoreServiceAdapter;
53import org.onosproject.core.DefaultApplicationId;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030054import org.onosproject.event.DefaultEventSinkRegistry;
55import org.onosproject.event.Event;
56import org.onosproject.event.EventDeliveryService;
57import org.onosproject.event.EventSink;
58import org.onosproject.mastership.MastershipServiceAdapter;
59import org.onosproject.net.AnnotationKeys;
60import org.onosproject.net.Annotations;
Amit Ghosh8951f042017-08-10 13:48:10 +010061import org.onosproject.net.ConnectPoint;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030062import org.onosproject.net.DefaultAnnotations;
63import org.onosproject.net.DefaultDevice;
64import org.onosproject.net.DefaultHost;
65import org.onosproject.net.Device;
66import org.onosproject.net.DeviceId;
67import org.onosproject.net.Element;
68import org.onosproject.net.Host;
69import org.onosproject.net.HostId;
70import org.onosproject.net.HostLocation;
71import org.onosproject.net.Port;
72import org.onosproject.net.PortNumber;
73import org.onosproject.net.device.DeviceServiceAdapter;
74import org.onosproject.net.host.HostServiceAdapter;
Amit Ghosh8951f042017-08-10 13:48:10 +010075import org.onosproject.net.packet.DefaultInboundPacket;
76import org.onosproject.net.packet.DefaultPacketContext;
77import org.onosproject.net.packet.InboundPacket;
78import org.onosproject.net.packet.OutboundPacket;
79import org.onosproject.net.packet.PacketContext;
80import org.onosproject.net.packet.PacketProcessor;
81import org.onosproject.net.packet.PacketServiceAdapter;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030082import org.onosproject.net.provider.ProviderId;
83import org.opencord.sadis.BandwidthProfileInformation;
84import org.opencord.sadis.BaseInformationService;
85import org.opencord.sadis.SadisService;
86import org.opencord.sadis.SubscriberAndDeviceInformation;
Gamze Abakaa64b3bc2020-01-31 06:51:43 +000087import org.opencord.sadis.UniTagInformation;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -030088import org.osgi.framework.Bundle;
89import org.osgi.framework.BundleContext;
90import org.osgi.framework.ServiceReference;
91import org.osgi.service.component.ComponentContext;
92import org.osgi.service.component.ComponentInstance;
Amit Ghosh8951f042017-08-10 13:48:10 +010093import org.slf4j.Logger;
94import org.slf4j.LoggerFactory;
95
Saurav Dasbd5ce9c2020-09-04 18:46:45 -070096import com.google.common.collect.ImmutableSet;
97
Amit Ghosh8951f042017-08-10 13:48:10 +010098
99/**
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700100 * Common methods for DHCP app testing.
Amit Ghosh8951f042017-08-10 13:48:10 +0100101 */
102public class DhcpL2RelayTestBase {
103 private final Logger log = LoggerFactory.getLogger(getClass());
104
Gamze Abakaa64b3bc2020-01-31 06:51:43 +0000105 static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 2);
106 static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 4);
107 static final short CLIENT_C_PBIT = 7;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300108 static final String CLIENT_ID_1 = "SUBSCRIBER_ID_1";
109 static final String CLIENT_NAS_PORT_ID = "PON 1/1";
110 static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
Gamze Abakaa64b3bc2020-01-31 06:51:43 +0000111 static final short NOT_PROVIDED = 0;
Amit Ghosh8951f042017-08-10 13:48:10 +0100112
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300113 static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
114 static final MacAddress SERVER_MAC = MacAddress.valueOf("bb:bb:bb:bb:bb:bb");
115 static final String DESTINATION_ADDRESS_IP = "1.1.1.1";
116 static final String DHCP_CLIENT_IP_ADDRESS = "2.2.2.2";
117 static final int UPLINK_PORT = 5;
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700118 static final int CLIENT_PORT = 1;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300119
120 static final String EXPECTED_IP = "10.2.0.2";
121 static final String OLT_DEV_ID = "of:00000000000000aa";
122 static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
123 static final int TRANSACTION_ID = 1000;
124 static final String SCHEME_NAME = "dhcpl2relay";
125 static final MacAddress OLT_MAC_ADDRESS = MacAddress.valueOf("01:02:03:04:05:06");
126
127 static final ConnectPoint SERVER_CONNECT_POINT =
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700128 ConnectPoint.deviceConnectPoint("of:00000000000000aa/" +
129 String.valueOf(UPLINK_PORT));
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300130
131 static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
132 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
Amit Ghosh8951f042017-08-10 13:48:10 +0100133
134 List<BasePacket> savedPackets = new LinkedList<>();
135 PacketProcessor packetProcessor;
136
137
138 /**
139 * Saves the given packet onto the saved packets list.
140 *
141 * @param packet packet to save
142 */
143 void savePacket(BasePacket packet) {
144 savedPackets.add(packet);
145 }
146
147 BasePacket getPacket() {
148 return savedPackets.remove(0);
149 }
150
151 /**
Saurav Dasb4e3e102018-10-02 15:31:17 -0700152 * Mock core service adaptor that provides an appId.
153 */
154 class MockCoreServiceAdapter extends CoreServiceAdapter {
155
156 @Override
157 public ApplicationId registerApplication(String name) {
158 return new DefaultApplicationId(10, name);
159 }
160 }
161
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300162 class MockDeviceService extends DeviceServiceAdapter {
163
164 private ProviderId providerId = new ProviderId("of", "foo");
165 private final Device device1 = new DhcpL2RelayTestBase.MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
166 "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
167 DEVICE_ANNOTATIONS);
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700168 private final Device otherDevice = new DhcpL2RelayTestBase.MockDevice(
169 providerId,
170 DeviceId.deviceId("of:0000b86a974385f7"),
171 Device.Type.SWITCH,
172 "foo.inc", "0", "0", "EC1838000853", new ChassisId(),
173 DEVICE_ANNOTATIONS);
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300174 @Override
175 public Device getDevice(DeviceId devId) {
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700176 if (devId.equals(DEVICE_ID_1)) {
177 return device1;
178 } else {
179 return otherDevice;
180 }
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300181 }
182
183 @Override
184 public Port getPort(ConnectPoint cp) {
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700185 return new DhcpL2RelayTestBase.MockPort(cp);
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300186 }
187
188 @Override
189 public Port getPort(DeviceId deviceId, PortNumber portNumber) {
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700190 return new DhcpL2RelayTestBase.MockPort(new ConnectPoint(deviceId,
191 portNumber));
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300192 }
193
194 @Override
195 public boolean isAvailable(DeviceId d) {
196 return true;
197 }
198 }
199
200 class MockDevice extends DefaultDevice {
201
202 public MockDevice(ProviderId providerId, DeviceId id, Type type,
203 String manufacturer, String hwVersion, String swVersion,
204 String serialNumber, ChassisId chassisId, Annotations... annotations) {
205 super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
206 chassisId, annotations);
207 }
208 }
209
210 class MockHostService extends HostServiceAdapter {
211
212 @Override
213 public Set<Host> getHostsByMac(MacAddress mac) {
214
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700215 HostLocation loc = new HostLocation(DEVICE_ID_1, PortNumber
216 .portNumber(CLIENT_PORT), 0);
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300217
218 IpAddress ip = IpAddress.valueOf("10.100.200.10");
219
220 Host h = new DefaultHost(ProviderId.NONE, HostId.hostId(mac, VlanId.NONE),
221 mac, VlanId.NONE, loc, ImmutableSet.of(ip));
222
223 return ImmutableSet.of(h);
224 }
225 }
226
227 class MockMastershipService extends MastershipServiceAdapter {
228 @Override
229 public boolean isLocalMaster(DeviceId d) {
230 return true;
231 }
232 }
233
234 class MockPort implements Port {
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700235 private ConnectPoint cp;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300236
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700237 public MockPort(ConnectPoint cp) {
238 this.cp = cp;
239 }
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300240 @Override
241 public boolean isEnabled() {
242 return true;
243 }
244 @Override
245 public long portSpeed() {
246 return 1000;
247 }
248 @Override
249 public Element element() {
250 return null;
251 }
252 @Override
253 public PortNumber number() {
254 return null;
255 }
256 @Override
257 public Annotations annotations() {
258 return new MockAnnotations();
259 }
260 @Override
261 public Type type() {
262 return Port.Type.FIBER;
263 }
264
265 private class MockAnnotations implements Annotations {
266
267 @Override
268 public String value(String val) {
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700269 if (cp.port().toLong() == 32) {
270 return "ALPHe3d1cea3-1";
271 } else if (cp.port().toLong() == 4112) {
272 return "ALPHe3d1ceb7-1";
273 } else {
274 return "PON 1/1";
275 }
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300276 }
277 @Override
278 public Set<String> keys() {
279 return null;
280 }
281 }
282 }
283
Saurav Dasb4e3e102018-10-02 15:31:17 -0700284 /**
Amit Ghosh8951f042017-08-10 13:48:10 +0100285 * Keeps a reference to the PacketProcessor and saves the OutboundPackets.
286 */
287 class MockPacketService extends PacketServiceAdapter {
288
289 @Override
290 public void addProcessor(PacketProcessor processor, int priority) {
291 packetProcessor = processor;
292 }
293
294 @Override
295 public void emit(OutboundPacket packet) {
296 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530297 Ethernet eth = Ethernet.deserializer().deserialize(packet.data().array(),
Amit Ghosh8951f042017-08-10 13:48:10 +0100298 0, packet.data().array().length);
299 savePacket(eth);
300 } catch (Exception e) {
301 fail(e.getMessage());
302 }
303 }
304 }
305
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300306 class MockSadisService implements SadisService {
307 @Override
308 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
309 return new DhcpL2RelayTestBase.MockSubService();
310 }
311
312 @Override
313 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
314 return null;
315 }
316 }
317
318 class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
319 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation device =
320 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation(OLT_DEV_ID, VlanId.NONE, VlanId.NONE, null,
321 null, OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"), UPLINK_PORT);
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700322 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation otherDevice =
323 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation(
324 "EC1838000853", VlanId.NONE, VlanId.NONE, null,
325 null, OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"), UPLINK_PORT);
326
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300327 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation sub =
328 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation(CLIENT_ID_1, CLIENT_C_TAG,
329 CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700330 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation sub32 =
331 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation("ALPHe3d1cea3-1", VlanId.vlanId((short) 801),
332 VlanId.vlanId((short) 111), CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
333 DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation sub4112 =
334 new DhcpL2RelayTestBase.MockSubscriberAndDeviceInformation("ALPHe3d1ceb7-1", VlanId.vlanId((short) 101),
335 VlanId.vlanId((short) 222), CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null, -1);
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300336 @Override
337 public SubscriberAndDeviceInformation get(String id) {
338 if (id.equals(OLT_DEV_ID)) {
339 return device;
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700340 } else if (id.equals("EC1838000853")) {
341 return otherDevice;
342 } else if (id.equals("ALPHe3d1cea3-1")) {
343 return sub32;
344 } else if (id.equals("ALPHe3d1ceb7-1")) {
345 return sub4112;
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300346 } else {
347 return sub;
348 }
349 }
350
351 @Override
352 public void invalidateAll() {}
353 @Override
354 public void invalidateId(String id) {}
355 @Override
356 public SubscriberAndDeviceInformation getfromCache(String id) {
357 return null;
358 }
359 }
360
361 class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
362
Gamze Abakaa64b3bc2020-01-31 06:51:43 +0000363 MockSubscriberAndDeviceInformation(String id, VlanId cTag,
364 VlanId sTag, String nasPortId,
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300365 String circuitId, MacAddress hardId,
366 Ip4Address ipAddress, int uplinkPort) {
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300367 this.setHardwareIdentifier(hardId);
368 this.setId(id);
369 this.setIPAddress(ipAddress);
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300370 this.setNasPortId(nasPortId);
371 this.setCircuitId(circuitId);
372 this.setUplinkPort(uplinkPort);
Gamze Abakaa64b3bc2020-01-31 06:51:43 +0000373
374 List<UniTagInformation> uniTagInformationList = new ArrayList<>();
375
376 UniTagInformation uniTagInformation = new UniTagInformation.Builder()
377 .setPonCTag(cTag)
378 .setPonSTag(sTag)
379 .setUsPonCTagPriority(CLIENT_C_PBIT)
380 .setIsDhcpRequired(true)
381 .build();
382 uniTagInformationList.add(uniTagInformation);
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700383
384 if (id.equals("ALPHe3d1cea3-1")) {
385 // a second service on the same UNI
386 uniTagInformation = new UniTagInformation.Builder()
387 .setPonCTag(VlanId.vlanId(((short) (cTag.toShort() + 1))))
388 .setPonSTag(sTag)
389 .setUsPonCTagPriority(CLIENT_C_PBIT)
390 .setIsDhcpRequired(true)
391 .build();
392 uniTagInformationList.add(uniTagInformation);
393 }
394
Gamze Abakaa64b3bc2020-01-31 06:51:43 +0000395 this.setUniTagList(uniTagInformationList);
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300396 }
397 }
398
399 class MockComponentContext implements ComponentContext {
400
401 @Override
402 public Dictionary<String, Object> getProperties() {
403 Dictionary<String, Object> cfgDict = new Hashtable<String, Object>();
404 cfgDict.put("publishCountersRate", 10);
405 return cfgDict;
406 }
407
408 @Override
409 public Object locateService(String name) {
410 // TODO Auto-generated method stub
411 return null;
412 }
413
414 @Override
415 public Object locateService(String name, ServiceReference reference) {
416 // TODO Auto-generated method stub
417 return null;
418 }
419
420 @Override
421 public Object[] locateServices(String name) {
422 // TODO Auto-generated method stub
423 return null;
424 }
425
426 @Override
427 public BundleContext getBundleContext() {
428 // TODO Auto-generated method stub
429 return null;
430 }
431
432 @Override
433 public Bundle getUsingBundle() {
434 // TODO Auto-generated method stub
435 return null;
436 }
437
438 @Override
439 public ComponentInstance getComponentInstance() {
440 // TODO Auto-generated method stub
441 return null;
442 }
443
444 @Override
445 public void enableComponent(String name) {
446 // TODO Auto-generated method stub
447 }
448
449 @Override
450 public void disableComponent(String name) {
451 // TODO Auto-generated method stub
452 }
453
454 @Override
455 public ServiceReference getServiceReference() {
456 // TODO Auto-generated method stub
457 return null;
458 }
459 }
460
461
Amit Ghosh8951f042017-08-10 13:48:10 +0100462 /**
463 * Mocks the DefaultPacketContext.
464 */
465 final class TestPacketContext extends DefaultPacketContext {
466
467 private TestPacketContext(long time, InboundPacket inPkt,
468 OutboundPacket outPkt, boolean block) {
469 super(time, inPkt, outPkt, block);
470 }
471
472 @Override
473 public void send() {
474 // We don't send anything out.
475 }
476 }
477
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300478 public static class TestEventDispatcher extends DefaultEventSinkRegistry
479 implements EventDeliveryService {
480 @Override
481 @SuppressWarnings("unchecked")
482 public synchronized void post(Event event) {
483 EventSink sink = getSink(event.getClass());
484 checkState(sink != null, "No sink for event %s", event);
485 sink.process(event);
486 }
487
488 @Override
489 public void setDispatchTimeLimit(long millis) {
490 }
491
492 @Override
493 public long getDispatchTimeLimit() {
494 return 0;
495 }
496 }
497
498 /**
499 * Creates a mock object for a scheduled executor service.
500 *
501 */
502 public static final class MockExecutor implements ScheduledExecutorService {
503 private ScheduledExecutorService executor;
504
505 MockExecutor(ScheduledExecutorService executor) {
506 this.executor = executor;
507 }
508
509 String lastMethodCalled = "";
510 long lastInitialDelay;
511 long lastDelay;
512 TimeUnit lastUnit;
513
514 public void assertLastMethodCalled(String method, long initialDelay, long delay, TimeUnit unit) {
515 assertEquals(method, lastMethodCalled);
516 assertEquals(initialDelay, lastInitialDelay);
517 assertEquals(delay, lastDelay);
518 assertEquals(unit, lastUnit);
519 }
520
521 @Override
522 public ScheduledFuture<?> schedule(Runnable command, long delay, TimeUnit unit) {
523 lastMethodCalled = "scheduleRunnable";
524 lastDelay = delay;
525 lastUnit = unit;
526 return null;
527 }
528
529 @Override
530 public <V> ScheduledFuture<V> schedule(Callable<V> callable, long delay, TimeUnit unit) {
531 lastMethodCalled = "scheduleCallable";
532 lastDelay = delay;
533 lastUnit = unit;
534 return null;
535 }
536
537 @Override
538 public ScheduledFuture<?> scheduleAtFixedRate(
539 Runnable command, long initialDelay, long period, TimeUnit unit) {
540 lastMethodCalled = "scheduleAtFixedRate";
541 lastInitialDelay = initialDelay;
542 lastDelay = period;
543 lastUnit = unit;
544 return null;
545 }
546
547 @Override
548 public ScheduledFuture<?> scheduleWithFixedDelay(
549 Runnable command, long initialDelay, long delay, TimeUnit unit) {
550 lastMethodCalled = "scheduleWithFixedDelay";
551 lastInitialDelay = initialDelay;
552 lastDelay = delay;
553 lastUnit = unit;
554 command.run();
555 return null;
556 }
557
558 @Override
559 public boolean awaitTermination(long timeout, TimeUnit unit) {
560 throw new UnsupportedOperationException();
561 }
562
563 @Override
564 public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
565 throws InterruptedException {
566 throw new UnsupportedOperationException();
567 }
568
569 @Override
570 public <T> List<Future<T>> invokeAll(
571 Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
572 throws InterruptedException {
573 throw new UnsupportedOperationException();
574 }
575
576 @Override
577 public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
578 throws ExecutionException, InterruptedException {
579 throw new UnsupportedOperationException();
580 }
581
582 @Override
583 public <T> T invokeAny(Collection<? extends Callable<T>> tasks, long timeout, TimeUnit unit)
584 throws ExecutionException, InterruptedException, TimeoutException {
585 throw new UnsupportedOperationException();
586 }
587
588 @Override
589 public boolean isShutdown() {
590 throw new UnsupportedOperationException();
591 }
592
593 @Override
594 public boolean isTerminated() {
595 throw new UnsupportedOperationException();
596 }
597
598 @Override
599 public void shutdown() {
600 throw new UnsupportedOperationException();
601 }
602
603 @Override
604 public List<Runnable> shutdownNow() {
605 return null;
606 }
607
608 @Override
609 public <T> Future<T> submit(Callable<T> task) {
610 throw new UnsupportedOperationException();
611 }
612
613 @Override
614 public Future<?> submit(Runnable task) {
615 throw new UnsupportedOperationException();
616 }
617
618 @Override
619 public <T> Future<T> submit(Runnable task, T result) {
620 throw new UnsupportedOperationException();
621 }
622
623 @Override
624 public void execute(Runnable command) {
625 throw new UnsupportedOperationException();
626 }
627 }
628
Amit Ghosh8951f042017-08-10 13:48:10 +0100629 /**
630 * Sends an Ethernet packet to the process method of the Packet Processor.
631 *
632 * @param pkt Ethernet packet
633 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530634 void sendPacket(Ethernet pkt, ConnectPoint cp) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100635 final ByteBuffer byteBuffer = ByteBuffer.wrap(pkt.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530636 InboundPacket inPacket = new DefaultInboundPacket(cp, pkt, byteBuffer);
Amit Ghosh8951f042017-08-10 13:48:10 +0100637
638 PacketContext context = new TestPacketContext(127L, inPacket, null, false);
639 packetProcessor.process(context);
640 }
641
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700642 private Ethernet constructEthernetPacket(MacAddress srcMac, MacAddress dstMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100643 String dstIp, byte dhcpReqRsp,
644 MacAddress clientHwAddress,
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700645 Ip4Address dhcpClientIpAddress,
646 VlanId clientVlan, short clientPbit) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100647 // Ethernet Frame.
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530648 Ethernet ethPkt = new Ethernet();
649 ethPkt.setSourceMACAddress(srcMac);
650 ethPkt.setDestinationMACAddress(dstMac);
Amit Ghosh8951f042017-08-10 13:48:10 +0100651 ethPkt.setEtherType(Ethernet.TYPE_IPV4);
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700652 ethPkt.setVlanID(clientVlan.toShort());
653 ethPkt.setPriorityCode((byte) clientPbit);
Gamze Abakaa64b3bc2020-01-31 06:51:43 +0000654
655 if (DHCP.OPCODE_REPLY == dhcpReqRsp) {
656 ethPkt.setQinQPriorityCode((byte) 3);
657 ethPkt.setQinQVID((short) 4);
658 }
Amit Ghosh8951f042017-08-10 13:48:10 +0100659
660 // IP Packet
661 IPv4 ipv4Reply = new IPv4();
662 ipv4Reply.setSourceAddress(0);
663 ipv4Reply.setDestinationAddress(dstIp);
664
665 ipv4Reply.setTtl((byte) 127);
666
667 // UDP Datagram.
668 UDP udpReply = new UDP();
669 udpReply.setSourcePort((byte) UDP.DHCP_CLIENT_PORT);
670 udpReply.setDestinationPort((byte) UDP.DHCP_SERVER_PORT);
671
672 // DHCP Payload.
673 DHCP dhcpReply = new DHCP();
674 dhcpReply.setOpCode(dhcpReqRsp);
675
676 dhcpReply.setYourIPAddress(dhcpClientIpAddress.toInt());
677 dhcpReply.setServerIPAddress(0);
678
679 final byte[] serverNameBytes = new byte[64];
680 String result = new String(serverNameBytes, StandardCharsets.US_ASCII).trim();
681 dhcpReply.setServerName(result);
682
683 final byte[] bootFileBytes = new byte[128];
684 String result1 = new String(bootFileBytes, StandardCharsets.US_ASCII).trim();
685 dhcpReply.setBootFileName(result1);
686
687 dhcpReply.setTransactionId(TRANSACTION_ID);
688 dhcpReply.setClientHardwareAddress(clientHwAddress.toBytes());
689 dhcpReply.setHardwareType(DHCP.HWTYPE_ETHERNET);
690 dhcpReply.setHardwareAddressLength((byte) 6);
691
692 udpReply.setPayload(dhcpReply);
693 ipv4Reply.setPayload(udpReply);
694 ethPkt.setPayload(ipv4Reply);
695
696 return ethPkt;
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700697
698 }
699
700 /**
701 * Constructs an Ethernet packet with IP/UDP/DHCP payload and client
702 * VLAN information.
703 *
704 * @return Ethernet packet
705 */
706 private Ethernet construcEthernetPacket(MacAddress srcMac, MacAddress dstMac,
707 String dstIp, byte dhcpReqRsp,
708 MacAddress clientHwAddress,
709 Ip4Address dhcpClientIpAddress) {
710 return constructEthernetPacket(srcMac, dstMac, dstIp, dhcpReqRsp,
711 clientHwAddress, dhcpClientIpAddress,
712 CLIENT_C_TAG, CLIENT_C_PBIT);
713
Amit Ghosh8951f042017-08-10 13:48:10 +0100714 }
715
716 /**
717 * Constructs DHCP Discover Packet.
718 *
719 * @return Ethernet packet
720 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530721 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac) {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530722 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700723 "255.255.255.255", DHCP.OPCODE_REQUEST, clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100724 Ip4Address.valueOf("0.0.0.0"));
725
726 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
727 UDP udpPacket = (UDP) ipv4Packet.getPayload();
728 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
729
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700730 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPDISCOVER));
Amit Ghosh8951f042017-08-10 13:48:10 +0100731
732 return pkt;
733 }
734
735 /**
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700736 * Constructs DHCP Discover Packet with client VLAN information.
737 *
738 * @return Ethernet packet
739 */
740 Ethernet constructDhcpDiscoverPacket(MacAddress clientMac, VlanId clientVlan,
741 short clientPbit) {
742 Ethernet pkt = constructEthernetPacket(clientMac, MacAddress.BROADCAST,
743 "255.255.255.255", DHCP.OPCODE_REQUEST, clientMac,
744 Ip4Address.valueOf("0.0.0.0"), clientVlan, clientPbit);
745
746 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
747 UDP udpPacket = (UDP) ipv4Packet.getPayload();
748 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
749
750 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPDISCOVER));
751
752 return pkt;
753 }
754
755 /**
Amit Ghosh8951f042017-08-10 13:48:10 +0100756 * Constructs DHCP Request Packet.
757 *
758 * @return Ethernet packet
759 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530760 Ethernet constructDhcpRequestPacket(MacAddress clientMac) {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530761 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700762 "255.255.255.255", DHCP.OPCODE_REQUEST, clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100763 Ip4Address.valueOf("0.0.0.0"));
764
765 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
766 UDP udpPacket = (UDP) ipv4Packet.getPayload();
767 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
768
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700769 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPREQUEST));
Amit Ghosh8951f042017-08-10 13:48:10 +0100770
771 return pkt;
772 }
773
774 /**
775 * Constructs DHCP Offer Packet.
776 *
777 * @return Ethernet packet
778 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530779 Ethernet constructDhcpOfferPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100780 String ipAddress, String dhcpClientIpAddress) {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530781 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100782 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
783
784 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
785 UDP udpPacket = (UDP) ipv4Packet.getPayload();
786 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
787
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700788 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPOFFER));
Amit Ghosh8951f042017-08-10 13:48:10 +0100789
790 return pkt;
791 }
792
793 /**
794 * Constructs DHCP Ack Packet.
795 *
796 * @return Ethernet packet
797 */
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530798 Ethernet constructDhcpAckPacket(MacAddress servMac, MacAddress clientMac,
Amit Ghosh8951f042017-08-10 13:48:10 +0100799 String ipAddress, String dhcpClientIpAddress) {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530800 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
Amit Ghosh8951f042017-08-10 13:48:10 +0100801 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
802
803 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
804 UDP udpPacket = (UDP) ipv4Packet.getPayload();
805 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
806
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700807 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPACK));
Amit Ghosh8951f042017-08-10 13:48:10 +0100808
809 return pkt;
810 }
811
812 /**
Arjun E K05ad20b2020-03-13 13:25:17 +0000813 * Constructs DHCP Nak Packet.
814 *
815 * @return Ethernet packet
816 */
817 Ethernet constructDhcpNakPacket(MacAddress servMac, MacAddress clientMac,
818 String ipAddress, String dhcpClientIpAddress) {
819
820 Ethernet pkt = construcEthernetPacket(servMac, clientMac, ipAddress, DHCP.OPCODE_REPLY,
821 clientMac, Ip4Address.valueOf(dhcpClientIpAddress));
822
823 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
824 UDP udpPacket = (UDP) ipv4Packet.getPayload();
825 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
826
827 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPNAK));
828
829 return pkt;
830 }
831
832 /**
833 * Constructs DHCP Decline Packet.
834 *
835 * @return Ethernet packet
836 */
837 Ethernet constructDhcpDeclinePacket(MacAddress clientMac) {
838
839 Ethernet pkt = construcEthernetPacket(clientMac, MacAddress.BROADCAST,
Saurav Dasbd5ce9c2020-09-04 18:46:45 -0700840 "255.255.255.255", DHCP.OPCODE_REQUEST, clientMac,
Arjun E K05ad20b2020-03-13 13:25:17 +0000841 Ip4Address.valueOf("0.0.0.0"));
842
843 IPv4 ipv4Packet = (IPv4) pkt.getPayload();
844 UDP udpPacket = (UDP) ipv4Packet.getPayload();
845 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
846
847 dhcpPacket.setOptions(constructDhcpOptions(DHCP.MsgType.DHCPDECLINE));
848
849 return pkt;
850 }
851
852 /**
Amit Ghosh8951f042017-08-10 13:48:10 +0100853 * Constructs DHCP Discover Options.
854 *
855 * @return Ethernet packet
856 */
Carmelo Casconede1e6e32019-07-15 19:39:08 -0700857 private List<DhcpOption> constructDhcpOptions(DHCP.MsgType packetType) {
Amit Ghosh8951f042017-08-10 13:48:10 +0100858
859 // DHCP Options.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700860 DhcpOption option = new DhcpOption();
861 List<DhcpOption> optionList = new ArrayList<>();
Amit Ghosh8951f042017-08-10 13:48:10 +0100862
863
864 // DHCP Message Type.
865 option.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
866 option.setLength((byte) 1);
867 byte[] optionData = {(byte) packetType.getValue()};
868 option.setData(optionData);
869 optionList.add(option);
870
871 // DHCP Requested IP.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700872 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100873 option.setCode(DHCP.DHCPOptionCode.OptionCode_RequestedIP.getValue());
874 option.setLength((byte) 4);
875 optionData = Ip4Address.valueOf(EXPECTED_IP).toOctets();
876 option.setData(optionData);
877 optionList.add(option);
878
879 // End Option.
Jonathan Hartedbf6422018-05-02 17:30:05 -0700880 option = new DhcpOption();
Amit Ghosh8951f042017-08-10 13:48:10 +0100881 option.setCode(DHCP.DHCPOptionCode.OptionCode_END.getValue());
882 option.setLength((byte) 1);
883 optionList.add(option);
884
885 return optionList;
886 }
Marcos Aurelio Carreroeaf02b82019-11-25 13:34:25 -0300887}