blob: 212cc42a8ebf7bded9bfa6739b2e0245dbbf903e [file] [log] [blame]
kishoredb79dc02016-03-07 16:24:55 +05301/*
Jonathan Hartf4bd0482017-01-27 15:11:18 -08002 * Copyright 2017-present Open Networking Laboratory
kishoredb79dc02016-03-07 16:24:55 +05303 *
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 */
Jonathan Hartf4bd0482017-01-27 15:11:18 -080016
17package org.onosproject.routing.cpr;
kishoredb79dc02016-03-07 16:24:55 +053018
Jonathan Hartf04b7d92016-03-29 09:39:11 -070019import com.google.common.collect.Sets;
kishoredb79dc02016-03-07 16:24:55 +053020import org.easymock.EasyMock;
21import org.junit.Before;
Jonathan Hartf8cd0522016-10-25 07:09:55 -070022import org.junit.Ignore;
kishoredb79dc02016-03-07 16:24:55 +053023import org.junit.Test;
24import org.onlab.packet.EthType;
Pier Luigi2b1ad872017-01-31 09:35:42 -080025import org.onlab.packet.Ip6Address;
kishoredb79dc02016-03-07 16:24:55 +053026import org.onlab.packet.IpAddress;
27import org.onlab.packet.IpPrefix;
28import org.onlab.packet.MacAddress;
29import org.onlab.packet.VlanId;
kishore786b7e42016-05-19 16:25:57 +053030import org.onosproject.app.ApplicationService;
kishoredb79dc02016-03-07 16:24:55 +053031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
33import org.onosproject.core.CoreServiceAdapter;
34import org.onosproject.incubator.net.intf.Interface;
kishore71a27532016-03-16 20:23:49 +053035import org.onosproject.incubator.net.intf.InterfaceEvent;
36import org.onosproject.incubator.net.intf.InterfaceListener;
kishoredb79dc02016-03-07 16:24:55 +053037import org.onosproject.incubator.net.intf.InterfaceService;
kishore71a27532016-03-16 20:23:49 +053038import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
kishoredb79dc02016-03-07 16:24:55 +053039import org.onosproject.mastership.MastershipService;
40import org.onosproject.mastership.MastershipServiceAdapter;
41import org.onosproject.net.ConnectPoint;
42import org.onosproject.net.Device;
43import org.onosproject.net.DeviceId;
44import org.onosproject.net.NetTestTools;
45import org.onosproject.net.PortNumber;
46import org.onosproject.net.config.Config;
47import org.onosproject.net.config.NetworkConfigEvent;
48import org.onosproject.net.config.NetworkConfigEvent.Type;
49import org.onosproject.net.config.NetworkConfigListener;
50import org.onosproject.net.config.NetworkConfigService;
51import org.onosproject.net.config.NetworkConfigServiceAdapter;
52import org.onosproject.net.device.DeviceEvent;
53import org.onosproject.net.device.DeviceListener;
54import org.onosproject.net.device.DeviceService;
55import org.onosproject.net.device.DeviceServiceAdapter;
56import org.onosproject.net.flow.DefaultTrafficSelector;
57import org.onosproject.net.flow.DefaultTrafficTreatment;
58import org.onosproject.net.flow.TrafficSelector;
59import org.onosproject.net.flow.TrafficTreatment;
60import org.onosproject.net.flowobjective.DefaultForwardingObjective;
61import org.onosproject.net.flowobjective.DefaultNextObjective;
62import org.onosproject.net.flowobjective.FlowObjectiveService;
63import org.onosproject.net.flowobjective.ForwardingObjective;
64import org.onosproject.net.flowobjective.NextObjective;
kishoredb79dc02016-03-07 16:24:55 +053065import org.onosproject.net.host.HostService;
kishoredb79dc02016-03-07 16:24:55 +053066import org.onosproject.net.host.InterfaceIpAddress;
kishoredb79dc02016-03-07 16:24:55 +053067import org.onosproject.routing.RoutingService;
68import org.onosproject.routing.config.RouterConfig;
kishoredb79dc02016-03-07 16:24:55 +053069
Jonathan Hartf04b7d92016-03-29 09:39:11 -070070import java.util.ArrayList;
71import java.util.HashSet;
72import java.util.List;
73import java.util.Objects;
74import java.util.Set;
75
76import static org.easymock.EasyMock.createMock;
77import static org.easymock.EasyMock.createNiceMock;
78import static org.easymock.EasyMock.expect;
79import static org.easymock.EasyMock.expectLastCall;
80import static org.easymock.EasyMock.replay;
81import static org.easymock.EasyMock.verify;
Vinayak Tejankar3a409c62017-01-12 02:20:53 +053082import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
83import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
Pier Luigi2b1ad872017-01-31 09:35:42 -080084import static org.onlab.packet.IPv6.getLinkLocalAddress;
85import static org.onlab.packet.IPv6.getSolicitNodeAddress;
Jonathan Hartf4bd0482017-01-27 15:11:18 -080086import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.ACL_PRIORITY;
87import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildArpSelector;
88import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildIPDstSelector;
89import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildIPSrcSelector;
90import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildNdpSelector;
kishoredb79dc02016-03-07 16:24:55 +053091
92/**
93 * UnitTests for ControlPlaneRedirectManager.
94 */
Jonathan Hartf8cd0522016-10-25 07:09:55 -070095@Ignore("Too many dependencies on internal implementation, too hard to maintain")
Jonathan Hartf04b7d92016-03-29 09:39:11 -070096public class ControlPlaneRedirectManagerTest {
kishoredb79dc02016-03-07 16:24:55 +053097
kishoredb79dc02016-03-07 16:24:55 +053098 private DeviceService deviceService;
99 private FlowObjectiveService flowObjectiveService;
100 private NetworkConfigService networkConfigService;
101 private final Set<Interface> interfaces = Sets.newHashSet();
102 static Device dev3 = NetTestTools.device("0000000000000001");
103 private static final int OSPF_IP_PROTO = 0x59;
104 private CoreService coreService = new TestCoreService();
105 private InterfaceService interfaceService;
kishore786b7e42016-05-19 16:25:57 +0530106 private static final ApplicationId APPID = TestApplicationId.create("org.onosproject.vrouter");
kishoredb79dc02016-03-07 16:24:55 +0530107
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700108 private static final DeviceId DEVICE_ID = DeviceId.deviceId("of:0000000000000001");
109
110 private ConnectPoint controlPlaneConnectPoint = new ConnectPoint(DEVICE_ID,
kishoredb79dc02016-03-07 16:24:55 +0530111 PortNumber.portNumber(1));
112
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700113 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(DEVICE_ID,
114 PortNumber.portNumber(1));
115
116 private static final ConnectPoint SW1_ETH2 = new ConnectPoint(DEVICE_ID,
kishoredb79dc02016-03-07 16:24:55 +0530117 PortNumber.portNumber(2));
118
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700119 private static final ConnectPoint SW1_ETH3 = new ConnectPoint(DEVICE_ID,
kishoredb79dc02016-03-07 16:24:55 +0530120 PortNumber.portNumber(3));
kishoredb79dc02016-03-07 16:24:55 +0530121
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700122 private ControlPlaneRedirectManager controlPlaneRedirectManager = new ControlPlaneRedirectManager();
kishoredb79dc02016-03-07 16:24:55 +0530123 private RouterConfig routerConfig = new TestRouterConfig();
124 private NetworkConfigListener networkConfigListener;
125 private DeviceListener deviceListener;
126 private MastershipService mastershipService = new InternalMastershipServiceTest();
kishore71a27532016-03-16 20:23:49 +0530127 private InterfaceListener interfaceListener;
kishore786b7e42016-05-19 16:25:57 +0530128 private ApplicationService applicationService;
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700129
kishoredb79dc02016-03-07 16:24:55 +0530130 @Before
kishore71a27532016-03-16 20:23:49 +0530131 public void setUp() {
kishoredb79dc02016-03-07 16:24:55 +0530132 networkConfigListener = createMock(NetworkConfigListener.class);
kishoredb79dc02016-03-07 16:24:55 +0530133 deviceService = new TestDeviceService();
134 deviceListener = createMock(DeviceListener.class);
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700135
kishore71a27532016-03-16 20:23:49 +0530136 interfaceListener = createMock(InterfaceListener.class);
kishoredb79dc02016-03-07 16:24:55 +0530137 deviceService.addListener(deviceListener);
138 setUpInterfaceService();
kishore71a27532016-03-16 20:23:49 +0530139 interfaceService = new InternalInterfaceService();
140 interfaceService.addListener(interfaceListener);
kishoredb79dc02016-03-07 16:24:55 +0530141 networkConfigService = new TestNetworkConfigService();
142 networkConfigService.addListener(networkConfigListener);
143 flowObjectiveService = createMock(FlowObjectiveService.class);
kishore786b7e42016-05-19 16:25:57 +0530144 applicationService = createNiceMock(ApplicationService.class);
145 replay(applicationService);
kishoredb79dc02016-03-07 16:24:55 +0530146 setUpFlowObjectiveService();
kishoredb79dc02016-03-07 16:24:55 +0530147 controlPlaneRedirectManager.coreService = coreService;
148 controlPlaneRedirectManager.flowObjectiveService = flowObjectiveService;
149 controlPlaneRedirectManager.networkConfigService = networkConfigService;
150 controlPlaneRedirectManager.interfaceService = interfaceService;
151 controlPlaneRedirectManager.deviceService = deviceService;
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700152 controlPlaneRedirectManager.hostService = createNiceMock(HostService.class);
kishoredb79dc02016-03-07 16:24:55 +0530153 controlPlaneRedirectManager.mastershipService = mastershipService;
kishore786b7e42016-05-19 16:25:57 +0530154 controlPlaneRedirectManager.applicationService = applicationService;
kishoredb79dc02016-03-07 16:24:55 +0530155 controlPlaneRedirectManager.activate();
156 verify(flowObjectiveService);
157 }
kishore71a27532016-03-16 20:23:49 +0530158
kishoredb79dc02016-03-07 16:24:55 +0530159 /**
kishore71a27532016-03-16 20:23:49 +0530160 * Tests adding new Device to a openflow router.
161 */
162 @Test
163 public void testAddDevice() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700164 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530165 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
166 interfaceIpAddresses.add(
167 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
168 );
169 interfaceIpAddresses.add(
170 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
171 );
kishore71a27532016-03-16 20:23:49 +0530172
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530173 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530174 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
175 interfaces.add(sw1Eth4);
176 EasyMock.reset(flowObjectiveService);
177 setUpFlowObjectiveService();
178 deviceListener.event(new DeviceEvent(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED, dev3));
179 verify(flowObjectiveService);
180 }
181
182 /**
183 * Tests adding while updating the networkConfig.
184 */
185 @Test
186 public void testUpdateNetworkConfig() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700187 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530188 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
189 interfaceIpAddresses.add(
190 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
191 );
192 interfaceIpAddresses.add(
193 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
194 );
kishore71a27532016-03-16 20:23:49 +0530195
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530196 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530197 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
198 interfaces.add(sw1Eth4);
199 EasyMock.reset(flowObjectiveService);
200 setUpFlowObjectiveService();
201 networkConfigListener
202 .event(new NetworkConfigEvent(Type.CONFIG_UPDATED, dev3, RoutingService.ROUTER_CONFIG_CLASS));
203 networkConfigService.addListener(networkConfigListener);
204 verify(flowObjectiveService);
205 }
206
207 /**
208 * Tests adding while updating the networkConfig.
209 */
210 @Test
211 public void testAddInterface() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700212 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530213 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
214 interfaceIpAddresses.add(
215 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
216 );
217 interfaceIpAddresses.add(
218 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
219 );
kishore71a27532016-03-16 20:23:49 +0530220
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530221 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530222 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
223 interfaces.add(sw1Eth4);
224
225 EasyMock.reset(flowObjectiveService);
226 expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
227
228 setUpInterfaceConfiguration(sw1Eth4, true);
229 replay(flowObjectiveService);
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700230 interfaceListener.event(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, sw1Eth4, 500L));
kishore71a27532016-03-16 20:23:49 +0530231 verify(flowObjectiveService);
232 }
233
234 @Test
235 public void testRemoveInterface() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700236 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530237 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
238 interfaceIpAddresses.add(
239 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
240 );
241 interfaceIpAddresses.add(
242 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
243 );
kishore71a27532016-03-16 20:23:49 +0530244
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530245 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530246 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
247 EasyMock.reset(flowObjectiveService);
248 expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
249
250 setUpInterfaceConfiguration(sw1Eth4, false);
251 replay(flowObjectiveService);
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700252 interfaceListener.event(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, sw1Eth4, 500L));
kishore71a27532016-03-16 20:23:49 +0530253 verify(flowObjectiveService);
254 }
255
256 /**
257 * Setup flow Configuration for all configured Interfaces.
kishoredb79dc02016-03-07 16:24:55 +0530258 *
259 **/
260 private void setUpFlowObjectiveService() {
kishoredb79dc02016-03-07 16:24:55 +0530261 expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
kishoredb79dc02016-03-07 16:24:55 +0530262 for (Interface intf : interfaceService.getInterfaces()) {
kishore71a27532016-03-16 20:23:49 +0530263 setUpInterfaceConfiguration(intf, true);
kishoredb79dc02016-03-07 16:24:55 +0530264 }
kishoredb79dc02016-03-07 16:24:55 +0530265 replay(flowObjectiveService);
266 }
267
268 /**
kishore71a27532016-03-16 20:23:49 +0530269 * Setting up flowobjective expectations for basic forwarding and ospf.
kishoredb79dc02016-03-07 16:24:55 +0530270 **/
kishore71a27532016-03-16 20:23:49 +0530271 private void setUpInterfaceConfiguration(Interface intf, boolean install) {
272 DeviceId deviceId = controlPlaneConnectPoint.deviceId();
273 PortNumber controlPlanePort = controlPlaneConnectPoint.port();
kishore71a27532016-03-16 20:23:49 +0530274 for (InterfaceIpAddress ip : intf.ipAddresses()) {
275 int cpNextId, intfNextId;
kishore71a27532016-03-16 20:23:49 +0530276 cpNextId = modifyNextObjective(deviceId, controlPlanePort,
Jonathan Hartf4bd0482017-01-27 15:11:18 -0800277 VlanId.vlanId(ControlPlaneRedirectManager.ASSIGNED_VLAN), true, install);
kishore71a27532016-03-16 20:23:49 +0530278 intfNextId = modifyNextObjective(deviceId, intf.connectPoint().port(),
Jonathan Hartf4bd0482017-01-27 15:11:18 -0800279 VlanId.vlanId(ControlPlaneRedirectManager.ASSIGNED_VLAN), true, install);
kishore71a27532016-03-16 20:23:49 +0530280
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530281 // IP to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800282 TrafficSelector toSelector = buildIPDstSelector(ip.ipAddress().toIpPrefix(),
283 intf.connectPoint().port(),
284 null,
285 intf.mac(),
286 intf.vlan());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530287 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, null,
288 cpNextId, install, ACL_PRIORITY));
kishore71a27532016-03-16 20:23:49 +0530289 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530290 // IP from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800291 TrafficSelector fromSelector = buildIPSrcSelector(ip.ipAddress().toIpPrefix(),
292 controlPlanePort,
293 intf.mac(),
294 null,
295 intf.vlan());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530296 flowObjectiveService.forward(deviceId, buildForwardingObjective(fromSelector, null,
297 intfNextId, install, ACL_PRIORITY));
kishore71a27532016-03-16 20:23:49 +0530298 expectLastCall().once();
kishore71a27532016-03-16 20:23:49 +0530299 TrafficTreatment puntTreatment = DefaultTrafficTreatment.builder().punt().build();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530300 if (ip.ipAddress().isIp4()) {
301 // ARP to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800302 toSelector = buildArpSelector(intf.connectPoint().port(),
303 intf.vlan(),
304 null,
305 null);
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530306 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
307 cpNextId, install, ACL_PRIORITY + 1));
308 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530309 // ARP from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800310 fromSelector = buildArpSelector(controlPlanePort,
311 intf.vlan(),
312 ip.ipAddress().getIp4Address(),
313 intf.mac());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530314 flowObjectiveService.forward(deviceId,
315 buildForwardingObjective(fromSelector, puntTreatment,
316 intfNextId, install, ACL_PRIORITY + 1));
317 expectLastCall().once();
318 } else {
319 // NDP solicitation to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800320 // Global unicast address
321 toSelector = buildNdpSelector(intf.connectPoint().port(),
322 intf.vlan(),
323 ip.ipAddress().toIpPrefix(),
324 null,
325 NEIGHBOR_SOLICITATION,
326 null);
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530327 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
328 cpNextId, install, ACL_PRIORITY + 1));
329 expectLastCall().once();
Pier Luigi2b1ad872017-01-31 09:35:42 -0800330 // NDP solicitation to router
331 // Link local address
332 toSelector = buildNdpSelector(intf.connectPoint().port(),
333 intf.vlan(),
334 Ip6Address.valueOf(
335 getLinkLocalAddress(intf.mac().toBytes())
336 ).toIpPrefix(),
337 null,
338 NEIGHBOR_SOLICITATION,
339 null);
340 flowObjectiveService.forward(deviceId,
341 buildForwardingObjective(toSelector, puntTreatment,
342 intfNextId, install, ACL_PRIORITY + 1));
343 expectLastCall().once();
344 // NDP solicitation to router
345 // solicitated global unicast address
346 toSelector = buildNdpSelector(intf.connectPoint().port(),
347 intf.vlan(),
348 Ip6Address.valueOf(
349 getSolicitNodeAddress(ip.ipAddress().toOctets())
350 ).toIpPrefix(),
351 null,
352 NEIGHBOR_SOLICITATION,
353 null);
354 flowObjectiveService.forward(deviceId,
355 buildForwardingObjective(toSelector, puntTreatment,
356 intfNextId, install, ACL_PRIORITY + 1));
357 // NDP solicitation to router
358 // solicitated link local address
359 toSelector = buildNdpSelector(intf.connectPoint().port(),
360 intf.vlan(),
361 Ip6Address.valueOf(
362 getSolicitNodeAddress(getLinkLocalAddress(intf.mac().toBytes()))
363 ).toIpPrefix(),
364 null,
365 NEIGHBOR_SOLICITATION,
366 null);
367 flowObjectiveService.forward(deviceId,
368 buildForwardingObjective(toSelector, puntTreatment,
369 intfNextId, install, ACL_PRIORITY + 1));
370 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530371 // NDP solicitation from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800372 // Global unicast address
373 fromSelector = buildNdpSelector(controlPlanePort,
374 intf.vlan(),
375 null,
376 ip.ipAddress().toIpPrefix(),
377 NEIGHBOR_SOLICITATION,
378 intf.mac());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530379 flowObjectiveService.forward(deviceId,
380 buildForwardingObjective(fromSelector, puntTreatment,
381 intfNextId, install, ACL_PRIORITY + 1));
Pier Luigi2b1ad872017-01-31 09:35:42 -0800382 expectLastCall().once();
383 // NDP solicitation from router
384 // Link local address
385 fromSelector = buildNdpSelector(controlPlanePort,
386 intf.vlan(),
387 null,
388 Ip6Address.valueOf(
389 getLinkLocalAddress(intf.mac().toBytes())
390 ).toIpPrefix(),
391 NEIGHBOR_SOLICITATION,
392 intf.mac());
393 flowObjectiveService.forward(deviceId,
394 buildForwardingObjective(fromSelector, puntTreatment,
395 intfNextId, install, ACL_PRIORITY + 1));
396 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530397 // NDP advertisement to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800398 // Global unicast address
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530399 toSelector = buildNdpSelector(
400 intf.connectPoint().port(),
401 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800402 ip.ipAddress().toIpPrefix(),
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530403 null,
404 NEIGHBOR_ADVERTISEMENT,
405 null
406 );
407
408 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
409 cpNextId, install, ACL_PRIORITY + 1));
410 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530411 // NDP advertisement from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800412 // Link local address
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530413 fromSelector = buildNdpSelector(
Pier Luigi2b1ad872017-01-31 09:35:42 -0800414 intf.connectPoint().port(),
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530415 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800416 Ip6Address.valueOf(getLinkLocalAddress(intf.mac().toBytes())).toIpPrefix(),
417 null,
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530418 NEIGHBOR_ADVERTISEMENT,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800419 null
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530420 );
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530421 flowObjectiveService.forward(deviceId,
422 buildForwardingObjective(fromSelector, puntTreatment,
423 intfNextId, install, ACL_PRIORITY + 1));
Pier Luigi2b1ad872017-01-31 09:35:42 -0800424 expectLastCall().once();
425 // NDP advertisement to router
426 // Global unicast address
427 toSelector = buildNdpSelector(controlPlanePort,
428 intf.vlan(),
429 null,
430 ip.ipAddress().toIpPrefix(),
431 NEIGHBOR_ADVERTISEMENT,
432 intf.mac());
433 flowObjectiveService.forward(deviceId,
434 buildForwardingObjective(toSelector, puntTreatment,
435 intfNextId, install, ACL_PRIORITY + 1));
436 expectLastCall().once();
437 // NDP advertisement to router
438 // Link local address
439 fromSelector = buildNdpSelector(controlPlanePort,
440 intf.vlan(),
441 null,
442 Ip6Address.valueOf(
443 getLinkLocalAddress(intf.mac().toBytes())
444 ).toIpPrefix(),
445 NEIGHBOR_ADVERTISEMENT,
446 intf.mac());
447 flowObjectiveService.forward(deviceId,
448 buildForwardingObjective(fromSelector, puntTreatment,
449 intfNextId, install, ACL_PRIORITY + 1));
450 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530451 }
kishore71a27532016-03-16 20:23:49 +0530452 }
453 // setting expectations for ospf forwarding.
kishoredb79dc02016-03-07 16:24:55 +0530454 TrafficSelector toSelector = DefaultTrafficSelector.builder().matchInPort(intf.connectPoint().port())
455 .matchEthType(EthType.EtherType.IPV4.ethType().toShort()).matchVlanId(intf.vlan())
456 .matchIPProtocol((byte) OSPF_IP_PROTO).build();
kishore71a27532016-03-16 20:23:49 +0530457 modifyNextObjective(deviceId, controlPlanePort, VlanId.vlanId((short) 4094), true, install);
kishoredb79dc02016-03-07 16:24:55 +0530458 flowObjectiveService.forward(controlPlaneConnectPoint.deviceId(),
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530459 buildForwardingObjective(toSelector, null, 1, install, 40001));
kishoredb79dc02016-03-07 16:24:55 +0530460 expectLastCall().once();
461 }
462
463 /**
kishore71a27532016-03-16 20:23:49 +0530464 * Setup expectations on flowObjectiveService.next for NextObjective.
kishoredb79dc02016-03-07 16:24:55 +0530465 *
466 **/
kishore71a27532016-03-16 20:23:49 +0530467 private int modifyNextObjective(DeviceId deviceId, PortNumber portNumber, VlanId vlanId, boolean popVlan,
468 boolean modifyFlag) {
kishoredb79dc02016-03-07 16:24:55 +0530469 NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(1)
470 .withType(NextObjective.Type.SIMPLE).fromApp(APPID);
471
472 TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
473 if (popVlan) {
474 ttBuilder.popVlan();
475 }
476 ttBuilder.setOutput(portNumber);
477
kishoredb79dc02016-03-07 16:24:55 +0530478 TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
479 metabuilder.matchVlanId(vlanId);
480
481 nextObjBuilder.withMeta(metabuilder.build());
482 nextObjBuilder.addTreatment(ttBuilder.build());
kishore71a27532016-03-16 20:23:49 +0530483 if (modifyFlag) {
484 flowObjectiveService.next(deviceId, nextObjBuilder.add());
485 expectLastCall().once();
486 } else {
487 flowObjectiveService.next(deviceId, nextObjBuilder.remove());
488 expectLastCall().once();
489 }
kishoredb79dc02016-03-07 16:24:55 +0530490 return 1;
491 }
492
493 /**
kishore71a27532016-03-16 20:23:49 +0530494 * Setup Interface expectation for all Testcases.
kishoredb79dc02016-03-07 16:24:55 +0530495 **/
496 private void setUpInterfaceService() {
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700497 List<InterfaceIpAddress> interfaceIpAddresses1 = new ArrayList<>();
kishoredb79dc02016-03-07 16:24:55 +0530498 interfaceIpAddresses1
499 .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"), IpPrefix.valueOf("192.168.10.0/24")));
500 Interface sw1Eth1 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH1, interfaceIpAddresses1,
501 MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE);
502 interfaces.add(sw1Eth1);
503
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700504 List<InterfaceIpAddress> interfaceIpAddresses2 = new ArrayList<>();
kishoredb79dc02016-03-07 16:24:55 +0530505 interfaceIpAddresses2
506 .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"), IpPrefix.valueOf("192.168.20.0/24")));
507 Interface sw1Eth2 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH2, interfaceIpAddresses2,
508 MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE);
509 interfaces.add(sw1Eth2);
510
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700511 List<InterfaceIpAddress> interfaceIpAddresses3 = new ArrayList<>();
kishoredb79dc02016-03-07 16:24:55 +0530512 interfaceIpAddresses3
513 .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"), IpPrefix.valueOf("192.168.30.0/24")));
514 Interface sw1Eth3 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH3, interfaceIpAddresses3,
515 MacAddress.valueOf("00:00:00:00:00:03"), VlanId.NONE);
516 interfaces.add(sw1Eth3);
517
kishoredb79dc02016-03-07 16:24:55 +0530518 }
519
kishoredb79dc02016-03-07 16:24:55 +0530520 private ForwardingObjective buildForwardingObjective(TrafficSelector selector, TrafficTreatment treatment,
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530521 int nextId, boolean add, int priority) {
kishoredb79dc02016-03-07 16:24:55 +0530522 DefaultForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder();
523 fobBuilder.withSelector(selector);
524 if (treatment != null) {
525 fobBuilder.withTreatment(treatment);
526 }
527 if (nextId != -1) {
528 fobBuilder.nextStep(nextId);
529 }
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530530 fobBuilder.fromApp(APPID).withPriority(priority).withFlag(ForwardingObjective.Flag.VERSATILE);
kishoredb79dc02016-03-07 16:24:55 +0530531
532 return add ? fobBuilder.add() : fobBuilder.remove();
533 }
534
kishoredb79dc02016-03-07 16:24:55 +0530535 private class TestCoreService extends CoreServiceAdapter {
kishore71a27532016-03-16 20:23:49 +0530536
kishoredb79dc02016-03-07 16:24:55 +0530537 @Override
538 public ApplicationId getAppId(String name) {
539 return APPID;
540 }
541
542 @Override
543 public ApplicationId registerApplication(String name) {
kishoredb79dc02016-03-07 16:24:55 +0530544 return new TestApplicationId(name);
545 }
546
547 }
548
549 private class TestDeviceService extends DeviceServiceAdapter {
550
551 @Override
552 public boolean isAvailable(DeviceId deviceId) {
kishoredb79dc02016-03-07 16:24:55 +0530553 boolean flag = false;
554 if (deviceId.equals(controlPlaneConnectPoint.deviceId())) {
555 flag = true;
556 }
557 return flag;
558 }
559
560 @Override
561 public void addListener(DeviceListener listener) {
kishoredb79dc02016-03-07 16:24:55 +0530562 ControlPlaneRedirectManagerTest.this.deviceListener = listener;
563 }
564
565 }
566
kishoredb79dc02016-03-07 16:24:55 +0530567 private class TestRouterConfig extends RouterConfig {
568
569 @Override
570 public ConnectPoint getControlPlaneConnectPoint() {
kishoredb79dc02016-03-07 16:24:55 +0530571 return controlPlaneConnectPoint;
572 }
573
574 @Override
575 public boolean getOspfEnabled() {
kishoredb79dc02016-03-07 16:24:55 +0530576 return true;
577 }
578
579 @Override
580 public List<String> getInterfaces() {
kishoredb79dc02016-03-07 16:24:55 +0530581 ArrayList<String> interfaces = new ArrayList<>();
582 interfaces.add("of:0000000000000001");
583 interfaces.add("of:0000000000000001/2");
584 interfaces.add("of:0000000000000001/3");
585 return interfaces;
586 }
587
588 }
589
590 private class TestNetworkConfigService extends NetworkConfigServiceAdapter {
591
592 @Override
593 public void addListener(NetworkConfigListener listener) {
kishoredb79dc02016-03-07 16:24:55 +0530594 ControlPlaneRedirectManagerTest.this.networkConfigListener = listener;
595 }
596
597 @Override
598 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
kishoredb79dc02016-03-07 16:24:55 +0530599 return (C) ControlPlaneRedirectManagerTest.this.routerConfig;
600 }
601
602 }
603
604 private static class TestApplicationId implements ApplicationId {
605
606 private final String name;
607 private final short id;
608
609 public TestApplicationId(String name) {
610 this.name = name;
611 this.id = (short) Objects.hash(name);
612 }
613
614 public static ApplicationId create(String name) {
615 return new TestApplicationId(name);
616 }
617
618 @Override
619 public short id() {
620 return id;
621 }
622
623 @Override
624 public String name() {
625 return name;
626 }
627
628 @Override
629 public int hashCode() {
630 final int prime = 31;
631 int result = 1;
632 result = prime * result + id;
633 result = prime * result + ((name == null) ? 0 : name.hashCode());
634 return result;
635 }
636
637 @Override
638 public boolean equals(Object obj) {
639 if (this == obj) {
640 return true;
641 }
642 if (obj == null) {
643 return false;
644 }
645 if (getClass() != obj.getClass()) {
646 return false;
647 }
648 TestApplicationId other = (TestApplicationId) obj;
649 if (id != other.id) {
650 return false;
651 }
652 if (name == null) {
653 if (other.name != null) {
654 return false;
kishore71a27532016-03-16 20:23:49 +0530655 }
kishoredb79dc02016-03-07 16:24:55 +0530656 } else if (!name.equals(other.name)) {
657 return false;
658 }
659 return true;
660 }
661 }
662
663 private class InternalMastershipServiceTest extends MastershipServiceAdapter {
664
665 @Override
666 public boolean isLocalMaster(DeviceId deviceId) {
kishoredb79dc02016-03-07 16:24:55 +0530667 boolean flag = deviceId.equals(controlPlaneConnectPoint.deviceId());
668 return flag;
669 }
670
671 }
kishore71a27532016-03-16 20:23:49 +0530672
673 private class InternalInterfaceService extends InterfaceServiceAdapter {
674
675 @Override
676 public void addListener(InterfaceListener listener) {
677 ControlPlaneRedirectManagerTest.this.interfaceListener = listener;
678 }
679
680 @Override
681 public Set<Interface> getInterfaces() {
682 return interfaces;
683 }
684
685 @Override
686 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
687 Set<Interface> setIntf = new HashSet<Interface>();
688 for (Interface intf : interfaces) {
689 if (intf.connectPoint().equals(port)) {
690 setIntf.add(intf);
691 }
692 }
693 return setIntf;
694 }
695
696 @Override
697 public Interface getMatchingInterface(IpAddress ip) {
698 Interface intff = null;
699 for (Interface intf : interfaces) {
700 for (InterfaceIpAddress address : intf.ipAddresses()) {
701 if (address.ipAddress().equals(ip)) {
702 intff = intf;
703 break;
704 }
705 }
706 }
707
708 return intff;
709 }
710
711 }
kishoredb79dc02016-03-07 16:24:55 +0530712}