blob: acf0a13be6a0ad59622718778fa55b425167f750 [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;
20import com.google.common.collect.Sets;
Madan Jampania3770c32015-12-11 12:07:41 -080021import com.google.common.util.concurrent.MoreExecutors;
22
alshabib4a179dc2014-10-17 17:17:01 -070023import org.junit.After;
24import org.junit.Before;
25import org.junit.Test;
Jonathan Hart3cfce8e2015-01-14 16:43:27 -080026import org.onlab.osgi.ComponentContextAdapter;
27import org.onlab.packet.ARP;
28import org.onlab.packet.ChassisId;
29import 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;
36import org.onlab.packet.VlanId;
Charles Chan5d5e0622015-09-25 13:00:06 -070037import org.onlab.packet.ndp.NeighborAdvertisement;
38import org.onlab.packet.ndp.NeighborSolicitation;
39import org.onlab.packet.ndp.RouterAdvertisement;
40import org.onlab.packet.ndp.RouterSolicitation;
Thomas Vachuska6519e6f2015-03-11 02:29:31 -070041import org.onosproject.cfg.ComponentConfigAdapter;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -080042import org.onosproject.core.ApplicationId;
43import org.onosproject.core.CoreService;
44import org.onosproject.core.DefaultApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080045import org.onosproject.net.ConnectPoint;
46import org.onosproject.net.DefaultDevice;
47import org.onosproject.net.DefaultHost;
48import org.onosproject.net.DefaultPort;
49import org.onosproject.net.Device;
50import org.onosproject.net.DeviceId;
51import org.onosproject.net.Host;
52import org.onosproject.net.HostId;
53import org.onosproject.net.HostLocation;
54import org.onosproject.net.device.DeviceEvent;
55import org.onosproject.net.device.DeviceListener;
56import org.onosproject.net.device.DeviceServiceAdapter;
57import org.onosproject.net.flow.TrafficTreatment;
58import 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;
65import org.onosproject.net.packet.OutboundPacket;
66import org.onosproject.net.packet.PacketContext;
67import org.onosproject.net.packet.PacketProcessor;
Thomas Vachuska27bee092015-06-23 19:03:10 -070068import org.onosproject.net.packet.PacketServiceAdapter;
Brian O'Connorabafb502014-12-02 22:26:20 -080069import org.onosproject.net.provider.AbstractProviderService;
70import org.onosproject.net.provider.ProviderId;
71import org.onosproject.net.topology.Topology;
72import org.onosproject.net.topology.TopologyServiceAdapter;
alshabib4a179dc2014-10-17 17:17:01 -070073
Thomas Vachuska27bee092015-06-23 19:03:10 -070074import java.nio.ByteBuffer;
75import java.util.Collections;
76import java.util.Dictionary;
77import java.util.Hashtable;
Charles Chan420e7372016-11-17 10:58:17 -080078import java.util.List;
Thomas Vachuska27bee092015-06-23 19:03:10 -070079import java.util.Set;
80
81import static org.easymock.EasyMock.*;
Charles Chan5d5e0622015-09-25 13:00:06 -070082import static org.hamcrest.Matchers.is;
Thomas Vachuska27bee092015-06-23 19:03:10 -070083import static org.junit.Assert.*;
84import static org.onlab.packet.VlanId.vlanId;
85import static org.onosproject.net.Device.Type.SWITCH;
86import static org.onosproject.net.DeviceId.deviceId;
87import static org.onosproject.net.HostId.hostId;
88import static org.onosproject.net.PortNumber.portNumber;
89import static org.onosproject.net.device.DeviceEvent.Type.*;
Thomas Vachuska33601602014-11-19 03:32:15 -080090
alshabib4a179dc2014-10-17 17:17:01 -070091public class HostLocationProviderTest {
Charles Chan8b0fdaa2016-02-23 18:35:27 -080092 private static final ProviderId PROVIDER_ID =
93 new ProviderId("of", "org.onosproject.provider.host");
94
alshabib4a179dc2014-10-17 17:17:01 -070095 private static final Integer INPORT = 10;
96 private static final String DEV1 = "of:1";
97 private static final String DEV2 = "of:2";
98 private static final String DEV3 = "of:3";
Charles Chan5d5e0622015-09-25 13:00:06 -070099 private static final String DEV4 = "of:4";
100 private static final String DEV5 = "of:5";
101 private static final String DEV6 = "of:6";
alshabib4a179dc2014-10-17 17:17:01 -0700102
Thomas Vachuska33601602014-11-19 03:32:15 -0800103 private static final VlanId VLAN = vlanId();
Charles Chan5d5e0622015-09-25 13:00:06 -0700104
105 // IPv4 Host
alshabib4a179dc2014-10-17 17:17:01 -0700106 private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
107 private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
108 private static final byte[] IP = new byte[]{10, 0, 0, 1};
Thomas Vachuska33601602014-11-19 03:32:15 -0800109 private static final IpAddress IP_ADDRESS =
110 IpAddress.valueOf(IpAddress.Version.INET, IP);
111 private static final HostLocation LOCATION =
112 new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
Thomas Vachuska33601602014-11-19 03:32:15 -0800113 private static final DefaultHost HOST =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800114 new DefaultHost(PROVIDER_ID, hostId(MAC), MAC,
Thomas Vachuska33601602014-11-19 03:32:15 -0800115 vlanId(VlanId.UNTAGGED), LOCATION,
116 ImmutableSet.of(IP_ADDRESS));
117
Charles Chan5d5e0622015-09-25 13:00:06 -0700118 // IPv6 Host
119 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
120 private static final MacAddress BCMAC2 = MacAddress.valueOf("33:33:00:00:00:01");
121 private static final byte[] IP2 = Ip6Address.valueOf("1000::1").toOctets();
122 private static final IpAddress IP_ADDRESS2 =
123 IpAddress.valueOf(IpAddress.Version.INET6, IP2);
124 private static final HostLocation LOCATION2 =
125 new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
126 private static final DefaultHost HOST2 =
Charles Chan8b0fdaa2016-02-23 18:35:27 -0800127 new DefaultHost(PROVIDER_ID, hostId(MAC2), MAC2,
Charles Chan5d5e0622015-09-25 13:00:06 -0700128 vlanId(VlanId.UNTAGGED), LOCATION2,
129 ImmutableSet.of(IP_ADDRESS2));
130
Thomas Vachuska33601602014-11-19 03:32:15 -0800131 private static final ComponentContextAdapter CTX_FOR_REMOVE =
132 new ComponentContextAdapter() {
133 @Override
134 public Dictionary getProperties() {
135 Hashtable<String, String> props = new Hashtable<>();
136 props.put("hostRemovalEnabled", "true");
137 return props;
138 }
139 };
140
141 public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
142 new ComponentContextAdapter() {
143 @Override
144 public Dictionary getProperties() {
145 return new Hashtable();
146 }
147 };
148
alshabib4a179dc2014-10-17 17:17:01 -0700149 private final HostLocationProvider provider = new HostLocationProvider();
Thomas Vachuska33601602014-11-19 03:32:15 -0800150 private final TestHostRegistry hostRegistry = new TestHostRegistry();
alshabib4a179dc2014-10-17 17:17:01 -0700151 private final TestTopologyService topoService = new TestTopologyService();
Thomas Vachuska33601602014-11-19 03:32:15 -0800152 private final TestDeviceService deviceService = new TestDeviceService();
153 private final TestHostService hostService = new TestHostService();
alshabib4a179dc2014-10-17 17:17:01 -0700154 private final TestPacketService packetService = new TestPacketService();
155
156 private PacketProcessor testProcessor;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800157 private CoreService coreService;
alshabib4a179dc2014-10-17 17:17:01 -0700158 private TestHostProviderService providerService;
159
Thomas Vachuska02aeb032015-01-06 22:36:30 -0800160 private ApplicationId appId =
161 new DefaultApplicationId(100, "org.onosproject.provider.host");
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800162
alshabib4a179dc2014-10-17 17:17:01 -0700163 @Before
164 public void setUp() {
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800165
166 coreService = createMock(CoreService.class);
167 expect(coreService.registerApplication(appId.name()))
Thomas Vachuska27bee092015-06-23 19:03:10 -0700168 .andReturn(appId).anyTimes();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800169 replay(coreService);
170
Thomas Vachuska6519e6f2015-03-11 02:29:31 -0700171 provider.cfgService = new ComponentConfigAdapter();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800172 provider.coreService = coreService;
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800173
Thomas Vachuska33601602014-11-19 03:32:15 -0800174 provider.providerRegistry = hostRegistry;
alshabib4a179dc2014-10-17 17:17:01 -0700175 provider.topologyService = topoService;
Pavlin Radoslavovd6612f92015-02-23 13:53:32 -0800176 provider.packetService = packetService;
Thomas Vachuska33601602014-11-19 03:32:15 -0800177 provider.deviceService = deviceService;
178 provider.hostService = hostService;
alshabib4a179dc2014-10-17 17:17:01 -0700179
Thomas Vachuska33601602014-11-19 03:32:15 -0800180 provider.activate(CTX_FOR_NO_REMOVE);
Madan Jampania3770c32015-12-11 12:07:41 -0800181
182 provider.eventHandler = MoreExecutors.newDirectExecutorService();
alshabib4a179dc2014-10-17 17:17:01 -0700183 }
184
185 @Test
186 public void basics() {
187 assertNotNull("registration expected", providerService);
188 assertEquals("incorrect provider", provider, providerService.provider());
189 }
190
191 @Test
192 public void events() {
Charles Chan420e7372016-11-17 10:58:17 -0800193 // New host. Expect one additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700194 testProcessor.process(new TestArpPacketContext(DEV1));
Charles Chan420e7372016-11-17 10:58:17 -0800195 assertThat("New host expected", providerService.descriptions.size(), is(1));
alshabib4a179dc2014-10-17 17:17:01 -0700196
Charles Chan420e7372016-11-17 10:58:17 -0800197 // The host moved to new switch. Expect one additional host description.
198 // The second host description should have a different location.
Charles Chan5d5e0622015-09-25 13:00:06 -0700199 testProcessor.process(new TestArpPacketContext(DEV2));
Charles Chan420e7372016-11-17 10:58:17 -0800200 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
201 HostLocation loc1 = providerService.descriptions.get(0).location();
202 HostLocation loc2 = providerService.descriptions.get(1).location();
203 assertNotEquals("Host location should be different", loc1, loc2);
alshabib4a179dc2014-10-17 17:17:01 -0700204
Charles Chan420e7372016-11-17 10:58:17 -0800205 // The host was misheard on a spine. Expect no additional host description.
Charles Chan5d5e0622015-09-25 13:00:06 -0700206 testProcessor.process(new TestArpPacketContext(DEV3));
Charles Chan420e7372016-11-17 10:58:17 -0800207 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
Charles Chan5d5e0622015-09-25 13:00:06 -0700208
209 providerService.clear();
210
Charles Chan420e7372016-11-17 10:58:17 -0800211 // New host. Expect one additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800212 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800213 assertThat("New host expected", providerService.descriptions.size(), is(1));
Charles Chan5d5e0622015-09-25 13:00:06 -0700214
Charles Chan420e7372016-11-17 10:58:17 -0800215 // The host moved to new switch. Expect one additional host description.
216 // The second host description should have a different location.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800217 testProcessor.process(new TestNaPacketContext(DEV5));
Charles Chan420e7372016-11-17 10:58:17 -0800218 assertThat("Host motion expected", providerService.descriptions.size(), is(2));
219 loc1 = providerService.descriptions.get(0).location();
220 loc2 = providerService.descriptions.get(1).location();
221 assertNotEquals("Host location should be different", loc1, loc2);
Charles Chan5d5e0622015-09-25 13:00:06 -0700222
Charles Chan420e7372016-11-17 10:58:17 -0800223 // The host was misheard on a spine. Expect no additional host description.
Jonathan Hartb35540a2015-11-17 09:30:56 -0800224 testProcessor.process(new TestNaPacketContext(DEV6));
Charles Chan420e7372016-11-17 10:58:17 -0800225 assertThat("Host misheard on spine switch", providerService.descriptions.size(), is(2));
alshabib4a179dc2014-10-17 17:17:01 -0700226 }
227
Thomas Vachuska33601602014-11-19 03:32:15 -0800228 @Test
229 public void removeHostByDeviceRemove() {
230 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700231 testProcessor.process(new TestArpPacketContext(DEV1));
Jonathan Hartb35540a2015-11-17 09:30:56 -0800232 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan5d5e0622015-09-25 13:00:06 -0700233
Thomas Vachuska33601602014-11-19 03:32:15 -0800234 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
235 "m", "h", "s", "n", new ChassisId(0L));
236 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
237 assertEquals("incorrect remove count", 1, providerService.removeCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700238
239 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
240 "m", "h", "s", "n", new ChassisId(0L));
241 deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
242 assertEquals("incorrect remove count", 2, providerService.removeCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800243 }
244
245 @Test
246 public void removeHostByDeviceOffline() {
247 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700248 testProcessor.process(new TestArpPacketContext(DEV1));
249 testProcessor.process(new TestArpPacketContext(DEV4));
250
Thomas Vachuska33601602014-11-19 03:32:15 -0800251 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
252 "m", "h", "s", "n", new ChassisId(0L));
253 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
254 assertEquals("incorrect remove count", 1, providerService.removeCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700255
256 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
257 "m", "h", "s", "n", new ChassisId(0L));
258 deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
259 assertEquals("incorrect remove count", 2, providerService.removeCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800260 }
261
262 @Test
263 public void removeHostByDevicePortDown() {
264 provider.modified(CTX_FOR_REMOVE);
Charles Chan5d5e0622015-09-25 13:00:06 -0700265 testProcessor.process(new TestArpPacketContext(DEV1));
266 testProcessor.process(new TestArpPacketContext(DEV4));
267
Thomas Vachuska33601602014-11-19 03:32:15 -0800268 Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
269 "m", "h", "s", "n", new ChassisId(0L));
270 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
Charles Chan5d5e0622015-09-25 13:00:06 -0700271 new DefaultPort(device, portNumber(INPORT), false)));
Thomas Vachuska33601602014-11-19 03:32:15 -0800272 assertEquals("incorrect remove count", 1, providerService.removeCount);
Charles Chan5d5e0622015-09-25 13:00:06 -0700273
274 device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
275 "m", "h", "s", "n", new ChassisId(0L));
276 deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
277 new DefaultPort(device, portNumber(INPORT), false)));
278 assertEquals("incorrect remove count", 2, providerService.removeCount);
Thomas Vachuska33601602014-11-19 03:32:15 -0800279 }
280
Charles Chan5d5e0622015-09-25 13:00:06 -0700281 /**
282 * When receiving ARP, updates location and IP.
283 */
284 @Test
285 public void testReceiveArp() {
286 testProcessor.process(new TestArpPacketContext(DEV1));
Charles Chan420e7372016-11-17 10:58:17 -0800287 assertThat("testReceiveArp. One host description expected",
288 providerService.descriptions.size(), is(1));
289 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700290 assertThat(descr.location(), is(LOCATION));
291 assertThat(descr.hwAddress(), is(MAC));
292 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS));
293 assertThat(descr.vlan(), is(VLAN));
294 }
295
296 /**
297 * When receiving IPv4, updates location only.
298 */
299 @Test
300 public void testReceiveIpv4() {
301 testProcessor.process(new TestIpv4PacketContext(DEV1));
Charles Chan420e7372016-11-17 10:58:17 -0800302 assertThat("testReceiveIpv4. One host description expected",
303 providerService.descriptions.size(), is(1));
304 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700305 assertThat(descr.location(), is(LOCATION));
306 assertThat(descr.hwAddress(), is(MAC));
307 assertThat(descr.ipAddress().size(), is(0));
308 assertThat(descr.vlan(), is(VLAN));
309 }
310
311 /**
312 * When receiving NeighborAdvertisement, updates location and IP.
313 */
314 @Test
Jonathan Hartb35540a2015-11-17 09:30:56 -0800315 public void testReceiveNa() {
316 testProcessor.process(new TestNaPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800317 assertThat("testReceiveNa. One host description expected",
318 providerService.descriptions.size(), is(1));
319 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700320 assertThat(descr.location(), is(LOCATION2));
321 assertThat(descr.hwAddress(), is(MAC2));
322 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
323 assertThat(descr.vlan(), is(VLAN));
324 }
325
326 /**
327 * When receiving NeighborSolicitation, updates location and IP.
328 */
329 @Test
Jonathan Hartb35540a2015-11-17 09:30:56 -0800330 public void testReceiveNs() {
331 testProcessor.process(new TestNsPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800332 assertThat("testReceiveNs. One host description expected",
333 providerService.descriptions.size(), is(1));
334 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700335 assertThat(descr.location(), is(LOCATION2));
336 assertThat(descr.hwAddress(), is(MAC2));
337 assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
338 assertThat(descr.vlan(), is(VLAN));
339 }
340
341 /**
342 * When receiving RouterAdvertisement, ignores it.
343 */
344 @Test
Jonathan Hartb35540a2015-11-17 09:30:56 -0800345 public void testReceivesRa() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700346 testProcessor.process(new TestRAPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800347 assertThat("testReceiveRa. No host description expected",
348 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700349 }
350
351 /**
352 * When receiving RouterSolicitation, ignores it.
353 */
354 @Test
Jonathan Hartb35540a2015-11-17 09:30:56 -0800355 public void testReceiveRs() {
Charles Chan5d5e0622015-09-25 13:00:06 -0700356 testProcessor.process(new TestRSPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800357 assertThat("testReceiveRs. No host description expected",
358 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700359 }
360
361 /**
362 * When receiving Duplicate Address Detection (DAD), ignores it.
363 */
364 @Test
Jonathan Hartb35540a2015-11-17 09:30:56 -0800365 public void testReceiveDad() {
366 testProcessor.process(new TestDadPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800367 assertThat("testReceiveDad. No host description expected",
368 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700369 }
370
371 /**
372 * When receiving IPv6 multicast packet, ignores it.
373 */
374 @Test
375 public void testReceiveIpv6Multicast() {
376 testProcessor.process(new TestIpv6McastPacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800377 assertThat("testReceiveIpv6Multicast. No host description expected",
378 providerService.descriptions.size(), is(0));
Charles Chan5d5e0622015-09-25 13:00:06 -0700379 }
380
381 /**
382 * When receiving IPv6 unicast packet, updates location only.
383 */
384 @Test
385 public void testReceiveIpv6Unicast() {
386 testProcessor.process(new TestIpv6PacketContext(DEV4));
Charles Chan420e7372016-11-17 10:58:17 -0800387 assertThat("testReceiveIpv6Unicast. One host description expected",
388 providerService.descriptions.size(), is(1));
389 HostDescription descr = providerService.descriptions.get(0);
Charles Chan5d5e0622015-09-25 13:00:06 -0700390 assertThat(descr.location(), is(LOCATION2));
391 assertThat(descr.hwAddress(), is(MAC2));
392 assertThat(descr.ipAddress().size(), is(0));
393 assertThat(descr.vlan(), is(VLAN));
394 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800395
alshabib4a179dc2014-10-17 17:17:01 -0700396 @After
397 public void tearDown() {
398 provider.deactivate();
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -0800399 provider.coreService = null;
alshabib4a179dc2014-10-17 17:17:01 -0700400 provider.providerRegistry = null;
alshabib4a179dc2014-10-17 17:17:01 -0700401 }
402
403 private class TestHostRegistry implements HostProviderRegistry {
404
405 @Override
406 public HostProviderService register(HostProvider provider) {
407 providerService = new TestHostProviderService(provider);
408 return providerService;
409 }
410
411 @Override
412 public void unregister(HostProvider provider) {
413 }
414
415 @Override
416 public Set<ProviderId> getProviders() {
417 return null;
418 }
419
420 }
421
422 private class TestHostProviderService
423 extends AbstractProviderService<HostProvider>
424 implements HostProviderService {
425
Charles Chan420e7372016-11-17 10:58:17 -0800426 List<HostDescription> descriptions = Lists.newArrayList();
427 int removeCount;
alshabib4a179dc2014-10-17 17:17:01 -0700428
Charles Chan5d5e0622015-09-25 13:00:06 -0700429 public void clear() {
Charles Chan420e7372016-11-17 10:58:17 -0800430 descriptions.clear();
Charles Chan5d5e0622015-09-25 13:00:06 -0700431 removeCount = 0;
432 }
433
alshabib4a179dc2014-10-17 17:17:01 -0700434 protected TestHostProviderService(HostProvider provider) {
435 super(provider);
436 }
437
438 @Override
Brian O'Connorf107bd72015-09-21 15:31:03 -0700439 public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
Charles Chan420e7372016-11-17 10:58:17 -0800440 descriptions.add(hostDescription);
alshabib4a179dc2014-10-17 17:17:01 -0700441 }
442
443 @Override
444 public void hostVanished(HostId hostId) {
Thomas Vachuska33601602014-11-19 03:32:15 -0800445 removeCount++;
alshabib4a179dc2014-10-17 17:17:01 -0700446 }
447
samanwita palc40e5ed2015-09-24 11:01:51 -0700448 @Override
449 public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
450 }
451
alshabib4a179dc2014-10-17 17:17:01 -0700452 }
453
Thomas Vachuska27bee092015-06-23 19:03:10 -0700454 private class TestPacketService extends PacketServiceAdapter {
alshabib4a179dc2014-10-17 17:17:01 -0700455 @Override
456 public void addProcessor(PacketProcessor processor, int priority) {
457 testProcessor = processor;
458 }
alshabib4a179dc2014-10-17 17:17:01 -0700459 }
460
alshabib4a179dc2014-10-17 17:17:01 -0700461 private class TestTopologyService extends TopologyServiceAdapter {
462 @Override
463 public boolean isInfrastructure(Topology topology,
464 ConnectPoint connectPoint) {
465 //simulate DPID3 as an infrastructure switch
Charles Chan5d5e0622015-09-25 13:00:06 -0700466 if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
467 connectPoint.deviceId().equals(deviceId(DEV6))) {
alshabib4a179dc2014-10-17 17:17:01 -0700468 return true;
469 }
470 return false;
471 }
472 }
473
Charles Chan5d5e0622015-09-25 13:00:06 -0700474 /**
475 * Generates ARP packet.
476 */
477 private class TestArpPacketContext implements PacketContext {
alshabib4a179dc2014-10-17 17:17:01 -0700478 private final String deviceId;
479
Charles Chan5d5e0622015-09-25 13:00:06 -0700480 public TestArpPacketContext(String deviceId) {
alshabib4a179dc2014-10-17 17:17:01 -0700481 this.deviceId = deviceId;
482 }
483
484 @Override
485 public long time() {
486 return 0;
487 }
488
489 @Override
490 public InboundPacket inPacket() {
491 ARP arp = new ARP();
492 arp.setSenderProtocolAddress(IP)
493 .setSenderHardwareAddress(MAC.toBytes())
494 .setTargetHardwareAddress(BCMAC.toBytes())
495 .setTargetProtocolAddress(IP);
496
497 Ethernet eth = new Ethernet();
498 eth.setEtherType(Ethernet.TYPE_ARP)
499 .setVlanID(VLAN.toShort())
500 .setSourceMACAddress(MAC.toBytes())
Yuta HIGUCHI3e848a82014-11-02 20:19:42 -0800501 .setDestinationMACAddress(BCMAC)
alshabib4a179dc2014-10-17 17:17:01 -0700502 .setPayload(arp);
Thomas Vachuska33601602014-11-19 03:32:15 -0800503 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
504 portNumber(INPORT));
alshabib4a179dc2014-10-17 17:17:01 -0700505 return new DefaultInboundPacket(receivedFrom, eth,
506 ByteBuffer.wrap(eth.serialize()));
507 }
508
509 @Override
510 public OutboundPacket outPacket() {
511 return null;
512 }
513
514 @Override
515 public TrafficTreatment.Builder treatmentBuilder() {
516 return null;
517 }
518
519 @Override
520 public void send() {
521
522 }
523
524 @Override
525 public boolean block() {
526 return false;
527 }
528
529 @Override
530 public boolean isHandled() {
531 return false;
532 }
533 }
Thomas Vachuska33601602014-11-19 03:32:15 -0800534
Charles Chan5d5e0622015-09-25 13:00:06 -0700535 /**
536 * Generates IPv6 Unicast packet.
537 */
538 private class TestIpv4PacketContext implements PacketContext {
539 private final String deviceId;
540
541 public TestIpv4PacketContext(String deviceId) {
542 this.deviceId = deviceId;
543 }
544
545 @Override
546 public long time() {
547 return 0;
548 }
549
550 @Override
551 public InboundPacket inPacket() {
552 IPv4 ipv4 = new IPv4();
553 ipv4.setDestinationAddress("10.0.0.1");
554 ipv4.setSourceAddress(IP_ADDRESS.toString());
555 Ethernet eth = new Ethernet();
556 eth.setEtherType(Ethernet.TYPE_IPV4)
557 .setVlanID(VLAN.toShort())
558 .setSourceMACAddress(MAC)
559 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
560 .setPayload(ipv4);
561 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
562 portNumber(INPORT));
563 return new DefaultInboundPacket(receivedFrom, eth,
564 ByteBuffer.wrap(eth.serialize()));
565 }
566
567 @Override
568 public OutboundPacket outPacket() {
569 return null;
570 }
571
572 @Override
573 public TrafficTreatment.Builder treatmentBuilder() {
574 return null;
575 }
576
577 @Override
578 public void send() {
579
580 }
581
582 @Override
583 public boolean block() {
584 return false;
585 }
586
587 @Override
588 public boolean isHandled() {
589 return false;
590 }
591 }
592
593 /**
594 * Generates NeighborAdvertisement packet.
595 */
Jonathan Hartb35540a2015-11-17 09:30:56 -0800596 private class TestNaPacketContext implements PacketContext {
Charles Chan5d5e0622015-09-25 13:00:06 -0700597 private final String deviceId;
598
Jonathan Hartb35540a2015-11-17 09:30:56 -0800599 public TestNaPacketContext(String deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700600 this.deviceId = deviceId;
601 }
602
603 @Override
604 public long time() {
605 return 0;
606 }
607
608 @Override
609 public InboundPacket inPacket() {
610 NeighborAdvertisement na = new NeighborAdvertisement();
611 ICMP6 icmp6 = new ICMP6();
612 icmp6.setPayload(na);
613 IPv6 ipv6 = new IPv6();
614 ipv6.setPayload(icmp6);
615 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
616 ipv6.setSourceAddress(IP2);
617 Ethernet eth = new Ethernet();
618 eth.setEtherType(Ethernet.TYPE_IPV6)
619 .setVlanID(VLAN.toShort())
620 .setSourceMACAddress(MAC2.toBytes())
621 .setDestinationMACAddress(BCMAC2)
622 .setPayload(ipv6);
623 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
624 portNumber(INPORT));
625 return new DefaultInboundPacket(receivedFrom, eth,
626 ByteBuffer.wrap(eth.serialize()));
627 }
628
629 @Override
630 public OutboundPacket outPacket() {
631 return null;
632 }
633
634 @Override
635 public TrafficTreatment.Builder treatmentBuilder() {
636 return null;
637 }
638
639 @Override
640 public void send() {
641
642 }
643
644 @Override
645 public boolean block() {
646 return false;
647 }
648
649 @Override
650 public boolean isHandled() {
651 return false;
652 }
653 }
654
655 /**
656 * Generates NeighborSolicitation packet.
657 */
Jonathan Hartb35540a2015-11-17 09:30:56 -0800658 private class TestNsPacketContext implements PacketContext {
Charles Chan5d5e0622015-09-25 13:00:06 -0700659 private final String deviceId;
660
Jonathan Hartb35540a2015-11-17 09:30:56 -0800661 public TestNsPacketContext(String deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700662 this.deviceId = deviceId;
663 }
664
665 @Override
666 public long time() {
667 return 0;
668 }
669
670 @Override
671 public InboundPacket inPacket() {
672 NeighborSolicitation ns = new NeighborSolicitation();
673 ICMP6 icmp6 = new ICMP6();
674 icmp6.setPayload(ns);
675 IPv6 ipv6 = new IPv6();
676 ipv6.setPayload(icmp6);
677 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
678 ipv6.setSourceAddress(IP2);
679 Ethernet eth = new Ethernet();
680 eth.setEtherType(Ethernet.TYPE_IPV6)
681 .setVlanID(VLAN.toShort())
682 .setSourceMACAddress(MAC2.toBytes())
683 .setDestinationMACAddress(BCMAC2)
684 .setPayload(ipv6);
685 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
686 portNumber(INPORT));
687 return new DefaultInboundPacket(receivedFrom, eth,
688 ByteBuffer.wrap(eth.serialize()));
689 }
690
691 @Override
692 public OutboundPacket outPacket() {
693 return null;
694 }
695
696 @Override
697 public TrafficTreatment.Builder treatmentBuilder() {
698 return null;
699 }
700
701 @Override
702 public void send() {
703
704 }
705
706 @Override
707 public boolean block() {
708 return false;
709 }
710
711 @Override
712 public boolean isHandled() {
713 return false;
714 }
715 }
716
717 /**
718 * Generates Duplicate Address Detection packet.
719 */
Jonathan Hartb35540a2015-11-17 09:30:56 -0800720 private class TestDadPacketContext implements PacketContext {
Charles Chan5d5e0622015-09-25 13:00:06 -0700721 private final String deviceId;
722
Jonathan Hartb35540a2015-11-17 09:30:56 -0800723 public TestDadPacketContext(String deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -0700724 this.deviceId = deviceId;
725 }
726
727 @Override
728 public long time() {
729 return 0;
730 }
731
732 @Override
733 public InboundPacket inPacket() {
734 NeighborSolicitation ns = new NeighborSolicitation();
735 ICMP6 icmp6 = new ICMP6();
736 icmp6.setPayload(ns);
737 IPv6 ipv6 = new IPv6();
738 ipv6.setPayload(icmp6);
739 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
740 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
741 Ethernet eth = new Ethernet();
742 eth.setEtherType(Ethernet.TYPE_IPV6)
743 .setVlanID(VLAN.toShort())
744 .setSourceMACAddress(MAC2.toBytes())
745 .setDestinationMACAddress(BCMAC2)
746 .setPayload(ipv6);
747 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
748 portNumber(INPORT));
749 return new DefaultInboundPacket(receivedFrom, eth,
750 ByteBuffer.wrap(eth.serialize()));
751 }
752
753 @Override
754 public OutboundPacket outPacket() {
755 return null;
756 }
757
758 @Override
759 public TrafficTreatment.Builder treatmentBuilder() {
760 return null;
761 }
762
763 @Override
764 public void send() {
765
766 }
767
768 @Override
769 public boolean block() {
770 return false;
771 }
772
773 @Override
774 public boolean isHandled() {
775 return false;
776 }
777 }
778
779 /**
780 * Generates Router Solicitation packet.
781 */
782 private class TestRSPacketContext implements PacketContext {
783 private final String deviceId;
784
785 public TestRSPacketContext(String deviceId) {
786 this.deviceId = deviceId;
787 }
788
789 @Override
790 public long time() {
791 return 0;
792 }
793
794 @Override
795 public InboundPacket inPacket() {
796 RouterSolicitation ns = new RouterSolicitation();
797 ICMP6 icmp6 = new ICMP6();
798 icmp6.setPayload(ns);
799 IPv6 ipv6 = new IPv6();
800 ipv6.setPayload(icmp6);
801 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
802 ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
803 Ethernet eth = new Ethernet();
804 eth.setEtherType(Ethernet.TYPE_IPV6)
805 .setVlanID(VLAN.toShort())
806 .setSourceMACAddress(MAC2.toBytes())
807 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
808 .setPayload(ipv6);
809 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
810 portNumber(INPORT));
811 return new DefaultInboundPacket(receivedFrom, eth,
812 ByteBuffer.wrap(eth.serialize()));
813 }
814
815 @Override
816 public OutboundPacket outPacket() {
817 return null;
818 }
819
820 @Override
821 public TrafficTreatment.Builder treatmentBuilder() {
822 return null;
823 }
824
825 @Override
826 public void send() {
827
828 }
829
830 @Override
831 public boolean block() {
832 return false;
833 }
834
835 @Override
836 public boolean isHandled() {
837 return false;
838 }
839 }
840
841 /**
842 * Generates Router Advertisement packet.
843 */
844 private class TestRAPacketContext implements PacketContext {
845 private final String deviceId;
846
847 public TestRAPacketContext(String deviceId) {
848 this.deviceId = deviceId;
849 }
850
851 @Override
852 public long time() {
853 return 0;
854 }
855
856 @Override
857 public InboundPacket inPacket() {
858 RouterAdvertisement ns = new RouterAdvertisement();
859 ICMP6 icmp6 = new ICMP6();
860 icmp6.setPayload(ns);
861 IPv6 ipv6 = new IPv6();
862 ipv6.setPayload(icmp6);
863 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
864 ipv6.setSourceAddress(IP2);
865 Ethernet eth = new Ethernet();
866 eth.setEtherType(Ethernet.TYPE_IPV6)
867 .setVlanID(VLAN.toShort())
868 .setSourceMACAddress(MAC2.toBytes())
869 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
870 .setPayload(ipv6);
871 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
872 portNumber(INPORT));
873 return new DefaultInboundPacket(receivedFrom, eth,
874 ByteBuffer.wrap(eth.serialize()));
875 }
876
877 @Override
878 public OutboundPacket outPacket() {
879 return null;
880 }
881
882 @Override
883 public TrafficTreatment.Builder treatmentBuilder() {
884 return null;
885 }
886
887 @Override
888 public void send() {
889
890 }
891
892 @Override
893 public boolean block() {
894 return false;
895 }
896
897 @Override
898 public boolean isHandled() {
899 return false;
900 }
901 }
902
903 /**
904 * Generates IPv6 Multicast packet.
905 */
906 private class TestIpv6McastPacketContext implements PacketContext {
907 private final String deviceId;
908
909 public TestIpv6McastPacketContext(String deviceId) {
910 this.deviceId = deviceId;
911 }
912
913 @Override
914 public long time() {
915 return 0;
916 }
917
918 @Override
919 public InboundPacket inPacket() {
920 IPv6 ipv6 = new IPv6();
921 ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
922 ipv6.setSourceAddress(IP2);
923 Ethernet eth = new Ethernet();
924 eth.setEtherType(Ethernet.TYPE_IPV6)
925 .setVlanID(VLAN.toShort())
926 .setSourceMACAddress(MAC2.toBytes())
927 .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
928 .setPayload(ipv6);
929 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
930 portNumber(INPORT));
931 return new DefaultInboundPacket(receivedFrom, eth,
932 ByteBuffer.wrap(eth.serialize()));
933 }
934
935 @Override
936 public OutboundPacket outPacket() {
937 return null;
938 }
939
940 @Override
941 public TrafficTreatment.Builder treatmentBuilder() {
942 return null;
943 }
944
945 @Override
946 public void send() {
947
948 }
949
950 @Override
951 public boolean block() {
952 return false;
953 }
954
955 @Override
956 public boolean isHandled() {
957 return false;
958 }
959 }
960
961 /**
962 * Generates IPv6 Unicast packet.
963 */
964 private class TestIpv6PacketContext implements PacketContext {
965 private final String deviceId;
966
967 public TestIpv6PacketContext(String deviceId) {
968 this.deviceId = deviceId;
969 }
970
971 @Override
972 public long time() {
973 return 0;
974 }
975
976 @Override
977 public InboundPacket inPacket() {
978 IPv6 ipv6 = new IPv6();
979 ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
980 ipv6.setSourceAddress(IP2);
981 Ethernet eth = new Ethernet();
982 eth.setEtherType(Ethernet.TYPE_IPV6)
983 .setVlanID(VLAN.toShort())
984 .setSourceMACAddress(MAC2)
985 .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
986 .setPayload(ipv6);
987 ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
988 portNumber(INPORT));
989 return new DefaultInboundPacket(receivedFrom, eth,
990 ByteBuffer.wrap(eth.serialize()));
991 }
992
993 @Override
994 public OutboundPacket outPacket() {
995 return null;
996 }
997
998 @Override
999 public TrafficTreatment.Builder treatmentBuilder() {
1000 return null;
1001 }
1002
1003 @Override
1004 public void send() {
1005
1006 }
1007
1008 @Override
1009 public boolean block() {
1010 return false;
1011 }
1012
1013 @Override
1014 public boolean isHandled() {
1015 return false;
1016 }
1017 }
1018
Thomas Vachuska33601602014-11-19 03:32:15 -08001019 private class TestDeviceService extends DeviceServiceAdapter {
1020 private DeviceListener listener;
1021
1022 @Override
1023 public void addListener(DeviceListener listener) {
1024 this.listener = listener;
1025 }
Pavlin Radoslavovd36a74b2015-01-09 11:59:07 -08001026
1027 @Override
1028 public Iterable<Device> getDevices() {
1029 return Collections.emptyList();
1030 }
Thomas Vachuska33601602014-11-19 03:32:15 -08001031 }
1032
1033 private class TestHostService extends HostServiceAdapter {
1034 @Override
1035 public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
Charles Chan5d5e0622015-09-25 13:00:06 -07001036 ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
1037 ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
1038 if (connectPoint.equals(cp1)) {
1039 return ImmutableSet.of(HOST);
1040 } else if (connectPoint.equals(cp2)) {
1041 return ImmutableSet.of(HOST2);
1042 } else {
1043 return ImmutableSet.of();
1044 }
Thomas Vachuska33601602014-11-19 03:32:15 -08001045 }
1046
1047 @Override
1048 public Set<Host> getConnectedHosts(DeviceId deviceId) {
Charles Chan5d5e0622015-09-25 13:00:06 -07001049 if (deviceId.equals(deviceId(DEV1))) {
1050 return ImmutableSet.of(HOST);
1051 } else if (deviceId.equals(deviceId(DEV4))) {
1052 return ImmutableSet.of(HOST2);
1053 } else {
1054 return ImmutableSet.of();
1055 }
Thomas Vachuska33601602014-11-19 03:32:15 -08001056 }
1057
1058 }
alshabib4a179dc2014-10-17 17:17:01 -07001059}