blob: b6424582362246fa2cbdaa379d763d58102c00c7 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * 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
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * 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.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.provider.host.impl;
alshabib4a179dc2014-10-17 17:17:01 -070017
Thomas Vachuska27bee092015-06-23 19:03:10 -070018import com.google.common.collect.ImmutableSet;
Charles Chan420e7372016-11-17 10:58:17 -080019import com.google.common.collect.Lists;
Madan Jampania3770c32015-12-11 12:07:41 -080020import com.google.common.util.concurrent.MoreExecutors;
alshabib4a179dc2014-10-17 17:17:01 -070021import org.junit.After;
22import org.junit.Before;
23import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080024import org.onlab.osgi.ComponentContextAdapter;
25import org.onlab.packet.ARP;
26import org.onlab.packet.ChassisId;
Charles Chane6067892016-11-17 10:23:46 -080027import org.onlab.packet.DHCP;
28import org.onlab.packet.DHCPOption;
29import org.onlab.packet.DHCPPacketType;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080030import org.onlab.packet.Ethernet;
Charles Chan5d5e0622015-09-25 13:00:06 -070031import org.onlab.packet.ICMP6;
32import org.onlab.packet.IPv4;
33import org.onlab.packet.IPv6;
34import org.onlab.packet.Ip6Address;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080035import org.onlab.packet.IpAddress;
36import org.onlab.packet.MacAddress;
Charles Chane6067892016-11-17 10:23:46 -080037import org.onlab.packet.UDP;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080038import org.onlab.packet.VlanId;
Charles Chan5d5e0622015-09-25 13:00:06 -070039import org.onlab.packet.ndp.NeighborAdvertisement;
40import org.onlab.packet.ndp.NeighborSolicitation;
41import org.onlab.packet.ndp.RouterAdvertisement;
42import org.onlab.packet.ndp.RouterSolicitation;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070043import org.onosproject.cfg.ComponentConfigAdapter;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080044import org.onosproject.core.ApplicationId;
45import org.onosproject.core.CoreService;
46import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080047import org.onosproject.net.ConnectPoint;
48import org.onosproject.net.DefaultDevice;
49import org.onosproject.net.DefaultHost;
50import org.onosproject.net.DefaultPort;
51import org.onosproject.net.Device;
52import org.onosproject.net.DeviceId;
53import org.onosproject.net.Host;
54import org.onosproject.net.HostId;
55import org.onosproject.net.HostLocation;
56import org.onosproject.net.device.DeviceEvent;
57import org.onosproject.net.device.DeviceListener;
58import org.onosproject.net.device.DeviceServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080059import org.onosproject.net.host.HostDescription;
60import org.onosproject.net.host.HostProvider;
61import org.onosproject.net.host.HostProviderRegistry;
62import org.onosproject.net.host.HostProviderService;
63import org.onosproject.net.host.HostServiceAdapter;
64import org.onosproject.net.packet.DefaultInboundPacket;
65import org.onosproject.net.packet.InboundPacket;
Andrey Komarov2398d962016-09-26 15:11:23 +030066import org.onosproject.net.packet.PacketContextAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080067import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070068import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080069import org.onosproject.net.provider.AbstractProviderService;
70import org.onosproject.net.provider.ProviderId;
71import org.onosproject.net.topology.Topology;
72import org.onosproject.net.topology.TopologyServiceAdapter;
alshabib4a179dc2014-10-17 17:17:01 -070073
Thomas Vachuska27bee092015-06-23 19:03:10 -070074import java.nio.ByteBuffer;
75import java.util.Collections;
76import java.util.Dictionary;
77import java.util.Hashtable;
Charles Chan420e7372016-11-17 10:58:17 -080078import java.util.List;
Thomas Vachuska27bee092015-06-23 19:03:10 -070079import java.util.Set;
80
Michele Santuari72f6bee2016-11-18 12:56:30 +010081import static org.easymock.EasyMock.createMock;
82import static org.easymock.EasyMock.expect;
83import static org.easymock.EasyMock.replay;
Charles Chan5d5e0622015-09-25 13:00:06 -070084import static org.hamcrest.Matchers.is;
Michele Santuari72f6bee2016-11-18 12:56:30 +010085import static org.junit.Assert.assertEquals;
86import static org.junit.Assert.assertNotEquals;
87import static org.junit.Assert.assertNotNull;
88import static org.junit.Assert.assertThat;
89import static org.junit.Assert.assertTrue;
Thomas Vachuska27bee092015-06-23 19:03:10 -070090import static org.onlab.packet.VlanId.vlanId;
91import static org.onosproject.net.Device.Type.SWITCH;
92import static org.onosproject.net.DeviceId.deviceId;
93import static org.onosproject.net.HostId.hostId;
94import static org.onosproject.net.PortNumber.portNumber;
Michele Santuari72f6bee2016-11-18 12:56:30 +010095import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
96import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
97import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
Thomas Vachuska33601602014-11-19 03:32:15 -080098
alshabib4a179dc2014-10-17 17:17:01 -070099public class HostLocationProviderTest {
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800100 private static final ProviderId PROVIDER_ID =
101 new ProviderId("of", "org.onosproject.provider.host");
102
alshabib4a179dc2014-10-17 17:17:01 -0700103 private static final Integer INPORT = 10;
Charles Chane6067892016-11-17 10:23:46 -0800104 private static final Integer INPORT2 = 11;
alshabib4a179dc2014-10-17 17:17:01 -0700105 private static final String DEV1 = "of:1";
106 private static final String DEV2 = "of:2";
107 private static final String DEV3 = "of:3";
Charles Chan5d5e0622015-09-25 13:00:06 -0700108 private static final String DEV4 = "of:4";
109 private static final String DEV5 = "of:5";
110 private static final String DEV6 = "of:6";
alshabib4a179dc2014-10-17 17:17:01 -0700111
Thomas Vachuska33601602014-11-19 03:32:15 -0800112 private static final VlanId VLAN = vlanId();
Charles Chan5d5e0622015-09-25 13:00:06 -0700113
114 // IPv4 Host
alshabib4a179dc2014-10-17 17:17:01 -0700115 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
116 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
117 private static final byte[] IP = new byte[]{10, 0, 0, 1};
Thomas Vachuska33601602014-11-19 03:32:15 -0800118 private static final IpAddress IP_ADDRESS =
119 IpAddress.valueOf(IpAddress.Version.INET, IP);
120 private static final HostLocation LOCATION =
121 new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
Thomas Vachuska33601602014-11-19 03:32:15 -0800122 private static final DefaultHost HOST =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800123 new DefaultHost(PROVIDER_ID, hostId(MAC), MAC,
Charles Chane6067892016-11-17 10:23:46 -0800124 VLAN, LOCATION,
125 ImmutableSet.of(IP_ADDRESS));
Thomas Vachuska33601602014-11-19 03:32:15 -0800126
Charles Chan5d5e0622015-09-25 13:00:06 -0700127 // IPv6 Host
128 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
129 private static final MacAddress BCMAC2 = MacAddress.valueOf("33:33:00:00:00:01");
130 private static final byte[] IP2 = Ip6Address.valueOf("1000::1").toOctets();
131 private static final IpAddress IP_ADDRESS2 =
132 IpAddress.valueOf(IpAddress.Version.INET6, IP2);
133 private static final HostLocation LOCATION2 =
134 new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
135 private static final DefaultHost HOST2 =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800136 new DefaultHost(PROVIDER_ID, hostId(MAC2), MAC2,
Charles Chane6067892016-11-17 10:23:46 -0800137 VLAN, LOCATION2,
138 ImmutableSet.of(IP_ADDRESS2));
139
140 // DHCP Server
141 private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03");
142 private static final byte[] IP3 = new byte[]{10, 0, 0, 2};
143 private static final IpAddress IP_ADDRESS3 =
144 IpAddress.valueOf(IpAddress.Version.INET, IP3);
145
146 private static final HostLocation LOCATION3 =
147 new HostLocation(deviceId(DEV1), portNumber(INPORT2), 0L);
148 private static final DefaultHost HOST3 =
149 new DefaultHost(PROVIDER_ID, hostId(MAC3), MAC3,
150 VLAN, LOCATION3,
151 ImmutableSet.of(IP_ADDRESS3));
Charles Chan5d5e0622015-09-25 13:00:06 -0700152
Thomas Vachuska33601602014-11-19 03:32:15 -0800153 private static final ComponentContextAdapter CTX_FOR_REMOVE =
154 new ComponentContextAdapter() {
155 @Override
156 public Dictionary getProperties() {
157 Hashtable<String, String> props = new Hashtable<>();
158 props.put("hostRemovalEnabled", "true");
159 return props;
160 }
161 };
162
163 public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
164 new ComponentContextAdapter() {
165 @Override
166 public Dictionary getProperties() {
167 return new Hashtable();
168 }
169 };
170
alshabib4a179dc2014-10-17 17:17:01 -0700171 private final HostLocationProvider provider = new HostLocationProvider();
Thomas Vachuska33601602014-11-19 03:32:15 -0800172 private final TestHostRegistry hostRegistry = new TestHostRegistry();
alshabib4a179dc2014-10-17 17:17:01 -0700173 private final TestTopologyService topoService = new TestTopologyService();
Thomas Vachuska33601602014-11-19 03:32:15 -0800174 private final TestDeviceService deviceService = new TestDeviceService();
175 private final TestHostService hostService = new TestHostService();
alshabib4a179dc2014-10-17 17:17:01 -0700176 private final TestPacketService packetService = new TestPacketService();
177
178 private PacketProcessor testProcessor;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800179 private CoreService coreService;
alshabib4a179dc2014-10-17 17:17:01 -0700180 private TestHostProviderService providerService;
181
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800182 private ApplicationId appId =
183 new DefaultApplicationId(100, "org.onosproject.provider.host");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800184
alshabib4a179dc2014-10-17 17:17:01 -0700185 @Before
186 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800187
188 coreService = createMock(CoreService.class);
189 expect(coreService.registerApplication(appId.name()))
Thomas Vachuska27bee092015-06-23 19:03:10 -0700190 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800191 replay(coreService);
192
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700193 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800194 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800195
Thomas Vachuska33601602014-11-19 03:32:15 -0800196 provider.providerRegistry = hostRegistry;
alshabib4a179dc2014-10-17 17:17:01 -0700197 provider.topologyService = topoService;
Pavlin Radoslavovd6612f92015-02-23 13:53:32 -0800198 provider.packetService = packetService;
Thomas Vachuska33601602014-11-19 03:32:15 -0800199 provider.deviceService = deviceService;
200 provider.hostService = hostService;
alshabib4a179dc2014-10-17 17:17:01 -0700201
Thomas Vachuska33601602014-11-19 03:32:15 -0800202 provider.activate(CTX_FOR_NO_REMOVE);
Madan Jampania3770c32015-12-11 12:07:41 -0800203
204 provider.eventHandler = MoreExecutors.newDirectExecutorService();
alshabib4a179dc2014-10-17 17:17:01 -0700205 }
206
207 @Test
208 public void basics() {
209 assertNotNull("registration expected", providerService);
210 assertEquals("incorrect provider", provider, providerService.provider());
211 }
212
213 @Test
214 public void events() {
Charles Chan420e7372016-11-17 10:58:17 -0800215 // New host. Expect one additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700216 testProcessor.process(new TestArpPacketContext(DEV1));
Charles Chan420e7372016-11-17 10:58:17 -0800217 assertThat("New host expected", providerService.descriptions.size(), is(1));
alshabib4a179dc2014-10-17 17:17:01 -0700218
Charles Chan420e7372016-11-17 10:58:17 -0800219 // The host moved to new switch. Expect one additional host description.
220 // The second host description should have a different location.
Charles Chan5d5e0622015-09-25 13:00:06 -0700221 testProcessor.process(new TestArpPacketContext(DEV2));
Charles Chan420e7372016-11-17 10:58:17 -0800222 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
223 HostLocation loc1 = providerService.descriptions.get(0).location();
224 HostLocation loc2 = providerService.descriptions.get(1).location();
225 assertNotEquals("Host location should be different", loc1, loc2);
alshabib4a179dc2014-10-17 17:17:01 -0700226
Charles Chan420e7372016-11-17 10:58:17 -0800227 // The host was misheard on a spine. Expect no additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700228 testProcessor.process(new TestArpPacketContext(DEV3));
Charles Chan420e7372016-11-17 10:58:17 -0800229 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700230
231 providerService.clear();
232
Charles Chan420e7372016-11-17 10:58:17 -0800233 // New host. Expect one additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800234 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800235 assertThat("New host expected", providerService.descriptions.size(), is(1));
Charles Chan5d5e0622015-09-25 13:00:06 -0700236
Charles Chan420e7372016-11-17 10:58:17 -0800237 // The host moved to new switch. Expect one additional host description.
238 // The second host description should have a different location.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800239 testProcessor.process(new TestNaPacketContext(DEV5));
Charles Chan420e7372016-11-17 10:58:17 -0800240 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
241 loc1 = providerService.descriptions.get(0).location();
242 loc2 = providerService.descriptions.get(1).location();
243 assertNotEquals("Host location should be different", loc1, loc2);
Charles Chan5d5e0622015-09-25 13:00:06 -0700244
Charles Chan420e7372016-11-17 10:58:17 -0800245 // The host was misheard on a spine. Expect no additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800246 testProcessor.process(new TestNaPacketContext(DEV6));
Charles Chan420e7372016-11-17 10:58:17 -0800247 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
alshabib4a179dc2014-10-17 17:17:01 -0700248 }
249
Thomas Vachuska33601602014-11-19 03:32:15 -0800250 @Test
251 public void removeHostByDeviceRemove() {
252 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700253 testProcessor.process(new TestArpPacketContext(DEV1));
Jonathan Hartb35540a2015-11-17 09:30:56 -0800254 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan5d5e0622015-09-25 13:00:06 -0700255
Thomas Vachuska33601602014-11-19 03:32:15 -0800256 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
257 "m", "h", "s", "n", new ChassisId(0L));
258 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700259 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700260
261 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
262 "m", "h", "s", "n", new ChassisId(0L));
263 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700264 assertEquals("incorrect remove count", 3, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800265 }
266
267 @Test
268 public void removeHostByDeviceOffline() {
269 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700270 testProcessor.process(new TestArpPacketContext(DEV1));
271 testProcessor.process(new TestArpPacketContext(DEV4));
272
Thomas Vachuska33601602014-11-19 03:32:15 -0800273 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
274 "m", "h", "s", "n", new ChassisId(0L));
275 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700276 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700277
278 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
279 "m", "h", "s", "n", new ChassisId(0L));
280 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700281 assertEquals("incorrect remove count", 3, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800282 }
283
284 @Test
285 public void removeHostByDevicePortDown() {
286 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700287 testProcessor.process(new TestArpPacketContext(DEV1));
288 testProcessor.process(new TestArpPacketContext(DEV4));
289
Thomas Vachuska33601602014-11-19 03:32:15 -0800290 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
291 "m", "h", "s", "n", new ChassisId(0L));
292 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
Charles Chan5d5e0622015-09-25 13:00:06 -0700293 new DefaultPort(device, portNumber(INPORT), false)));
Charles Chan888e20a2017-05-01 15:44:23 -0700294 assertEquals("incorrect remove count", 1, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700295
296 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
297 "m", "h", "s", "n", new ChassisId(0L));
298 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
299 new DefaultPort(device, portNumber(INPORT), false)));
Charles Chan888e20a2017-05-01 15:44:23 -0700300 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800301 }
302
Charles Chan5d5e0622015-09-25 13:00:06 -0700303 /**
304 * When receiving ARP, updates location and IP.
305 */
306 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300307 public void receiveArp() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700308 testProcessor.process(new TestArpPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300309 assertThat("receiveArp. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800310 providerService.descriptions.size(), is(1));
311 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700312 assertThat(descr.location(), is(LOCATION));
313 assertThat(descr.hwAddress(), is(MAC));
314 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS));
315 assertThat(descr.vlan(), is(VLAN));
316 }
317
318 /**
319 * When receiving IPv4, updates location only.
320 */
321 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300322 public void receiveIpv4() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700323 testProcessor.process(new TestIpv4PacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300324 assertThat("receiveIpv4. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800325 providerService.descriptions.size(), is(1));
326 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700327 assertThat(descr.location(), is(LOCATION));
328 assertThat(descr.hwAddress(), is(MAC));
329 assertThat(descr.ipAddress().size(), is(0));
330 assertThat(descr.vlan(), is(VLAN));
331 }
332
333 /**
Charles Chane6067892016-11-17 10:23:46 -0800334 * When receiving DHCP REQUEST, update MAC, location of client.
335 * When receiving DHCP ACK, update MAC, location of server and IP of client.
336 */
337 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300338 public void receiveDhcp() {
Charles Chane6067892016-11-17 10:23:46 -0800339 // DHCP Request
340 testProcessor.process(new TestDhcpRequestPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300341 assertThat("receiveDhcpRequest. One host description expected",
Charles Chane6067892016-11-17 10:23:46 -0800342 providerService.descriptions.size(), is(1));
343 // Should learn the MAC and location of DHCP client
344 HostDescription descr = providerService.descriptions.get(0);
345 assertThat(descr.location(), is(LOCATION));
346 assertThat(descr.hwAddress(), is(MAC));
347 assertThat(descr.ipAddress().size(), is(0));
348 assertThat(descr.vlan(), is(VLAN));
349
350 // DHCP Ack
351 testProcessor.process(new TestDhcpAckPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300352 assertThat("receiveDhcpAck. Two additional host descriptions expected",
Charles Chane6067892016-11-17 10:23:46 -0800353 providerService.descriptions.size(), is(3));
354 // Should learn the IP of DHCP client
355 HostDescription descr2 = providerService.descriptions.get(1);
356 assertThat(descr2.location(), is(LOCATION));
357 assertThat(descr2.hwAddress(), is(MAC));
358 assertThat(descr2.ipAddress().size(), is(1));
359 assertTrue(descr2.ipAddress().contains(IP_ADDRESS));
360 assertThat(descr2.vlan(), is(VLAN));
361 // Should also learn the MAC, location of DHCP server
362 HostDescription descr3 = providerService.descriptions.get(2);
363 assertThat(descr3.location(), is(LOCATION3));
364 assertThat(descr3.hwAddress(), is(MAC3));
365 assertThat(descr3.ipAddress().size(), is(0));
366 assertThat(descr3.vlan(), is(VLAN));
367
368 }
369
370 /**
Charles Chan5d5e0622015-09-25 13:00:06 -0700371 * When receiving NeighborAdvertisement, updates location and IP.
372 */
373 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300374 public void receiveNa() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800375 testProcessor.process(new TestNaPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300376 assertThat("receiveNa. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800377 providerService.descriptions.size(), is(1));
378 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700379 assertThat(descr.location(), is(LOCATION2));
380 assertThat(descr.hwAddress(), is(MAC2));
381 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
382 assertThat(descr.vlan(), is(VLAN));
383 }
384
385 /**
386 * When receiving NeighborSolicitation, updates location and IP.
387 */
388 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300389 public void receiveNs() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800390 testProcessor.process(new TestNsPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300391 assertThat("receiveNs. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800392 providerService.descriptions.size(), is(1));
393 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700394 assertThat(descr.location(), is(LOCATION2));
395 assertThat(descr.hwAddress(), is(MAC2));
396 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
397 assertThat(descr.vlan(), is(VLAN));
398 }
399
400 /**
401 * When receiving RouterAdvertisement, ignores it.
402 */
403 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300404 public void receivesRa() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700405 testProcessor.process(new TestRAPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300406 assertThat("receivesRa. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800407 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700408 }
409
410 /**
411 * When receiving RouterSolicitation, ignores it.
412 */
413 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300414 public void receiveRs() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700415 testProcessor.process(new TestRSPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300416 assertThat("receiveRs. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800417 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700418 }
419
420 /**
421 * When receiving Duplicate Address Detection (DAD), ignores it.
422 */
423 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300424 public void receiveDad() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800425 testProcessor.process(new TestDadPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300426 assertThat("receiveDad. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800427 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700428 }
429
430 /**
431 * When receiving IPv6 multicast packet, ignores it.
432 */
433 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300434 public void receiveIpv6Multicast() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700435 testProcessor.process(new TestIpv6McastPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300436 assertThat("receiveIpv6Multicast. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800437 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700438 }
439
440 /**
441 * When receiving IPv6 unicast packet, updates location only.
442 */
443 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300444 public void receiveIpv6Unicast() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700445 testProcessor.process(new TestIpv6PacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300446 assertThat("receiveIpv6Unicast. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800447 providerService.descriptions.size(), is(1));
448 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700449 assertThat(descr.location(), is(LOCATION2));
450 assertThat(descr.hwAddress(), is(MAC2));
451 assertThat(descr.ipAddress().size(), is(0));
452 assertThat(descr.vlan(), is(VLAN));
453 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800454
alshabib4a179dc2014-10-17 17:17:01 -0700455 @After
456 public void tearDown() {
457 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800458 provider.coreService = null;
alshabib4a179dc2014-10-17 17:17:01 -0700459 provider.providerRegistry = null;
alshabib4a179dc2014-10-17 17:17:01 -0700460 }
461
462 private class TestHostRegistry implements HostProviderRegistry {
463
464 @Override
465 public HostProviderService register(HostProvider provider) {
466 providerService = new TestHostProviderService(provider);
467 return providerService;
468 }
469
470 @Override
471 public void unregister(HostProvider provider) {
472 }
473
474 @Override
475 public Set<ProviderId> getProviders() {
476 return null;
477 }
478
479 }
480
481 private class TestHostProviderService
482 extends AbstractProviderService<HostProvider>
483 implements HostProviderService {
484
Charles Chan420e7372016-11-17 10:58:17 -0800485 List<HostDescription> descriptions = Lists.newArrayList();
Charles Chan888e20a2017-05-01 15:44:23 -0700486 int hostRemoveCount;
487 int ipRemoveCount;
488 int locationRemoveCount;
alshabib4a179dc2014-10-17 17:17:01 -0700489
Charles Chan5d5e0622015-09-25 13:00:06 -0700490 public void clear() {
Charles Chan420e7372016-11-17 10:58:17 -0800491 descriptions.clear();
Charles Chan888e20a2017-05-01 15:44:23 -0700492 hostRemoveCount = 0;
493 ipRemoveCount = 0;
494 locationRemoveCount = 0;
Charles Chan5d5e0622015-09-25 13:00:06 -0700495 }
496
alshabib4a179dc2014-10-17 17:17:01 -0700497 protected TestHostProviderService(HostProvider provider) {
498 super(provider);
499 }
500
501 @Override
Brian O'Connorf107bd72015-09-21 15:31:03 -0700502 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
Charles Chan420e7372016-11-17 10:58:17 -0800503 descriptions.add(hostDescription);
alshabib4a179dc2014-10-17 17:17:01 -0700504 }
505
506 @Override
507 public void hostVanished(HostId hostId) {
Charles Chan888e20a2017-05-01 15:44:23 -0700508 hostRemoveCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700509 }
510
samanwita palc40e5ed2015-09-24 11:01:51 -0700511 @Override
512 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
Charles Chan888e20a2017-05-01 15:44:23 -0700513 ipRemoveCount++;
514 }
515
516 @Override
517 public void removeLocationFromHost(HostId hostId, HostLocation location) {
518 locationRemoveCount++;
samanwita palc40e5ed2015-09-24 11:01:51 -0700519 }
520
alshabib4a179dc2014-10-17 17:17:01 -0700521 }
522
Thomas Vachuska27bee092015-06-23 19:03:10 -0700523 private class TestPacketService extends PacketServiceAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700524 @Override
525 public void addProcessor(PacketProcessor processor, int priority) {
526 testProcessor = processor;
527 }
alshabib4a179dc2014-10-17 17:17:01 -0700528 }
529
alshabib4a179dc2014-10-17 17:17:01 -0700530 private class TestTopologyService extends TopologyServiceAdapter {
531 @Override
532 public boolean isInfrastructure(Topology topology,
533 ConnectPoint connectPoint) {
534 //simulate DPID3 as an infrastructure switch
Charles Chan5d5e0622015-09-25 13:00:06 -0700535 if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
536 connectPoint.deviceId().equals(deviceId(DEV6))) {
alshabib4a179dc2014-10-17 17:17:01 -0700537 return true;
538 }
539 return false;
540 }
541 }
542
Charles Chan5d5e0622015-09-25 13:00:06 -0700543 /**
544 * Generates ARP packet.
545 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300546 private class TestArpPacketContext extends PacketContextAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700547 private final String deviceId;
548
Charles Chan5d5e0622015-09-25 13:00:06 -0700549 public TestArpPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300550 super(0, null, null, false);
alshabib4a179dc2014-10-17 17:17:01 -0700551 this.deviceId = deviceId;
552 }
553
554 @Override
alshabib4a179dc2014-10-17 17:17:01 -0700555 public InboundPacket inPacket() {
556 ARP arp = new ARP();
557 arp.setSenderProtocolAddress(IP)
558 .setSenderHardwareAddress(MAC.toBytes())
559 .setTargetHardwareAddress(BCMAC.toBytes())
560 .setTargetProtocolAddress(IP);
561
562 Ethernet eth = new Ethernet();
563 eth.setEtherType(Ethernet.TYPE_ARP)
564 .setVlanID(VLAN.toShort())
565 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800566 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700567 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800568 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
569 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700570 return new DefaultInboundPacket(receivedFrom, eth,
571 ByteBuffer.wrap(eth.serialize()));
572 }
alshabib4a179dc2014-10-17 17:17:01 -0700573 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800574
Charles Chan5d5e0622015-09-25 13:00:06 -0700575 /**
Charles Chane6067892016-11-17 10:23:46 -0800576 * Generates IPv4 Unicast packet.
Charles Chan5d5e0622015-09-25 13:00:06 -0700577 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300578 private class TestIpv4PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700579 private final String deviceId;
580
581 public TestIpv4PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300582 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700583 this.deviceId = deviceId;
584 }
585
586 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700587 public InboundPacket inPacket() {
588 IPv4 ipv4 = new IPv4();
589 ipv4.setDestinationAddress("10.0.0.1");
590 ipv4.setSourceAddress(IP_ADDRESS.toString());
591 Ethernet eth = new Ethernet();
592 eth.setEtherType(Ethernet.TYPE_IPV4)
593 .setVlanID(VLAN.toShort())
594 .setSourceMACAddress(MAC)
595 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
596 .setPayload(ipv4);
597 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
598 portNumber(INPORT));
599 return new DefaultInboundPacket(receivedFrom, eth,
600 ByteBuffer.wrap(eth.serialize()));
601 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700602 }
Charles Chane6067892016-11-17 10:23:46 -0800603 /**
604 * Generates DHCP REQUEST packet.
605 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300606 private class TestDhcpRequestPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800607 private final String deviceId;
608
609 public TestDhcpRequestPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300610 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800611 this.deviceId = deviceId;
612 }
613
614 @Override
Charles Chane6067892016-11-17 10:23:46 -0800615 public InboundPacket inPacket() {
616 byte[] dhcpMsgType = new byte[1];
617 dhcpMsgType[0] = (byte) DHCPPacketType.DHCPREQUEST.getValue();
618
619 DHCPOption dhcpOption = new DHCPOption();
620 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
621 dhcpOption.setData(dhcpMsgType);
622 dhcpOption.setLength((byte) 1);
623 DHCP dhcp = new DHCP();
624 dhcp.setOptions(Collections.singletonList(dhcpOption));
625 dhcp.setClientHardwareAddress(MAC.toBytes());
626 UDP udp = new UDP();
627 udp.setPayload(dhcp);
628 udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
629 udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
630 IPv4 ipv4 = new IPv4();
631 ipv4.setPayload(udp);
632 ipv4.setDestinationAddress(IP_ADDRESS3.toString());
633 ipv4.setSourceAddress(IP_ADDRESS.toString());
634 Ethernet eth = new Ethernet();
635 eth.setEtherType(Ethernet.TYPE_IPV4)
636 .setVlanID(VLAN.toShort())
637 .setSourceMACAddress(MAC)
638 .setDestinationMACAddress(MAC3)
639 .setPayload(ipv4);
640 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
641 portNumber(INPORT));
642 return new DefaultInboundPacket(receivedFrom, eth,
643 ByteBuffer.wrap(eth.serialize()));
644 }
Charles Chane6067892016-11-17 10:23:46 -0800645 }
646
647 /**
648 * Generates DHCP ACK packet.
649 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300650 private class TestDhcpAckPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800651 private final String deviceId;
652
653 public TestDhcpAckPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300654 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800655 this.deviceId = deviceId;
656 }
657
658 @Override
Charles Chane6067892016-11-17 10:23:46 -0800659 public InboundPacket inPacket() {
660 byte[] dhcpMsgType = new byte[1];
661 dhcpMsgType[0] = (byte) DHCPPacketType.DHCPACK.getValue();
662
663 DHCPOption dhcpOption = new DHCPOption();
664 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
665 dhcpOption.setData(dhcpMsgType);
666 dhcpOption.setLength((byte) 1);
667 DHCP dhcp = new DHCP();
668 dhcp.setOptions(Collections.singletonList(dhcpOption));
669 dhcp.setClientHardwareAddress(MAC.toBytes());
670 dhcp.setYourIPAddress(IP_ADDRESS.getIp4Address().toInt());
671 UDP udp = new UDP();
672 udp.setPayload(dhcp);
673 udp.setSourcePort(UDP.DHCP_SERVER_PORT);
674 udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
675 IPv4 ipv4 = new IPv4();
676 ipv4.setPayload(udp);
677 ipv4.setDestinationAddress(IP_ADDRESS.toString());
678 ipv4.setSourceAddress(IP_ADDRESS3.toString());
679 Ethernet eth = new Ethernet();
680 eth.setEtherType(Ethernet.TYPE_IPV4)
681 .setVlanID(VLAN.toShort())
682 .setSourceMACAddress(MAC3)
683 .setDestinationMACAddress(MAC)
684 .setPayload(ipv4);
685 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
686 portNumber(INPORT2));
687 return new DefaultInboundPacket(receivedFrom, eth,
688 ByteBuffer.wrap(eth.serialize()));
689 }
Charles Chane6067892016-11-17 10:23:46 -0800690 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700691
692 /**
693 * Generates NeighborAdvertisement packet.
694 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300695 private class TestNaPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700696 private final String deviceId;
697
Jonathan Hartb35540a2015-11-17 09:30:56 -0800698 public TestNaPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300699 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700700 this.deviceId = deviceId;
701 }
702
703 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700704 public InboundPacket inPacket() {
705 NeighborAdvertisement na = new NeighborAdvertisement();
706 ICMP6 icmp6 = new ICMP6();
707 icmp6.setPayload(na);
708 IPv6 ipv6 = new IPv6();
709 ipv6.setPayload(icmp6);
710 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
711 ipv6.setSourceAddress(IP2);
712 Ethernet eth = new Ethernet();
713 eth.setEtherType(Ethernet.TYPE_IPV6)
714 .setVlanID(VLAN.toShort())
715 .setSourceMACAddress(MAC2.toBytes())
716 .setDestinationMACAddress(BCMAC2)
717 .setPayload(ipv6);
718 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
719 portNumber(INPORT));
720 return new DefaultInboundPacket(receivedFrom, eth,
721 ByteBuffer.wrap(eth.serialize()));
722 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700723 }
724
725 /**
726 * Generates NeighborSolicitation packet.
727 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300728 private class TestNsPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700729 private final String deviceId;
730
Jonathan Hartb35540a2015-11-17 09:30:56 -0800731 public TestNsPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300732 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700733 this.deviceId = deviceId;
734 }
735
736 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700737 public InboundPacket inPacket() {
738 NeighborSolicitation ns = new NeighborSolicitation();
739 ICMP6 icmp6 = new ICMP6();
740 icmp6.setPayload(ns);
741 IPv6 ipv6 = new IPv6();
742 ipv6.setPayload(icmp6);
743 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
744 ipv6.setSourceAddress(IP2);
745 Ethernet eth = new Ethernet();
746 eth.setEtherType(Ethernet.TYPE_IPV6)
747 .setVlanID(VLAN.toShort())
748 .setSourceMACAddress(MAC2.toBytes())
749 .setDestinationMACAddress(BCMAC2)
750 .setPayload(ipv6);
751 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
752 portNumber(INPORT));
753 return new DefaultInboundPacket(receivedFrom, eth,
754 ByteBuffer.wrap(eth.serialize()));
755 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700756 }
757
758 /**
759 * Generates Duplicate Address Detection packet.
760 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300761 private class TestDadPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700762 private final String deviceId;
763
Jonathan Hartb35540a2015-11-17 09:30:56 -0800764 public TestDadPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300765 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700766 this.deviceId = deviceId;
767 }
768
769 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700770 public InboundPacket inPacket() {
771 NeighborSolicitation ns = new NeighborSolicitation();
772 ICMP6 icmp6 = new ICMP6();
773 icmp6.setPayload(ns);
774 IPv6 ipv6 = new IPv6();
775 ipv6.setPayload(icmp6);
776 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
777 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
778 Ethernet eth = new Ethernet();
779 eth.setEtherType(Ethernet.TYPE_IPV6)
780 .setVlanID(VLAN.toShort())
781 .setSourceMACAddress(MAC2.toBytes())
782 .setDestinationMACAddress(BCMAC2)
783 .setPayload(ipv6);
784 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
785 portNumber(INPORT));
786 return new DefaultInboundPacket(receivedFrom, eth,
787 ByteBuffer.wrap(eth.serialize()));
788 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700789 }
790
791 /**
792 * Generates Router Solicitation packet.
793 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300794 private class TestRSPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700795 private final String deviceId;
796
797 public TestRSPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300798 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700799 this.deviceId = deviceId;
800 }
801
802 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700803 public InboundPacket inPacket() {
804 RouterSolicitation ns = new RouterSolicitation();
805 ICMP6 icmp6 = new ICMP6();
806 icmp6.setPayload(ns);
807 IPv6 ipv6 = new IPv6();
808 ipv6.setPayload(icmp6);
809 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
810 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
811 Ethernet eth = new Ethernet();
812 eth.setEtherType(Ethernet.TYPE_IPV6)
813 .setVlanID(VLAN.toShort())
814 .setSourceMACAddress(MAC2.toBytes())
815 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
816 .setPayload(ipv6);
817 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
818 portNumber(INPORT));
819 return new DefaultInboundPacket(receivedFrom, eth,
820 ByteBuffer.wrap(eth.serialize()));
821 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700822 }
823
824 /**
825 * Generates Router Advertisement packet.
826 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300827 private class TestRAPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700828 private final String deviceId;
829
830 public TestRAPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300831 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700832 this.deviceId = deviceId;
833 }
834
835 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700836 public InboundPacket inPacket() {
837 RouterAdvertisement ns = new RouterAdvertisement();
838 ICMP6 icmp6 = new ICMP6();
839 icmp6.setPayload(ns);
840 IPv6 ipv6 = new IPv6();
841 ipv6.setPayload(icmp6);
842 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
843 ipv6.setSourceAddress(IP2);
844 Ethernet eth = new Ethernet();
845 eth.setEtherType(Ethernet.TYPE_IPV6)
846 .setVlanID(VLAN.toShort())
847 .setSourceMACAddress(MAC2.toBytes())
848 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
849 .setPayload(ipv6);
850 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
851 portNumber(INPORT));
852 return new DefaultInboundPacket(receivedFrom, eth,
853 ByteBuffer.wrap(eth.serialize()));
854 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700855 }
856
857 /**
858 * Generates IPv6 Multicast packet.
859 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300860 private class TestIpv6McastPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700861 private final String deviceId;
862
863 public TestIpv6McastPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300864 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700865 this.deviceId = deviceId;
866 }
867
868 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700869 public InboundPacket inPacket() {
870 IPv6 ipv6 = new IPv6();
871 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
872 ipv6.setSourceAddress(IP2);
873 Ethernet eth = new Ethernet();
874 eth.setEtherType(Ethernet.TYPE_IPV6)
875 .setVlanID(VLAN.toShort())
876 .setSourceMACAddress(MAC2.toBytes())
877 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
878 .setPayload(ipv6);
879 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
880 portNumber(INPORT));
881 return new DefaultInboundPacket(receivedFrom, eth,
882 ByteBuffer.wrap(eth.serialize()));
883 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700884 }
885
886 /**
887 * Generates IPv6 Unicast packet.
888 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300889 private class TestIpv6PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700890 private final String deviceId;
891
892 public TestIpv6PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300893 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700894 this.deviceId = deviceId;
895 }
896
897 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700898 public InboundPacket inPacket() {
899 IPv6 ipv6 = new IPv6();
900 ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
901 ipv6.setSourceAddress(IP2);
902 Ethernet eth = new Ethernet();
903 eth.setEtherType(Ethernet.TYPE_IPV6)
904 .setVlanID(VLAN.toShort())
905 .setSourceMACAddress(MAC2)
906 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
907 .setPayload(ipv6);
908 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
909 portNumber(INPORT));
910 return new DefaultInboundPacket(receivedFrom, eth,
911 ByteBuffer.wrap(eth.serialize()));
912 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700913 }
914
Thomas Vachuska33601602014-11-19 03:32:15 -0800915 private class TestDeviceService extends DeviceServiceAdapter {
916 private DeviceListener listener;
917
918 @Override
919 public void addListener(DeviceListener listener) {
920 this.listener = listener;
921 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800922
923 @Override
924 public Iterable<Device> getDevices() {
925 return Collections.emptyList();
926 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800927 }
928
929 private class TestHostService extends HostServiceAdapter {
930 @Override
931 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700932 ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
933 ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
Charles Chane6067892016-11-17 10:23:46 -0800934 ConnectPoint cp3 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700935 if (connectPoint.equals(cp1)) {
936 return ImmutableSet.of(HOST);
937 } else if (connectPoint.equals(cp2)) {
938 return ImmutableSet.of(HOST2);
Charles Chane6067892016-11-17 10:23:46 -0800939 } else if (connectPoint.equals(cp3)) {
940 return ImmutableSet.of(HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700941 } else {
942 return ImmutableSet.of();
943 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800944 }
945
946 @Override
947 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700948 if (deviceId.equals(deviceId(DEV1))) {
Charles Chane6067892016-11-17 10:23:46 -0800949 return ImmutableSet.of(HOST, HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700950 } else if (deviceId.equals(deviceId(DEV4))) {
951 return ImmutableSet.of(HOST2);
952 } else {
953 return ImmutableSet.of();
954 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800955 }
956
Charles Chane6067892016-11-17 10:23:46 -0800957 @Override
958 public Host getHost(HostId hostId) {
959 if (hostId.equals(HostId.hostId(MAC, VLAN))) {
960 return HOST;
961 } else if (hostId.equals(HostId.hostId(MAC2, VLAN))) {
962 return HOST2;
963 } else if (hostId.equals(HostId.hostId(MAC3, VLAN))) {
964 return HOST3;
965 }
966 return null;
967 }
968
Thomas Vachuska33601602014-11-19 03:32:15 -0800969 }
alshabib4a179dc2014-10-17 17:17:01 -0700970}