blob: 111780442bba5f4e5f0308ab71cd1c83f0289afa [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 */
16package org.opencord.dhcpl2relay;
17
Saurav Dasb4e3e102018-10-02 15:31:17 -070018import static org.junit.Assert.assertEquals;
19
20import java.nio.ByteBuffer;
21import java.util.List;
22import java.util.Set;
23
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053024import org.easymock.EasyMock;
Amit Ghosh8951f042017-08-10 13:48:10 +010025import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
Jonathan Hartc36c9552018-07-31 15:07:53 -040028import org.onlab.junit.TestUtils;
Amit Ghosh8951f042017-08-10 13:48:10 +010029import org.onlab.osgi.ComponentContextAdapter;
30import org.onlab.packet.ChassisId;
31import org.onlab.packet.DHCP;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053032import org.onlab.packet.Ethernet;
Amit Ghosh8951f042017-08-10 13:48:10 +010033import org.onlab.packet.IPv4;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053034import org.onlab.packet.Ip4Address;
35import org.onlab.packet.IpAddress;
Amit Ghosh8951f042017-08-10 13:48:10 +010036import org.onlab.packet.MacAddress;
37import org.onlab.packet.UDP;
38import org.onlab.packet.VlanId;
Jonathan Hartedbf6422018-05-02 17:30:05 -070039import org.onlab.packet.dhcp.DhcpOption;
Amit Ghosh8951f042017-08-10 13:48:10 +010040import org.onosproject.cfg.ComponentConfigService;
Jonathan Hartc36c9552018-07-31 15:07:53 -040041import org.onosproject.common.event.impl.TestEventDispatcher;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053042import org.onosproject.mastership.MastershipServiceAdapter;
43import org.onosproject.net.AnnotationKeys;
44import org.onosproject.net.Annotations;
Amit Ghosh8951f042017-08-10 13:48:10 +010045import org.onosproject.net.ConnectPoint;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053046import org.onosproject.net.DefaultAnnotations;
Amit Ghosh8951f042017-08-10 13:48:10 +010047import org.onosproject.net.DefaultDevice;
48import org.onosproject.net.DefaultHost;
49import org.onosproject.net.Device;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053050import org.onosproject.net.DeviceId;
Amit Ghosh8951f042017-08-10 13:48:10 +010051import org.onosproject.net.Element;
Amit Ghosh8951f042017-08-10 13:48:10 +010052import org.onosproject.net.Host;
53import org.onosproject.net.HostId;
54import org.onosproject.net.HostLocation;
Amit Ghosh8951f042017-08-10 13:48:10 +010055import org.onosproject.net.Port;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053056import org.onosproject.net.PortNumber;
57import org.onosproject.net.config.Config;
58import org.onosproject.net.config.NetworkConfigRegistryAdapter;
59import org.onosproject.net.device.DeviceServiceAdapter;
Saurav Dasb4e3e102018-10-02 15:31:17 -070060import org.onosproject.net.flowobjective.FlowObjectiveServiceAdapter;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053061import org.onosproject.net.host.HostServiceAdapter;
62import org.onosproject.net.provider.ProviderId;
Amit Ghosh8951f042017-08-10 13:48:10 +010063import org.opencord.dhcpl2relay.packet.DhcpOption82;
64import org.opencord.sadis.SubscriberAndDeviceInformation;
Gamze Abakac806c6c2018-12-03 12:49:46 +000065import org.opencord.sadis.BandwidthProfileInformation;
66import org.opencord.sadis.BaseInformationService;
67import org.opencord.sadis.SadisService;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053068import org.slf4j.Logger;
69import org.slf4j.LoggerFactory;
Amit Ghosh8951f042017-08-10 13:48:10 +010070
Saurav Dasb4e3e102018-10-02 15:31:17 -070071import com.google.common.collect.ImmutableSet;
72import com.google.common.collect.Lists;
Amit Ghosh8951f042017-08-10 13:48:10 +010073
74public class DhcpL2RelayTest extends DhcpL2RelayTestBase {
75
76 private final Logger log = LoggerFactory.getLogger(getClass());
77
78 private DhcpL2Relay dhcpL2Relay;
79
80 private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
81 private static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 999);
82 private static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 111);
83 private static final String CLIENT_NAS_PORT_ID = "PON 1/1";
84 private static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
85
86 private static final String OLT_DEV_ID = "of:00000000000000aa";
87 private static final MacAddress OLT_MAC_ADDRESS = MacAddress.valueOf("01:02:03:04:05:06");
88 private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
89
90 private static final ConnectPoint SERVER_CONNECT_POINT =
91 ConnectPoint.deviceConnectPoint("of:0000000000000001/5");
92
93 private static final String SCHEME_NAME = "dhcpl2relay";
94 private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
95 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
96
97 ComponentConfigService mockConfigService =
98 EasyMock.createMock(ComponentConfigService.class);
99
100 /**
101 * Sets up the services required by the dhcpl2relay app.
102 */
103 @Before
104 public void setUp() {
105 dhcpL2Relay = new DhcpL2Relay();
106 dhcpL2Relay.cfgService = new TestNetworkConfigRegistry();
Saurav Dasb4e3e102018-10-02 15:31:17 -0700107 dhcpL2Relay.coreService = new MockCoreServiceAdapter();
108 dhcpL2Relay.flowObjectiveService = new FlowObjectiveServiceAdapter();
Amit Ghosh8951f042017-08-10 13:48:10 +0100109 dhcpL2Relay.packetService = new MockPacketService();
110 dhcpL2Relay.componentConfigService = mockConfigService;
111 dhcpL2Relay.deviceService = new MockDeviceService();
Gamze Abakac806c6c2018-12-03 12:49:46 +0000112 dhcpL2Relay.sadisService = new MockSadisService();
Amit Ghosh8951f042017-08-10 13:48:10 +0100113 dhcpL2Relay.hostService = new MockHostService();
114 dhcpL2Relay.mastershipService = new MockMastershipService();
Jonathan Hartc36c9552018-07-31 15:07:53 -0400115 TestUtils.setField(dhcpL2Relay, "eventDispatcher", new TestEventDispatcher());
Amit Ghosh8951f042017-08-10 13:48:10 +0100116 dhcpL2Relay.activate(new ComponentContextAdapter());
117 }
118
119 /**
120 * Tears down the dhcpL2Relay application.
121 */
122 @After
123 public void tearDown() {
124 dhcpL2Relay.deactivate();
125 }
126
127 /**
128 * Tests the DHCP relay app by sending DHCP discovery Packet.
129 *
130 * @throws Exception when an unhandled error occurs
131 */
132 @Test
133 public void testDhcpDiscover() throws Exception {
134 // (1) Sending DHCP discover packet
135 System.out.println("Sending pakcet");
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530136 Ethernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
Amit Ghosh8951f042017-08-10 13:48:10 +0100137
138 sendPacket(discoverPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
139
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530140 Ethernet discoverRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100141 compareClientPackets(discoverPacket, discoverRelayed);
142 }
143
144 /**
145 * Tests the DHCP relay app by sending DHCP Request Packet.
146 *
147 * @throws Exception when an unhandled error occurs
148 */
149 @Test
150 public void testDhcpRequest() throws Exception {
151 // (1) Sending DHCP discover packet
152 System.out.println("Sending pakcet");
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530153 Ethernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
Amit Ghosh8951f042017-08-10 13:48:10 +0100154
155 sendPacket(requestPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
156
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530157 Ethernet requestRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100158 compareClientPackets(requestPacket, requestRelayed);
159 }
160
161 /**
162 * Tests the DHCP relay app by sending DHCP Offer Packet.
163 *
164 * @throws Exception when an unhandled error occurs
165 */
166 @Test
167 public void testDhcpOffer() {
168 // (1) Sending DHCP discover packet
169 System.out.println("Sending pakcet");
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530170 Ethernet offerPacket = constructDhcpOfferPacket(MacAddress.valueOf("bb:bb:bb:bb:bb:bb"),
Amit Ghosh8951f042017-08-10 13:48:10 +0100171 CLIENT_MAC, "1.1.1.1", "2.2.2.2");
172
173 sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
174
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530175 Ethernet offerRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100176 compareServerPackets(offerPacket, offerRelayed);
177 }
178
179 /**
180 * Tests the DHCP relay app by sending DHCP Ack Packet.
181 *
182 * @throws Exception when an unhandled error occurs
183 */
184 @Test
185 public void testDhcpAck() {
186
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530187 Ethernet ackPacket = constructDhcpAckPacket(MacAddress.valueOf("bb:bb:bb:bb:bb:bb"),
Amit Ghosh8951f042017-08-10 13:48:10 +0100188 CLIENT_MAC, "1.1.1.1", "2.2.2.2");
189
190 sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
191
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530192 Ethernet ackRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100193 compareServerPackets(ackPacket, ackRelayed);
194 }
195
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530196 public void compareClientPackets(Ethernet sent, Ethernet relayed) {
197 sent.setSourceMACAddress(OLT_MAC_ADDRESS);
198 sent.setQinQVID(CLIENT_S_TAG.toShort());
Amit Ghosh8951f042017-08-10 13:48:10 +0100199 sent.setVlanID(CLIENT_C_TAG.toShort());
200
201 IPv4 ipv4Packet = (IPv4) sent.getPayload();
202 UDP udpPacket = (UDP) ipv4Packet.getPayload();
203 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
204
Jonathan Hartedbf6422018-05-02 17:30:05 -0700205 List<DhcpOption> options = Lists.newArrayList(dhcpPacket.getOptions());
Amit Ghosh8951f042017-08-10 13:48:10 +0100206 DhcpOption82 option82 = new DhcpOption82();
207 option82.setAgentCircuitId(CLIENT_CIRCUIT_ID);
208
Jonathan Hartedbf6422018-05-02 17:30:05 -0700209 DhcpOption option = new DhcpOption()
Amit Ghosh8951f042017-08-10 13:48:10 +0100210 .setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
211 .setData(option82.toByteArray())
212 .setLength(option82.length());
213
214 options.add(options.size() - 1, option);
215 dhcpPacket.setOptions(options);
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530216 assertEquals(sent, relayed);
Amit Ghosh8951f042017-08-10 13:48:10 +0100217
218 }
219
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530220 public void compareServerPackets(Ethernet sent, Ethernet relayed) {
221 sent.setDestinationMACAddress(CLIENT_MAC);
222 sent.setQinQVID(CLIENT_S_TAG.toShort());
Amit Ghosh8951f042017-08-10 13:48:10 +0100223 sent.setVlanID(CLIENT_C_TAG.toShort());
224
225 final ByteBuffer byteBuffer = ByteBuffer.wrap(sent.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530226 Ethernet expectedPacket = null;
Amit Ghosh8951f042017-08-10 13:48:10 +0100227 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530228 expectedPacket = Ethernet.deserializer().deserialize(byteBuffer.array(),
Amit Ghosh8951f042017-08-10 13:48:10 +0100229 0, byteBuffer.array().length);
230 } catch (Exception e) {
231 }
232 assertEquals(expectedPacket, relayed);
233
234 }
235
236 private class MockDevice extends DefaultDevice {
237
238 public MockDevice(ProviderId providerId, DeviceId id, Type type,
239 String manufacturer, String hwVersion, String swVersion,
240 String serialNumber, ChassisId chassisId, Annotations... annotations) {
241 super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
242 chassisId, annotations);
243 }
244 }
245
246 private class MockDeviceService extends DeviceServiceAdapter {
247
248 private ProviderId providerId = new ProviderId("of", "foo");
249 private final Device device1 = new MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
250 "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
251 DEVICE_ANNOTATIONS);
252
253 @Override
254 public Device getDevice(DeviceId devId) {
255 return device1;
256
257 }
258
259 @Override
260 public Port getPort(ConnectPoint cp) {
261 return new MockPort();
262 }
263
264 @Override
265 public boolean isAvailable(DeviceId d) {
266 return true;
267 }
268 }
269
270 private class MockPort implements Port {
271
272 @Override
273 public boolean isEnabled() {
274 return true;
275 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700276 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100277 public long portSpeed() {
278 return 1000;
279 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700280 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100281 public Element element() {
282 return null;
283 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700284 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100285 public PortNumber number() {
286 return null;
287 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700288 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100289 public Annotations annotations() {
290 return new MockAnnotations();
291 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700292 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100293 public Type type() {
294 return Port.Type.FIBER;
295 }
296
297 private class MockAnnotations implements Annotations {
298
299 @Override
300 public String value(String val) {
301 return "PON 1/1";
302 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700303 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100304 public Set<String> keys() {
305 return null;
306 }
307 }
308 }
309
Gamze Abakac806c6c2018-12-03 12:49:46 +0000310 private class MockSadisService implements SadisService {
311 @Override
312 public BaseInformationService<SubscriberAndDeviceInformation> getSubscriberInfoService() {
313 return new MockSubService();
314 }
315
316 @Override
317 public BaseInformationService<BandwidthProfileInformation> getBandwidthProfileService() {
318 return null;
319 }
320 }
321
322 private class MockSubService implements BaseInformationService<SubscriberAndDeviceInformation> {
Amit Ghosh8951f042017-08-10 13:48:10 +0100323 MockSubscriberAndDeviceInformation device =
324 new MockSubscriberAndDeviceInformation(OLT_DEV_ID, VlanId.NONE, VlanId.NONE, null, null,
325 OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"));
326 MockSubscriberAndDeviceInformation sub =
327 new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID, CLIENT_C_TAG,
328 CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
329 @Override
330 public SubscriberAndDeviceInformation get(String id) {
331 if (id.equals(OLT_DEV_ID)) {
332 return device;
333 } else {
334 return sub;
335 }
336 }
337
338 @Override
339 public void invalidateAll() {}
Saurav Dasb4e3e102018-10-02 15:31:17 -0700340 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100341 public void invalidateId(String id) {}
Saurav Dasb4e3e102018-10-02 15:31:17 -0700342 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100343 public SubscriberAndDeviceInformation getfromCache(String id) {
344 return null;
345 }
346 }
347
348 private class MockMastershipService extends MastershipServiceAdapter {
349 @Override
350 public boolean isLocalMaster(DeviceId d) {
351 return true;
352 }
353 }
354
355 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
356
357 MockSubscriberAndDeviceInformation(String id, VlanId ctag,
358 VlanId stag, String nasPortId,
359 String circuitId, MacAddress hardId,
360 Ip4Address ipAddress) {
361 this.setCTag(ctag);
362 this.setHardwareIdentifier(hardId);
363 this.setId(id);
364 this.setIPAddress(ipAddress);
365 this.setSTag(stag);
366 this.setNasPortId(nasPortId);
367 this.setCircuitId(circuitId);
368 }
369 }
370
371 private class MockHostService extends HostServiceAdapter {
372
373 @Override
374 public Set<Host> getHostsByMac(MacAddress mac) {
375
376 HostLocation loc = new HostLocation(DEVICE_ID_1, PortNumber.portNumber(22), 0);
377
378 IpAddress ip = IpAddress.valueOf("10.100.200.10");
379
380 Host h = new DefaultHost(ProviderId.NONE, HostId.hostId(mac, VlanId.NONE),
381 mac, VlanId.NONE, loc, ImmutableSet.of(ip));
382
383 return ImmutableSet.of(h);
384 }
385 }
386
387
388 /**
389 * Mocks the AAAConfig class to force usage of an unroutable address for the
390 * RADIUS server.
391 */
392 static class MockDhcpL2RealyConfig extends DhcpL2RelayConfig {
393 @Override
394 public Set<ConnectPoint> getDhcpServerConnectPoint() {
395 return ImmutableSet.of(SERVER_CONNECT_POINT);
396 }
Amit Ghosh83c8c892017-11-09 11:08:27 +0000397
398 @Override
399 public boolean getModifySrcDstMacAddresses() {
400 return true;
401 }
Amit Ghosh8951f042017-08-10 13:48:10 +0100402 }
403
404 /**
405 * Mocks the network config registry.
406 */
407 @SuppressWarnings("unchecked")
408 private static final class TestNetworkConfigRegistry
409 extends NetworkConfigRegistryAdapter {
410 @Override
411 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
412 DhcpL2RelayConfig dhcpConfig = new MockDhcpL2RealyConfig();
413 return (C) dhcpConfig;
414 }
415 }
416}
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433