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