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