blob: e91fddd8809ba011d98f74ce804cb070d5091d2d [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
18//import com.fasterxml.jackson.databind.util.Annotations;
19
20import org.easymock.EasyMock;
21
22import com.google.common.collect.Lists;
23import com.google.common.collect.ImmutableSet;
24
25import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28
29import org.onlab.osgi.ComponentContextAdapter;
30import org.onlab.packet.ChassisId;
31import org.onlab.packet.DHCP;
32import org.onlab.packet.DHCPOption;
33import org.onlab.packet.IpAddress;
34import org.onlab.packet.Ip4Address;
35import org.onlab.packet.IPv4;
36import org.onlab.packet.MacAddress;
37import org.onlab.packet.UDP;
38import org.onlab.packet.VlanId;
39
40import org.onosproject.mastership.MastershipServiceAdapter;
41import org.onosproject.net.Annotations;
42import org.onosproject.net.AnnotationKeys;
43import org.onosproject.net.DeviceId;
44import org.onosproject.net.DefaultAnnotations;
45import org.onosproject.net.PortNumber;
46import org.onosproject.cfg.ComponentConfigService;
47import org.onosproject.core.CoreServiceAdapter;
48import org.onosproject.net.config.Config;
49import org.onosproject.net.config.NetworkConfigRegistryAdapter;
50import org.onosproject.net.ConnectPoint;
51import org.onosproject.net.device.DeviceServiceAdapter;
52import org.onosproject.net.DefaultDevice;
53import org.onosproject.net.DefaultHost;
54import org.onosproject.net.Device;
55import org.onosproject.net.Element;
56import org.onosproject.net.host.HostServiceAdapter;
57import org.onosproject.net.Host;
58import org.onosproject.net.HostId;
59import org.onosproject.net.HostLocation;
60import org.onosproject.net.provider.ProviderId;
61import org.onosproject.net.Port;
62
63import org.opencord.dhcpl2relay.packet.DhcpEthernet;
64import org.opencord.dhcpl2relay.packet.DhcpOption82;
65import org.opencord.sadis.SubscriberAndDeviceInformation;
66import org.opencord.sadis.SubscriberAndDeviceInformationService;
67
68import java.nio.ByteBuffer;
69import java.util.List;
70import java.util.Set;
71
72import org.slf4j.Logger;
73import org.slf4j.LoggerFactory;
74
75import static org.junit.Assert.assertEquals;
76
77public class DhcpL2RelayTest extends DhcpL2RelayTestBase {
78
79 private final Logger log = LoggerFactory.getLogger(getClass());
80
81 private DhcpL2Relay dhcpL2Relay;
82
83 private static final MacAddress CLIENT_MAC = MacAddress.valueOf("00:00:00:00:00:01");
84 private static final VlanId CLIENT_C_TAG = VlanId.vlanId((short) 999);
85 private static final VlanId CLIENT_S_TAG = VlanId.vlanId((short) 111);
86 private static final String CLIENT_NAS_PORT_ID = "PON 1/1";
87 private static final String CLIENT_CIRCUIT_ID = "CIR-PON 1/1";
88
89 private static final String OLT_DEV_ID = "of:00000000000000aa";
90 private static final MacAddress OLT_MAC_ADDRESS = MacAddress.valueOf("01:02:03:04:05:06");
91 private static final DeviceId DEVICE_ID_1 = DeviceId.deviceId(OLT_DEV_ID);
92
93 private static final ConnectPoint SERVER_CONNECT_POINT =
94 ConnectPoint.deviceConnectPoint("of:0000000000000001/5");
95
96 private static final String SCHEME_NAME = "dhcpl2relay";
97 private static final DefaultAnnotations DEVICE_ANNOTATIONS = DefaultAnnotations.builder()
98 .set(AnnotationKeys.PROTOCOL, SCHEME_NAME.toUpperCase()).build();
99
100 ComponentConfigService mockConfigService =
101 EasyMock.createMock(ComponentConfigService.class);
102
103 /**
104 * Sets up the services required by the dhcpl2relay app.
105 */
106 @Before
107 public void setUp() {
108 dhcpL2Relay = new DhcpL2Relay();
109 dhcpL2Relay.cfgService = new TestNetworkConfigRegistry();
110 dhcpL2Relay.coreService = new CoreServiceAdapter();
111 dhcpL2Relay.packetService = new MockPacketService();
112 dhcpL2Relay.componentConfigService = mockConfigService;
113 dhcpL2Relay.deviceService = new MockDeviceService();
114 dhcpL2Relay.subsService = new MockSubService();
115 dhcpL2Relay.hostService = new MockHostService();
116 dhcpL2Relay.mastershipService = new MockMastershipService();
117 dhcpL2Relay.activate(new ComponentContextAdapter());
118 }
119
120 /**
121 * Tears down the dhcpL2Relay application.
122 */
123 @After
124 public void tearDown() {
125 dhcpL2Relay.deactivate();
126 }
127
128 /**
129 * Tests the DHCP relay app by sending DHCP discovery Packet.
130 *
131 * @throws Exception when an unhandled error occurs
132 */
133 @Test
134 public void testDhcpDiscover() throws Exception {
135 // (1) Sending DHCP discover packet
136 System.out.println("Sending pakcet");
137 DhcpEthernet discoverPacket = constructDhcpDiscoverPacket(CLIENT_MAC);
138
139 sendPacket(discoverPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
140
141 DhcpEthernet discoverRelayed = (DhcpEthernet) getPacket();
142 compareClientPackets(discoverPacket, discoverRelayed);
143 }
144
145 /**
146 * Tests the DHCP relay app by sending DHCP Request Packet.
147 *
148 * @throws Exception when an unhandled error occurs
149 */
150 @Test
151 public void testDhcpRequest() throws Exception {
152 // (1) Sending DHCP discover packet
153 System.out.println("Sending pakcet");
154 DhcpEthernet requestPacket = constructDhcpRequestPacket(CLIENT_MAC);
155
156 sendPacket(requestPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
157
158 DhcpEthernet requestRelayed = (DhcpEthernet) getPacket();
159 compareClientPackets(requestPacket, requestRelayed);
160 }
161
162 /**
163 * Tests the DHCP relay app by sending DHCP Offer Packet.
164 *
165 * @throws Exception when an unhandled error occurs
166 */
167 @Test
168 public void testDhcpOffer() {
169 // (1) Sending DHCP discover packet
170 System.out.println("Sending pakcet");
171 DhcpEthernet offerPacket = constructDhcpOfferPacket(MacAddress.valueOf("bb:bb:bb:bb:bb:bb"),
172 CLIENT_MAC, "1.1.1.1", "2.2.2.2");
173
174 sendPacket(offerPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
175
176 DhcpEthernet offerRelayed = (DhcpEthernet) getPacket();
177 compareServerPackets(offerPacket, offerRelayed);
178 }
179
180 /**
181 * Tests the DHCP relay app by sending DHCP Ack Packet.
182 *
183 * @throws Exception when an unhandled error occurs
184 */
185 @Test
186 public void testDhcpAck() {
187
188 DhcpEthernet ackPacket = constructDhcpAckPacket(MacAddress.valueOf("bb:bb:bb:bb:bb:bb"),
189 CLIENT_MAC, "1.1.1.1", "2.2.2.2");
190
191 sendPacket(ackPacket, ConnectPoint.deviceConnectPoint(OLT_DEV_ID + "/" + 1));
192
193 DhcpEthernet ackRelayed = (DhcpEthernet) getPacket();
194 compareServerPackets(ackPacket, ackRelayed);
195 }
196
197 public void compareClientPackets(DhcpEthernet sent, DhcpEthernet relayed) {
198 sent.setSourceMacAddress(OLT_MAC_ADDRESS);
199 sent.setQinQVid(CLIENT_S_TAG.toShort());
200 sent.setVlanID(CLIENT_C_TAG.toShort());
201
202 IPv4 ipv4Packet = (IPv4) sent.getPayload();
203 UDP udpPacket = (UDP) ipv4Packet.getPayload();
204 DHCP dhcpPacket = (DHCP) udpPacket.getPayload();
205
206 List<DHCPOption> options = Lists.newArrayList(dhcpPacket.getOptions());
207 DhcpOption82 option82 = new DhcpOption82();
208 option82.setAgentCircuitId(CLIENT_CIRCUIT_ID);
209
210 DHCPOption option = new DHCPOption()
211 .setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue())
212 .setData(option82.toByteArray())
213 .setLength(option82.length());
214
215 options.add(options.size() - 1, option);
216 dhcpPacket.setOptions(options);
217
218 final ByteBuffer byteBuffer = ByteBuffer.wrap(sent.serialize());
219 DhcpEthernet expectedPacket = null;
220 try {
221 expectedPacket = DhcpEthernet.deserializer().deserialize(byteBuffer.array(),
222 0, byteBuffer.array().length);
223 } catch (Exception e) {
224 }
225 assertEquals(expectedPacket, relayed);
226
227 }
228
229 public void compareServerPackets(DhcpEthernet sent, DhcpEthernet relayed) {
230 sent.setDestinationMacAddress(CLIENT_MAC);
231 sent.setQinQVid(CLIENT_S_TAG.toShort());
232 sent.setVlanID(CLIENT_C_TAG.toShort());
233
234 final ByteBuffer byteBuffer = ByteBuffer.wrap(sent.serialize());
235 DhcpEthernet expectedPacket = null;
236 try {
237 expectedPacket = DhcpEthernet.deserializer().deserialize(byteBuffer.array(),
238 0, byteBuffer.array().length);
239 } catch (Exception e) {
240 }
241 assertEquals(expectedPacket, relayed);
242
243 }
244
245 private class MockDevice extends DefaultDevice {
246
247 public MockDevice(ProviderId providerId, DeviceId id, Type type,
248 String manufacturer, String hwVersion, String swVersion,
249 String serialNumber, ChassisId chassisId, Annotations... annotations) {
250 super(providerId, id, type, manufacturer, hwVersion, swVersion, serialNumber,
251 chassisId, annotations);
252 }
253 }
254
255 private class MockDeviceService extends DeviceServiceAdapter {
256
257 private ProviderId providerId = new ProviderId("of", "foo");
258 private final Device device1 = new MockDevice(providerId, DEVICE_ID_1, Device.Type.SWITCH,
259 "foo.inc", "0", "0", OLT_DEV_ID, new ChassisId(),
260 DEVICE_ANNOTATIONS);
261
262 @Override
263 public Device getDevice(DeviceId devId) {
264 return device1;
265
266 }
267
268 @Override
269 public Port getPort(ConnectPoint cp) {
270 return new MockPort();
271 }
272
273 @Override
274 public boolean isAvailable(DeviceId d) {
275 return true;
276 }
277 }
278
279 private class MockPort implements Port {
280
281 @Override
282 public boolean isEnabled() {
283 return true;
284 }
285 public long portSpeed() {
286 return 1000;
287 }
288 public Element element() {
289 return null;
290 }
291 public PortNumber number() {
292 return null;
293 }
294 public Annotations annotations() {
295 return new MockAnnotations();
296 }
297 public Type type() {
298 return Port.Type.FIBER;
299 }
300
301 private class MockAnnotations implements Annotations {
302
303 @Override
304 public String value(String val) {
305 return "PON 1/1";
306 }
307 public Set<String> keys() {
308 return null;
309 }
310 }
311 }
312
313 private class MockSubService implements SubscriberAndDeviceInformationService {
314 MockSubscriberAndDeviceInformation device =
315 new MockSubscriberAndDeviceInformation(OLT_DEV_ID, VlanId.NONE, VlanId.NONE, null, null,
316 OLT_MAC_ADDRESS, Ip4Address.valueOf("10.10.10.10"));
317 MockSubscriberAndDeviceInformation sub =
318 new MockSubscriberAndDeviceInformation(CLIENT_NAS_PORT_ID, CLIENT_C_TAG,
319 CLIENT_S_TAG, CLIENT_NAS_PORT_ID, CLIENT_CIRCUIT_ID, null, null);
320 @Override
321 public SubscriberAndDeviceInformation get(String id) {
322 if (id.equals(OLT_DEV_ID)) {
323 return device;
324 } else {
325 return sub;
326 }
327 }
328
329 @Override
330 public void invalidateAll() {}
331 public void invalidateId(String id) {}
332 public SubscriberAndDeviceInformation getfromCache(String id) {
333 return null;
334 }
335 }
336
337 private class MockMastershipService extends MastershipServiceAdapter {
338 @Override
339 public boolean isLocalMaster(DeviceId d) {
340 return true;
341 }
342 }
343
344 private class MockSubscriberAndDeviceInformation extends SubscriberAndDeviceInformation {
345
346 MockSubscriberAndDeviceInformation(String id, VlanId ctag,
347 VlanId stag, String nasPortId,
348 String circuitId, MacAddress hardId,
349 Ip4Address ipAddress) {
350 this.setCTag(ctag);
351 this.setHardwareIdentifier(hardId);
352 this.setId(id);
353 this.setIPAddress(ipAddress);
354 this.setSTag(stag);
355 this.setNasPortId(nasPortId);
356 this.setCircuitId(circuitId);
357 }
358 }
359
360 private class MockHostService extends HostServiceAdapter {
361
362 @Override
363 public Set<Host> getHostsByMac(MacAddress mac) {
364
365 HostLocation loc = new HostLocation(DEVICE_ID_1, PortNumber.portNumber(22), 0);
366
367 IpAddress ip = IpAddress.valueOf("10.100.200.10");
368
369 Host h = new DefaultHost(ProviderId.NONE, HostId.hostId(mac, VlanId.NONE),
370 mac, VlanId.NONE, loc, ImmutableSet.of(ip));
371
372 return ImmutableSet.of(h);
373 }
374 }
375
376
377 /**
378 * Mocks the AAAConfig class to force usage of an unroutable address for the
379 * RADIUS server.
380 */
381 static class MockDhcpL2RealyConfig extends DhcpL2RelayConfig {
382 @Override
383 public Set<ConnectPoint> getDhcpServerConnectPoint() {
384 return ImmutableSet.of(SERVER_CONNECT_POINT);
385 }
386 }
387
388 /**
389 * Mocks the network config registry.
390 */
391 @SuppressWarnings("unchecked")
392 private static final class TestNetworkConfigRegistry
393 extends NetworkConfigRegistryAdapter {
394 @Override
395 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
396 DhcpL2RelayConfig dhcpConfig = new MockDhcpL2RealyConfig();
397 return (C) dhcpConfig;
398 }
399 }
400}
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417