blob: ab2b7f42d22ab3801b210ebed6d667988c53eeec [file] [log] [blame]
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -07001/*
2 * Copyright 2016-present 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
17package org.onosproject.vpls;
18
19import com.google.common.collect.HashMultimap;
20import com.google.common.collect.ImmutableSet;
21import com.google.common.collect.ImmutableSetMultimap;
Luca Prete092e8952016-10-26 16:25:56 +020022import com.google.common.collect.Maps;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070023import com.google.common.collect.SetMultimap;
24import com.google.common.collect.Sets;
25import org.junit.After;
26import org.junit.Before;
27import org.junit.Test;
28import org.onlab.packet.Ethernet;
29import org.onlab.packet.IpAddress;
30import org.onlab.packet.MacAddress;
31import org.onlab.packet.VlanId;
32import org.onosproject.core.ApplicationId;
33import org.onosproject.incubator.net.intf.Interface;
34import org.onosproject.incubator.net.intf.InterfaceListener;
35import org.onosproject.incubator.net.intf.InterfaceService;
36import org.onosproject.incubator.net.neighbour.NeighbourHandlerRegistration;
37import org.onosproject.incubator.net.neighbour.NeighbourMessageContext;
38import org.onosproject.incubator.net.neighbour.NeighbourMessageHandler;
39import org.onosproject.incubator.net.neighbour.NeighbourMessageType;
40import org.onosproject.incubator.net.neighbour.NeighbourProtocol;
41import org.onosproject.incubator.net.neighbour.NeighbourResolutionService;
42import org.onosproject.net.ConnectPoint;
43import org.onosproject.net.DefaultHost;
44import org.onosproject.net.DeviceId;
Luca Prete092e8952016-10-26 16:25:56 +020045import org.onosproject.net.EncapsulationType;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070046import org.onosproject.net.Host;
47import org.onosproject.net.HostId;
48import org.onosproject.net.HostLocation;
49import org.onosproject.net.PortNumber;
50import org.onosproject.net.host.HostService;
51import org.onosproject.net.host.HostServiceAdapter;
52import org.onosproject.net.provider.ProviderId;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070053
54import java.util.Collection;
Luca Prete092e8952016-10-26 16:25:56 +020055import java.util.HashMap;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070056import java.util.Map;
57import java.util.Set;
58import java.util.stream.Collectors;
59
60import static junit.framework.TestCase.assertEquals;
61
62/**
63 * Tests the the {@link VplsNeighbourHandler} class.
64 */
65public class VplsNeighbourHandlerTest {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070066
Luca Prete092e8952016-10-26 16:25:56 +020067 private static final String IFACES_NOT_EXPECTED =
68 "The interfaces reached by the packet are not equal to the " +
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010069 "interfaces expected.";
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070070
Luca Prete092e8952016-10-26 16:25:56 +020071 private static final DeviceId DID1 = getDeviceId(1);
72 private static final DeviceId DID2 = getDeviceId(2);
73 private static final DeviceId DID3 = getDeviceId(3);
74 private static final DeviceId DID4 = getDeviceId(4);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010075 private static final DeviceId DID5 = getDeviceId(5);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070076
Luca Prete092e8952016-10-26 16:25:56 +020077 private static final PortNumber P1 = PortNumber.portNumber(1);
78 private static final PortNumber P2 = PortNumber.portNumber(2);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010079 private static final PortNumber P3 = PortNumber.portNumber(3);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070080
Luca Prete092e8952016-10-26 16:25:56 +020081 private static final ConnectPoint OF1P1 = new ConnectPoint(DID1, P1);
82 private static final ConnectPoint OF2P1 = new ConnectPoint(DID2, P1);
83 private static final ConnectPoint OF3P1 = new ConnectPoint(DID3, P1);
84 private static final ConnectPoint OF4P1 = new ConnectPoint(DID4, P1);
85 private static final ConnectPoint OF4P2 = new ConnectPoint(DID4, P2);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010086 private static final ConnectPoint OF4P3 = new ConnectPoint(DID4, P3);
87 private static final ConnectPoint OF5P1 = new ConnectPoint(DID5, P1);
88 private static final ConnectPoint OF5P2 = new ConnectPoint(DID5, P2);
89 private static final ConnectPoint OF5P3 = new ConnectPoint(DID5, P3);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070090
Luca Prete092e8952016-10-26 16:25:56 +020091 private static final String VPLS1 = "vpls1";
92 private static final String VPLS2 = "vpls2";
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010093 private static final String VPLS3 = "vpls3";
94 private static final String VPLS4 = "vpls4";
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -070095
Luca Prete092e8952016-10-26 16:25:56 +020096 private static final VlanId VLAN100 = VlanId.vlanId("100");
97 private static final VlanId VLAN200 = VlanId.vlanId("200");
98 private static final VlanId VLAN300 = VlanId.vlanId("300");
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +010099 private static final VlanId VLAN400 = VlanId.vlanId("400");
100 private static final VlanId VLAN_NONE = VlanId.NONE;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700101
Luca Prete092e8952016-10-26 16:25:56 +0200102 private static final Interface V100H1 =
103 new Interface("v100h1", OF1P1, null, null, VLAN100);
104 private static final Interface V100H2 =
105 new Interface("v100h2", OF4P1, null, null, VLAN100);
106 private static final Interface V200H1 =
107 new Interface("v200h1", OF4P2, null, null, VLAN200);
108 private static final Interface V200H2 =
109 new Interface("v200h2", OF2P1, null, null, VLAN200);
110 private static final Interface V300H1 =
111 new Interface("v300h1", OF3P1, null, null, VLAN300);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100112 private static final Interface V400H1 =
113 new Interface("v400h1", OF5P1, null, null, VLAN400);
114 private static final Interface VNONEH1 =
115 new Interface("vNoneh1", OF5P2, null, null, VLAN_NONE);
116 private static final Interface VNONEH2 =
117 new Interface("vNoneh2", OF5P3, null, null, VLAN_NONE);
118 private static final Interface VNONEH3 =
119 new Interface("vNoneh3", OF4P3, null, null, VLAN_NONE);
Luca Prete092e8952016-10-26 16:25:56 +0200120
121 private static final MacAddress MAC1 = MacAddress.valueOf("00:00:00:00:00:01");
122 private static final MacAddress MAC2 = MacAddress.valueOf("00:00:00:00:00:02");
123 private static final MacAddress MAC3 = MacAddress.valueOf("00:00:00:00:00:03");
124 private static final MacAddress MAC4 = MacAddress.valueOf("00:00:00:00:00:04");
125 private static final MacAddress MAC5 = MacAddress.valueOf("00:00:00:00:00:05");
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100126 private static final MacAddress MAC6 = MacAddress.valueOf("00:00:00:00:00:06");
127 private static final MacAddress MAC7 = MacAddress.valueOf("00:00:00:00:00:07");
128 private static final MacAddress MAC8 = MacAddress.valueOf("00:00:00:00:00:08");
129 private static final MacAddress MAC9 = MacAddress.valueOf("00:00:00:00:00:09");
Luca Prete092e8952016-10-26 16:25:56 +0200130
131 private static final ProviderId PID = new ProviderId("of", "foo");
132
133 private final Host v100Host1 = makeHost(MAC1, VLAN100, OF1P1);
134 private final Host v100Host2 = makeHost(MAC2, VLAN100, OF4P1);
135 private final Host v200Host1 = makeHost(MAC3, VLAN200, OF4P2);
136 private final Host v200Host2 = makeHost(MAC5, VLAN200, OF2P1);
137 private final Host v300Host1 = makeHost(MAC4, VLAN300, OF3P1);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100138 private final Host v400Host1 = makeHost(MAC6, VLAN400, OF5P1);
139 private final Host vNoneHost1 = makeHost(MAC7, VLAN_NONE, OF5P2);
140 private final Host vNoneHost2 = makeHost(MAC8, VLAN_NONE, OF5P3);
141 private final Host vNoneHost3 = makeHost(MAC9, VLAN_NONE, OF4P3);
Luca Prete092e8952016-10-26 16:25:56 +0200142
143 private final Set<Host> availableHosts = ImmutableSet.of(v100Host1,
144 v100Host2,
145 v200Host1,
146 v300Host1,
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100147 v200Host2,
148 v400Host1,
149 vNoneHost1,
150 vNoneHost2,
151 vNoneHost3);
Luca Prete092e8952016-10-26 16:25:56 +0200152
153 private final Set<Interface> availableInterfaces =
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100154 ImmutableSet.of(V100H1, V100H2, V200H1, V200H2, V300H1,
155 V400H1, VNONEH1, VNONEH2, VNONEH3);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700156
157 private VplsNeighbourHandler vplsNeighbourHandler;
158
159 private HostService hostService;
160
161 /**
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100162 * Sets up 4 VPLS.
Luca Prete092e8952016-10-26 16:25:56 +0200163 * VPLS 1 contains 3 hosts: v100h1, v200h1 and v300h1
164 * VPLS 2 contains 2 hosts: v100h2, v200h2
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100165 * VPLS 3 contains 2 hosts: vNoneh1, vNoneh2
166 * VPLS 4 contains 2 hosts: v400h1, vNoneh3
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700167 */
168 @Before
169 public void setUp() {
170 vplsNeighbourHandler = new VplsNeighbourHandler();
Luca Prete092e8952016-10-26 16:25:56 +0200171 SetMultimap<String, Interface> ifacesByVpls =
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700172 HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200173 ifacesByVpls.put(VPLS1, V100H1);
174 ifacesByVpls.put(VPLS1, V200H1);
175 ifacesByVpls.put(VPLS1, V300H1);
176 ifacesByVpls.put(VPLS2, V100H2);
177 ifacesByVpls.put(VPLS2, V200H2);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100178 ifacesByVpls.put(VPLS3, VNONEH1);
179 ifacesByVpls.put(VPLS3, VNONEH2);
180 ifacesByVpls.put(VPLS4, V400H1);
181 ifacesByVpls.put(VPLS4, VNONEH3);
Luca Prete092e8952016-10-26 16:25:56 +0200182 HashMap<String, EncapsulationType> encap = Maps.newHashMap();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700183 vplsNeighbourHandler.vplsConfigService =
Luca Prete092e8952016-10-26 16:25:56 +0200184 new TestVplsConfigService(ifacesByVpls, encap);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700185 vplsNeighbourHandler.interfaceService =
186 new TestInterfaceService();
187 vplsNeighbourHandler.neighbourService =
188 new TestNeighbourService();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700189 hostService = new TestHostService();
190 }
191
192 @After
193 public void tearDown() {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700194 }
195
196 /**
Luca Prete092e8952016-10-26 16:25:56 +0200197 * Sends request messages to all hosts in VPLS 1.
198 * Request messages should be received from other hosts in VPLS 1.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700199 */
200 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200201 public void vpls1RequestMessage() {
202 // Request messages from v100h1 (VPLS 1) should be received by v200h1 and v300h1
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700203 TestMessageContext requestMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200204 makeBroadcastRequestContext(v100Host1);
205 Set<Interface> expectInterfaces = ImmutableSet.of(V200H1, V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700206 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200207 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700208
Luca Prete092e8952016-10-26 16:25:56 +0200209 // Request messages from v200h1 (VPLS 1) should be received by v100h1 and v300h1
210 requestMessage = makeBroadcastRequestContext(v200Host1);
211 expectInterfaces = ImmutableSet.of(V100H1, V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700212 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200213 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700214
Luca Prete092e8952016-10-26 16:25:56 +0200215 // Request from v300h1 (VPLS 1) should be received by v100h1 and v200h1
216 requestMessage = makeBroadcastRequestContext(v300Host1);
217 expectInterfaces = ImmutableSet.of(V100H1, V200H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700218 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200219 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700220 }
221
222 /**
Luca Prete092e8952016-10-26 16:25:56 +0200223 * Sends request messages to all hosts in VPLS 2.
224 * Request messages should be received from other hosts in VPLS 2.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700225 */
226 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200227 public void vpls2RequestMessage() {
228 // Request messages from v100h2 (VPLS 2) should be received by v200h2
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700229 TestMessageContext requestMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200230 makeBroadcastRequestContext(v100Host2);
231 Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700232 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200233 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700234
Luca Prete092e8952016-10-26 16:25:56 +0200235 // Request messages from v200h2 (VPLS 2) should be received by v100h2
236 requestMessage = makeBroadcastRequestContext(v200Host2);
237 expectInterfaces = ImmutableSet.of(V100H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700238 vplsNeighbourHandler.handleRequest(requestMessage);
Luca Prete092e8952016-10-26 16:25:56 +0200239 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700240 }
241
242 /**
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100243 * Tests correct connection between untagged interfaces.
244 *
245 * Sends request messages to all hosts in VPLS 3.
246 * Request messages should be received from other hosts in VPLS 3.
247 */
248 @Test
249 public void vpls3RequestMessage() {
250 // Request messages from vNoneHost1 (VPLS 3) should be received by vNoneHost2
251 TestMessageContext requestMessage =
252 makeBroadcastRequestContext(vNoneHost1);
253 Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
254 vplsNeighbourHandler.handleRequest(requestMessage);
255 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
256
257 // Request messages from vNoneh2 (VPLS 3) should be received by vNoneh1
258 requestMessage = makeBroadcastRequestContext(vNoneHost2);
259 expectInterfaces = ImmutableSet.of(VNONEH1);
260 vplsNeighbourHandler.handleRequest(requestMessage);
261 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
262 }
263
264 /**
265 * Tests correct connection between tagged and untagged interfaces.
266 *
267 * Sends request messages to all hosts in VPLS 4.
268 * Request messages should be received from other hosts in VPLS 4.
269 */
270 @Test
271 public void vpls4RequestMessage() {
272 // Request messages from v400Host1 (VPLS 4) should be received by vNoneHost3
273 TestMessageContext requestMessage =
274 makeBroadcastRequestContext(v400Host1);
275 Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
276 vplsNeighbourHandler.handleRequest(requestMessage);
277 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
278
279 // Request messages from vNoneHost3 (VPLS 4) should be received by v400Host1
280 requestMessage = makeBroadcastRequestContext(vNoneHost3);
281 expectInterfaces = ImmutableSet.of(V400H1);
282 vplsNeighbourHandler.handleRequest(requestMessage);
283 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, requestMessage.forwardResults);
284 }
285
286 /**
Luca Prete092e8952016-10-26 16:25:56 +0200287 * Sends reply messages to hosts in VPLS 1.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700288 * Reply messages should be received by the host with MAC address equal to
289 * the dstMac of the message context.
290 */
291 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200292 public void vpls1ReplyMessage() {
293 // Reply messages from v100h1 (VPLS 1) should be received by v200h1
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700294 TestMessageContext replyMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200295 makeReplyContext(v100Host1, v200Host1);
296 Set<Interface> expectInterfaces = ImmutableSet.of(V200H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700297 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200298 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700299
Luca Prete092e8952016-10-26 16:25:56 +0200300 // Reply messages from v200h1 (VPLS 1) should be received by v300h1
301 replyMessage = makeReplyContext(v200Host1, v300Host1);
302 expectInterfaces = ImmutableSet.of(V300H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700303 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200304 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700305
Luca Prete092e8952016-10-26 16:25:56 +0200306 // Reply messages from v300h1 (VPLS 1) should be received by v100h1
307 replyMessage = makeReplyContext(v300Host1, v100Host1);
308 expectInterfaces = ImmutableSet.of(V100H1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700309 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200310 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700311 }
312
313 /**
Luca Prete092e8952016-10-26 16:25:56 +0200314 * Sends reply messages to hosts in VPLS 2.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700315 * Reply messages should be received by the host with MAC address equal to
316 * the dstMac of the message context.
317 */
318 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200319 public void vpls2ReplyMessage() {
320 // Reply messages from v100h2 (VPLS 2) should be received by v200h2
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700321 TestMessageContext replyMessage =
Luca Prete092e8952016-10-26 16:25:56 +0200322 makeReplyContext(v100Host2, v200Host2);
323 Set<Interface> expectInterfaces = ImmutableSet.of(V200H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700324 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200325 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700326
Luca Prete092e8952016-10-26 16:25:56 +0200327 // Reply messages from v200h2 (VPLS 2) should be received by v100h2
328 replyMessage = makeReplyContext(v200Host2, v100Host2);
329 expectInterfaces = ImmutableSet.of(V100H2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700330 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200331 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700332 }
333
334 /**
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100335 * Sends reply messages to hosts in VPLS 3.
336 * Reply messages should be received by the host with MAC address equal to
337 * the dstMac of the message context.
338 */
339 @Test
340 public void vpls3ReplyMessage() {
341 // Reply messages from vNoneh1 (VPLS 3) should be received by vNoneh2
342 TestMessageContext replyMessage =
343 makeReplyContext(vNoneHost1, vNoneHost2);
344 Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH2);
345 vplsNeighbourHandler.handleReply(replyMessage, hostService);
346 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
347
348 // Reply messages from vNoneh2 (VPLS 3) should be received by vNoneh1
349 replyMessage = makeReplyContext(vNoneHost2, vNoneHost1);
350 expectInterfaces = ImmutableSet.of(VNONEH1);
351 vplsNeighbourHandler.handleReply(replyMessage, hostService);
352 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
353 }
354
355 /**
356 * Sends reply messages to hosts in VPLS 4.
357 * Reply messages should be received by the host with MAC address equal to
358 * the dstMac of the message context.
359 */
360 @Test
361 public void vpls4ReplyMessage() {
362 // Reply messages from v400h1 (VPLS 4) should be received by vNoneh3
363 TestMessageContext replyMessage =
364 makeReplyContext(v400Host1, vNoneHost3);
365 Set<Interface> expectInterfaces = ImmutableSet.of(VNONEH3);
366 vplsNeighbourHandler.handleReply(replyMessage, hostService);
367 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
368
369 // Reply messages from vNoneh3 (VPLS 4) should be received by v400h1
370 replyMessage = makeReplyContext(vNoneHost3, v400Host1);
371 expectInterfaces = ImmutableSet.of(V400H1);
372 vplsNeighbourHandler.handleReply(replyMessage, hostService);
373 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
374 }
375
376 /**
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700377 * Sends wrong reply messages to hosts.
378 * The source and the destination MAC addresses are not set on any host of the VPLS.
Luca Prete092e8952016-10-26 16:25:56 +0200379 * The reply messages will not be received by any hosts.
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700380 */
381 @Test
Luca Prete092e8952016-10-26 16:25:56 +0200382 public void wrongReplyMessage() {
383 // Reply message from v100h1 (VPLS 1) to v100h2 (VPLS 2).
384 // Forward results should be empty
385 TestMessageContext replyMessage = makeReplyContext(v100Host1, v100Host2);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700386 Set<Interface> expectInterfaces = ImmutableSet.of();
387 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200388 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700389
Luca Prete092e8952016-10-26 16:25:56 +0200390 // Reply message from v200h2 (VPLS 2) to v300h1 (VPLS 1).
391 // Forward results should be empty
392 replyMessage = makeReplyContext(v200Host2, v300Host1);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700393 expectInterfaces = ImmutableSet.of();
394 vplsNeighbourHandler.handleReply(replyMessage, hostService);
Luca Prete092e8952016-10-26 16:25:56 +0200395 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100396
397 // Reply message from vNoneh1 (VPLS 3) to v400h1 (VPLS 4).
398 // Forward results should be empty
399 replyMessage = makeReplyContext(vNoneHost1, v400Host1);
400 expectInterfaces = ImmutableSet.of();
401 vplsNeighbourHandler.handleReply(replyMessage, hostService);
402 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
403
404 // Reply message from vNoneh3 (VPLS 4) to vNoneH2 (VPLS 3).
405 // Forward results should be empty
406 replyMessage = makeReplyContext(vNoneHost3, vNoneHost2);
407 expectInterfaces = ImmutableSet.of();
408 vplsNeighbourHandler.handleReply(replyMessage, hostService);
409 assertEquals(IFACES_NOT_EXPECTED, expectInterfaces, replyMessage.forwardResults);
Luca Prete092e8952016-10-26 16:25:56 +0200410 }
411
412 /**
413 * Returns the device Id of the ith device.
414 *
415 * @param i the device to get the Id of
416 * @return the device Id
417 */
418 private static DeviceId getDeviceId(int i) {
419 return DeviceId.deviceId("" + i);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700420 }
421
422 private Host makeHost(MacAddress mac, VlanId vlan, ConnectPoint cp) {
Luca Prete092e8952016-10-26 16:25:56 +0200423 return new DefaultHost(PID,
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700424 HostId.hostId(mac, vlan),
425 mac,
426 vlan,
427 new HostLocation(cp, 0),
428 Sets.newHashSet());
429 }
430
431 private TestMessageContext makeBroadcastRequestContext(Host host) {
432 return new TestMessageContext(host.location(),
433 host.mac(),
434 MacAddress.BROADCAST,
435 host.vlan(),
436 NeighbourMessageType.REQUEST);
437 }
438
439 private TestMessageContext makeReplyContext(Host src, Host dst) {
440 return new TestMessageContext(src.location(),
441 src.mac(),
442 dst.mac(),
443 src.vlan(),
444 NeighbourMessageType.REPLY);
445 }
446
447 private class TestMessageContext implements NeighbourMessageContext {
448
449
450 private final NeighbourMessageType type;
451 private final MacAddress srcMac;
452 private final MacAddress dstMac;
453 private final ConnectPoint inPort;
454 private final VlanId vlanId;
455
456 public Set<Interface> forwardResults;
457
458 /**
459 * Creates new neighbour message context for test.
460 *
461 * @param inPort the input port
462 * @param srcMac the source Mac
463 * @param dstMac the destination Mac
464 * @param vlanId the VLAN Id
465 * @param type the message context type
466 */
467 public TestMessageContext(
468 ConnectPoint inPort,
469 MacAddress srcMac,
470 MacAddress dstMac,
471 VlanId vlanId,
472 NeighbourMessageType type) {
473
474 this.inPort = inPort;
475 this.srcMac = srcMac;
476 this.dstMac = dstMac;
477 this.vlanId = vlanId;
478 this.type = type;
479
480 this.forwardResults = Sets.newHashSet();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700481 }
Luca Prete092e8952016-10-26 16:25:56 +0200482
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700483 @Override
484 public ConnectPoint inPort() {
485 return inPort;
486 }
487
488 @Override
489 public NeighbourMessageType type() {
490 return type;
491 }
492
493 @Override
494 public VlanId vlan() {
495 return vlanId;
496 }
497
498 @Override
499 public MacAddress srcMac() {
500 return srcMac;
501 }
502
503 @Override
504 public MacAddress dstMac() {
505 return dstMac;
506 }
507
508 @Override
509 public IpAddress target() {
510 return null;
511 }
512
513 @Override
514 public IpAddress sender() {
515 return null;
516 }
517
518 @Override
519 public void forward(ConnectPoint outPort) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700520 }
521
522 @Override
523 public void forward(Interface outIntf) {
524 forwardResults.add(outIntf);
525 }
526
527 @Override
528 public void reply(MacAddress targetMac) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700529 }
530
531 @Override
532 public void flood() {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700533 }
534
535 @Override
536 public void drop() {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700537 }
538
539 @Override
540 public Ethernet packet() {
541 return null;
542 }
543
544 @Override
545 public NeighbourProtocol protocol() {
546 return null;
547 }
548 }
549
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100550 private class TestVplsConfigService extends VplsConfigServiceAdapter {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700551
Luca Prete092e8952016-10-26 16:25:56 +0200552 private final SetMultimap<String, Interface> ifacesByVplsName;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700553
Luca Prete092e8952016-10-26 16:25:56 +0200554 public TestVplsConfigService(SetMultimap<String, Interface> ifacesByVplsName,
555 HashMap<String, EncapsulationType> encapByVplsName) {
556 this.ifacesByVplsName = ifacesByVplsName;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700557 }
558
559 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200560 public void addVpls(String vplsName, Set<String> ifaceNames, String encap) {
561 if (!ifacesByVplsName.containsKey(vplsName)) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700562 ifaceNames.forEach(ifaceName -> {
Luca Prete092e8952016-10-26 16:25:56 +0200563 availableInterfaces.forEach(iface -> {
564 if (iface.name().equals(ifaceName)) {
565 ifacesByVplsName.put(vplsName, iface);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700566 }
567 });
568 });
569 }
570 }
571
572 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200573 public void removeVpls(String vplsName) {
574 if (ifacesByVplsName.containsKey(vplsName)) {
575 ifacesByVplsName.removeAll(vplsName);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700576 }
577 }
578
579 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200580 public void addIface(String vplsName, String ifaceName) {
581 availableInterfaces.forEach(intf -> {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700582 if (intf.name().equals(ifaceName)) {
Luca Prete092e8952016-10-26 16:25:56 +0200583 ifacesByVplsName.put(vplsName, intf);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700584 }
585 });
586 }
587
588 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200589 public void removeIface(String ifaceName) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700590 SetMultimap<String, Interface> toBeRemoved = HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200591 ifacesByVplsName.entries().forEach(e -> {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700592 if (e.getValue().name().equals(ifaceName)) {
593 toBeRemoved.put(e.getKey(), e.getValue());
594 }
595 });
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700596 toBeRemoved.entries()
Luca Prete092e8952016-10-26 16:25:56 +0200597 .forEach(e -> ifacesByVplsName.remove(e.getKey(),
598 e.getValue()));
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700599 }
600
601 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200602 public void cleanVplsConfig() {
603 ifacesByVplsName.clear();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700604 }
605
606 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200607 public Set<Interface> allIfaces() {
608 return ImmutableSet.copyOf(ifacesByVplsName.values());
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700609 }
610
611 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200612 public Set<Interface> ifaces(String name) {
613 return ifacesByVplsName.get(name)
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700614 .stream()
615 .collect(Collectors.toSet());
616 }
617
618 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200619 public Set<String> vplsNames() {
620 return ifacesByVplsName.keySet();
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700621 }
622
623 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200624 public SetMultimap<String, Interface> ifacesByVplsName() {
625 return ImmutableSetMultimap.copyOf(ifacesByVplsName);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700626 }
627
628 @Override
Luca Prete092e8952016-10-26 16:25:56 +0200629 public SetMultimap<String, Interface> ifacesByVplsName(VlanId vlan,
630 ConnectPoint connectPoint) {
631 String vplsName =
632 ifacesByVplsName.entries().stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700633 .filter(e -> e.getValue().connectPoint().equals(connectPoint))
634 .filter(e -> e.getValue().vlan().equals(vlan))
Carolina Fernandezb1cef5c2016-11-22 19:18:40 +0100635 .map(Map.Entry::getKey)
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700636 .findFirst()
637 .orElse(null);
638 SetMultimap<String, Interface> result = HashMultimap.create();
Luca Prete092e8952016-10-26 16:25:56 +0200639 if (vplsName != null &&
640 ifacesByVplsName.containsKey(vplsName)) {
641 ifacesByVplsName.get(vplsName)
642 .forEach(intf -> result.put(vplsName, intf));
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700643 return result;
644 }
645 return null;
646 }
647 }
648
649 class TestHostService extends HostServiceAdapter {
650 @Override
651 public Set<Host> getHostsByMac(MacAddress mac) {
652 return availableHosts.stream()
653 .filter(host -> host.mac().equals(mac))
654 .collect(Collectors.toSet());
655 }
656
657 @Override
658 public Iterable<Host> getHosts() {
659 return availableHosts;
660 }
661
662 @Override
663 public Set<Host> getHostsByVlan(VlanId vlanId) {
664 return availableHosts.stream()
665 .filter(host -> host.vlan().equals(vlanId))
666 .collect(Collectors.toSet());
667 }
668
669 @Override
670 public int getHostCount() {
671 return availableHosts.size();
672 }
673
674 @Override
675 public Host getHost(HostId hostId) {
676 return availableHosts.stream()
677 .filter(host -> host.id().equals(hostId))
678 .findFirst()
679 .orElse(null);
680 }
681 }
682
683 private class TestNeighbourService implements NeighbourResolutionService {
684 private SetMultimap<ConnectPoint, NeighbourHandlerRegistration> handlerRegs;
685
686 public TestNeighbourService() {
687 handlerRegs = HashMultimap.create();
688 }
689
690 @Override
691 public void registerNeighbourHandler(ConnectPoint connectPoint,
692 NeighbourMessageHandler handler,
693 ApplicationId appId) {
694 Interface intf =
695 new Interface(null, connectPoint, null, null, null);
696
697 NeighbourHandlerRegistration reg =
698 new HandlerRegistration(handler, intf, appId);
699
700 handlerRegs.put(connectPoint, reg);
701 }
702
703 @Override
704 public void registerNeighbourHandler(Interface intf,
705 NeighbourMessageHandler handler,
706 ApplicationId appId) {
707 NeighbourHandlerRegistration reg =
708 new HandlerRegistration(handler, intf, appId);
709 handlerRegs.put(intf.connectPoint(), reg);
710 }
711
712 @Override
713 public void unregisterNeighbourHandler(ConnectPoint connectPoint,
714 NeighbourMessageHandler handler,
715 ApplicationId appId) {
716 handlerRegs.removeAll(connectPoint);
717 }
718
719 @Override
720 public void unregisterNeighbourHandler(Interface intf,
721 NeighbourMessageHandler handler,
722 ApplicationId appId) {
723 handlerRegs.removeAll(intf.connectPoint());
724 }
725
726 @Override
727 public void unregisterNeighbourHandlers(ApplicationId appId) {
728 handlerRegs.clear();
729 }
730
731 @Override
732 public Map<ConnectPoint, Collection<NeighbourHandlerRegistration>> getHandlerRegistrations() {
733 return handlerRegs.asMap();
734 }
735
736 private class HandlerRegistration implements NeighbourHandlerRegistration {
737 private final Interface intf;
738 private final NeighbourMessageHandler handler;
739 private final ApplicationId appId;
740
741 /**
742 * Creates a new registration handler.
743 *
744 * @param handler the neighbour message handler
745 * @param intf the interface
746 */
747 public HandlerRegistration(NeighbourMessageHandler handler,
748 Interface intf,
749 ApplicationId appId) {
750 this.intf = intf;
751 this.handler = handler;
752 this.appId = appId;
753 }
754
755 @Override
756 public Interface intf() {
757 return intf;
758 }
759
760 @Override
761 public NeighbourMessageHandler handler() {
762 return handler;
763 }
764
765 @Override
766 public ApplicationId appId() {
767 return appId;
768 }
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700769 }
770 }
771
772 class TestInterfaceService implements InterfaceService {
773
774 @Override
775 public void addListener(InterfaceListener listener) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700776 }
777
778 @Override
779 public void removeListener(InterfaceListener listener) {
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700780 }
781
782 @Override
783 public Set<Interface> getInterfaces() {
Luca Prete092e8952016-10-26 16:25:56 +0200784 return availableInterfaces;
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700785 }
786
787 @Override
788 public Interface getInterfaceByName(ConnectPoint connectPoint,
789 String name) {
Luca Prete092e8952016-10-26 16:25:56 +0200790 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700791 .filter(intf -> intf.name().equals(name))
792 .findFirst()
793 .orElse(null);
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700794 }
795
796 @Override
797 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
Luca Prete092e8952016-10-26 16:25:56 +0200798 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700799 .filter(intf -> intf.connectPoint().equals(port))
800 .collect(Collectors.toSet());
801 }
802
803 @Override
804 public Set<Interface> getInterfacesByIp(IpAddress ip) {
Luca Prete092e8952016-10-26 16:25:56 +0200805 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700806 .filter(intf -> intf.ipAddressesList().contains(ip))
807 .collect(Collectors.toSet());
808 }
809
810 @Override
811 public Set<Interface> getInterfacesByVlan(VlanId vlan) {
Luca Prete092e8952016-10-26 16:25:56 +0200812 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700813 .filter(intf -> intf.vlan().equals(vlan))
814 .collect(Collectors.toSet());
815 }
816
817 @Override
818 public Interface getMatchingInterface(IpAddress ip) {
Luca Prete092e8952016-10-26 16:25:56 +0200819 return availableInterfaces.stream()
Yong-hwan Kimfbf653c2016-09-21 10:05:22 -0700820 .filter(intf -> intf.ipAddressesList().contains(ip))
821 .findFirst()
822 .orElse(null);
823 }
824 }
825}