blob: 080e0e43258e4fc66fbc6fafd6ba91a022c64079 [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
Yi Tseng7a38f9a2017-06-09 14:36:40 -070018import com.google.common.collect.ImmutableList;
Thomas Vachuska27bee092015-06-23 19:03:10 -070019import com.google.common.collect.ImmutableSet;
Charles Chan420e7372016-11-17 10:58:17 -080020import com.google.common.collect.Lists;
Madan Jampania3770c32015-12-11 12:07:41 -080021import com.google.common.util.concurrent.MoreExecutors;
alshabib4a179dc2014-10-17 17:17:01 -070022import org.junit.After;
23import org.junit.Before;
24import org.junit.Test;
Yi Tseng7a38f9a2017-06-09 14:36:40 -070025import org.onlab.junit.TestUtils;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080026import org.onlab.osgi.ComponentContextAdapter;
27import org.onlab.packet.ARP;
28import org.onlab.packet.ChassisId;
Charles Chane6067892016-11-17 10:23:46 -080029import org.onlab.packet.DHCP;
Yi Tseng7a38f9a2017-06-09 14:36:40 -070030import org.onlab.packet.dhcp.CircuitId;
Yi Tsengc7403c22017-06-19 16:23:22 -070031import org.onlab.packet.dhcp.DhcpOption;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080032import org.onlab.packet.Ethernet;
Charles Chan5d5e0622015-09-25 13:00:06 -070033import org.onlab.packet.ICMP6;
34import org.onlab.packet.IPv4;
35import org.onlab.packet.IPv6;
36import org.onlab.packet.Ip6Address;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080037import org.onlab.packet.IpAddress;
38import org.onlab.packet.MacAddress;
Charles Chane6067892016-11-17 10:23:46 -080039import org.onlab.packet.UDP;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080040import org.onlab.packet.VlanId;
Yi Tseng7a38f9a2017-06-09 14:36:40 -070041import org.onlab.packet.dhcp.DhcpRelayAgentOption;
Charles Chan5d5e0622015-09-25 13:00:06 -070042import org.onlab.packet.ndp.NeighborAdvertisement;
43import org.onlab.packet.ndp.NeighborSolicitation;
44import org.onlab.packet.ndp.RouterAdvertisement;
45import org.onlab.packet.ndp.RouterSolicitation;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070046import org.onosproject.cfg.ComponentConfigAdapter;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080047import org.onosproject.core.ApplicationId;
48import org.onosproject.core.CoreService;
49import org.onosproject.core.DefaultApplicationId;
Yi Tseng7a38f9a2017-06-09 14:36:40 -070050import org.onosproject.incubator.net.intf.Interface;
51import org.onosproject.incubator.net.intf.InterfaceListener;
52import org.onosproject.incubator.net.intf.InterfaceService;
Brian O'Connorabafb502014-12-02 22:26:20 -080053import org.onosproject.net.ConnectPoint;
54import org.onosproject.net.DefaultDevice;
55import org.onosproject.net.DefaultHost;
56import org.onosproject.net.DefaultPort;
57import org.onosproject.net.Device;
58import org.onosproject.net.DeviceId;
59import org.onosproject.net.Host;
60import org.onosproject.net.HostId;
61import org.onosproject.net.HostLocation;
62import org.onosproject.net.device.DeviceEvent;
63import org.onosproject.net.device.DeviceListener;
64import org.onosproject.net.device.DeviceServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080065import org.onosproject.net.host.HostDescription;
66import org.onosproject.net.host.HostProvider;
67import org.onosproject.net.host.HostProviderRegistry;
68import org.onosproject.net.host.HostProviderService;
69import org.onosproject.net.host.HostServiceAdapter;
Yi Tseng7a38f9a2017-06-09 14:36:40 -070070import org.onosproject.net.host.InterfaceIpAddress;
Brian O'Connorabafb502014-12-02 22:26:20 -080071import org.onosproject.net.packet.DefaultInboundPacket;
72import org.onosproject.net.packet.InboundPacket;
Andrey Komarov2398d962016-09-26 15:11:23 +030073import org.onosproject.net.packet.PacketContextAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080074import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070075import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080076import org.onosproject.net.provider.AbstractProviderService;
77import org.onosproject.net.provider.ProviderId;
78import org.onosproject.net.topology.Topology;
79import org.onosproject.net.topology.TopologyServiceAdapter;
alshabib4a179dc2014-10-17 17:17:01 -070080
Thomas Vachuska27bee092015-06-23 19:03:10 -070081import java.nio.ByteBuffer;
82import java.util.Collections;
83import java.util.Dictionary;
84import java.util.Hashtable;
Charles Chan420e7372016-11-17 10:58:17 -080085import java.util.List;
Thomas Vachuska27bee092015-06-23 19:03:10 -070086import java.util.Set;
87
Michele Santuari72f6bee2016-11-18 12:56:30 +010088import static org.easymock.EasyMock.createMock;
89import static org.easymock.EasyMock.expect;
90import static org.easymock.EasyMock.replay;
Charles Chan5d5e0622015-09-25 13:00:06 -070091import static org.hamcrest.Matchers.is;
Michele Santuari72f6bee2016-11-18 12:56:30 +010092import static org.junit.Assert.assertEquals;
93import static org.junit.Assert.assertNotEquals;
94import static org.junit.Assert.assertNotNull;
95import static org.junit.Assert.assertThat;
Thomas Vachuska27bee092015-06-23 19:03:10 -070096import static org.onlab.packet.VlanId.vlanId;
97import static org.onosproject.net.Device.Type.SWITCH;
98import static org.onosproject.net.DeviceId.deviceId;
99import static org.onosproject.net.HostId.hostId;
100import static org.onosproject.net.PortNumber.portNumber;
Michele Santuari72f6bee2016-11-18 12:56:30 +0100101import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED;
102import static org.onosproject.net.device.DeviceEvent.Type.DEVICE_REMOVED;
103import static org.onosproject.net.device.DeviceEvent.Type.PORT_UPDATED;
Thomas Vachuska33601602014-11-19 03:32:15 -0800104
alshabib4a179dc2014-10-17 17:17:01 -0700105public class HostLocationProviderTest {
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800106 private static final ProviderId PROVIDER_ID =
107 new ProviderId("of", "org.onosproject.provider.host");
108
alshabib4a179dc2014-10-17 17:17:01 -0700109 private static final Integer INPORT = 10;
Charles Chane6067892016-11-17 10:23:46 -0800110 private static final Integer INPORT2 = 11;
alshabib4a179dc2014-10-17 17:17:01 -0700111 private static final String DEV1 = "of:1";
112 private static final String DEV2 = "of:2";
113 private static final String DEV3 = "of:3";
Charles Chan5d5e0622015-09-25 13:00:06 -0700114 private static final String DEV4 = "of:4";
115 private static final String DEV5 = "of:5";
116 private static final String DEV6 = "of:6";
alshabib4a179dc2014-10-17 17:17:01 -0700117
Thomas Vachuska33601602014-11-19 03:32:15 -0800118 private static final VlanId VLAN = vlanId();
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700119 private static final VlanId VLAN_100 = VlanId.vlanId("100");
Charles Chan5d5e0622015-09-25 13:00:06 -0700120
121 // IPv4 Host
alshabib4a179dc2014-10-17 17:17:01 -0700122 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
123 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
124 private static final byte[] IP = new byte[]{10, 0, 0, 1};
Thomas Vachuska33601602014-11-19 03:32:15 -0800125 private static final IpAddress IP_ADDRESS =
126 IpAddress.valueOf(IpAddress.Version.INET, IP);
127 private static final HostLocation LOCATION =
128 new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
Thomas Vachuska33601602014-11-19 03:32:15 -0800129 private static final DefaultHost HOST =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800130 new DefaultHost(PROVIDER_ID, hostId(MAC), MAC,
Charles Chane6067892016-11-17 10:23:46 -0800131 VLAN, LOCATION,
132 ImmutableSet.of(IP_ADDRESS));
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700133 private static final DefaultHost HOST_VLAN_100 =
134 new DefaultHost(PROVIDER_ID, hostId(MAC, VLAN_100), MAC,
135 VLAN_100, LOCATION,
136 ImmutableSet.of(IP_ADDRESS));
Thomas Vachuska33601602014-11-19 03:32:15 -0800137
Charles Chan5d5e0622015-09-25 13:00:06 -0700138 // IPv6 Host
139 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
140 private static final MacAddress BCMAC2 = MacAddress.valueOf("33:33:00:00:00:01");
141 private static final byte[] IP2 = Ip6Address.valueOf("1000::1").toOctets();
142 private static final IpAddress IP_ADDRESS2 =
143 IpAddress.valueOf(IpAddress.Version.INET6, IP2);
144 private static final HostLocation LOCATION2 =
145 new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
146 private static final DefaultHost HOST2 =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800147 new DefaultHost(PROVIDER_ID, hostId(MAC2), MAC2,
Charles Chane6067892016-11-17 10:23:46 -0800148 VLAN, LOCATION2,
149 ImmutableSet.of(IP_ADDRESS2));
150
151 // DHCP Server
152 private static final MacAddress MAC3 = MacAddress.valueOf("00:00:33:00:00:03");
153 private static final byte[] IP3 = new byte[]{10, 0, 0, 2};
154 private static final IpAddress IP_ADDRESS3 =
155 IpAddress.valueOf(IpAddress.Version.INET, IP3);
156
157 private static final HostLocation LOCATION3 =
158 new HostLocation(deviceId(DEV1), portNumber(INPORT2), 0L);
159 private static final DefaultHost HOST3 =
160 new DefaultHost(PROVIDER_ID, hostId(MAC3), MAC3,
161 VLAN, LOCATION3,
162 ImmutableSet.of(IP_ADDRESS3));
Charles Chan5d5e0622015-09-25 13:00:06 -0700163
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700164 // Gateway information for relay agent
165 private static final InterfaceIpAddress GW_IFACE_ADDR = InterfaceIpAddress.valueOf("10.0.1.1/32");
166 private static final Interface GW_IFACE = new Interface("gateway",
167 LOCATION,
168 ImmutableList.of(GW_IFACE_ADDR),
169 null,
170 VLAN_100);
171
Thomas Vachuska33601602014-11-19 03:32:15 -0800172 private static final ComponentContextAdapter CTX_FOR_REMOVE =
173 new ComponentContextAdapter() {
174 @Override
175 public Dictionary getProperties() {
176 Hashtable<String, String> props = new Hashtable<>();
177 props.put("hostRemovalEnabled", "true");
178 return props;
179 }
180 };
181
182 public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
183 new ComponentContextAdapter() {
184 @Override
185 public Dictionary getProperties() {
186 return new Hashtable();
187 }
188 };
189
alshabib4a179dc2014-10-17 17:17:01 -0700190 private final HostLocationProvider provider = new HostLocationProvider();
Thomas Vachuska33601602014-11-19 03:32:15 -0800191 private final TestHostRegistry hostRegistry = new TestHostRegistry();
alshabib4a179dc2014-10-17 17:17:01 -0700192 private final TestTopologyService topoService = new TestTopologyService();
Thomas Vachuska33601602014-11-19 03:32:15 -0800193 private final TestDeviceService deviceService = new TestDeviceService();
194 private final TestHostService hostService = new TestHostService();
alshabib4a179dc2014-10-17 17:17:01 -0700195 private final TestPacketService packetService = new TestPacketService();
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700196 private final TestInterfaceService interfaceService = new TestInterfaceService();
alshabib4a179dc2014-10-17 17:17:01 -0700197
198 private PacketProcessor testProcessor;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800199 private CoreService coreService;
alshabib4a179dc2014-10-17 17:17:01 -0700200 private TestHostProviderService providerService;
201
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800202 private ApplicationId appId =
203 new DefaultApplicationId(100, "org.onosproject.provider.host");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800204
alshabib4a179dc2014-10-17 17:17:01 -0700205 @Before
206 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800207 coreService = createMock(CoreService.class);
208 expect(coreService.registerApplication(appId.name()))
Thomas Vachuska27bee092015-06-23 19:03:10 -0700209 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800210 replay(coreService);
211
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700212 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800213 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800214
Thomas Vachuska33601602014-11-19 03:32:15 -0800215 provider.providerRegistry = hostRegistry;
alshabib4a179dc2014-10-17 17:17:01 -0700216 provider.topologyService = topoService;
Pavlin Radoslavovd6612f92015-02-23 13:53:32 -0800217 provider.packetService = packetService;
Thomas Vachuska33601602014-11-19 03:32:15 -0800218 provider.deviceService = deviceService;
219 provider.hostService = hostService;
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700220 provider.interfaceService = interfaceService;
alshabib4a179dc2014-10-17 17:17:01 -0700221
Thomas Vachuska33601602014-11-19 03:32:15 -0800222 provider.activate(CTX_FOR_NO_REMOVE);
Madan Jampania3770c32015-12-11 12:07:41 -0800223
224 provider.eventHandler = MoreExecutors.newDirectExecutorService();
alshabib4a179dc2014-10-17 17:17:01 -0700225 }
226
227 @Test
228 public void basics() {
229 assertNotNull("registration expected", providerService);
230 assertEquals("incorrect provider", provider, providerService.provider());
231 }
232
233 @Test
234 public void events() {
Charles Chan420e7372016-11-17 10:58:17 -0800235 // New host. Expect one additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700236 testProcessor.process(new TestArpPacketContext(DEV1));
Charles Chan420e7372016-11-17 10:58:17 -0800237 assertThat("New host expected", providerService.descriptions.size(), is(1));
alshabib4a179dc2014-10-17 17:17:01 -0700238
Charles Chan420e7372016-11-17 10:58:17 -0800239 // The host moved to new switch. Expect one additional host description.
240 // The second host description should have a different location.
Charles Chan5d5e0622015-09-25 13:00:06 -0700241 testProcessor.process(new TestArpPacketContext(DEV2));
Charles Chan420e7372016-11-17 10:58:17 -0800242 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
243 HostLocation loc1 = providerService.descriptions.get(0).location();
244 HostLocation loc2 = providerService.descriptions.get(1).location();
245 assertNotEquals("Host location should be different", loc1, loc2);
alshabib4a179dc2014-10-17 17:17:01 -0700246
Charles Chan420e7372016-11-17 10:58:17 -0800247 // The host was misheard on a spine. Expect no additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700248 testProcessor.process(new TestArpPacketContext(DEV3));
Charles Chan420e7372016-11-17 10:58:17 -0800249 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700250
251 providerService.clear();
252
Charles Chan420e7372016-11-17 10:58:17 -0800253 // New host. Expect one additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800254 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800255 assertThat("New host expected", providerService.descriptions.size(), is(1));
Charles Chan5d5e0622015-09-25 13:00:06 -0700256
Charles Chan420e7372016-11-17 10:58:17 -0800257 // The host moved to new switch. Expect one additional host description.
258 // The second host description should have a different location.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800259 testProcessor.process(new TestNaPacketContext(DEV5));
Charles Chan420e7372016-11-17 10:58:17 -0800260 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
261 loc1 = providerService.descriptions.get(0).location();
262 loc2 = providerService.descriptions.get(1).location();
263 assertNotEquals("Host location should be different", loc1, loc2);
Charles Chan5d5e0622015-09-25 13:00:06 -0700264
Charles Chan420e7372016-11-17 10:58:17 -0800265 // The host was misheard on a spine. Expect no additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800266 testProcessor.process(new TestNaPacketContext(DEV6));
Charles Chan420e7372016-11-17 10:58:17 -0800267 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
alshabib4a179dc2014-10-17 17:17:01 -0700268 }
269
Thomas Vachuska33601602014-11-19 03:32:15 -0800270 @Test
271 public void removeHostByDeviceRemove() {
272 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700273 testProcessor.process(new TestArpPacketContext(DEV1));
Jonathan Hartb35540a2015-11-17 09:30:56 -0800274 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan5d5e0622015-09-25 13:00:06 -0700275
Thomas Vachuska33601602014-11-19 03:32:15 -0800276 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
277 "m", "h", "s", "n", new ChassisId(0L));
278 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700279 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700280
281 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
282 "m", "h", "s", "n", new ChassisId(0L));
283 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700284 assertEquals("incorrect remove count", 3, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800285 }
286
287 @Test
288 public void removeHostByDeviceOffline() {
289 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700290 testProcessor.process(new TestArpPacketContext(DEV1));
291 testProcessor.process(new TestArpPacketContext(DEV4));
292
Thomas Vachuska33601602014-11-19 03:32:15 -0800293 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
294 "m", "h", "s", "n", new ChassisId(0L));
295 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700296 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700297
298 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
299 "m", "h", "s", "n", new ChassisId(0L));
300 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
Charles Chan888e20a2017-05-01 15:44:23 -0700301 assertEquals("incorrect remove count", 3, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800302 }
303
304 @Test
305 public void removeHostByDevicePortDown() {
306 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700307 testProcessor.process(new TestArpPacketContext(DEV1));
308 testProcessor.process(new TestArpPacketContext(DEV4));
309
Thomas Vachuska33601602014-11-19 03:32:15 -0800310 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
311 "m", "h", "s", "n", new ChassisId(0L));
312 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
Charles Chan5d5e0622015-09-25 13:00:06 -0700313 new DefaultPort(device, portNumber(INPORT), false)));
Charles Chan888e20a2017-05-01 15:44:23 -0700314 assertEquals("incorrect remove count", 1, providerService.locationRemoveCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700315
316 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
317 "m", "h", "s", "n", new ChassisId(0L));
318 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
319 new DefaultPort(device, portNumber(INPORT), false)));
Charles Chan888e20a2017-05-01 15:44:23 -0700320 assertEquals("incorrect remove count", 2, providerService.locationRemoveCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800321 }
322
Charles Chan5d5e0622015-09-25 13:00:06 -0700323 /**
324 * When receiving ARP, updates location and IP.
325 */
326 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300327 public void receiveArp() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700328 testProcessor.process(new TestArpPacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300329 assertThat("receiveArp. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800330 providerService.descriptions.size(), is(1));
331 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700332 assertThat(descr.location(), is(LOCATION));
333 assertThat(descr.hwAddress(), is(MAC));
334 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS));
335 assertThat(descr.vlan(), is(VLAN));
336 }
337
338 /**
339 * When receiving IPv4, updates location only.
340 */
341 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300342 public void receiveIpv4() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700343 testProcessor.process(new TestIpv4PacketContext(DEV1));
Andrey Komarov2398d962016-09-26 15:11:23 +0300344 assertThat("receiveIpv4. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800345 providerService.descriptions.size(), is(1));
346 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700347 assertThat(descr.location(), is(LOCATION));
348 assertThat(descr.hwAddress(), is(MAC));
349 assertThat(descr.ipAddress().size(), is(0));
350 assertThat(descr.vlan(), is(VLAN));
351 }
352
353 /**
Charles Chane6067892016-11-17 10:23:46 -0800354 * When receiving DHCP REQUEST, update MAC, location of client.
355 * When receiving DHCP ACK, update MAC, location of server and IP of client.
356 */
357 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300358 public void receiveDhcp() {
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700359 TestUtils.setField(provider, "useDhcp", true);
Charles Chane6067892016-11-17 10:23:46 -0800360 // DHCP Request
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700361 testProcessor.process(new TestDhcpRequestPacketContext(DEV1, VLAN));
Andrey Komarov2398d962016-09-26 15:11:23 +0300362 assertThat("receiveDhcpRequest. One host description expected",
Charles Chane6067892016-11-17 10:23:46 -0800363 providerService.descriptions.size(), is(1));
364 // Should learn the MAC and location of DHCP client
365 HostDescription descr = providerService.descriptions.get(0);
366 assertThat(descr.location(), is(LOCATION));
367 assertThat(descr.hwAddress(), is(MAC));
368 assertThat(descr.ipAddress().size(), is(0));
369 assertThat(descr.vlan(), is(VLAN));
370
371 // DHCP Ack
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700372 testProcessor.process(new TestDhcpAckPacketContext(DEV1, false));
Andrey Komarov2398d962016-09-26 15:11:23 +0300373 assertThat("receiveDhcpAck. Two additional host descriptions expected",
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700374 providerService.descriptions.size(), is(2));
Charles Chane6067892016-11-17 10:23:46 -0800375
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700376 // Should also learn the MAC, location of DHCP server
377 HostDescription descr2 = providerService.descriptions.get(1);
378 assertThat(descr2.location(), is(LOCATION3));
379 assertThat(descr2.hwAddress(), is(MAC3));
380 assertThat(descr2.ipAddress().size(), is(0));
381 assertThat(descr2.vlan(), is(VLAN));
382
383 // Should not update the IP address of the host.
384 }
385
386 /**
387 * The host store should not updated when we disabled "useDhcp".
388 */
389 @Test
390 public void receiveDhcpButNotEnabled() {
391 TestUtils.setField(provider, "useDhcp", false);
392 // DHCP Request
393 testProcessor.process(new TestDhcpRequestPacketContext(DEV1, VLAN));
394 assertThat("receiveDhcpButNotEnabled. No host description expected",
395 providerService.descriptions.size(), is(0));
Charles Chane6067892016-11-17 10:23:46 -0800396 }
397
398 /**
Charles Chan5d5e0622015-09-25 13:00:06 -0700399 * When receiving NeighborAdvertisement, updates location and IP.
400 */
401 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300402 public void receiveNa() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800403 testProcessor.process(new TestNaPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300404 assertThat("receiveNa. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800405 providerService.descriptions.size(), is(1));
406 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700407 assertThat(descr.location(), is(LOCATION2));
408 assertThat(descr.hwAddress(), is(MAC2));
409 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
410 assertThat(descr.vlan(), is(VLAN));
411 }
412
413 /**
414 * When receiving NeighborSolicitation, updates location and IP.
415 */
416 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300417 public void receiveNs() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800418 testProcessor.process(new TestNsPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300419 assertThat("receiveNs. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800420 providerService.descriptions.size(), is(1));
421 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700422 assertThat(descr.location(), is(LOCATION2));
423 assertThat(descr.hwAddress(), is(MAC2));
424 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
425 assertThat(descr.vlan(), is(VLAN));
426 }
427
428 /**
429 * When receiving RouterAdvertisement, ignores it.
430 */
431 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300432 public void receivesRa() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700433 testProcessor.process(new TestRAPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300434 assertThat("receivesRa. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800435 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700436 }
437
438 /**
439 * When receiving RouterSolicitation, ignores it.
440 */
441 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300442 public void receiveRs() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700443 testProcessor.process(new TestRSPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300444 assertThat("receiveRs. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800445 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700446 }
447
448 /**
449 * When receiving Duplicate Address Detection (DAD), ignores it.
450 */
451 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300452 public void receiveDad() {
Jonathan Hartb35540a2015-11-17 09:30:56 -0800453 testProcessor.process(new TestDadPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300454 assertThat("receiveDad. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800455 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700456 }
457
458 /**
459 * When receiving IPv6 multicast packet, ignores it.
460 */
461 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300462 public void receiveIpv6Multicast() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700463 testProcessor.process(new TestIpv6McastPacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300464 assertThat("receiveIpv6Multicast. No host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800465 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700466 }
467
468 /**
469 * When receiving IPv6 unicast packet, updates location only.
470 */
471 @Test
Andrey Komarov2398d962016-09-26 15:11:23 +0300472 public void receiveIpv6Unicast() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700473 testProcessor.process(new TestIpv6PacketContext(DEV4));
Andrey Komarov2398d962016-09-26 15:11:23 +0300474 assertThat("receiveIpv6Unicast. One host description expected",
Charles Chan420e7372016-11-17 10:58:17 -0800475 providerService.descriptions.size(), is(1));
476 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700477 assertThat(descr.location(), is(LOCATION2));
478 assertThat(descr.hwAddress(), is(MAC2));
479 assertThat(descr.ipAddress().size(), is(0));
480 assertThat(descr.vlan(), is(VLAN));
481 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800482
alshabib4a179dc2014-10-17 17:17:01 -0700483 @After
484 public void tearDown() {
485 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800486 provider.coreService = null;
alshabib4a179dc2014-10-17 17:17:01 -0700487 provider.providerRegistry = null;
alshabib4a179dc2014-10-17 17:17:01 -0700488 }
489
490 private class TestHostRegistry implements HostProviderRegistry {
491
492 @Override
493 public HostProviderService register(HostProvider provider) {
494 providerService = new TestHostProviderService(provider);
495 return providerService;
496 }
497
498 @Override
499 public void unregister(HostProvider provider) {
500 }
501
502 @Override
503 public Set<ProviderId> getProviders() {
504 return null;
505 }
506
507 }
508
509 private class TestHostProviderService
510 extends AbstractProviderService<HostProvider>
511 implements HostProviderService {
512
Charles Chan420e7372016-11-17 10:58:17 -0800513 List<HostDescription> descriptions = Lists.newArrayList();
Charles Chan888e20a2017-05-01 15:44:23 -0700514 int hostRemoveCount;
515 int ipRemoveCount;
516 int locationRemoveCount;
alshabib4a179dc2014-10-17 17:17:01 -0700517
Charles Chan5d5e0622015-09-25 13:00:06 -0700518 public void clear() {
Charles Chan420e7372016-11-17 10:58:17 -0800519 descriptions.clear();
Charles Chan888e20a2017-05-01 15:44:23 -0700520 hostRemoveCount = 0;
521 ipRemoveCount = 0;
522 locationRemoveCount = 0;
Charles Chan5d5e0622015-09-25 13:00:06 -0700523 }
524
alshabib4a179dc2014-10-17 17:17:01 -0700525 protected TestHostProviderService(HostProvider provider) {
526 super(provider);
527 }
528
529 @Override
Brian O'Connorf107bd72015-09-21 15:31:03 -0700530 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
Charles Chan420e7372016-11-17 10:58:17 -0800531 descriptions.add(hostDescription);
alshabib4a179dc2014-10-17 17:17:01 -0700532 }
533
534 @Override
535 public void hostVanished(HostId hostId) {
Charles Chan888e20a2017-05-01 15:44:23 -0700536 hostRemoveCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700537 }
538
samanwita palc40e5ed2015-09-24 11:01:51 -0700539 @Override
540 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
Charles Chan888e20a2017-05-01 15:44:23 -0700541 ipRemoveCount++;
542 }
543
544 @Override
545 public void removeLocationFromHost(HostId hostId, HostLocation location) {
546 locationRemoveCount++;
samanwita palc40e5ed2015-09-24 11:01:51 -0700547 }
548
alshabib4a179dc2014-10-17 17:17:01 -0700549 }
550
Thomas Vachuska27bee092015-06-23 19:03:10 -0700551 private class TestPacketService extends PacketServiceAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700552 @Override
553 public void addProcessor(PacketProcessor processor, int priority) {
554 testProcessor = processor;
555 }
alshabib4a179dc2014-10-17 17:17:01 -0700556 }
557
alshabib4a179dc2014-10-17 17:17:01 -0700558 private class TestTopologyService extends TopologyServiceAdapter {
559 @Override
560 public boolean isInfrastructure(Topology topology,
561 ConnectPoint connectPoint) {
562 //simulate DPID3 as an infrastructure switch
Charles Chan5d5e0622015-09-25 13:00:06 -0700563 if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
564 connectPoint.deviceId().equals(deviceId(DEV6))) {
alshabib4a179dc2014-10-17 17:17:01 -0700565 return true;
566 }
567 return false;
568 }
569 }
570
Charles Chan5d5e0622015-09-25 13:00:06 -0700571 /**
572 * Generates ARP packet.
573 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300574 private class TestArpPacketContext extends PacketContextAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700575 private final String deviceId;
576
Charles Chan5d5e0622015-09-25 13:00:06 -0700577 public TestArpPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300578 super(0, null, null, false);
alshabib4a179dc2014-10-17 17:17:01 -0700579 this.deviceId = deviceId;
580 }
581
582 @Override
alshabib4a179dc2014-10-17 17:17:01 -0700583 public InboundPacket inPacket() {
584 ARP arp = new ARP();
585 arp.setSenderProtocolAddress(IP)
586 .setSenderHardwareAddress(MAC.toBytes())
587 .setTargetHardwareAddress(BCMAC.toBytes())
588 .setTargetProtocolAddress(IP);
589
590 Ethernet eth = new Ethernet();
591 eth.setEtherType(Ethernet.TYPE_ARP)
592 .setVlanID(VLAN.toShort())
593 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800594 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700595 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800596 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
597 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700598 return new DefaultInboundPacket(receivedFrom, eth,
599 ByteBuffer.wrap(eth.serialize()));
600 }
alshabib4a179dc2014-10-17 17:17:01 -0700601 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800602
Charles Chan5d5e0622015-09-25 13:00:06 -0700603 /**
Charles Chane6067892016-11-17 10:23:46 -0800604 * Generates IPv4 Unicast packet.
Charles Chan5d5e0622015-09-25 13:00:06 -0700605 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300606 private class TestIpv4PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700607 private final String deviceId;
608
609 public TestIpv4PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300610 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700611 this.deviceId = deviceId;
612 }
613
614 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700615 public InboundPacket inPacket() {
616 IPv4 ipv4 = new IPv4();
617 ipv4.setDestinationAddress("10.0.0.1");
618 ipv4.setSourceAddress(IP_ADDRESS.toString());
619 Ethernet eth = new Ethernet();
620 eth.setEtherType(Ethernet.TYPE_IPV4)
621 .setVlanID(VLAN.toShort())
622 .setSourceMACAddress(MAC)
623 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
624 .setPayload(ipv4);
625 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
626 portNumber(INPORT));
627 return new DefaultInboundPacket(receivedFrom, eth,
628 ByteBuffer.wrap(eth.serialize()));
629 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700630 }
Charles Chane6067892016-11-17 10:23:46 -0800631 /**
632 * Generates DHCP REQUEST packet.
633 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300634 private class TestDhcpRequestPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800635 private final String deviceId;
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700636 private final VlanId vlanId;
Charles Chane6067892016-11-17 10:23:46 -0800637
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700638 public TestDhcpRequestPacketContext(String deviceId, VlanId vlanId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300639 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800640 this.deviceId = deviceId;
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700641 this.vlanId = vlanId;
Charles Chane6067892016-11-17 10:23:46 -0800642 }
643
644 @Override
Charles Chane6067892016-11-17 10:23:46 -0800645 public InboundPacket inPacket() {
646 byte[] dhcpMsgType = new byte[1];
Yi Tsengc7403c22017-06-19 16:23:22 -0700647 dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPREQUEST.getValue();
Charles Chane6067892016-11-17 10:23:46 -0800648
Yi Tsengc7403c22017-06-19 16:23:22 -0700649 DhcpOption dhcpOption = new DhcpOption();
Charles Chane6067892016-11-17 10:23:46 -0800650 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
651 dhcpOption.setData(dhcpMsgType);
652 dhcpOption.setLength((byte) 1);
653 DHCP dhcp = new DHCP();
654 dhcp.setOptions(Collections.singletonList(dhcpOption));
655 dhcp.setClientHardwareAddress(MAC.toBytes());
656 UDP udp = new UDP();
657 udp.setPayload(dhcp);
658 udp.setSourcePort(UDP.DHCP_CLIENT_PORT);
659 udp.setDestinationPort(UDP.DHCP_SERVER_PORT);
660 IPv4 ipv4 = new IPv4();
661 ipv4.setPayload(udp);
662 ipv4.setDestinationAddress(IP_ADDRESS3.toString());
663 ipv4.setSourceAddress(IP_ADDRESS.toString());
664 Ethernet eth = new Ethernet();
665 eth.setEtherType(Ethernet.TYPE_IPV4)
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700666 .setVlanID(this.vlanId.toShort())
Charles Chane6067892016-11-17 10:23:46 -0800667 .setSourceMACAddress(MAC)
668 .setDestinationMACAddress(MAC3)
669 .setPayload(ipv4);
670 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
671 portNumber(INPORT));
672 return new DefaultInboundPacket(receivedFrom, eth,
673 ByteBuffer.wrap(eth.serialize()));
674 }
Charles Chane6067892016-11-17 10:23:46 -0800675 }
676
677 /**
678 * Generates DHCP ACK packet.
679 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300680 private class TestDhcpAckPacketContext extends PacketContextAdapter {
Charles Chane6067892016-11-17 10:23:46 -0800681 private final String deviceId;
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700682 private final boolean withRelayinfo;
Charles Chane6067892016-11-17 10:23:46 -0800683
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700684 public TestDhcpAckPacketContext(String deviceId, boolean withRelayInfo) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300685 super(0, null, null, false);
Charles Chane6067892016-11-17 10:23:46 -0800686 this.deviceId = deviceId;
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700687 this.withRelayinfo = withRelayInfo;
Charles Chane6067892016-11-17 10:23:46 -0800688 }
689
690 @Override
Charles Chane6067892016-11-17 10:23:46 -0800691 public InboundPacket inPacket() {
692 byte[] dhcpMsgType = new byte[1];
Yi Tsengc7403c22017-06-19 16:23:22 -0700693 dhcpMsgType[0] = (byte) DHCP.MsgType.DHCPACK.getValue();
Charles Chane6067892016-11-17 10:23:46 -0800694
Yi Tsengc7403c22017-06-19 16:23:22 -0700695 DhcpOption dhcpOption = new DhcpOption();
Charles Chane6067892016-11-17 10:23:46 -0800696 dhcpOption.setCode(DHCP.DHCPOptionCode.OptionCode_MessageType.getValue());
697 dhcpOption.setData(dhcpMsgType);
698 dhcpOption.setLength((byte) 1);
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700699
Charles Chane6067892016-11-17 10:23:46 -0800700 DHCP dhcp = new DHCP();
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700701
702 if (withRelayinfo) {
703 CircuitId cid = new CircuitId(LOCATION.toString(), VLAN_100);
704 byte[] circuitId = cid.serialize();
705 DhcpOption circuitIdSubOption = new DhcpOption();
706 circuitIdSubOption.setCode(DhcpRelayAgentOption.RelayAgentInfoOptions.CIRCUIT_ID.getValue());
707 circuitIdSubOption.setData(circuitId);
708 circuitIdSubOption.setLength((byte) circuitId.length);
709
710 DhcpRelayAgentOption relayInfoOption = new DhcpRelayAgentOption();
711 relayInfoOption.setCode(DHCP.DHCPOptionCode.OptionCode_CircuitID.getValue());
712 relayInfoOption.addSubOption(circuitIdSubOption);
713 dhcp.setOptions(ImmutableList.of(dhcpOption, relayInfoOption));
714 dhcp.setGatewayIPAddress(GW_IFACE_ADDR.ipAddress().getIp4Address().toInt());
715 } else {
716 dhcp.setOptions(ImmutableList.of(dhcpOption));
717 }
718
Charles Chane6067892016-11-17 10:23:46 -0800719 dhcp.setClientHardwareAddress(MAC.toBytes());
720 dhcp.setYourIPAddress(IP_ADDRESS.getIp4Address().toInt());
Yi Tseng7a38f9a2017-06-09 14:36:40 -0700721
Charles Chane6067892016-11-17 10:23:46 -0800722 UDP udp = new UDP();
723 udp.setPayload(dhcp);
724 udp.setSourcePort(UDP.DHCP_SERVER_PORT);
725 udp.setDestinationPort(UDP.DHCP_CLIENT_PORT);
726 IPv4 ipv4 = new IPv4();
727 ipv4.setPayload(udp);
728 ipv4.setDestinationAddress(IP_ADDRESS.toString());
729 ipv4.setSourceAddress(IP_ADDRESS3.toString());
730 Ethernet eth = new Ethernet();
731 eth.setEtherType(Ethernet.TYPE_IPV4)
732 .setVlanID(VLAN.toShort())
733 .setSourceMACAddress(MAC3)
734 .setDestinationMACAddress(MAC)
735 .setPayload(ipv4);
736 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
737 portNumber(INPORT2));
738 return new DefaultInboundPacket(receivedFrom, eth,
739 ByteBuffer.wrap(eth.serialize()));
740 }
Charles Chane6067892016-11-17 10:23:46 -0800741 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700742
743 /**
744 * Generates NeighborAdvertisement packet.
745 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300746 private class TestNaPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700747 private final String deviceId;
748
Jonathan Hartb35540a2015-11-17 09:30:56 -0800749 public TestNaPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300750 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700751 this.deviceId = deviceId;
752 }
753
754 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700755 public InboundPacket inPacket() {
756 NeighborAdvertisement na = new NeighborAdvertisement();
757 ICMP6 icmp6 = new ICMP6();
758 icmp6.setPayload(na);
759 IPv6 ipv6 = new IPv6();
760 ipv6.setPayload(icmp6);
761 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
762 ipv6.setSourceAddress(IP2);
763 Ethernet eth = new Ethernet();
764 eth.setEtherType(Ethernet.TYPE_IPV6)
765 .setVlanID(VLAN.toShort())
766 .setSourceMACAddress(MAC2.toBytes())
767 .setDestinationMACAddress(BCMAC2)
768 .setPayload(ipv6);
769 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
770 portNumber(INPORT));
771 return new DefaultInboundPacket(receivedFrom, eth,
772 ByteBuffer.wrap(eth.serialize()));
773 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700774 }
775
776 /**
777 * Generates NeighborSolicitation packet.
778 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300779 private class TestNsPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700780 private final String deviceId;
781
Jonathan Hartb35540a2015-11-17 09:30:56 -0800782 public TestNsPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300783 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700784 this.deviceId = deviceId;
785 }
786
787 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700788 public InboundPacket inPacket() {
789 NeighborSolicitation ns = new NeighborSolicitation();
790 ICMP6 icmp6 = new ICMP6();
791 icmp6.setPayload(ns);
792 IPv6 ipv6 = new IPv6();
793 ipv6.setPayload(icmp6);
794 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
795 ipv6.setSourceAddress(IP2);
796 Ethernet eth = new Ethernet();
797 eth.setEtherType(Ethernet.TYPE_IPV6)
798 .setVlanID(VLAN.toShort())
799 .setSourceMACAddress(MAC2.toBytes())
800 .setDestinationMACAddress(BCMAC2)
801 .setPayload(ipv6);
802 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
803 portNumber(INPORT));
804 return new DefaultInboundPacket(receivedFrom, eth,
805 ByteBuffer.wrap(eth.serialize()));
806 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700807 }
808
809 /**
810 * Generates Duplicate Address Detection packet.
811 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300812 private class TestDadPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700813 private final String deviceId;
814
Jonathan Hartb35540a2015-11-17 09:30:56 -0800815 public TestDadPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300816 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700817 this.deviceId = deviceId;
818 }
819
820 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700821 public InboundPacket inPacket() {
822 NeighborSolicitation ns = new NeighborSolicitation();
823 ICMP6 icmp6 = new ICMP6();
824 icmp6.setPayload(ns);
825 IPv6 ipv6 = new IPv6();
826 ipv6.setPayload(icmp6);
827 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
828 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
829 Ethernet eth = new Ethernet();
830 eth.setEtherType(Ethernet.TYPE_IPV6)
831 .setVlanID(VLAN.toShort())
832 .setSourceMACAddress(MAC2.toBytes())
833 .setDestinationMACAddress(BCMAC2)
834 .setPayload(ipv6);
835 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
836 portNumber(INPORT));
837 return new DefaultInboundPacket(receivedFrom, eth,
838 ByteBuffer.wrap(eth.serialize()));
839 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700840 }
841
842 /**
843 * Generates Router Solicitation packet.
844 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300845 private class TestRSPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700846 private final String deviceId;
847
848 public TestRSPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300849 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700850 this.deviceId = deviceId;
851 }
852
853 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700854 public InboundPacket inPacket() {
855 RouterSolicitation ns = new RouterSolicitation();
856 ICMP6 icmp6 = new ICMP6();
857 icmp6.setPayload(ns);
858 IPv6 ipv6 = new IPv6();
859 ipv6.setPayload(icmp6);
860 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
861 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
862 Ethernet eth = new Ethernet();
863 eth.setEtherType(Ethernet.TYPE_IPV6)
864 .setVlanID(VLAN.toShort())
865 .setSourceMACAddress(MAC2.toBytes())
866 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
867 .setPayload(ipv6);
868 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
869 portNumber(INPORT));
870 return new DefaultInboundPacket(receivedFrom, eth,
871 ByteBuffer.wrap(eth.serialize()));
872 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700873 }
874
875 /**
876 * Generates Router Advertisement packet.
877 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300878 private class TestRAPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700879 private final String deviceId;
880
881 public TestRAPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300882 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700883 this.deviceId = deviceId;
884 }
885
886 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700887 public InboundPacket inPacket() {
888 RouterAdvertisement ns = new RouterAdvertisement();
889 ICMP6 icmp6 = new ICMP6();
890 icmp6.setPayload(ns);
891 IPv6 ipv6 = new IPv6();
892 ipv6.setPayload(icmp6);
893 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
894 ipv6.setSourceAddress(IP2);
895 Ethernet eth = new Ethernet();
896 eth.setEtherType(Ethernet.TYPE_IPV6)
897 .setVlanID(VLAN.toShort())
898 .setSourceMACAddress(MAC2.toBytes())
899 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
900 .setPayload(ipv6);
901 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
902 portNumber(INPORT));
903 return new DefaultInboundPacket(receivedFrom, eth,
904 ByteBuffer.wrap(eth.serialize()));
905 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700906 }
907
908 /**
909 * Generates IPv6 Multicast packet.
910 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300911 private class TestIpv6McastPacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700912 private final String deviceId;
913
914 public TestIpv6McastPacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300915 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700916 this.deviceId = deviceId;
917 }
918
919 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700920 public InboundPacket inPacket() {
921 IPv6 ipv6 = new IPv6();
922 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
923 ipv6.setSourceAddress(IP2);
924 Ethernet eth = new Ethernet();
925 eth.setEtherType(Ethernet.TYPE_IPV6)
926 .setVlanID(VLAN.toShort())
927 .setSourceMACAddress(MAC2.toBytes())
928 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
929 .setPayload(ipv6);
930 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
931 portNumber(INPORT));
932 return new DefaultInboundPacket(receivedFrom, eth,
933 ByteBuffer.wrap(eth.serialize()));
934 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700935 }
936
937 /**
938 * Generates IPv6 Unicast packet.
939 */
Andrey Komarov2398d962016-09-26 15:11:23 +0300940 private class TestIpv6PacketContext extends PacketContextAdapter {
Charles Chan5d5e0622015-09-25 13:00:06 -0700941 private final String deviceId;
942
943 public TestIpv6PacketContext(String deviceId) {
Andrey Komarov2398d962016-09-26 15:11:23 +0300944 super(0, null, null, false);
Charles Chan5d5e0622015-09-25 13:00:06 -0700945 this.deviceId = deviceId;
946 }
947
948 @Override
Charles Chan5d5e0622015-09-25 13:00:06 -0700949 public InboundPacket inPacket() {
950 IPv6 ipv6 = new IPv6();
951 ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
952 ipv6.setSourceAddress(IP2);
953 Ethernet eth = new Ethernet();
954 eth.setEtherType(Ethernet.TYPE_IPV6)
955 .setVlanID(VLAN.toShort())
956 .setSourceMACAddress(MAC2)
957 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
958 .setPayload(ipv6);
959 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
960 portNumber(INPORT));
961 return new DefaultInboundPacket(receivedFrom, eth,
962 ByteBuffer.wrap(eth.serialize()));
963 }
Charles Chan5d5e0622015-09-25 13:00:06 -0700964 }
965
Thomas Vachuska33601602014-11-19 03:32:15 -0800966 private class TestDeviceService extends DeviceServiceAdapter {
967 private DeviceListener listener;
968
969 @Override
970 public void addListener(DeviceListener listener) {
971 this.listener = listener;
972 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800973
974 @Override
975 public Iterable<Device> getDevices() {
976 return Collections.emptyList();
977 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800978 }
979
980 private class TestHostService extends HostServiceAdapter {
981 @Override
982 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700983 ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
984 ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
Charles Chane6067892016-11-17 10:23:46 -0800985 ConnectPoint cp3 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700986 if (connectPoint.equals(cp1)) {
987 return ImmutableSet.of(HOST);
988 } else if (connectPoint.equals(cp2)) {
989 return ImmutableSet.of(HOST2);
Charles Chane6067892016-11-17 10:23:46 -0800990 } else if (connectPoint.equals(cp3)) {
991 return ImmutableSet.of(HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -0700992 } else {
993 return ImmutableSet.of();
994 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800995 }
996
997 @Override
998 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700999 if (deviceId.equals(deviceId(DEV1))) {
Charles Chane6067892016-11-17 10:23:46 -08001000 return ImmutableSet.of(HOST, HOST3);
Charles Chan5d5e0622015-09-25 13:00:06 -07001001 } else if (deviceId.equals(deviceId(DEV4))) {
1002 return ImmutableSet.of(HOST2);
1003 } else {
1004 return ImmutableSet.of();
1005 }
Thomas Vachuska33601602014-11-19 03:32:15 -08001006 }
1007
Charles Chane6067892016-11-17 10:23:46 -08001008 @Override
1009 public Host getHost(HostId hostId) {
1010 if (hostId.equals(HostId.hostId(MAC, VLAN))) {
1011 return HOST;
1012 } else if (hostId.equals(HostId.hostId(MAC2, VLAN))) {
1013 return HOST2;
1014 } else if (hostId.equals(HostId.hostId(MAC3, VLAN))) {
1015 return HOST3;
Yi Tseng7a38f9a2017-06-09 14:36:40 -07001016 } else if (hostId.equals(HostId.hostId(MAC, VLAN_100))) {
1017 return HOST_VLAN_100;
Charles Chane6067892016-11-17 10:23:46 -08001018 }
1019 return null;
1020 }
Yi Tseng7a38f9a2017-06-09 14:36:40 -07001021 }
Charles Chane6067892016-11-17 10:23:46 -08001022
Yi Tseng7a38f9a2017-06-09 14:36:40 -07001023 private class TestInterfaceService implements InterfaceService {
1024 @Override
1025 public Set<Interface> getInterfaces() {
1026 return null;
1027 }
1028
1029 @Override
1030 public Interface getInterfaceByName(ConnectPoint connectPoint, String name) {
1031 return null;
1032 }
1033
1034 @Override
1035 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
1036 return null;
1037 }
1038
1039 public Set<Interface> getInterfacesByIp(IpAddress ip) {
1040 if (ip.equals(GW_IFACE_ADDR.ipAddress())) {
1041 return ImmutableSet.of(GW_IFACE);
1042 } else {
1043 return ImmutableSet.of();
1044 }
1045 }
1046
1047 @Override
1048 public Set<Interface> getInterfacesByVlan(VlanId vlan) {
1049 return null;
1050 }
1051
1052 @Override
1053 public Interface getMatchingInterface(IpAddress ip) {
1054 return null;
1055 }
1056
1057 @Override
1058 public Set<Interface> getMatchingInterfaces(IpAddress ip) {
1059 return null;
1060 }
1061
1062 @Override
1063 public void addListener(InterfaceListener listener) {
1064
1065 }
1066
1067 @Override
1068 public void removeListener(InterfaceListener listener) {
1069
1070 }
Thomas Vachuska33601602014-11-19 03:32:15 -08001071 }
alshabib4a179dc2014-10-17 17:17:01 -07001072}