blob: b28ec170878412d2fa9daa0e4d8d74c71978128a [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;
Yi Tsengc7403c22017-06-19 16:23:22 -070028import org.onlab.packet.dhcp.DhcpOption;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080029import org.onlab.packet.Ethernet;
Charles Chan5d5e0622015-09-25 13:00:06 -070030import org.onlab.packet.ICMP6;
31import org.onlab.packet.IPv4;
32import org.onlab.packet.IPv6;
33import org.onlab.packet.Ip6Address;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080034import org.onlab.packet.IpAddress;
35import org.onlab.packet.MacAddress;
Charles Chane6067892016-11-17 10:23:46 -080036import org.onlab.packet.UDP;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080037import org.onlab.packet.VlanId;
Charles Chan5d5e0622015-09-25 13:00:06 -070038import org.onlab.packet.ndp.NeighborAdvertisement;
39import org.onlab.packet.ndp.NeighborSolicitation;
40import org.onlab.packet.ndp.RouterAdvertisement;
41import org.onlab.packet.ndp.RouterSolicitation;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070042import org.onosproject.cfg.ComponentConfigAdapter;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080043import org.onosproject.core.ApplicationId;
44import org.onosproject.core.CoreService;
45import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080046import org.onosproject.net.ConnectPoint;
47import org.onosproject.net.DefaultDevice;
48import org.onosproject.net.DefaultHost;
49import org.onosproject.net.DefaultPort;
50import org.onosproject.net.Device;
51import org.onosproject.net.DeviceId;
52import org.onosproject.net.Host;
53import org.onosproject.net.HostId;
54import org.onosproject.net.HostLocation;
55import org.onosproject.net.device.DeviceEvent;
56import org.onosproject.net.device.DeviceListener;
57import org.onosproject.net.device.DeviceServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080058import org.onosproject.net.host.HostDescription;
59import org.onosproject.net.host.HostProvider;
60import org.onosproject.net.host.HostProviderRegistry;
61import org.onosproject.net.host.HostProviderService;
62import org.onosproject.net.host.HostServiceAdapter;
63import org.onosproject.net.packet.DefaultInboundPacket;
64import org.onosproject.net.packet.InboundPacket;
Andrey Komarov2398d962016-09-26 15:11:23 +030065import org.onosproject.net.packet.PacketContextAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080066import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070067import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080068import org.onosproject.net.provider.AbstractProviderService;
69import org.onosproject.net.provider.ProviderId;
70import org.onosproject.net.topology.Topology;
71import org.onosproject.net.topology.TopologyServiceAdapter;
alshabib4a179dc2014-10-17 17:17:01 -070072
Thomas Vachuska27bee092015-06-23 19:03:10 -070073import java.nio.ByteBuffer;
74import java.util.Collections;
75import java.util.Dictionary;
76import java.util.Hashtable;
Charles Chan420e7372016-11-17 10:58:17 -080077import java.util.List;
Thomas Vachuska27bee092015-06-23 19:03:10 -070078import java.util.Set;
79
Michele Santuari72f6bee2016-11-18 12:56:30 +010080import static org.easymock.EasyMock.createMock;
81import static org.easymock.EasyMock.expect;
82import static org.easymock.EasyMock.replay;
Charles Chan5d5e0622015-09-25 13:00:06 -070083import static org.hamcrest.Matchers.is;
Michele Santuari72f6bee2016-11-18 12:56:30 +010084import static org.junit.Assert.assertEquals;
85import static org.junit.Assert.assertNotEquals;
86import static org.junit.Assert.assertNotNull;
87import static org.junit.Assert.assertThat;
88import static org.junit.Assert.assertTrue;
Thomas Vachuska27bee092015-06-23 19:03:10 -070089import static org.onlab.packet.VlanId.vlanId;
90import static org.onosproject.net.Device.Type.SWITCH;
91import static org.onosproject.net.DeviceId.deviceId;
92import static org.onosproject.net.HostId.hostId;
93import static org.onosproject.net.PortNumber.portNumber;
Michele Santuari72f6bee2016-11-18 12:56:30 +010094import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
95import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
96import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
Thomas Vachuska33601602014-11-19 03:32:15 -080097
alshabib4a179dc2014-10-17 17:17:01 -070098public class HostLocationProviderTest {
Charles Chan8b0fdaa2016-02-23 18:35:27 -080099 private static final ProviderId PROVIDER_ID =
100 new ProviderId("of", "org.onosproject.provider.host");
101
alshabib4a179dc2014-10-17 17:17:01 -0700102 private static final Integer INPORT = 10;
Charles Chane6067892016-11-17 10:23:46 -0800103 private static final Integer INPORT2 = 11;
alshabib4a179dc2014-10-17 17:17:01 -0700104 private static final String DEV1 = "of:1";
105 private static final String DEV2 = "of:2";
106 private static final String DEV3 = "of:3";
Charles Chan5d5e0622015-09-25 13:00:06 -0700107 private static final String DEV4 = "of:4";
108 private static final String DEV5 = "of:5";
109 private static final String DEV6 = "of:6";
alshabib4a179dc2014-10-17 17:17:01 -0700110
Thomas Vachuska33601602014-11-19 03:32:15 -0800111 private static final VlanId VLAN = vlanId();
Charles Chan5d5e0622015-09-25 13:00:06 -0700112
113 // IPv4 Host
alshabib4a179dc2014-10-17 17:17:01 -0700114 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
115 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
116 private static final byte[] IP = new byte[]{10, 0, 0, 1};
Thomas Vachuska33601602014-11-19 03:32:15 -0800117 private static final IpAddress IP_ADDRESS =
118 IpAddress.valueOf(IpAddress.Version.INET, IP);
119 private static final HostLocation LOCATION =
120 new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
Thomas Vachuska33601602014-11-19 03:32:15 -0800121 private static final DefaultHost HOST =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800122 new DefaultHost(PROVIDER_ID, hostId(MAC), MAC,
Charles Chane6067892016-11-17 10:23:46 -0800123 VLAN, LOCATION,
124 ImmutableSet.of(IP_ADDRESS));
Thomas Vachuska33601602014-11-19 03:32:15 -0800125
Charles Chan5d5e0622015-09-25 13:00:06 -0700126 // IPv6 Host
127 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
128 private static final MacAddress BCMAC2 = MacAddress.valueOf("33:33:00:00:00:01");
129 private static final byte[] IP2 = Ip6Address.valueOf("1000::1").toOctets();
130 private static final IpAddress IP_ADDRESS2 =
131 IpAddress.valueOf(IpAddress.Version.INET6, IP2);
132 private static final HostLocation LOCATION2 =
133 new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
134 private static final DefaultHost HOST2 =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800135 new DefaultHost(PROVIDER_ID, hostId(MAC2), MAC2,
Charles Chane6067892016-11-17 10:23:46 -0800136 VLAN, LOCATION2,
137 ImmutableSet.of(IP_ADDRESS2));
138
139 // DHCP Server
140 private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03");
141 private static final byte[] IP3 = new byte[]{10, 0, 0, 2};
142 private static final IpAddress IP_ADDRESS3 =
143 IpAddress.valueOf(IpAddress.Version.INET, IP3);
144
145 private static final HostLocation LOCATION3 =
146 new HostLocation(deviceId(DEV1), portNumber(INPORT2), 0L);
147 private static final DefaultHost HOST3 =
148 new DefaultHost(PROVIDER_ID, hostId(MAC3), MAC3,
149 VLAN, LOCATION3,
150 ImmutableSet.of(IP_ADDRESS3));
Charles Chan5d5e0622015-09-25 13:00:06 -0700151
Thomas Vachuska33601602014-11-19 03:32:15 -0800152 private static final ComponentContextAdapter CTX_FOR_REMOVE =
153 new ComponentContextAdapter() {
154 @Override
155 public Dictionary getProperties() {
156 Hashtable<String, String> props = new Hashtable<>();
157 props.put("hostRemovalEnabled", "true");
158 return props;
159 }
160 };
161
162 public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
163 new ComponentContextAdapter() {
164 @Override
165 public Dictionary getProperties() {
166 return new Hashtable();
167 }
168 };
169
alshabib4a179dc2014-10-17 17:17:01 -0700170 private final HostLocationProvider provider = new HostLocationProvider();
Thomas Vachuska33601602014-11-19 03:32:15 -0800171 private final TestHostRegistry hostRegistry = new TestHostRegistry();
alshabib4a179dc2014-10-17 17:17:01 -0700172 private final TestTopologyService topoService = new TestTopologyService();
Thomas Vachuska33601602014-11-19 03:32:15 -0800173 private final TestDeviceService deviceService = new TestDeviceService();
174 private final TestHostService hostService = new TestHostService();
alshabib4a179dc2014-10-17 17:17:01 -0700175 private final TestPacketService packetService = new TestPacketService();
176
177 private PacketProcessor testProcessor;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800178 private CoreService coreService;
alshabib4a179dc2014-10-17 17:17:01 -0700179 private TestHostProviderService providerService;
180
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800181 private ApplicationId appId =
182 new DefaultApplicationId(100, "org.onosproject.provider.host");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800183
alshabib4a179dc2014-10-17 17:17:01 -0700184 @Before
185 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800186
187 coreService = createMock(CoreService.class);
188 expect(coreService.registerApplication(appId.name()))
Thomas Vachuska27bee092015-06-23 19:03:10 -0700189 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800190 replay(coreService);
191
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700192 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800193 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800194
Thomas Vachuska33601602014-11-19 03:32:15 -0800195 provider.providerRegistry = hostRegistry;
alshabib4a179dc2014-10-17 17:17:01 -0700196 provider.topologyService = topoService;
Pavlin Radoslavovd6612f92015-02-23 13:53:32 -0800197 provider.packetService = packetService;
Thomas Vachuska33601602014-11-19 03:32:15 -0800198 provider.deviceService = deviceService;
199 provider.hostService = hostService;
alshabib4a179dc2014-10-17 17:17:01 -0700200
Thomas Vachuska33601602014-11-19 03:32:15 -0800201 provider.activate(CTX_FOR_NO_REMOVE);
Madan Jampania3770c32015-12-11 12:07:41 -0800202
203 provider.eventHandler = MoreExecutors.newDirectExecutorService();
alshabib4a179dc2014-10-17 17:17:01 -0700204 }
205
206 @Test
207 public void basics() {
208 assertNotNull("registration expected", providerService);
209 assertEquals("incorrect provider", provider, providerService.provider());
210 }
211
212 @Test
213 public void events() {
Charles Chan420e7372016-11-17 10:58:17 -0800214 // New host. Expect one additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700215 testProcessor.process(new TestArpPacketContext(DEV1));
Charles Chan420e7372016-11-17 10:58:17 -0800216 assertThat("New host expected", providerService.descriptions.size(), is(1));
alshabib4a179dc2014-10-17 17:17:01 -0700217
Charles Chan420e7372016-11-17 10:58:17 -0800218 // The host moved to new switch. Expect one additional host description.
219 // The second host description should have a different location.
Charles Chan5d5e0622015-09-25 13:00:06 -0700220 testProcessor.process(new TestArpPacketContext(DEV2));
Charles Chan420e7372016-11-17 10:58:17 -0800221 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
222 HostLocation loc1 = providerService.descriptions.get(0).location();
223 HostLocation loc2 = providerService.descriptions.get(1).location();
224 assertNotEquals("Host location should be different", loc1, loc2);
alshabib4a179dc2014-10-17 17:17:01 -0700225
Charles Chan420e7372016-11-17 10:58:17 -0800226 // The host was misheard on a spine. Expect no additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700227 testProcessor.process(new TestArpPacketContext(DEV3));
Charles Chan420e7372016-11-17 10:58:17 -0800228 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700229
230 providerService.clear();
231
Charles Chan420e7372016-11-17 10:58:17 -0800232 // New host. Expect one additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800233 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800234 assertThat("New host expected", providerService.descriptions.size(), is(1));
Charles Chan5d5e0622015-09-25 13:00:06 -0700235
Charles Chan420e7372016-11-17 10:58:17 -0800236 // The host moved to new switch. Expect one additional host description.
237 // The second host description should have a different location.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800238 testProcessor.process(new TestNaPacketContext(DEV5));
Charles Chan420e7372016-11-17 10:58:17 -0800239 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
240 loc1 = providerService.descriptions.get(0).location();
241 loc2 = providerService.descriptions.get(1).location();
242 assertNotEquals("Host location should be different", loc1, loc2);
Charles Chan5d5e0622015-09-25 13:00:06 -0700243
Charles Chan420e7372016-11-17 10:58:17 -0800244 // The host was misheard on a spine. Expect no additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800245 testProcessor.process(new TestNaPacketContext(DEV6));
Charles Chan420e7372016-11-17 10:58:17 -0800246 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
alshabib4a179dc2014-10-17 17:17:01 -0700247 }
248
Thomas Vachuska33601602014-11-19 03:32:15 -0800249 @Test
250 public void removeHostByDeviceRemove() {
251 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700252 testProcessor.process(new TestArpPacketContext(DEV1));
Jonathan Hartb35540a2015-11-17 09:30:56 -0800253 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan5d5e0622015-09-25 13:00:06 -0700254
Thomas Vachuska33601602014-11-19 03:32:15 -0800255 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
256 "m", "h", "s", "n", new ChassisId(0L));
257 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700258 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700259
260 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
261 "m", "h", "s", "n", new ChassisId(0L));
262 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700263 assertEquals("incorrect remove count", 3, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800264 }
265
266 @Test
267 public void removeHostByDeviceOffline() {
268 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700269 testProcessor.process(new TestArpPacketContext(DEV1));
270 testProcessor.process(new TestArpPacketContext(DEV4));
271
Thomas Vachuska33601602014-11-19 03:32:15 -0800272 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
273 "m", "h", "s", "n", new ChassisId(0L));
274 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700275 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700276
277 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
278 "m", "h", "s", "n", new ChassisId(0L));
279 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700280 assertEquals("incorrect remove count", 3, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800281 }
282
283 @Test
284 public void removeHostByDevicePortDown() {
285 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700286 testProcessor.process(new TestArpPacketContext(DEV1));
287 testProcessor.process(new TestArpPacketContext(DEV4));
288
Thomas Vachuska33601602014-11-19 03:32:15 -0800289 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
290 "m", "h", "s", "n", new ChassisId(0L));
291 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
Charles Chan5d5e0622015-09-25 13:00:06 -0700292 new DefaultPort(device, portNumber(INPORT), false)));
Charles Chan888e20a2017-05-01 15:44:23 -0700293 assertEquals("incorrect remove count", 1, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700294
295 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
296 "m", "h", "s", "n", new ChassisId(0L));
297 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
298 new DefaultPort(device, portNumber(INPORT), false)));
Charles Chan888e20a2017-05-01 15:44:23 -0700299 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800300 }
301
Charles Chan5d5e0622015-09-25 13:00:06 -0700302 /**
303 * When receiving ARP, updates location and IP.
304 */
305 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300306 public void receiveArp() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700307 testProcessor.process(new TestArpPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300308 assertThat("receiveArp. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800309 providerService.descriptions.size(), is(1));
310 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700311 assertThat(descr.location(), is(LOCATION));
312 assertThat(descr.hwAddress(), is(MAC));
313 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS));
314 assertThat(descr.vlan(), is(VLAN));
315 }
316
317 /**
318 * When receiving IPv4, updates location only.
319 */
320 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300321 public void receiveIpv4() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700322 testProcessor.process(new TestIpv4PacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300323 assertThat("receiveIpv4. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800324 providerService.descriptions.size(), is(1));
325 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700326 assertThat(descr.location(), is(LOCATION));
327 assertThat(descr.hwAddress(), is(MAC));
328 assertThat(descr.ipAddress().size(), is(0));
329 assertThat(descr.vlan(), is(VLAN));
330 }
331
332 /**
Charles Chane6067892016-11-17 10:23:46 -0800333 * When receiving DHCP REQUEST, update MAC, location of client.
334 * When receiving DHCP ACK, update MAC, location of server and IP of client.
335 */
336 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300337 public void receiveDhcp() {
Charles Chane6067892016-11-17 10:23:46 -0800338 // DHCP Request
339 testProcessor.process(new TestDhcpRequestPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300340 assertThat("receiveDhcpRequest. One host description expected",
Charles Chane6067892016-11-17 10:23:46 -0800341 providerService.descriptions.size(), is(1));
342 // Should learn the MAC and location of DHCP client
343 HostDescription descr = providerService.descriptions.get(0);
344 assertThat(descr.location(), is(LOCATION));
345 assertThat(descr.hwAddress(), is(MAC));
346 assertThat(descr.ipAddress().size(), is(0));
347 assertThat(descr.vlan(), is(VLAN));
348
349 // DHCP Ack
350 testProcessor.process(new TestDhcpAckPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300351 assertThat("receiveDhcpAck. Two additional host descriptions expected",
Charles Chane6067892016-11-17 10:23:46 -0800352 providerService.descriptions.size(), is(3));
353 // Should learn the IP of DHCP client
354 HostDescription descr2 = providerService.descriptions.get(1);
355 assertThat(descr2.location(), is(LOCATION));
356 assertThat(descr2.hwAddress(), is(MAC));
357 assertThat(descr2.ipAddress().size(), is(1));
358 assertTrue(descr2.ipAddress().contains(IP_ADDRESS));
359 assertThat(descr2.vlan(), is(VLAN));
360 // Should also learn the MAC, location of DHCP server
361 HostDescription descr3 = providerService.descriptions.get(2);
362 assertThat(descr3.location(), is(LOCATION3));
363 assertThat(descr3.hwAddress(), is(MAC3));
364 assertThat(descr3.ipAddress().size(), is(0));
365 assertThat(descr3.vlan(), is(VLAN));
366
367 }
368
369 /**
Charles Chan5d5e0622015-09-25 13:00:06 -0700370 * When receiving NeighborAdvertisement, updates location and IP.
371 */
372 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300373 public void receiveNa() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800374 testProcessor.process(new TestNaPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300375 assertThat("receiveNa. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800376 providerService.descriptions.size(), is(1));
377 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700378 assertThat(descr.location(), is(LOCATION2));
379 assertThat(descr.hwAddress(), is(MAC2));
380 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
381 assertThat(descr.vlan(), is(VLAN));
382 }
383
384 /**
385 * When receiving NeighborSolicitation, updates location and IP.
386 */
387 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300388 public void receiveNs() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800389 testProcessor.process(new TestNsPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300390 assertThat("receiveNs. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800391 providerService.descriptions.size(), is(1));
392 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700393 assertThat(descr.location(), is(LOCATION2));
394 assertThat(descr.hwAddress(), is(MAC2));
395 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
396 assertThat(descr.vlan(), is(VLAN));
397 }
398
399 /**
400 * When receiving RouterAdvertisement, ignores it.
401 */
402 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300403 public void receivesRa() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700404 testProcessor.process(new TestRAPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300405 assertThat("receivesRa. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800406 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700407 }
408
409 /**
410 * When receiving RouterSolicitation, ignores it.
411 */
412 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300413 public void receiveRs() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700414 testProcessor.process(new TestRSPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300415 assertThat("receiveRs. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800416 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700417 }
418
419 /**
420 * When receiving Duplicate Address Detection (DAD), ignores it.
421 */
422 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300423 public void receiveDad() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800424 testProcessor.process(new TestDadPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300425 assertThat("receiveDad. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800426 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700427 }
428
429 /**
430 * When receiving IPv6 multicast packet, ignores it.
431 */
432 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300433 public void receiveIpv6Multicast() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700434 testProcessor.process(new TestIpv6McastPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300435 assertThat("receiveIpv6Multicast. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800436 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700437 }
438
439 /**
440 * When receiving IPv6 unicast packet, updates location only.
441 */
442 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300443 public void receiveIpv6Unicast() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700444 testProcessor.process(new TestIpv6PacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300445 assertThat("receiveIpv6Unicast. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800446 providerService.descriptions.size(), is(1));
447 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700448 assertThat(descr.location(), is(LOCATION2));
449 assertThat(descr.hwAddress(), is(MAC2));
450 assertThat(descr.ipAddress().size(), is(0));
451 assertThat(descr.vlan(), is(VLAN));
452 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800453
alshabib4a179dc2014-10-17 17:17:01 -0700454 @After
455 public void tearDown() {
456 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800457 provider.coreService = null;
alshabib4a179dc2014-10-17 17:17:01 -0700458 provider.providerRegistry = null;
alshabib4a179dc2014-10-17 17:17:01 -0700459 }
460
461 private class TestHostRegistry implements HostProviderRegistry {
462
463 @Override
464 public HostProviderService register(HostProvider provider) {
465 providerService = new TestHostProviderService(provider);
466 return providerService;
467 }
468
469 @Override
470 public void unregister(HostProvider provider) {
471 }
472
473 @Override
474 public Set<ProviderId> getProviders() {
475 return null;
476 }
477
478 }
479
480 private class TestHostProviderService
481 extends AbstractProviderService<HostProvider>
482 implements HostProviderService {
483
Charles Chan420e7372016-11-17 10:58:17 -0800484 List<HostDescription> descriptions = Lists.newArrayList();
Charles Chan888e20a2017-05-01 15:44:23 -0700485 int hostRemoveCount;
486 int ipRemoveCount;
487 int locationRemoveCount;
alshabib4a179dc2014-10-17 17:17:01 -0700488
Charles Chan5d5e0622015-09-25 13:00:06 -0700489 public void clear() {
Charles Chan420e7372016-11-17 10:58:17 -0800490 descriptions.clear();
Charles Chan888e20a2017-05-01 15:44:23 -0700491 hostRemoveCount = 0;
492 ipRemoveCount = 0;
493 locationRemoveCount = 0;
Charles Chan5d5e0622015-09-25 13:00:06 -0700494 }
495
alshabib4a179dc2014-10-17 17:17:01 -0700496 protected TestHostProviderService(HostProvider provider) {
497 super(provider);
498 }
499
500 @Override
Brian O'Connorf107bd72015-09-21 15:31:03 -0700501 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
Charles Chan420e7372016-11-17 10:58:17 -0800502 descriptions.add(hostDescription);
alshabib4a179dc2014-10-17 17:17:01 -0700503 }
504
505 @Override
506 public void hostVanished(HostId hostId) {
Charles Chan888e20a2017-05-01 15:44:23 -0700507 hostRemoveCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700508 }
509
samanwita palc40e5ed2015-09-24 11:01:51 -0700510 @Override
511 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
Charles Chan888e20a2017-05-01 15:44:23 -0700512 ipRemoveCount++;
513 }
514
515 @Override
516 public void removeLocationFromHost(HostId hostId, HostLocation location) {
517 locationRemoveCount++;
samanwita palc40e5ed2015-09-24 11:01:51 -0700518 }
519
alshabib4a179dc2014-10-17 17:17:01 -0700520 }
521
Thomas Vachuska27bee092015-06-23 19:03:10 -0700522 private class TestPacketService extends PacketServiceAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700523 @Override
524 public void addProcessor(PacketProcessor processor, int priority) {
525 testProcessor = processor;
526 }
alshabib4a179dc2014-10-17 17:17:01 -0700527 }
528
alshabib4a179dc2014-10-17 17:17:01 -0700529 private class TestTopologyService extends TopologyServiceAdapter {
530 @Override
531 public boolean isInfrastructure(Topology topology,
532 ConnectPoint connectPoint) {
533 //simulate DPID3 as an infrastructure switch
Charles Chan5d5e0622015-09-25 13:00:06 -0700534 if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
535 connectPoint.deviceId().equals(deviceId(DEV6))) {
alshabib4a179dc2014-10-17 17:17:01 -0700536 return true;
537 }
538 return false;
539 }
540 }
541
Charles Chan5d5e0622015-09-25 13:00:06 -0700542 /**
543 * Generates ARP packet.
544 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300545 private class TestArpPacketContext extends PacketContextAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700546 private final String deviceId;
547
Charles Chan5d5e0622015-09-25 13:00:06 -0700548 public TestArpPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300549 super(0, null, null, false);
alshabib4a179dc2014-10-17 17:17:01 -0700550 this.deviceId = deviceId;
551 }
552
553 @Override
alshabib4a179dc2014-10-17 17:17:01 -0700554 public InboundPacket inPacket() {
555 ARP arp = new ARP();
556 arp.setSenderProtocolAddress(IP)
557 .setSenderHardwareAddress(MAC.toBytes())
558 .setTargetHardwareAddress(BCMAC.toBytes())
559 .setTargetProtocolAddress(IP);
560
561 Ethernet eth = new Ethernet();
562 eth.setEtherType(Ethernet.TYPE_ARP)
563 .setVlanID(VLAN.toShort())
564 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800565 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700566 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800567 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
568 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700569 return new DefaultInboundPacket(receivedFrom, eth,
570 ByteBuffer.wrap(eth.serialize()));
571 }
alshabib4a179dc2014-10-17 17:17:01 -0700572 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800573
Charles Chan5d5e0622015-09-25 13:00:06 -0700574 /**
Charles Chane6067892016-11-17 10:23:46 -0800575 * Generates IPv4 Unicast packet.
Charles Chan5d5e0622015-09-25 13:00:06 -0700576 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300577 private class TestIpv4PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700578 private final String deviceId;
579
580 public TestIpv4PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300581 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700582 this.deviceId = deviceId;
583 }
584
585 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700586 public InboundPacket inPacket() {
587 IPv4 ipv4 = new IPv4();
588 ipv4.setDestinationAddress("10.0.0.1");
589 ipv4.setSourceAddress(IP_ADDRESS.toString());
590 Ethernet eth = new Ethernet();
591 eth.setEtherType(Ethernet.TYPE_IPV4)
592 .setVlanID(VLAN.toShort())
593 .setSourceMACAddress(MAC)
594 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
595 .setPayload(ipv4);
596 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
597 portNumber(INPORT));
598 return new DefaultInboundPacket(receivedFrom, eth,
599 ByteBuffer.wrap(eth.serialize()));
600 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700601 }
Charles Chane6067892016-11-17 10:23:46 -0800602 /**
603 * Generates DHCP REQUEST packet.
604 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300605 private class TestDhcpRequestPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800606 private final String deviceId;
607
608 public TestDhcpRequestPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300609 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800610 this.deviceId = deviceId;
611 }
612
613 @Override
Charles Chane6067892016-11-17 10:23:46 -0800614 public InboundPacket inPacket() {
615 byte[] dhcpMsgType = new byte[1];
Yi Tsengc7403c22017-06-19 16:23:22 -0700616 dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPREQUEST.getValue();
Charles Chane6067892016-11-17 10:23:46 -0800617
Yi Tsengc7403c22017-06-19 16:23:22 -0700618 DhcpOption dhcpOption = new DhcpOption();
Charles Chane6067892016-11-17 10:23:46 -0800619 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
620 dhcpOption.setData(dhcpMsgType);
621 dhcpOption.setLength((byte) 1);
622 DHCP dhcp = new DHCP();
623 dhcp.setOptions(Collections.singletonList(dhcpOption));
624 dhcp.setClientHardwareAddress(MAC.toBytes());
625 UDP udp = new UDP();
626 udp.setPayload(dhcp);
627 udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
628 udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
629 IPv4 ipv4 = new IPv4();
630 ipv4.setPayload(udp);
631 ipv4.setDestinationAddress(IP_ADDRESS3.toString());
632 ipv4.setSourceAddress(IP_ADDRESS.toString());
633 Ethernet eth = new Ethernet();
634 eth.setEtherType(Ethernet.TYPE_IPV4)
635 .setVlanID(VLAN.toShort())
636 .setSourceMACAddress(MAC)
637 .setDestinationMACAddress(MAC3)
638 .setPayload(ipv4);
639 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
640 portNumber(INPORT));
641 return new DefaultInboundPacket(receivedFrom, eth,
642 ByteBuffer.wrap(eth.serialize()));
643 }
Charles Chane6067892016-11-17 10:23:46 -0800644 }
645
646 /**
647 * Generates DHCP ACK packet.
648 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300649 private class TestDhcpAckPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800650 private final String deviceId;
651
652 public TestDhcpAckPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300653 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800654 this.deviceId = deviceId;
655 }
656
657 @Override
Charles Chane6067892016-11-17 10:23:46 -0800658 public InboundPacket inPacket() {
659 byte[] dhcpMsgType = new byte[1];
Yi Tsengc7403c22017-06-19 16:23:22 -0700660 dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPACK.getValue();
Charles Chane6067892016-11-17 10:23:46 -0800661
Yi Tsengc7403c22017-06-19 16:23:22 -0700662 DhcpOption dhcpOption = new DhcpOption();
Charles Chane6067892016-11-17 10:23:46 -0800663 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
664 dhcpOption.setData(dhcpMsgType);
665 dhcpOption.setLength((byte) 1);
666 DHCP dhcp = new DHCP();
667 dhcp.setOptions(Collections.singletonList(dhcpOption));
668 dhcp.setClientHardwareAddress(MAC.toBytes());
669 dhcp.setYourIPAddress(IP_ADDRESS.getIp4Address().toInt());
670 UDP udp = new UDP();
671 udp.setPayload(dhcp);
672 udp.setSourcePort(UDP.DHCP_SERVER_PORT);
673 udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
674 IPv4 ipv4 = new IPv4();
675 ipv4.setPayload(udp);
676 ipv4.setDestinationAddress(IP_ADDRESS.toString());
677 ipv4.setSourceAddress(IP_ADDRESS3.toString());
678 Ethernet eth = new Ethernet();
679 eth.setEtherType(Ethernet.TYPE_IPV4)
680 .setVlanID(VLAN.toShort())
681 .setSourceMACAddress(MAC3)
682 .setDestinationMACAddress(MAC)
683 .setPayload(ipv4);
684 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
685 portNumber(INPORT2));
686 return new DefaultInboundPacket(receivedFrom, eth,
687 ByteBuffer.wrap(eth.serialize()));
688 }
Charles Chane6067892016-11-17 10:23:46 -0800689 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700690
691 /**
692 * Generates NeighborAdvertisement packet.
693 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300694 private class TestNaPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700695 private final String deviceId;
696
Jonathan Hartb35540a2015-11-17 09:30:56 -0800697 public TestNaPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300698 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700699 this.deviceId = deviceId;
700 }
701
702 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700703 public InboundPacket inPacket() {
704 NeighborAdvertisement na = new NeighborAdvertisement();
705 ICMP6 icmp6 = new ICMP6();
706 icmp6.setPayload(na);
707 IPv6 ipv6 = new IPv6();
708 ipv6.setPayload(icmp6);
709 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
710 ipv6.setSourceAddress(IP2);
711 Ethernet eth = new Ethernet();
712 eth.setEtherType(Ethernet.TYPE_IPV6)
713 .setVlanID(VLAN.toShort())
714 .setSourceMACAddress(MAC2.toBytes())
715 .setDestinationMACAddress(BCMAC2)
716 .setPayload(ipv6);
717 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
718 portNumber(INPORT));
719 return new DefaultInboundPacket(receivedFrom, eth,
720 ByteBuffer.wrap(eth.serialize()));
721 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700722 }
723
724 /**
725 * Generates NeighborSolicitation packet.
726 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300727 private class TestNsPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700728 private final String deviceId;
729
Jonathan Hartb35540a2015-11-17 09:30:56 -0800730 public TestNsPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300731 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700732 this.deviceId = deviceId;
733 }
734
735 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700736 public InboundPacket inPacket() {
737 NeighborSolicitation ns = new NeighborSolicitation();
738 ICMP6 icmp6 = new ICMP6();
739 icmp6.setPayload(ns);
740 IPv6 ipv6 = new IPv6();
741 ipv6.setPayload(icmp6);
742 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
743 ipv6.setSourceAddress(IP2);
744 Ethernet eth = new Ethernet();
745 eth.setEtherType(Ethernet.TYPE_IPV6)
746 .setVlanID(VLAN.toShort())
747 .setSourceMACAddress(MAC2.toBytes())
748 .setDestinationMACAddress(BCMAC2)
749 .setPayload(ipv6);
750 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
751 portNumber(INPORT));
752 return new DefaultInboundPacket(receivedFrom, eth,
753 ByteBuffer.wrap(eth.serialize()));
754 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700755 }
756
757 /**
758 * Generates Duplicate Address Detection packet.
759 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300760 private class TestDadPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700761 private final String deviceId;
762
Jonathan Hartb35540a2015-11-17 09:30:56 -0800763 public TestDadPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300764 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700765 this.deviceId = deviceId;
766 }
767
768 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700769 public InboundPacket inPacket() {
770 NeighborSolicitation ns = new NeighborSolicitation();
771 ICMP6 icmp6 = new ICMP6();
772 icmp6.setPayload(ns);
773 IPv6 ipv6 = new IPv6();
774 ipv6.setPayload(icmp6);
775 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
776 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
777 Ethernet eth = new Ethernet();
778 eth.setEtherType(Ethernet.TYPE_IPV6)
779 .setVlanID(VLAN.toShort())
780 .setSourceMACAddress(MAC2.toBytes())
781 .setDestinationMACAddress(BCMAC2)
782 .setPayload(ipv6);
783 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
784 portNumber(INPORT));
785 return new DefaultInboundPacket(receivedFrom, eth,
786 ByteBuffer.wrap(eth.serialize()));
787 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700788 }
789
790 /**
791 * Generates Router Solicitation packet.
792 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300793 private class TestRSPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700794 private final String deviceId;
795
796 public TestRSPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300797 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700798 this.deviceId = deviceId;
799 }
800
801 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700802 public InboundPacket inPacket() {
803 RouterSolicitation ns = new RouterSolicitation();
804 ICMP6 icmp6 = new ICMP6();
805 icmp6.setPayload(ns);
806 IPv6 ipv6 = new IPv6();
807 ipv6.setPayload(icmp6);
808 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
809 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
810 Ethernet eth = new Ethernet();
811 eth.setEtherType(Ethernet.TYPE_IPV6)
812 .setVlanID(VLAN.toShort())
813 .setSourceMACAddress(MAC2.toBytes())
814 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
815 .setPayload(ipv6);
816 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
817 portNumber(INPORT));
818 return new DefaultInboundPacket(receivedFrom, eth,
819 ByteBuffer.wrap(eth.serialize()));
820 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700821 }
822
823 /**
824 * Generates Router Advertisement packet.
825 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300826 private class TestRAPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700827 private final String deviceId;
828
829 public TestRAPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300830 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700831 this.deviceId = deviceId;
832 }
833
834 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700835 public InboundPacket inPacket() {
836 RouterAdvertisement ns = new RouterAdvertisement();
837 ICMP6 icmp6 = new ICMP6();
838 icmp6.setPayload(ns);
839 IPv6 ipv6 = new IPv6();
840 ipv6.setPayload(icmp6);
841 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
842 ipv6.setSourceAddress(IP2);
843 Ethernet eth = new Ethernet();
844 eth.setEtherType(Ethernet.TYPE_IPV6)
845 .setVlanID(VLAN.toShort())
846 .setSourceMACAddress(MAC2.toBytes())
847 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
848 .setPayload(ipv6);
849 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
850 portNumber(INPORT));
851 return new DefaultInboundPacket(receivedFrom, eth,
852 ByteBuffer.wrap(eth.serialize()));
853 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700854 }
855
856 /**
857 * Generates IPv6 Multicast packet.
858 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300859 private class TestIpv6McastPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700860 private final String deviceId;
861
862 public TestIpv6McastPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300863 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700864 this.deviceId = deviceId;
865 }
866
867 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700868 public InboundPacket inPacket() {
869 IPv6 ipv6 = new IPv6();
870 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
871 ipv6.setSourceAddress(IP2);
872 Ethernet eth = new Ethernet();
873 eth.setEtherType(Ethernet.TYPE_IPV6)
874 .setVlanID(VLAN.toShort())
875 .setSourceMACAddress(MAC2.toBytes())
876 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
877 .setPayload(ipv6);
878 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
879 portNumber(INPORT));
880 return new DefaultInboundPacket(receivedFrom, eth,
881 ByteBuffer.wrap(eth.serialize()));
882 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700883 }
884
885 /**
886 * Generates IPv6 Unicast packet.
887 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300888 private class TestIpv6PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700889 private final String deviceId;
890
891 public TestIpv6PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300892 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700893 this.deviceId = deviceId;
894 }
895
896 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700897 public InboundPacket inPacket() {
898 IPv6 ipv6 = new IPv6();
899 ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
900 ipv6.setSourceAddress(IP2);
901 Ethernet eth = new Ethernet();
902 eth.setEtherType(Ethernet.TYPE_IPV6)
903 .setVlanID(VLAN.toShort())
904 .setSourceMACAddress(MAC2)
905 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
906 .setPayload(ipv6);
907 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
908 portNumber(INPORT));
909 return new DefaultInboundPacket(receivedFrom, eth,
910 ByteBuffer.wrap(eth.serialize()));
911 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700912 }
913
Thomas Vachuska33601602014-11-19 03:32:15 -0800914 private class TestDeviceService extends DeviceServiceAdapter {
915 private DeviceListener listener;
916
917 @Override
918 public void addListener(DeviceListener listener) {
919 this.listener = listener;
920 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800921
922 @Override
923 public Iterable<Device> getDevices() {
924 return Collections.emptyList();
925 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800926 }
927
928 private class TestHostService extends HostServiceAdapter {
929 @Override
930 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700931 ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
932 ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
Charles Chane6067892016-11-17 10:23:46 -0800933 ConnectPoint cp3 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700934 if (connectPoint.equals(cp1)) {
935 return ImmutableSet.of(HOST);
936 } else if (connectPoint.equals(cp2)) {
937 return ImmutableSet.of(HOST2);
Charles Chane6067892016-11-17 10:23:46 -0800938 } else if (connectPoint.equals(cp3)) {
939 return ImmutableSet.of(HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700940 } else {
941 return ImmutableSet.of();
942 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800943 }
944
945 @Override
946 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700947 if (deviceId.equals(deviceId(DEV1))) {
Charles Chane6067892016-11-17 10:23:46 -0800948 return ImmutableSet.of(HOST, HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700949 } else if (deviceId.equals(deviceId(DEV4))) {
950 return ImmutableSet.of(HOST2);
951 } else {
952 return ImmutableSet.of();
953 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800954 }
955
Charles Chane6067892016-11-17 10:23:46 -0800956 @Override
957 public Host getHost(HostId hostId) {
958 if (hostId.equals(HostId.hostId(MAC, VLAN))) {
959 return HOST;
960 } else if (hostId.equals(HostId.hostId(MAC2, VLAN))) {
961 return HOST2;
962 } else if (hostId.equals(HostId.hostId(MAC3, VLAN))) {
963 return HOST3;
964 }
965 return null;
966 }
967
Thomas Vachuska33601602014-11-19 03:32:15 -0800968 }
alshabib4a179dc2014-10-17 17:17:01 -0700969}