6cbb623b6fe1de5044366a68a5dfbeae1eae3dc3
[onosfw.git] /
1 /*
2  * Copyright 2014-2015 Open Networking Laboratory
3  *
4  * 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
7  *
8  *     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.
15  */
16 package org.onosproject.provider.host.impl;
17
18 import com.google.common.collect.ImmutableSet;
19 import org.junit.After;
20 import org.junit.Before;
21 import org.junit.Test;
22 import org.onlab.osgi.ComponentContextAdapter;
23 import org.onlab.packet.ARP;
24 import org.onlab.packet.ChassisId;
25 import org.onlab.packet.Ethernet;
26 import org.onlab.packet.ICMP6;
27 import org.onlab.packet.IPv4;
28 import org.onlab.packet.IPv6;
29 import org.onlab.packet.Ip6Address;
30 import org.onlab.packet.IpAddress;
31 import org.onlab.packet.MacAddress;
32 import org.onlab.packet.VlanId;
33 import org.onlab.packet.ndp.NeighborAdvertisement;
34 import org.onlab.packet.ndp.NeighborSolicitation;
35 import org.onlab.packet.ndp.RouterAdvertisement;
36 import org.onlab.packet.ndp.RouterSolicitation;
37 import org.onosproject.cfg.ComponentConfigAdapter;
38 import org.onosproject.core.ApplicationId;
39 import org.onosproject.core.CoreService;
40 import org.onosproject.core.DefaultApplicationId;
41 import org.onosproject.net.ConnectPoint;
42 import org.onosproject.net.DefaultDevice;
43 import org.onosproject.net.DefaultHost;
44 import org.onosproject.net.DefaultPort;
45 import org.onosproject.net.Device;
46 import org.onosproject.net.DeviceId;
47 import org.onosproject.net.Host;
48 import org.onosproject.net.HostId;
49 import org.onosproject.net.HostLocation;
50 import org.onosproject.net.device.DeviceEvent;
51 import org.onosproject.net.device.DeviceListener;
52 import org.onosproject.net.device.DeviceServiceAdapter;
53 import org.onosproject.net.flow.TrafficTreatment;
54 import org.onosproject.net.host.HostDescription;
55 import org.onosproject.net.host.HostProvider;
56 import org.onosproject.net.host.HostProviderRegistry;
57 import org.onosproject.net.host.HostProviderService;
58 import org.onosproject.net.host.HostServiceAdapter;
59 import org.onosproject.net.packet.DefaultInboundPacket;
60 import org.onosproject.net.packet.InboundPacket;
61 import org.onosproject.net.packet.OutboundPacket;
62 import org.onosproject.net.packet.PacketContext;
63 import org.onosproject.net.packet.PacketProcessor;
64 import org.onosproject.net.packet.PacketServiceAdapter;
65 import org.onosproject.net.provider.AbstractProviderService;
66 import org.onosproject.net.provider.ProviderId;
67 import org.onosproject.net.topology.Topology;
68 import org.onosproject.net.topology.TopologyServiceAdapter;
69
70 import java.nio.ByteBuffer;
71 import java.util.Collections;
72 import java.util.Dictionary;
73 import java.util.Hashtable;
74 import java.util.Set;
75
76 import static org.easymock.EasyMock.*;
77 import static org.hamcrest.Matchers.is;
78 import static org.junit.Assert.*;
79 import static org.onlab.packet.VlanId.vlanId;
80 import static org.onosproject.net.Device.Type.SWITCH;
81 import static org.onosproject.net.DeviceId.deviceId;
82 import static org.onosproject.net.HostId.hostId;
83 import static org.onosproject.net.PortNumber.portNumber;
84 import static org.onosproject.net.device.DeviceEvent.Type.*;
85
86 public class HostLocationProviderTest {
87     private static final Integer INPORT = 10;
88     private static final String DEV1 = "of:1";
89     private static final String DEV2 = "of:2";
90     private static final String DEV3 = "of:3";
91     private static final String DEV4 = "of:4";
92     private static final String DEV5 = "of:5";
93     private static final String DEV6 = "of:6";
94
95     private static final VlanId VLAN = vlanId();
96
97     // IPv4 Host
98     private static final MacAddress MAC = MacAddress.valueOf("00:00:11:00:00:01");
99     private static final MacAddress BCMAC = MacAddress.valueOf("ff:ff:ff:ff:ff:ff");
100     private static final byte[] IP = new byte[]{10, 0, 0, 1};
101     private static final IpAddress IP_ADDRESS =
102             IpAddress.valueOf(IpAddress.Version.INET, IP);
103     private static final HostLocation LOCATION =
104             new HostLocation(deviceId(DEV1), portNumber(INPORT), 0L);
105     private static final DefaultHost HOST =
106             new DefaultHost(ProviderId.NONE, hostId(MAC), MAC,
107                             vlanId(VlanId.UNTAGGED), LOCATION,
108                             ImmutableSet.of(IP_ADDRESS));
109
110     // IPv6 Host
111     private static final MacAddress MAC2 = MacAddress.valueOf("00:00:22:00:00:02");
112     private static final MacAddress BCMAC2 = MacAddress.valueOf("33:33:00:00:00:01");
113     private static final byte[] IP2 = Ip6Address.valueOf("1000::1").toOctets();
114     private static final IpAddress IP_ADDRESS2 =
115             IpAddress.valueOf(IpAddress.Version.INET6, IP2);
116     private static final HostLocation LOCATION2 =
117             new HostLocation(deviceId(DEV4), portNumber(INPORT), 0L);
118     private static final DefaultHost HOST2 =
119             new DefaultHost(ProviderId.NONE, hostId(MAC2), MAC2,
120                             vlanId(VlanId.UNTAGGED), LOCATION2,
121                             ImmutableSet.of(IP_ADDRESS2));
122
123     private static final ComponentContextAdapter CTX_FOR_REMOVE =
124             new ComponentContextAdapter() {
125                 @Override
126                 public Dictionary getProperties() {
127                     Hashtable<String, String> props = new Hashtable<>();
128                     props.put("hostRemovalEnabled", "true");
129                     return props;
130                 }
131             };
132
133     public static final ComponentContextAdapter CTX_FOR_NO_REMOVE =
134             new ComponentContextAdapter() {
135                 @Override
136                 public Dictionary getProperties() {
137                     return new Hashtable();
138                 }
139             };
140
141     private final HostLocationProvider provider = new HostLocationProvider();
142     private final TestHostRegistry hostRegistry = new TestHostRegistry();
143     private final TestTopologyService topoService = new TestTopologyService();
144     private final TestDeviceService deviceService = new TestDeviceService();
145     private final TestHostService hostService = new TestHostService();
146     private final TestPacketService packetService = new TestPacketService();
147
148     private PacketProcessor testProcessor;
149     private CoreService coreService;
150     private TestHostProviderService providerService;
151
152     private ApplicationId appId =
153             new DefaultApplicationId(100, "org.onosproject.provider.host");
154
155     @Before
156     public void setUp() {
157
158         coreService = createMock(CoreService.class);
159         expect(coreService.registerApplication(appId.name()))
160                 .andReturn(appId).anyTimes();
161         replay(coreService);
162
163         provider.cfgService = new ComponentConfigAdapter();
164         provider.coreService = coreService;
165
166         provider.providerRegistry = hostRegistry;
167         provider.topologyService = topoService;
168         provider.packetService = packetService;
169         provider.deviceService = deviceService;
170         provider.hostService = hostService;
171
172         provider.activate(CTX_FOR_NO_REMOVE);
173     }
174
175     @Test
176     public void basics() {
177         assertNotNull("registration expected", providerService);
178         assertEquals("incorrect provider", provider, providerService.provider());
179     }
180
181     @Test
182     public void events() {
183         // new host
184         testProcessor.process(new TestArpPacketContext(DEV1));
185         assertNotNull("new host expected", providerService.added);
186         assertNull("host motion unexpected", providerService.moved);
187
188         // the host moved to new switch
189         testProcessor.process(new TestArpPacketContext(DEV2));
190         assertNotNull("host motion expected", providerService.moved);
191
192         // the host was misheard on a spine
193         testProcessor.process(new TestArpPacketContext(DEV3));
194         assertNull("host misheard on spine switch", providerService.spine);
195
196         providerService.clear();
197
198         // new host
199         testProcessor.process(new TestNAPacketContext(DEV4));
200         assertNotNull("new host expected", providerService.added);
201         assertNull("host motion unexpected", providerService.moved);
202
203         // the host moved to new switch
204         testProcessor.process(new TestNAPacketContext(DEV5));
205         assertNotNull("host motion expected", providerService.moved);
206
207         // the host was misheard on a spine
208         testProcessor.process(new TestNAPacketContext(DEV6));
209         assertNull("host misheard on spine switch", providerService.spine);
210     }
211
212     @Test
213     public void removeHostByDeviceRemove() {
214         provider.modified(CTX_FOR_REMOVE);
215         testProcessor.process(new TestArpPacketContext(DEV1));
216         testProcessor.process(new TestNAPacketContext(DEV4));
217
218         Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
219                                           "m", "h", "s", "n", new ChassisId(0L));
220         deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
221         assertEquals("incorrect remove count", 1, providerService.removeCount);
222
223         device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
224                                           "m", "h", "s", "n", new ChassisId(0L));
225         deviceService.listener.event(new DeviceEvent(DEVICE_REMOVED, device));
226         assertEquals("incorrect remove count", 2, providerService.removeCount);
227     }
228
229     @Test
230     public void removeHostByDeviceOffline() {
231         provider.modified(CTX_FOR_REMOVE);
232         testProcessor.process(new TestArpPacketContext(DEV1));
233         testProcessor.process(new TestArpPacketContext(DEV4));
234
235         Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
236                                           "m", "h", "s", "n", new ChassisId(0L));
237         deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
238         assertEquals("incorrect remove count", 1, providerService.removeCount);
239
240         device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
241                                           "m", "h", "s", "n", new ChassisId(0L));
242         deviceService.listener.event(new DeviceEvent(DEVICE_AVAILABILITY_CHANGED, device));
243         assertEquals("incorrect remove count", 2, providerService.removeCount);
244     }
245
246     @Test
247     public void removeHostByDevicePortDown() {
248         provider.modified(CTX_FOR_REMOVE);
249         testProcessor.process(new TestArpPacketContext(DEV1));
250         testProcessor.process(new TestArpPacketContext(DEV4));
251
252         Device device = new DefaultDevice(ProviderId.NONE, deviceId(DEV1), SWITCH,
253                                           "m", "h", "s", "n", new ChassisId(0L));
254         deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
255                 new DefaultPort(device, portNumber(INPORT), false)));
256         assertEquals("incorrect remove count", 1, providerService.removeCount);
257
258         device = new DefaultDevice(ProviderId.NONE, deviceId(DEV4), SWITCH,
259                                           "m", "h", "s", "n", new ChassisId(0L));
260         deviceService.listener.event(new DeviceEvent(PORT_UPDATED, device,
261                 new DefaultPort(device, portNumber(INPORT), false)));
262         assertEquals("incorrect remove count", 2, providerService.removeCount);
263     }
264
265     /**
266      * When receiving ARP, updates location and IP.
267      */
268     @Test
269     public void testReceiveArp() {
270         testProcessor.process(new TestArpPacketContext(DEV1));
271         HostDescription descr = providerService.added;
272         assertThat(descr.location(), is(LOCATION));
273         assertThat(descr.hwAddress(), is(MAC));
274         assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS));
275         assertThat(descr.vlan(), is(VLAN));
276     }
277
278     /**
279      * When receiving IPv4, updates location only.
280      */
281     @Test
282     public void testReceiveIpv4() {
283         testProcessor.process(new TestIpv4PacketContext(DEV1));
284         HostDescription descr = providerService.added;
285         assertThat(descr.location(), is(LOCATION));
286         assertThat(descr.hwAddress(), is(MAC));
287         assertThat(descr.ipAddress().size(), is(0));
288         assertThat(descr.vlan(), is(VLAN));
289     }
290
291     /**
292      * When receiving NeighborAdvertisement, updates location and IP.
293      */
294     @Test
295     public void testReceiveNA() {
296         testProcessor.process(new TestNAPacketContext(DEV4));
297         assertNotNull(providerService.added);
298         HostDescription descr = providerService.added;
299         assertThat(descr.location(), is(LOCATION2));
300         assertThat(descr.hwAddress(), is(MAC2));
301         assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
302         assertThat(descr.vlan(), is(VLAN));
303     }
304
305     /**
306      * When receiving NeighborSolicitation, updates location and IP.
307      */
308     @Test
309     public void testReceiveNS() {
310         testProcessor.process(new TestNSPacketContext(DEV4));
311         HostDescription descr = providerService.added;
312         assertThat(descr.location(), is(LOCATION2));
313         assertThat(descr.hwAddress(), is(MAC2));
314         assertThat(descr.ipAddress().toArray()[0], is(IP_ADDRESS2));
315         assertThat(descr.vlan(), is(VLAN));
316     }
317
318     /**
319      * When receiving RouterAdvertisement, ignores it.
320      */
321     @Test
322     public void testReceivesRA() {
323         testProcessor.process(new TestRAPacketContext(DEV4));
324         assertNull(providerService.added);
325     }
326
327     /**
328      * When receiving RouterSolicitation, ignores it.
329      */
330     @Test
331     public void testReceiveRS() {
332         testProcessor.process(new TestRSPacketContext(DEV4));
333         assertNull(providerService.added);
334     }
335
336     /**
337      * When receiving Duplicate Address Detection (DAD), ignores it.
338      */
339     @Test
340     public void testReceiveDAD() {
341         testProcessor.process(new TestDADPacketContext(DEV4));
342         assertNull(providerService.added);
343     }
344
345     /**
346      * When receiving IPv6 multicast packet, ignores it.
347      */
348     @Test
349     public void testReceiveIpv6Multicast() {
350         testProcessor.process(new TestIpv6McastPacketContext(DEV4));
351         assertNull(providerService.added);
352     }
353
354     /**
355      * When receiving IPv6 unicast packet, updates location only.
356      */
357     @Test
358     public void testReceiveIpv6Unicast() {
359         testProcessor.process(new TestIpv6PacketContext(DEV4));
360         assertNotNull(providerService.added);
361         HostDescription descr = providerService.added;
362         assertThat(descr.location(), is(LOCATION2));
363         assertThat(descr.hwAddress(), is(MAC2));
364         assertThat(descr.ipAddress().size(), is(0));
365         assertThat(descr.vlan(), is(VLAN));
366     }
367
368     @After
369     public void tearDown() {
370         provider.deactivate();
371         provider.coreService = null;
372         provider.providerRegistry = null;
373     }
374
375     private class TestHostRegistry implements HostProviderRegistry {
376
377         @Override
378         public HostProviderService register(HostProvider provider) {
379             providerService = new TestHostProviderService(provider);
380             return providerService;
381         }
382
383         @Override
384         public void unregister(HostProvider provider) {
385         }
386
387         @Override
388         public Set<ProviderId> getProviders() {
389             return null;
390         }
391
392     }
393
394     private class TestHostProviderService
395             extends AbstractProviderService<HostProvider>
396             implements HostProviderService {
397
398         HostDescription added = null;
399         HostDescription moved = null;
400         HostDescription spine = null;
401         public int removeCount;
402
403         public void clear() {
404             added = null;
405             moved = null;
406             spine = null;
407             removeCount = 0;
408         }
409
410         protected TestHostProviderService(HostProvider provider) {
411             super(provider);
412         }
413
414         @Override
415         public void hostDetected(HostId hostId, HostDescription hostDescription, boolean replaceIps) {
416             if (added == null) {
417                 added = hostDescription;
418             } else if ((moved == null) && !hostDescription.equals(added)) {
419                 moved = hostDescription;
420             } else {
421                 spine = hostDescription;
422             }
423         }
424
425         @Override
426         public void hostVanished(HostId hostId) {
427             removeCount++;
428         }
429
430         @Override
431         public void removeIpFromHost(HostId hostId, IpAddress ipAddress) {
432         }
433
434     }
435
436     private class TestPacketService extends PacketServiceAdapter {
437         @Override
438         public void addProcessor(PacketProcessor processor, int priority) {
439             testProcessor = processor;
440         }
441     }
442
443     private class TestTopologyService extends TopologyServiceAdapter {
444         @Override
445         public boolean isInfrastructure(Topology topology,
446                                         ConnectPoint connectPoint) {
447             //simulate DPID3 as an infrastructure switch
448             if ((connectPoint.deviceId()).equals(deviceId(DEV3)) ||
449                     connectPoint.deviceId().equals(deviceId(DEV6))) {
450                 return true;
451             }
452             return false;
453         }
454     }
455
456     /**
457      * Generates ARP packet.
458      */
459     private class TestArpPacketContext implements PacketContext {
460         private final String deviceId;
461
462         public TestArpPacketContext(String deviceId) {
463             this.deviceId = deviceId;
464         }
465
466         @Override
467         public long time() {
468             return 0;
469         }
470
471         @Override
472         public InboundPacket inPacket() {
473             ARP arp = new ARP();
474             arp.setSenderProtocolAddress(IP)
475                     .setSenderHardwareAddress(MAC.toBytes())
476                     .setTargetHardwareAddress(BCMAC.toBytes())
477                     .setTargetProtocolAddress(IP);
478
479             Ethernet eth = new Ethernet();
480             eth.setEtherType(Ethernet.TYPE_ARP)
481                     .setVlanID(VLAN.toShort())
482                     .setSourceMACAddress(MAC.toBytes())
483                     .setDestinationMACAddress(BCMAC)
484                     .setPayload(arp);
485             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
486                                                          portNumber(INPORT));
487             return new DefaultInboundPacket(receivedFrom, eth,
488                                             ByteBuffer.wrap(eth.serialize()));
489         }
490
491         @Override
492         public OutboundPacket outPacket() {
493             return null;
494         }
495
496         @Override
497         public TrafficTreatment.Builder treatmentBuilder() {
498             return null;
499         }
500
501         @Override
502         public void send() {
503
504         }
505
506         @Override
507         public boolean block() {
508             return false;
509         }
510
511         @Override
512         public boolean isHandled() {
513             return false;
514         }
515     }
516
517     /**
518      * Generates IPv6 Unicast packet.
519      */
520     private class TestIpv4PacketContext implements PacketContext {
521         private final String deviceId;
522
523         public TestIpv4PacketContext(String deviceId) {
524             this.deviceId = deviceId;
525         }
526
527         @Override
528         public long time() {
529             return 0;
530         }
531
532         @Override
533         public InboundPacket inPacket() {
534             IPv4 ipv4 = new IPv4();
535             ipv4.setDestinationAddress("10.0.0.1");
536             ipv4.setSourceAddress(IP_ADDRESS.toString());
537             Ethernet eth = new Ethernet();
538             eth.setEtherType(Ethernet.TYPE_IPV4)
539                     .setVlanID(VLAN.toShort())
540                     .setSourceMACAddress(MAC)
541                     .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
542                     .setPayload(ipv4);
543             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
544                                                          portNumber(INPORT));
545             return new DefaultInboundPacket(receivedFrom, eth,
546                                             ByteBuffer.wrap(eth.serialize()));
547         }
548
549         @Override
550         public OutboundPacket outPacket() {
551             return null;
552         }
553
554         @Override
555         public TrafficTreatment.Builder treatmentBuilder() {
556             return null;
557         }
558
559         @Override
560         public void send() {
561
562         }
563
564         @Override
565         public boolean block() {
566             return false;
567         }
568
569         @Override
570         public boolean isHandled() {
571             return false;
572         }
573     }
574
575     /**
576      * Generates NeighborAdvertisement packet.
577      */
578     private class TestNAPacketContext implements PacketContext {
579         private final String deviceId;
580
581         public TestNAPacketContext(String deviceId) {
582             this.deviceId = deviceId;
583         }
584
585         @Override
586         public long time() {
587             return 0;
588         }
589
590         @Override
591         public InboundPacket inPacket() {
592             NeighborAdvertisement na = new NeighborAdvertisement();
593             ICMP6 icmp6 = new ICMP6();
594             icmp6.setPayload(na);
595             IPv6 ipv6 = new IPv6();
596             ipv6.setPayload(icmp6);
597             ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
598             ipv6.setSourceAddress(IP2);
599             Ethernet eth = new Ethernet();
600             eth.setEtherType(Ethernet.TYPE_IPV6)
601                     .setVlanID(VLAN.toShort())
602                     .setSourceMACAddress(MAC2.toBytes())
603                     .setDestinationMACAddress(BCMAC2)
604                     .setPayload(ipv6);
605             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
606                                                          portNumber(INPORT));
607             return new DefaultInboundPacket(receivedFrom, eth,
608                                             ByteBuffer.wrap(eth.serialize()));
609         }
610
611         @Override
612         public OutboundPacket outPacket() {
613             return null;
614         }
615
616         @Override
617         public TrafficTreatment.Builder treatmentBuilder() {
618             return null;
619         }
620
621         @Override
622         public void send() {
623
624         }
625
626         @Override
627         public boolean block() {
628             return false;
629         }
630
631         @Override
632         public boolean isHandled() {
633             return false;
634         }
635     }
636
637     /**
638      * Generates NeighborSolicitation packet.
639      */
640     private class TestNSPacketContext implements PacketContext {
641         private final String deviceId;
642
643         public TestNSPacketContext(String deviceId) {
644             this.deviceId = deviceId;
645         }
646
647         @Override
648         public long time() {
649             return 0;
650         }
651
652         @Override
653         public InboundPacket inPacket() {
654             NeighborSolicitation ns = new NeighborSolicitation();
655             ICMP6 icmp6 = new ICMP6();
656             icmp6.setPayload(ns);
657             IPv6 ipv6 = new IPv6();
658             ipv6.setPayload(icmp6);
659             ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1:ff00:0000").toOctets());
660             ipv6.setSourceAddress(IP2);
661             Ethernet eth = new Ethernet();
662             eth.setEtherType(Ethernet.TYPE_IPV6)
663                     .setVlanID(VLAN.toShort())
664                     .setSourceMACAddress(MAC2.toBytes())
665                     .setDestinationMACAddress(BCMAC2)
666                     .setPayload(ipv6);
667             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
668                                                          portNumber(INPORT));
669             return new DefaultInboundPacket(receivedFrom, eth,
670                                             ByteBuffer.wrap(eth.serialize()));
671         }
672
673         @Override
674         public OutboundPacket outPacket() {
675             return null;
676         }
677
678         @Override
679         public TrafficTreatment.Builder treatmentBuilder() {
680             return null;
681         }
682
683         @Override
684         public void send() {
685
686         }
687
688         @Override
689         public boolean block() {
690             return false;
691         }
692
693         @Override
694         public boolean isHandled() {
695             return false;
696         }
697     }
698
699     /**
700      * Generates Duplicate Address Detection packet.
701      */
702     private class TestDADPacketContext implements PacketContext {
703         private final String deviceId;
704
705         public TestDADPacketContext(String deviceId) {
706             this.deviceId = deviceId;
707         }
708
709         @Override
710         public long time() {
711             return 0;
712         }
713
714         @Override
715         public InboundPacket inPacket() {
716             NeighborSolicitation ns = new NeighborSolicitation();
717             ICMP6 icmp6 = new ICMP6();
718             icmp6.setPayload(ns);
719             IPv6 ipv6 = new IPv6();
720             ipv6.setPayload(icmp6);
721             ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
722             ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
723             Ethernet eth = new Ethernet();
724             eth.setEtherType(Ethernet.TYPE_IPV6)
725                     .setVlanID(VLAN.toShort())
726                     .setSourceMACAddress(MAC2.toBytes())
727                     .setDestinationMACAddress(BCMAC2)
728                     .setPayload(ipv6);
729             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
730                                                          portNumber(INPORT));
731             return new DefaultInboundPacket(receivedFrom, eth,
732                                             ByteBuffer.wrap(eth.serialize()));
733         }
734
735         @Override
736         public OutboundPacket outPacket() {
737             return null;
738         }
739
740         @Override
741         public TrafficTreatment.Builder treatmentBuilder() {
742             return null;
743         }
744
745         @Override
746         public void send() {
747
748         }
749
750         @Override
751         public boolean block() {
752             return false;
753         }
754
755         @Override
756         public boolean isHandled() {
757             return false;
758         }
759     }
760
761     /**
762      * Generates Router Solicitation packet.
763      */
764     private class TestRSPacketContext implements PacketContext {
765         private final String deviceId;
766
767         public TestRSPacketContext(String deviceId) {
768             this.deviceId = deviceId;
769         }
770
771         @Override
772         public long time() {
773             return 0;
774         }
775
776         @Override
777         public InboundPacket inPacket() {
778             RouterSolicitation ns = new RouterSolicitation();
779             ICMP6 icmp6 = new ICMP6();
780             icmp6.setPayload(ns);
781             IPv6 ipv6 = new IPv6();
782             ipv6.setPayload(icmp6);
783             ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::2").toOctets());
784             ipv6.setSourceAddress(Ip6Address.valueOf("::").toOctets());
785             Ethernet eth = new Ethernet();
786             eth.setEtherType(Ethernet.TYPE_IPV6)
787                     .setVlanID(VLAN.toShort())
788                     .setSourceMACAddress(MAC2.toBytes())
789                     .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:02"))
790                     .setPayload(ipv6);
791             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
792                                                          portNumber(INPORT));
793             return new DefaultInboundPacket(receivedFrom, eth,
794                                             ByteBuffer.wrap(eth.serialize()));
795         }
796
797         @Override
798         public OutboundPacket outPacket() {
799             return null;
800         }
801
802         @Override
803         public TrafficTreatment.Builder treatmentBuilder() {
804             return null;
805         }
806
807         @Override
808         public void send() {
809
810         }
811
812         @Override
813         public boolean block() {
814             return false;
815         }
816
817         @Override
818         public boolean isHandled() {
819             return false;
820         }
821     }
822
823     /**
824      * Generates Router Advertisement packet.
825      */
826     private class TestRAPacketContext implements PacketContext {
827         private final String deviceId;
828
829         public TestRAPacketContext(String deviceId) {
830             this.deviceId = deviceId;
831         }
832
833         @Override
834         public long time() {
835             return 0;
836         }
837
838         @Override
839         public InboundPacket inPacket() {
840             RouterAdvertisement ns = new RouterAdvertisement();
841             ICMP6 icmp6 = new ICMP6();
842             icmp6.setPayload(ns);
843             IPv6 ipv6 = new IPv6();
844             ipv6.setPayload(icmp6);
845             ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
846             ipv6.setSourceAddress(IP2);
847             Ethernet eth = new Ethernet();
848             eth.setEtherType(Ethernet.TYPE_IPV6)
849                     .setVlanID(VLAN.toShort())
850                     .setSourceMACAddress(MAC2.toBytes())
851                     .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
852                     .setPayload(ipv6);
853             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
854                                                          portNumber(INPORT));
855             return new DefaultInboundPacket(receivedFrom, eth,
856                                             ByteBuffer.wrap(eth.serialize()));
857         }
858
859         @Override
860         public OutboundPacket outPacket() {
861             return null;
862         }
863
864         @Override
865         public TrafficTreatment.Builder treatmentBuilder() {
866             return null;
867         }
868
869         @Override
870         public void send() {
871
872         }
873
874         @Override
875         public boolean block() {
876             return false;
877         }
878
879         @Override
880         public boolean isHandled() {
881             return false;
882         }
883     }
884
885     /**
886      * Generates IPv6 Multicast packet.
887      */
888     private class TestIpv6McastPacketContext implements PacketContext {
889         private final String deviceId;
890
891         public TestIpv6McastPacketContext(String deviceId) {
892             this.deviceId = deviceId;
893         }
894
895         @Override
896         public long time() {
897             return 0;
898         }
899
900         @Override
901         public InboundPacket inPacket() {
902             IPv6 ipv6 = new IPv6();
903             ipv6.setDestinationAddress(Ip6Address.valueOf("ff02::1").toOctets());
904             ipv6.setSourceAddress(IP2);
905             Ethernet eth = new Ethernet();
906             eth.setEtherType(Ethernet.TYPE_IPV6)
907                     .setVlanID(VLAN.toShort())
908                     .setSourceMACAddress(MAC2.toBytes())
909                     .setDestinationMACAddress(MacAddress.valueOf("33:33:00:00:00:01"))
910                     .setPayload(ipv6);
911             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
912                                                          portNumber(INPORT));
913             return new DefaultInboundPacket(receivedFrom, eth,
914                                             ByteBuffer.wrap(eth.serialize()));
915         }
916
917         @Override
918         public OutboundPacket outPacket() {
919             return null;
920         }
921
922         @Override
923         public TrafficTreatment.Builder treatmentBuilder() {
924             return null;
925         }
926
927         @Override
928         public void send() {
929
930         }
931
932         @Override
933         public boolean block() {
934             return false;
935         }
936
937         @Override
938         public boolean isHandled() {
939             return false;
940         }
941     }
942
943     /**
944      * Generates IPv6 Unicast packet.
945      */
946     private class TestIpv6PacketContext implements PacketContext {
947         private final String deviceId;
948
949         public TestIpv6PacketContext(String deviceId) {
950             this.deviceId = deviceId;
951         }
952
953         @Override
954         public long time() {
955             return 0;
956         }
957
958         @Override
959         public InboundPacket inPacket() {
960             IPv6 ipv6 = new IPv6();
961             ipv6.setDestinationAddress(Ip6Address.valueOf("1000::1").toOctets());
962             ipv6.setSourceAddress(IP2);
963             Ethernet eth = new Ethernet();
964             eth.setEtherType(Ethernet.TYPE_IPV6)
965                     .setVlanID(VLAN.toShort())
966                     .setSourceMACAddress(MAC2)
967                     .setDestinationMACAddress(MacAddress.valueOf("00:00:00:00:00:01"))
968                     .setPayload(ipv6);
969             ConnectPoint receivedFrom = new ConnectPoint(deviceId(deviceId),
970                                                          portNumber(INPORT));
971             return new DefaultInboundPacket(receivedFrom, eth,
972                                             ByteBuffer.wrap(eth.serialize()));
973         }
974
975         @Override
976         public OutboundPacket outPacket() {
977             return null;
978         }
979
980         @Override
981         public TrafficTreatment.Builder treatmentBuilder() {
982             return null;
983         }
984
985         @Override
986         public void send() {
987
988         }
989
990         @Override
991         public boolean block() {
992             return false;
993         }
994
995         @Override
996         public boolean isHandled() {
997             return false;
998         }
999     }
1000
1001     private class TestDeviceService extends DeviceServiceAdapter {
1002         private DeviceListener listener;
1003
1004         @Override
1005         public void addListener(DeviceListener listener) {
1006             this.listener = listener;
1007         }
1008
1009         @Override
1010         public Iterable<Device> getDevices() {
1011             return Collections.emptyList();
1012         }
1013     }
1014
1015     private class TestHostService extends HostServiceAdapter {
1016         @Override
1017         public Set<Host> getConnectedHosts(ConnectPoint connectPoint) {
1018             ConnectPoint cp1 = new ConnectPoint(deviceId(DEV1), portNumber(INPORT));
1019             ConnectPoint cp2 = new ConnectPoint(deviceId(DEV4), portNumber(INPORT));
1020             if (connectPoint.equals(cp1)) {
1021                 return ImmutableSet.of(HOST);
1022             } else if (connectPoint.equals(cp2)) {
1023                 return ImmutableSet.of(HOST2);
1024             } else {
1025                 return ImmutableSet.of();
1026             }
1027         }
1028
1029         @Override
1030         public Set<Host> getConnectedHosts(DeviceId deviceId) {
1031             if (deviceId.equals(deviceId(DEV1))) {
1032                 return ImmutableSet.of(HOST);
1033             } else if (deviceId.equals(deviceId(DEV4))) {
1034                 return ImmutableSet.of(HOST2);
1035             } else {
1036                 return ImmutableSet.of();
1037             }
1038         }
1039
1040     }
1041 }