blob: b282728aad2be7782aea73b2536be0868f2204fd [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;
65import org.opencord.sadis.SubscriberAndDeviceInformationService;
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +053066import org.slf4j.Logger;
67import org.slf4j.LoggerFactory;
Amit Ghosh8951f042017-08-10 13:48:10 +010068
Saurav Dasb4e3e102018-10-02 15:31:17 -070069import com.google.common.collect.ImmutableSet;
70import com.google.common.collect.Lists;
Amit Ghosh8951f042017-08-10 13:48:10 +010071
72public class DhcpL2RelayTest extends DhcpL2RelayTestBase {
73
74 private final Logger log = LoggerFactory.getLogger(getClass());
75
76 private DhcpL2Relay dhcpL2Relay;
77
78 private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
79 private static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 999);
80 private static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 111);
81 private static final String CLIENT_NAS_PORT_ID = "PON 1/1";
82 private static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
83
84 private static final String OLT_DEV_ID = "of:00000000000000aa";
85 private static final MacAddress OLT_MAC_ADDRESS = MacAddress.valueOf("01:02:03:04:05:06");
86 private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
87
88 private static final ConnectPoint SERVER_CONNECT_POINT =
89 ConnectPoint.deviceConnectPoint("of:0000000000000001/5");
90
91 private static final String SCHEME_NAME = "dhcpl2relay";
92 private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
93 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
94
95 ComponentConfigService mockConfigService =
96 EasyMock.createMock(ComponentConfigService.class);
97
98 /**
99 * Sets up the services required by the dhcpl2relay app.
100 */
101 @Before
102 public void setUp() {
103 dhcpL2Relay = new DhcpL2Relay();
104 dhcpL2Relay.cfgService = new TestNetworkConfigRegistry();
Saurav Dasb4e3e102018-10-02 15:31:17 -0700105 dhcpL2Relay.coreService = new MockCoreServiceAdapter();
106 dhcpL2Relay.flowObjectiveService = new FlowObjectiveServiceAdapter();
Amit Ghosh8951f042017-08-10 13:48:10 +0100107 dhcpL2Relay.packetService = new MockPacketService();
108 dhcpL2Relay.componentConfigService = mockConfigService;
109 dhcpL2Relay.deviceService = new MockDeviceService();
110 dhcpL2Relay.subsService = new MockSubService();
111 dhcpL2Relay.hostService = new MockHostService();
112 dhcpL2Relay.mastershipService = new MockMastershipService();
Jonathan Hartc36c9552018-07-31 15:07:53 -0400113 TestUtils.setField(dhcpL2Relay, "eventDispatcher", new TestEventDispatcher());
Amit Ghosh8951f042017-08-10 13:48:10 +0100114 dhcpL2Relay.activate(new ComponentContextAdapter());
115 }
116
117 /**
118 * Tears down the dhcpL2Relay application.
119 */
120 @After
121 public void tearDown() {
122 dhcpL2Relay.deactivate();
123 }
124
125 /**
126 * Tests the DHCP relay app by sending DHCP discovery Packet.
127 *
128 * @throws Exception when an unhandled error occurs
129 */
130 @Test
131 public void testDhcpDiscover() throws Exception {
132 // (1) Sending DHCP discover packet
133 System.out.println("Sending pakcet");
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530134 Ethernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
Amit Ghosh8951f042017-08-10 13:48:10 +0100135
136 sendPacket(discoverPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
137
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530138 Ethernet discoverRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100139 compareClientPackets(discoverPacket, discoverRelayed);
140 }
141
142 /**
143 * Tests the DHCP relay app by sending DHCP Request Packet.
144 *
145 * @throws Exception when an unhandled error occurs
146 */
147 @Test
148 public void testDhcpRequest() throws Exception {
149 // (1) Sending DHCP discover packet
150 System.out.println("Sending pakcet");
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530151 Ethernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
Amit Ghosh8951f042017-08-10 13:48:10 +0100152
153 sendPacket(requestPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
154
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530155 Ethernet requestRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100156 compareClientPackets(requestPacket, requestRelayed);
157 }
158
159 /**
160 * Tests the DHCP relay app by sending DHCP Offer Packet.
161 *
162 * @throws Exception when an unhandled error occurs
163 */
164 @Test
165 public void testDhcpOffer() {
166 // (1) Sending DHCP discover packet
167 System.out.println("Sending pakcet");
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530168 Ethernet offerPacket = constructDhcpOfferPacket(MacAddress.valueOf("bb:bb:bb:bb:bb:bb"),
Amit Ghosh8951f042017-08-10 13:48:10 +0100169 CLIENT_MAC, "1.1.1.1", "2.2.2.2");
170
171 sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
172
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530173 Ethernet offerRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100174 compareServerPackets(offerPacket, offerRelayed);
175 }
176
177 /**
178 * Tests the DHCP relay app by sending DHCP Ack Packet.
179 *
180 * @throws Exception when an unhandled error occurs
181 */
182 @Test
183 public void testDhcpAck() {
184
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530185 Ethernet ackPacket = constructDhcpAckPacket(MacAddress.valueOf("bb:bb:bb:bb:bb:bb"),
Amit Ghosh8951f042017-08-10 13:48:10 +0100186 CLIENT_MAC, "1.1.1.1", "2.2.2.2");
187
188 sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
189
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530190 Ethernet ackRelayed = (Ethernet) getPacket();
Amit Ghosh8951f042017-08-10 13:48:10 +0100191 compareServerPackets(ackPacket, ackRelayed);
192 }
193
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530194 public void compareClientPackets(Ethernet sent, Ethernet relayed) {
195 sent.setSourceMACAddress(OLT_MAC_ADDRESS);
196 sent.setQinQVID(CLIENT_S_TAG.toShort());
Amit Ghosh8951f042017-08-10 13:48:10 +0100197 sent.setVlanID(CLIENT_C_TAG.toShort());
198
199 IPv4 ipv4Packet = (IPv4) sent.getPayload();
200 UDP udpPacket = (UDP) ipv4Packet.getPayload();
201 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
202
Jonathan Hartedbf6422018-05-02 17:30:05 -0700203 List<DhcpOption> options = Lists.newArrayList(dhcpPacket.getOptions());
Amit Ghosh8951f042017-08-10 13:48:10 +0100204 DhcpOption82 option82 = new DhcpOption82();
205 option82.setAgentCircuitId(CLIENT_CIRCUIT_ID);
206
Jonathan Hartedbf6422018-05-02 17:30:05 -0700207 DhcpOption option = new DhcpOption()
Amit Ghosh8951f042017-08-10 13:48:10 +0100208 .setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
209 .setData(option82.toByteArray())
210 .setLength(option82.length());
211
212 options.add(options.size() - 1, option);
213 dhcpPacket.setOptions(options);
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530214 assertEquals(sent, relayed);
Amit Ghosh8951f042017-08-10 13:48:10 +0100215
216 }
217
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530218 public void compareServerPackets(Ethernet sent, Ethernet relayed) {
219 sent.setDestinationMACAddress(CLIENT_MAC);
220 sent.setQinQVID(CLIENT_S_TAG.toShort());
Amit Ghosh8951f042017-08-10 13:48:10 +0100221 sent.setVlanID(CLIENT_C_TAG.toShort());
222
223 final ByteBuffer byteBuffer = ByteBuffer.wrap(sent.serialize());
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530224 Ethernet expectedPacket = null;
Amit Ghosh8951f042017-08-10 13:48:10 +0100225 try {
Deepa Vaddireddy5f278d62017-08-30 05:59:39 +0530226 expectedPacket = Ethernet.deserializer().deserialize(byteBuffer.array(),
Amit Ghosh8951f042017-08-10 13:48:10 +0100227 0, byteBuffer.array().length);
228 } catch (Exception e) {
229 }
230 assertEquals(expectedPacket, relayed);
231
232 }
233
234 private class MockDevice extends DefaultDevice {
235
236 public MockDevice(ProviderId providerId, DeviceId id, Type type,
237 String manufacturer, String hwVersion, String swVersion,
238 String serialNumber, ChassisId chassisId, Annotations... annotations) {
239 super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
240 chassisId, annotations);
241 }
242 }
243
244 private class MockDeviceService extends DeviceServiceAdapter {
245
246 private ProviderId providerId = new ProviderId("of", "foo");
247 private final Device device1 = new MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
248 "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
249 DEVICE_ANNOTATIONS);
250
251 @Override
252 public Device getDevice(DeviceId devId) {
253 return device1;
254
255 }
256
257 @Override
258 public Port getPort(ConnectPoint cp) {
259 return new MockPort();
260 }
261
262 @Override
263 public boolean isAvailable(DeviceId d) {
264 return true;
265 }
266 }
267
268 private class MockPort implements Port {
269
270 @Override
271 public boolean isEnabled() {
272 return true;
273 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700274 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100275 public long portSpeed() {
276 return 1000;
277 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700278 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100279 public Element element() {
280 return null;
281 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700282 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100283 public PortNumber number() {
284 return null;
285 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700286 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100287 public Annotations annotations() {
288 return new MockAnnotations();
289 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700290 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100291 public Type type() {
292 return Port.Type.FIBER;
293 }
294
295 private class MockAnnotations implements Annotations {
296
297 @Override
298 public String value(String val) {
299 return "PON 1/1";
300 }
Saurav Dasb4e3e102018-10-02 15:31:17 -0700301 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100302 public Set<String> keys() {
303 return null;
304 }
305 }
306 }
307
308 private class MockSubService implements SubscriberAndDeviceInformationService {
309 MockSubscriberAndDeviceInformation device =
310 new MockSubscriberAndDeviceInformation(OLT_DEV_ID, VlanId.NONE, VlanId.NONE, null, null,
311 OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"));
312 MockSubscriberAndDeviceInformation sub =
313 new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID, CLIENT_C_TAG,
314 CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
315 @Override
316 public SubscriberAndDeviceInformation get(String id) {
317 if (id.equals(OLT_DEV_ID)) {
318 return device;
319 } else {
320 return sub;
321 }
322 }
323
324 @Override
325 public void invalidateAll() {}
Saurav Dasb4e3e102018-10-02 15:31:17 -0700326 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100327 public void invalidateId(String id) {}
Saurav Dasb4e3e102018-10-02 15:31:17 -0700328 @Override
Amit Ghosh8951f042017-08-10 13:48:10 +0100329 public SubscriberAndDeviceInformation getfromCache(String id) {
330 return null;
331 }
332 }
333
334 private class MockMastershipService extends MastershipServiceAdapter {
335 @Override
336 public boolean isLocalMaster(DeviceId d) {
337 return true;
338 }
339 }
340
341 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
342
343 MockSubscriberAndDeviceInformation(String id, VlanId ctag,
344 VlanId stag, String nasPortId,
345 String circuitId, MacAddress hardId,
346 Ip4Address ipAddress) {
347 this.setCTag(ctag);
348 this.setHardwareIdentifier(hardId);
349 this.setId(id);
350 this.setIPAddress(ipAddress);
351 this.setSTag(stag);
352 this.setNasPortId(nasPortId);
353 this.setCircuitId(circuitId);
354 }
355 }
356
357 private class MockHostService extends HostServiceAdapter {
358
359 @Override
360 public Set<Host> getHostsByMac(MacAddress mac) {
361
362 HostLocation loc = new HostLocation(DEVICE_ID_1, PortNumber.portNumber(22), 0);
363
364 IpAddress ip = IpAddress.valueOf("10.100.200.10");
365
366 Host h = new DefaultHost(ProviderId.NONE, HostId.hostId(mac, VlanId.NONE),
367 mac, VlanId.NONE, loc, ImmutableSet.of(ip));
368
369 return ImmutableSet.of(h);
370 }
371 }
372
373
374 /**
375 * Mocks the AAAConfig class to force usage of an unroutable address for the
376 * RADIUS server.
377 */
378 static class MockDhcpL2RealyConfig extends DhcpL2RelayConfig {
379 @Override
380 public Set<ConnectPoint> getDhcpServerConnectPoint() {
381 return ImmutableSet.of(SERVER_CONNECT_POINT);
382 }
Amit Ghosh83c8c892017-11-09 11:08:27 +0000383
384 @Override
385 public boolean getModifySrcDstMacAddresses() {
386 return true;
387 }
Amit Ghosh8951f042017-08-10 13:48:10 +0100388 }
389
390 /**
391 * Mocks the network config registry.
392 */
393 @SuppressWarnings("unchecked")
394 private static final class TestNetworkConfigRegistry
395 extends NetworkConfigRegistryAdapter {
396 @Override
397 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
398 DhcpL2RelayConfig dhcpConfig = new MockDhcpL2RealyConfig();
399 return (C) dhcpConfig;
400 }
401 }
402}
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419