blob: b1c661c53ebcaf9ce47fc7a948c1496430cec939 [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 Chane6067892016-11-17 10:23:46 -0800259 assertEquals("incorrect remove count", 2, providerService.removeCount);
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 Chane6067892016-11-17 10:23:46 -0800264 assertEquals("incorrect remove count", 3, providerService.removeCount);
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 Chane6067892016-11-17 10:23:46 -0800276 assertEquals("incorrect remove count", 2, providerService.removeCount);
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 Chane6067892016-11-17 10:23:46 -0800281 assertEquals("incorrect remove count", 3, providerService.removeCount);
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)));
Thomas Vachuska33601602014-11-19 03:32:15 -0800294 assertEquals("incorrect remove count", 1, providerService.removeCount);
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)));
300 assertEquals("incorrect remove count", 2, providerService.removeCount);
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();
486 int removeCount;
alshabib4a179dc2014-10-17 17:17:01 -0700487
Charles Chan5d5e0622015-09-25 13:00:06 -0700488 public void clear() {
Charles Chan420e7372016-11-17 10:58:17 -0800489 descriptions.clear();
Charles Chan5d5e0622015-09-25 13:00:06 -0700490 removeCount = 0;
491 }
492
alshabib4a179dc2014-10-17 17:17:01 -0700493 protected TestHostProviderService(HostProvider provider) {
494 super(provider);
495 }
496
497 @Override
Brian O'Connorf107bd72015-09-21 15:31:03 -0700498 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
Charles Chan420e7372016-11-17 10:58:17 -0800499 descriptions.add(hostDescription);
alshabib4a179dc2014-10-17 17:17:01 -0700500 }
501
502 @Override
503 public void hostVanished(HostId hostId) {
Thomas Vachuska33601602014-11-19 03:32:15 -0800504 removeCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700505 }
506
samanwita palc40e5ed2015-09-24 11:01:51 -0700507 @Override
508 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
509 }
510
alshabib4a179dc2014-10-17 17:17:01 -0700511 }
512
Thomas Vachuska27bee092015-06-23 19:03:10 -0700513 private class TestPacketService extends PacketServiceAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700514 @Override
515 public void addProcessor(PacketProcessor processor, int priority) {
516 testProcessor = processor;
517 }
alshabib4a179dc2014-10-17 17:17:01 -0700518 }
519
alshabib4a179dc2014-10-17 17:17:01 -0700520 private class TestTopologyService extends TopologyServiceAdapter {
521 @Override
522 public boolean isInfrastructure(Topology topology,
523 ConnectPoint connectPoint) {
524 //simulate DPID3 as an infrastructure switch
Charles Chan5d5e0622015-09-25 13:00:06 -0700525 if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
526 connectPoint.deviceId().equals(deviceId(DEV6))) {
alshabib4a179dc2014-10-17 17:17:01 -0700527 return true;
528 }
529 return false;
530 }
531 }
532
Charles Chan5d5e0622015-09-25 13:00:06 -0700533 /**
534 * Generates ARP packet.
535 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300536 private class TestArpPacketContext extends PacketContextAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700537 private final String deviceId;
538
Charles Chan5d5e0622015-09-25 13:00:06 -0700539 public TestArpPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300540 super(0, null, null, false);
alshabib4a179dc2014-10-17 17:17:01 -0700541 this.deviceId = deviceId;
542 }
543
544 @Override
alshabib4a179dc2014-10-17 17:17:01 -0700545 public InboundPacket inPacket() {
546 ARP arp = new ARP();
547 arp.setSenderProtocolAddress(IP)
548 .setSenderHardwareAddress(MAC.toBytes())
549 .setTargetHardwareAddress(BCMAC.toBytes())
550 .setTargetProtocolAddress(IP);
551
552 Ethernet eth = new Ethernet();
553 eth.setEtherType(Ethernet.TYPE_ARP)
554 .setVlanID(VLAN.toShort())
555 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800556 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700557 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800558 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
559 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700560 return new DefaultInboundPacket(receivedFrom, eth,
561 ByteBuffer.wrap(eth.serialize()));
562 }
alshabib4a179dc2014-10-17 17:17:01 -0700563 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800564
Charles Chan5d5e0622015-09-25 13:00:06 -0700565 /**
Charles Chane6067892016-11-17 10:23:46 -0800566 * Generates IPv4 Unicast packet.
Charles Chan5d5e0622015-09-25 13:00:06 -0700567 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300568 private class TestIpv4PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700569 private final String deviceId;
570
571 public TestIpv4PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300572 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700573 this.deviceId = deviceId;
574 }
575
576 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700577 public InboundPacket inPacket() {
578 IPv4 ipv4 = new IPv4();
579 ipv4.setDestinationAddress("10.0.0.1");
580 ipv4.setSourceAddress(IP_ADDRESS.toString());
581 Ethernet eth = new Ethernet();
582 eth.setEtherType(Ethernet.TYPE_IPV4)
583 .setVlanID(VLAN.toShort())
584 .setSourceMACAddress(MAC)
585 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
586 .setPayload(ipv4);
587 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
588 portNumber(INPORT));
589 return new DefaultInboundPacket(receivedFrom, eth,
590 ByteBuffer.wrap(eth.serialize()));
591 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700592 }
Charles Chane6067892016-11-17 10:23:46 -0800593 /**
594 * Generates DHCP REQUEST packet.
595 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300596 private class TestDhcpRequestPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800597 private final String deviceId;
598
599 public TestDhcpRequestPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300600 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800601 this.deviceId = deviceId;
602 }
603
604 @Override
Charles Chane6067892016-11-17 10:23:46 -0800605 public InboundPacket inPacket() {
606 byte[] dhcpMsgType = new byte[1];
607 dhcpMsgType[0] = (byte) DHCPPacketType.DHCPREQUEST.getValue();
608
609 DHCPOption dhcpOption = new DHCPOption();
610 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
611 dhcpOption.setData(dhcpMsgType);
612 dhcpOption.setLength((byte) 1);
613 DHCP dhcp = new DHCP();
614 dhcp.setOptions(Collections.singletonList(dhcpOption));
615 dhcp.setClientHardwareAddress(MAC.toBytes());
616 UDP udp = new UDP();
617 udp.setPayload(dhcp);
618 udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
619 udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
620 IPv4 ipv4 = new IPv4();
621 ipv4.setPayload(udp);
622 ipv4.setDestinationAddress(IP_ADDRESS3.toString());
623 ipv4.setSourceAddress(IP_ADDRESS.toString());
624 Ethernet eth = new Ethernet();
625 eth.setEtherType(Ethernet.TYPE_IPV4)
626 .setVlanID(VLAN.toShort())
627 .setSourceMACAddress(MAC)
628 .setDestinationMACAddress(MAC3)
629 .setPayload(ipv4);
630 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
631 portNumber(INPORT));
632 return new DefaultInboundPacket(receivedFrom, eth,
633 ByteBuffer.wrap(eth.serialize()));
634 }
Charles Chane6067892016-11-17 10:23:46 -0800635 }
636
637 /**
638 * Generates DHCP ACK packet.
639 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300640 private class TestDhcpAckPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800641 private final String deviceId;
642
643 public TestDhcpAckPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300644 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800645 this.deviceId = deviceId;
646 }
647
648 @Override
Charles Chane6067892016-11-17 10:23:46 -0800649 public InboundPacket inPacket() {
650 byte[] dhcpMsgType = new byte[1];
651 dhcpMsgType[0] = (byte) DHCPPacketType.DHCPACK.getValue();
652
653 DHCPOption dhcpOption = new DHCPOption();
654 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
655 dhcpOption.setData(dhcpMsgType);
656 dhcpOption.setLength((byte) 1);
657 DHCP dhcp = new DHCP();
658 dhcp.setOptions(Collections.singletonList(dhcpOption));
659 dhcp.setClientHardwareAddress(MAC.toBytes());
660 dhcp.setYourIPAddress(IP_ADDRESS.getIp4Address().toInt());
661 UDP udp = new UDP();
662 udp.setPayload(dhcp);
663 udp.setSourcePort(UDP.DHCP_SERVER_PORT);
664 udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
665 IPv4 ipv4 = new IPv4();
666 ipv4.setPayload(udp);
667 ipv4.setDestinationAddress(IP_ADDRESS.toString());
668 ipv4.setSourceAddress(IP_ADDRESS3.toString());
669 Ethernet eth = new Ethernet();
670 eth.setEtherType(Ethernet.TYPE_IPV4)
671 .setVlanID(VLAN.toShort())
672 .setSourceMACAddress(MAC3)
673 .setDestinationMACAddress(MAC)
674 .setPayload(ipv4);
675 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
676 portNumber(INPORT2));
677 return new DefaultInboundPacket(receivedFrom, eth,
678 ByteBuffer.wrap(eth.serialize()));
679 }
Charles Chane6067892016-11-17 10:23:46 -0800680 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700681
682 /**
683 * Generates NeighborAdvertisement packet.
684 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300685 private class TestNaPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700686 private final String deviceId;
687
Jonathan Hartb35540a2015-11-17 09:30:56 -0800688 public TestNaPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300689 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700690 this.deviceId = deviceId;
691 }
692
693 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700694 public InboundPacket inPacket() {
695 NeighborAdvertisement na = new NeighborAdvertisement();
696 ICMP6 icmp6 = new ICMP6();
697 icmp6.setPayload(na);
698 IPv6 ipv6 = new IPv6();
699 ipv6.setPayload(icmp6);
700 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
701 ipv6.setSourceAddress(IP2);
702 Ethernet eth = new Ethernet();
703 eth.setEtherType(Ethernet.TYPE_IPV6)
704 .setVlanID(VLAN.toShort())
705 .setSourceMACAddress(MAC2.toBytes())
706 .setDestinationMACAddress(BCMAC2)
707 .setPayload(ipv6);
708 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
709 portNumber(INPORT));
710 return new DefaultInboundPacket(receivedFrom, eth,
711 ByteBuffer.wrap(eth.serialize()));
712 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700713 }
714
715 /**
716 * Generates NeighborSolicitation packet.
717 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300718 private class TestNsPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700719 private final String deviceId;
720
Jonathan Hartb35540a2015-11-17 09:30:56 -0800721 public TestNsPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300722 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700723 this.deviceId = deviceId;
724 }
725
726 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700727 public InboundPacket inPacket() {
728 NeighborSolicitation ns = new NeighborSolicitation();
729 ICMP6 icmp6 = new ICMP6();
730 icmp6.setPayload(ns);
731 IPv6 ipv6 = new IPv6();
732 ipv6.setPayload(icmp6);
733 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
734 ipv6.setSourceAddress(IP2);
735 Ethernet eth = new Ethernet();
736 eth.setEtherType(Ethernet.TYPE_IPV6)
737 .setVlanID(VLAN.toShort())
738 .setSourceMACAddress(MAC2.toBytes())
739 .setDestinationMACAddress(BCMAC2)
740 .setPayload(ipv6);
741 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
742 portNumber(INPORT));
743 return new DefaultInboundPacket(receivedFrom, eth,
744 ByteBuffer.wrap(eth.serialize()));
745 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700746 }
747
748 /**
749 * Generates Duplicate Address Detection packet.
750 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300751 private class TestDadPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700752 private final String deviceId;
753
Jonathan Hartb35540a2015-11-17 09:30:56 -0800754 public TestDadPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300755 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700756 this.deviceId = deviceId;
757 }
758
759 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700760 public InboundPacket inPacket() {
761 NeighborSolicitation ns = new NeighborSolicitation();
762 ICMP6 icmp6 = new ICMP6();
763 icmp6.setPayload(ns);
764 IPv6 ipv6 = new IPv6();
765 ipv6.setPayload(icmp6);
766 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
767 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
768 Ethernet eth = new Ethernet();
769 eth.setEtherType(Ethernet.TYPE_IPV6)
770 .setVlanID(VLAN.toShort())
771 .setSourceMACAddress(MAC2.toBytes())
772 .setDestinationMACAddress(BCMAC2)
773 .setPayload(ipv6);
774 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
775 portNumber(INPORT));
776 return new DefaultInboundPacket(receivedFrom, eth,
777 ByteBuffer.wrap(eth.serialize()));
778 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700779 }
780
781 /**
782 * Generates Router Solicitation packet.
783 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300784 private class TestRSPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700785 private final String deviceId;
786
787 public TestRSPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300788 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700789 this.deviceId = deviceId;
790 }
791
792 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700793 public InboundPacket inPacket() {
794 RouterSolicitation ns = new RouterSolicitation();
795 ICMP6 icmp6 = new ICMP6();
796 icmp6.setPayload(ns);
797 IPv6 ipv6 = new IPv6();
798 ipv6.setPayload(icmp6);
799 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
800 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
801 Ethernet eth = new Ethernet();
802 eth.setEtherType(Ethernet.TYPE_IPV6)
803 .setVlanID(VLAN.toShort())
804 .setSourceMACAddress(MAC2.toBytes())
805 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
806 .setPayload(ipv6);
807 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
808 portNumber(INPORT));
809 return new DefaultInboundPacket(receivedFrom, eth,
810 ByteBuffer.wrap(eth.serialize()));
811 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700812 }
813
814 /**
815 * Generates Router Advertisement packet.
816 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300817 private class TestRAPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700818 private final String deviceId;
819
820 public TestRAPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300821 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700822 this.deviceId = deviceId;
823 }
824
825 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700826 public InboundPacket inPacket() {
827 RouterAdvertisement ns = new RouterAdvertisement();
828 ICMP6 icmp6 = new ICMP6();
829 icmp6.setPayload(ns);
830 IPv6 ipv6 = new IPv6();
831 ipv6.setPayload(icmp6);
832 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
833 ipv6.setSourceAddress(IP2);
834 Ethernet eth = new Ethernet();
835 eth.setEtherType(Ethernet.TYPE_IPV6)
836 .setVlanID(VLAN.toShort())
837 .setSourceMACAddress(MAC2.toBytes())
838 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
839 .setPayload(ipv6);
840 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
841 portNumber(INPORT));
842 return new DefaultInboundPacket(receivedFrom, eth,
843 ByteBuffer.wrap(eth.serialize()));
844 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700845 }
846
847 /**
848 * Generates IPv6 Multicast packet.
849 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300850 private class TestIpv6McastPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700851 private final String deviceId;
852
853 public TestIpv6McastPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300854 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700855 this.deviceId = deviceId;
856 }
857
858 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700859 public InboundPacket inPacket() {
860 IPv6 ipv6 = new IPv6();
861 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
862 ipv6.setSourceAddress(IP2);
863 Ethernet eth = new Ethernet();
864 eth.setEtherType(Ethernet.TYPE_IPV6)
865 .setVlanID(VLAN.toShort())
866 .setSourceMACAddress(MAC2.toBytes())
867 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
868 .setPayload(ipv6);
869 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
870 portNumber(INPORT));
871 return new DefaultInboundPacket(receivedFrom, eth,
872 ByteBuffer.wrap(eth.serialize()));
873 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700874 }
875
876 /**
877 * Generates IPv6 Unicast packet.
878 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300879 private class TestIpv6PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700880 private final String deviceId;
881
882 public TestIpv6PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300883 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700884 this.deviceId = deviceId;
885 }
886
887 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700888 public InboundPacket inPacket() {
889 IPv6 ipv6 = new IPv6();
890 ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
891 ipv6.setSourceAddress(IP2);
892 Ethernet eth = new Ethernet();
893 eth.setEtherType(Ethernet.TYPE_IPV6)
894 .setVlanID(VLAN.toShort())
895 .setSourceMACAddress(MAC2)
896 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
897 .setPayload(ipv6);
898 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
899 portNumber(INPORT));
900 return new DefaultInboundPacket(receivedFrom, eth,
901 ByteBuffer.wrap(eth.serialize()));
902 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700903 }
904
Thomas Vachuska33601602014-11-19 03:32:15 -0800905 private class TestDeviceService extends DeviceServiceAdapter {
906 private DeviceListener listener;
907
908 @Override
909 public void addListener(DeviceListener listener) {
910 this.listener = listener;
911 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800912
913 @Override
914 public Iterable<Device> getDevices() {
915 return Collections.emptyList();
916 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800917 }
918
919 private class TestHostService extends HostServiceAdapter {
920 @Override
921 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700922 ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
923 ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
Charles Chane6067892016-11-17 10:23:46 -0800924 ConnectPoint cp3 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700925 if (connectPoint.equals(cp1)) {
926 return ImmutableSet.of(HOST);
927 } else if (connectPoint.equals(cp2)) {
928 return ImmutableSet.of(HOST2);
Charles Chane6067892016-11-17 10:23:46 -0800929 } else if (connectPoint.equals(cp3)) {
930 return ImmutableSet.of(HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700931 } else {
932 return ImmutableSet.of();
933 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800934 }
935
936 @Override
937 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700938 if (deviceId.equals(deviceId(DEV1))) {
Charles Chane6067892016-11-17 10:23:46 -0800939 return ImmutableSet.of(HOST, HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700940 } else if (deviceId.equals(deviceId(DEV4))) {
941 return ImmutableSet.of(HOST2);
942 } else {
943 return ImmutableSet.of();
944 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800945 }
946
Charles Chane6067892016-11-17 10:23:46 -0800947 @Override
948 public Host getHost(HostId hostId) {
949 if (hostId.equals(HostId.hostId(MAC, VLAN))) {
950 return HOST;
951 } else if (hostId.equals(HostId.hostId(MAC2, VLAN))) {
952 return HOST2;
953 } else if (hostId.equals(HostId.hostId(MAC3, VLAN))) {
954 return HOST3;
955 }
956 return null;
957 }
958
Thomas Vachuska33601602014-11-19 03:32:15 -0800959 }
alshabib4a179dc2014-10-17 17:17:01 -0700960}