blob: 40c27d32f873942a90083696cd35fd3bf93af10d [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;
Charles Chanc6d227e2017-02-28 15:15:17 -080024import org.onlab.osgi.ComponentContextAdapter;
kishoredb79dc02016-03-07 16:24:55 +053025import org.onlab.packet.EthType;
Pier Luigi2b1ad872017-01-31 09:35:42 -080026import org.onlab.packet.Ip6Address;
kishoredb79dc02016-03-07 16:24:55 +053027import org.onlab.packet.IpAddress;
28import org.onlab.packet.IpPrefix;
29import org.onlab.packet.MacAddress;
30import org.onlab.packet.VlanId;
kishore786b7e42016-05-19 16:25:57 +053031import org.onosproject.app.ApplicationService;
kishoredb79dc02016-03-07 16:24:55 +053032import org.onosproject.core.ApplicationId;
33import org.onosproject.core.CoreService;
34import org.onosproject.core.CoreServiceAdapter;
35import org.onosproject.incubator.net.intf.Interface;
kishore71a27532016-03-16 20:23:49 +053036import org.onosproject.incubator.net.intf.InterfaceEvent;
37import org.onosproject.incubator.net.intf.InterfaceListener;
kishoredb79dc02016-03-07 16:24:55 +053038import org.onosproject.incubator.net.intf.InterfaceService;
kishore71a27532016-03-16 20:23:49 +053039import org.onosproject.incubator.net.intf.InterfaceServiceAdapter;
kishoredb79dc02016-03-07 16:24:55 +053040import org.onosproject.mastership.MastershipService;
41import org.onosproject.mastership.MastershipServiceAdapter;
42import org.onosproject.net.ConnectPoint;
43import org.onosproject.net.Device;
44import org.onosproject.net.DeviceId;
45import org.onosproject.net.NetTestTools;
46import org.onosproject.net.PortNumber;
47import org.onosproject.net.config.Config;
48import org.onosproject.net.config.NetworkConfigEvent;
49import org.onosproject.net.config.NetworkConfigEvent.Type;
50import org.onosproject.net.config.NetworkConfigListener;
51import org.onosproject.net.config.NetworkConfigService;
52import org.onosproject.net.config.NetworkConfigServiceAdapter;
53import org.onosproject.net.device.DeviceEvent;
54import org.onosproject.net.device.DeviceListener;
55import org.onosproject.net.device.DeviceService;
56import org.onosproject.net.device.DeviceServiceAdapter;
57import org.onosproject.net.flow.DefaultTrafficSelector;
58import org.onosproject.net.flow.DefaultTrafficTreatment;
59import org.onosproject.net.flow.TrafficSelector;
60import org.onosproject.net.flow.TrafficTreatment;
61import org.onosproject.net.flowobjective.DefaultForwardingObjective;
62import org.onosproject.net.flowobjective.DefaultNextObjective;
63import org.onosproject.net.flowobjective.FlowObjectiveService;
64import org.onosproject.net.flowobjective.ForwardingObjective;
65import org.onosproject.net.flowobjective.NextObjective;
kishoredb79dc02016-03-07 16:24:55 +053066import org.onosproject.net.host.HostService;
kishoredb79dc02016-03-07 16:24:55 +053067import org.onosproject.net.host.InterfaceIpAddress;
kishoredb79dc02016-03-07 16:24:55 +053068import org.onosproject.routing.RoutingService;
69import org.onosproject.routing.config.RouterConfig;
kishoredb79dc02016-03-07 16:24:55 +053070
Jonathan Hartf04b7d92016-03-29 09:39:11 -070071import java.util.ArrayList;
72import java.util.HashSet;
73import java.util.List;
74import java.util.Objects;
75import java.util.Set;
76
77import static org.easymock.EasyMock.createMock;
78import static org.easymock.EasyMock.createNiceMock;
79import static org.easymock.EasyMock.expect;
80import static org.easymock.EasyMock.expectLastCall;
81import static org.easymock.EasyMock.replay;
82import static org.easymock.EasyMock.verify;
Vinayak Tejankar3a409c62017-01-12 02:20:53 +053083import static org.onlab.packet.ICMP6.NEIGHBOR_ADVERTISEMENT;
84import static org.onlab.packet.ICMP6.NEIGHBOR_SOLICITATION;
Pier Luigi2b1ad872017-01-31 09:35:42 -080085import static org.onlab.packet.IPv6.getLinkLocalAddress;
86import static org.onlab.packet.IPv6.getSolicitNodeAddress;
Jonathan Hartf4bd0482017-01-27 15:11:18 -080087import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.ACL_PRIORITY;
88import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildArpSelector;
89import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildIPDstSelector;
90import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildIPSrcSelector;
91import static org.onosproject.routing.cpr.ControlPlaneRedirectManager.buildNdpSelector;
kishoredb79dc02016-03-07 16:24:55 +053092
93/**
94 * UnitTests for ControlPlaneRedirectManager.
95 */
Jonathan Hartf8cd0522016-10-25 07:09:55 -070096@Ignore("Too many dependencies on internal implementation, too hard to maintain")
Jonathan Hartf04b7d92016-03-29 09:39:11 -070097public class ControlPlaneRedirectManagerTest {
kishoredb79dc02016-03-07 16:24:55 +053098
kishoredb79dc02016-03-07 16:24:55 +053099 private DeviceService deviceService;
100 private FlowObjectiveService flowObjectiveService;
101 private NetworkConfigService networkConfigService;
102 private final Set<Interface> interfaces = Sets.newHashSet();
103 static Device dev3 = NetTestTools.device("0000000000000001");
104 private static final int OSPF_IP_PROTO = 0x59;
105 private CoreService coreService = new TestCoreService();
106 private InterfaceService interfaceService;
kishore786b7e42016-05-19 16:25:57 +0530107 private static final ApplicationId APPID = TestApplicationId.create("org.onosproject.vrouter");
kishoredb79dc02016-03-07 16:24:55 +0530108
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700109 private static final DeviceId DEVICE_ID = DeviceId.deviceId("of:0000000000000001");
110
111 private ConnectPoint controlPlaneConnectPoint = new ConnectPoint(DEVICE_ID,
kishoredb79dc02016-03-07 16:24:55 +0530112 PortNumber.portNumber(1));
113
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700114 private static final ConnectPoint SW1_ETH1 = new ConnectPoint(DEVICE_ID,
115 PortNumber.portNumber(1));
116
117 private static final ConnectPoint SW1_ETH2 = new ConnectPoint(DEVICE_ID,
kishoredb79dc02016-03-07 16:24:55 +0530118 PortNumber.portNumber(2));
119
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700120 private static final ConnectPoint SW1_ETH3 = new ConnectPoint(DEVICE_ID,
kishoredb79dc02016-03-07 16:24:55 +0530121 PortNumber.portNumber(3));
kishoredb79dc02016-03-07 16:24:55 +0530122
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700123 private ControlPlaneRedirectManager controlPlaneRedirectManager = new ControlPlaneRedirectManager();
kishoredb79dc02016-03-07 16:24:55 +0530124 private RouterConfig routerConfig = new TestRouterConfig();
125 private NetworkConfigListener networkConfigListener;
126 private DeviceListener deviceListener;
127 private MastershipService mastershipService = new InternalMastershipServiceTest();
kishore71a27532016-03-16 20:23:49 +0530128 private InterfaceListener interfaceListener;
kishore786b7e42016-05-19 16:25:57 +0530129 private ApplicationService applicationService;
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700130
kishoredb79dc02016-03-07 16:24:55 +0530131 @Before
kishore71a27532016-03-16 20:23:49 +0530132 public void setUp() {
kishoredb79dc02016-03-07 16:24:55 +0530133 networkConfigListener = createMock(NetworkConfigListener.class);
kishoredb79dc02016-03-07 16:24:55 +0530134 deviceService = new TestDeviceService();
135 deviceListener = createMock(DeviceListener.class);
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700136
kishore71a27532016-03-16 20:23:49 +0530137 interfaceListener = createMock(InterfaceListener.class);
kishoredb79dc02016-03-07 16:24:55 +0530138 deviceService.addListener(deviceListener);
139 setUpInterfaceService();
kishore71a27532016-03-16 20:23:49 +0530140 interfaceService = new InternalInterfaceService();
141 interfaceService.addListener(interfaceListener);
kishoredb79dc02016-03-07 16:24:55 +0530142 networkConfigService = new TestNetworkConfigService();
143 networkConfigService.addListener(networkConfigListener);
144 flowObjectiveService = createMock(FlowObjectiveService.class);
kishore786b7e42016-05-19 16:25:57 +0530145 applicationService = createNiceMock(ApplicationService.class);
146 replay(applicationService);
kishoredb79dc02016-03-07 16:24:55 +0530147 setUpFlowObjectiveService();
kishoredb79dc02016-03-07 16:24:55 +0530148 controlPlaneRedirectManager.coreService = coreService;
149 controlPlaneRedirectManager.flowObjectiveService = flowObjectiveService;
150 controlPlaneRedirectManager.networkConfigService = networkConfigService;
151 controlPlaneRedirectManager.interfaceService = interfaceService;
152 controlPlaneRedirectManager.deviceService = deviceService;
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700153 controlPlaneRedirectManager.hostService = createNiceMock(HostService.class);
kishoredb79dc02016-03-07 16:24:55 +0530154 controlPlaneRedirectManager.mastershipService = mastershipService;
kishore786b7e42016-05-19 16:25:57 +0530155 controlPlaneRedirectManager.applicationService = applicationService;
Charles Chanc6d227e2017-02-28 15:15:17 -0800156 controlPlaneRedirectManager.activate(new ComponentContextAdapter());
kishoredb79dc02016-03-07 16:24:55 +0530157 verify(flowObjectiveService);
158 }
kishore71a27532016-03-16 20:23:49 +0530159
kishoredb79dc02016-03-07 16:24:55 +0530160 /**
kishore71a27532016-03-16 20:23:49 +0530161 * Tests adding new Device to a openflow router.
162 */
163 @Test
164 public void testAddDevice() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700165 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530166 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
167 interfaceIpAddresses.add(
168 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
169 );
170 interfaceIpAddresses.add(
171 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
172 );
kishore71a27532016-03-16 20:23:49 +0530173
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530174 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530175 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
176 interfaces.add(sw1Eth4);
177 EasyMock.reset(flowObjectiveService);
178 setUpFlowObjectiveService();
179 deviceListener.event(new DeviceEvent(DeviceEvent.Type.DEVICE_AVAILABILITY_CHANGED, dev3));
180 verify(flowObjectiveService);
181 }
182
183 /**
184 * Tests adding while updating the networkConfig.
185 */
186 @Test
187 public void testUpdateNetworkConfig() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700188 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530189 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
190 interfaceIpAddresses.add(
191 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
192 );
193 interfaceIpAddresses.add(
194 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
195 );
kishore71a27532016-03-16 20:23:49 +0530196
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530197 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530198 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
199 interfaces.add(sw1Eth4);
200 EasyMock.reset(flowObjectiveService);
201 setUpFlowObjectiveService();
202 networkConfigListener
203 .event(new NetworkConfigEvent(Type.CONFIG_UPDATED, dev3, RoutingService.ROUTER_CONFIG_CLASS));
204 networkConfigService.addListener(networkConfigListener);
205 verify(flowObjectiveService);
206 }
207
208 /**
209 * Tests adding while updating the networkConfig.
210 */
211 @Test
212 public void testAddInterface() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700213 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530214 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
215 interfaceIpAddresses.add(
216 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
217 );
218 interfaceIpAddresses.add(
219 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
220 );
kishore71a27532016-03-16 20:23:49 +0530221
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530222 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530223 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
224 interfaces.add(sw1Eth4);
225
226 EasyMock.reset(flowObjectiveService);
227 expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
228
229 setUpInterfaceConfiguration(sw1Eth4, true);
230 replay(flowObjectiveService);
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700231 interfaceListener.event(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_ADDED, sw1Eth4, 500L));
kishore71a27532016-03-16 20:23:49 +0530232 verify(flowObjectiveService);
233 }
234
235 @Test
236 public void testRemoveInterface() {
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700237 ConnectPoint sw1eth4 = new ConnectPoint(DEVICE_ID, PortNumber.portNumber(4));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530238 List<InterfaceIpAddress> interfaceIpAddresses = new ArrayList<>();
239 interfaceIpAddresses.add(
240 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"), IpPrefix.valueOf("192.168.40.0/24"))
241 );
242 interfaceIpAddresses.add(
243 new InterfaceIpAddress(IpAddress.valueOf("2000::ff"), IpPrefix.valueOf("2000::ff/120"))
244 );
kishore71a27532016-03-16 20:23:49 +0530245
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530246 Interface sw1Eth4 = new Interface(sw1eth4.deviceId().toString(), sw1eth4, interfaceIpAddresses,
kishore71a27532016-03-16 20:23:49 +0530247 MacAddress.valueOf("00:00:00:00:00:04"), VlanId.NONE);
248 EasyMock.reset(flowObjectiveService);
249 expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
250
251 setUpInterfaceConfiguration(sw1Eth4, false);
252 replay(flowObjectiveService);
Jonathan Hartf04b7d92016-03-29 09:39:11 -0700253 interfaceListener.event(new InterfaceEvent(InterfaceEvent.Type.INTERFACE_REMOVED, sw1Eth4, 500L));
kishore71a27532016-03-16 20:23:49 +0530254 verify(flowObjectiveService);
255 }
256
257 /**
258 * Setup flow Configuration for all configured Interfaces.
kishoredb79dc02016-03-07 16:24:55 +0530259 *
260 **/
261 private void setUpFlowObjectiveService() {
kishoredb79dc02016-03-07 16:24:55 +0530262 expect(flowObjectiveService.allocateNextId()).andReturn(1).anyTimes();
kishoredb79dc02016-03-07 16:24:55 +0530263 for (Interface intf : interfaceService.getInterfaces()) {
kishore71a27532016-03-16 20:23:49 +0530264 setUpInterfaceConfiguration(intf, true);
kishoredb79dc02016-03-07 16:24:55 +0530265 }
kishoredb79dc02016-03-07 16:24:55 +0530266 replay(flowObjectiveService);
267 }
268
269 /**
kishore71a27532016-03-16 20:23:49 +0530270 * Setting up flowobjective expectations for basic forwarding and ospf.
kishoredb79dc02016-03-07 16:24:55 +0530271 **/
kishore71a27532016-03-16 20:23:49 +0530272 private void setUpInterfaceConfiguration(Interface intf, boolean install) {
273 DeviceId deviceId = controlPlaneConnectPoint.deviceId();
274 PortNumber controlPlanePort = controlPlaneConnectPoint.port();
Ray Milkey048bf9a2017-05-12 14:31:50 -0700275 for (InterfaceIpAddress ip : intf.ipAddressesList()) {
kishore71a27532016-03-16 20:23:49 +0530276 int cpNextId, intfNextId;
kishore71a27532016-03-16 20:23:49 +0530277 cpNextId = modifyNextObjective(deviceId, controlPlanePort,
Jonathan Hartf4bd0482017-01-27 15:11:18 -0800278 VlanId.vlanId(ControlPlaneRedirectManager.ASSIGNED_VLAN), true, install);
kishore71a27532016-03-16 20:23:49 +0530279 intfNextId = modifyNextObjective(deviceId, intf.connectPoint().port(),
Jonathan Hartf4bd0482017-01-27 15:11:18 -0800280 VlanId.vlanId(ControlPlaneRedirectManager.ASSIGNED_VLAN), true, install);
kishore71a27532016-03-16 20:23:49 +0530281
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530282 // IP to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800283 TrafficSelector toSelector = buildIPDstSelector(ip.ipAddress().toIpPrefix(),
284 intf.connectPoint().port(),
285 null,
286 intf.mac(),
287 intf.vlan());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530288 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, null,
289 cpNextId, install, ACL_PRIORITY));
kishore71a27532016-03-16 20:23:49 +0530290 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530291 // IP from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800292 TrafficSelector fromSelector = buildIPSrcSelector(ip.ipAddress().toIpPrefix(),
293 controlPlanePort,
294 intf.mac(),
295 null,
296 intf.vlan());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530297 flowObjectiveService.forward(deviceId, buildForwardingObjective(fromSelector, null,
298 intfNextId, install, ACL_PRIORITY));
kishore71a27532016-03-16 20:23:49 +0530299 expectLastCall().once();
kishore71a27532016-03-16 20:23:49 +0530300 TrafficTreatment puntTreatment = DefaultTrafficTreatment.builder().punt().build();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530301 if (ip.ipAddress().isIp4()) {
302 // ARP to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800303 toSelector = buildArpSelector(intf.connectPoint().port(),
304 intf.vlan(),
305 null,
306 null);
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530307 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
308 cpNextId, install, ACL_PRIORITY + 1));
309 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530310 // ARP from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800311 fromSelector = buildArpSelector(controlPlanePort,
312 intf.vlan(),
313 ip.ipAddress().getIp4Address(),
314 intf.mac());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530315 flowObjectiveService.forward(deviceId,
316 buildForwardingObjective(fromSelector, puntTreatment,
317 intfNextId, install, ACL_PRIORITY + 1));
318 expectLastCall().once();
319 } else {
320 // NDP solicitation to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800321 // Global unicast address
322 toSelector = buildNdpSelector(intf.connectPoint().port(),
323 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800324 null,
Pier Luigi9f765dc2017-02-03 13:35:23 -0800325 ip.ipAddress().toIpPrefix(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800326 NEIGHBOR_SOLICITATION,
327 null);
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530328 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
329 cpNextId, install, ACL_PRIORITY + 1));
330 expectLastCall().once();
Pier Luigi2b1ad872017-01-31 09:35:42 -0800331 // NDP solicitation to router
332 // Link local address
333 toSelector = buildNdpSelector(intf.connectPoint().port(),
334 intf.vlan(),
Pier Luigi9f765dc2017-02-03 13:35:23 -0800335 null,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800336 Ip6Address.valueOf(
337 getLinkLocalAddress(intf.mac().toBytes())
338 ).toIpPrefix(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800339 NEIGHBOR_SOLICITATION,
340 null);
341 flowObjectiveService.forward(deviceId,
342 buildForwardingObjective(toSelector, puntTreatment,
Pier Luigi9f765dc2017-02-03 13:35:23 -0800343 cpNextId, install, ACL_PRIORITY + 1));
Pier Luigi2b1ad872017-01-31 09:35:42 -0800344 expectLastCall().once();
345 // NDP solicitation to router
346 // solicitated global unicast address
347 toSelector = buildNdpSelector(intf.connectPoint().port(),
348 intf.vlan(),
Pier Luigi9f765dc2017-02-03 13:35:23 -0800349 null,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800350 Ip6Address.valueOf(
351 getSolicitNodeAddress(ip.ipAddress().toOctets())
352 ).toIpPrefix(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800353 NEIGHBOR_SOLICITATION,
354 null);
355 flowObjectiveService.forward(deviceId,
356 buildForwardingObjective(toSelector, puntTreatment,
Pier Luigi9f765dc2017-02-03 13:35:23 -0800357 cpNextId, install, ACL_PRIORITY + 1));
358 expectLastCall().once();
Pier Luigi2b1ad872017-01-31 09:35:42 -0800359 // NDP solicitation to router
360 // solicitated link local address
361 toSelector = buildNdpSelector(intf.connectPoint().port(),
362 intf.vlan(),
Pier Luigi9f765dc2017-02-03 13:35:23 -0800363 null,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800364 Ip6Address.valueOf(
365 getSolicitNodeAddress(getLinkLocalAddress(intf.mac().toBytes()))
366 ).toIpPrefix(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800367 NEIGHBOR_SOLICITATION,
368 null);
369 flowObjectiveService.forward(deviceId,
370 buildForwardingObjective(toSelector, puntTreatment,
Pier Luigi9f765dc2017-02-03 13:35:23 -0800371 cpNextId, install, ACL_PRIORITY + 1));
Pier Luigi2b1ad872017-01-31 09:35:42 -0800372 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530373 // NDP solicitation from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800374 // Global unicast address
375 fromSelector = buildNdpSelector(controlPlanePort,
376 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800377 ip.ipAddress().toIpPrefix(),
Pier Luigi9f765dc2017-02-03 13:35:23 -0800378 null,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800379 NEIGHBOR_SOLICITATION,
380 intf.mac());
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530381 flowObjectiveService.forward(deviceId,
382 buildForwardingObjective(fromSelector, puntTreatment,
383 intfNextId, install, ACL_PRIORITY + 1));
Pier Luigi2b1ad872017-01-31 09:35:42 -0800384 expectLastCall().once();
385 // NDP solicitation from router
386 // Link local address
387 fromSelector = buildNdpSelector(controlPlanePort,
388 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800389 Ip6Address.valueOf(
390 getLinkLocalAddress(intf.mac().toBytes())
391 ).toIpPrefix(),
Pier Luigi9f765dc2017-02-03 13:35:23 -0800392 null,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800393 NEIGHBOR_SOLICITATION,
394 intf.mac());
395 flowObjectiveService.forward(deviceId,
396 buildForwardingObjective(fromSelector, puntTreatment,
397 intfNextId, install, ACL_PRIORITY + 1));
398 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530399 // NDP advertisement to router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800400 // Global unicast address
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530401 toSelector = buildNdpSelector(
402 intf.connectPoint().port(),
403 intf.vlan(),
Pier Luigi9f765dc2017-02-03 13:35:23 -0800404 null,
405 ip.ipAddress().toIpPrefix(),
406 NEIGHBOR_ADVERTISEMENT,
407 null
408 );
409 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
410 cpNextId, install, ACL_PRIORITY + 1));
411 expectLastCall().once();
412 // NDP advertisement to router
413 // Link local address
414 toSelector = buildNdpSelector(
415 intf.connectPoint().port(),
416 intf.vlan(),
417 null,
418 Ip6Address.valueOf(getLinkLocalAddress(intf.mac().toBytes())).toIpPrefix(),
419 NEIGHBOR_ADVERTISEMENT,
420 null
421 );
422 flowObjectiveService.forward(deviceId, buildForwardingObjective(toSelector, puntTreatment,
423 cpNextId, install, ACL_PRIORITY + 1));
424 expectLastCall().once();
425 // NDP advertisement from the router
426 // Global unicast address
427 fromSelector = buildNdpSelector(
428 controlPlanePort,
429 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800430 ip.ipAddress().toIpPrefix(),
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530431 null,
432 NEIGHBOR_ADVERTISEMENT,
433 null
434 );
Pier Luigi9f765dc2017-02-03 13:35:23 -0800435 flowObjectiveService.forward(deviceId, buildForwardingObjective(fromSelector, puntTreatment,
436 intfNextId, install, ACL_PRIORITY + 1));
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530437 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530438 // NDP advertisement from router
Pier Luigi2b1ad872017-01-31 09:35:42 -0800439 // Link local address
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530440 fromSelector = buildNdpSelector(
Pier Luigi9f765dc2017-02-03 13:35:23 -0800441 controlPlanePort,
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530442 intf.vlan(),
Pier Luigi2b1ad872017-01-31 09:35:42 -0800443 Ip6Address.valueOf(getLinkLocalAddress(intf.mac().toBytes())).toIpPrefix(),
444 null,
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530445 NEIGHBOR_ADVERTISEMENT,
Pier Luigi2b1ad872017-01-31 09:35:42 -0800446 null
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530447 );
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530448 flowObjectiveService.forward(deviceId,
449 buildForwardingObjective(fromSelector, puntTreatment,
450 intfNextId, install, ACL_PRIORITY + 1));
Pier Luigi2b1ad872017-01-31 09:35:42 -0800451 expectLastCall().once();
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530452 }
kishore71a27532016-03-16 20:23:49 +0530453 }
454 // setting expectations for ospf forwarding.
kishoredb79dc02016-03-07 16:24:55 +0530455 TrafficSelector toSelector = DefaultTrafficSelector.builder().matchInPort(intf.connectPoint().port())
456 .matchEthType(EthType.EtherType.IPV4.ethType().toShort()).matchVlanId(intf.vlan())
457 .matchIPProtocol((byte) OSPF_IP_PROTO).build();
kishore71a27532016-03-16 20:23:49 +0530458 modifyNextObjective(deviceId, controlPlanePort, VlanId.vlanId((short) 4094), true, install);
kishoredb79dc02016-03-07 16:24:55 +0530459 flowObjectiveService.forward(controlPlaneConnectPoint.deviceId(),
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530460 buildForwardingObjective(toSelector, null, 1, install, 40001));
kishoredb79dc02016-03-07 16:24:55 +0530461 expectLastCall().once();
462 }
463
464 /**
kishore71a27532016-03-16 20:23:49 +0530465 * Setup expectations on flowObjectiveService.next for NextObjective.
kishoredb79dc02016-03-07 16:24:55 +0530466 *
467 **/
kishore71a27532016-03-16 20:23:49 +0530468 private int modifyNextObjective(DeviceId deviceId, PortNumber portNumber, VlanId vlanId, boolean popVlan,
469 boolean modifyFlag) {
kishoredb79dc02016-03-07 16:24:55 +0530470 NextObjective.Builder nextObjBuilder = DefaultNextObjective.builder().withId(1)
471 .withType(NextObjective.Type.SIMPLE).fromApp(APPID);
472
473 TrafficTreatment.Builder ttBuilder = DefaultTrafficTreatment.builder();
474 if (popVlan) {
475 ttBuilder.popVlan();
476 }
477 ttBuilder.setOutput(portNumber);
478
kishoredb79dc02016-03-07 16:24:55 +0530479 TrafficSelector.Builder metabuilder = DefaultTrafficSelector.builder();
480 metabuilder.matchVlanId(vlanId);
481
482 nextObjBuilder.withMeta(metabuilder.build());
483 nextObjBuilder.addTreatment(ttBuilder.build());
kishore71a27532016-03-16 20:23:49 +0530484 if (modifyFlag) {
485 flowObjectiveService.next(deviceId, nextObjBuilder.add());
486 expectLastCall().once();
487 } else {
488 flowObjectiveService.next(deviceId, nextObjBuilder.remove());
489 expectLastCall().once();
490 }
kishoredb79dc02016-03-07 16:24:55 +0530491 return 1;
492 }
493
494 /**
kishore71a27532016-03-16 20:23:49 +0530495 * Setup Interface expectation for all Testcases.
kishoredb79dc02016-03-07 16:24:55 +0530496 **/
497 private void setUpInterfaceService() {
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700498 List<InterfaceIpAddress> interfaceIpAddresses1 = new ArrayList<>();
kishoredb79dc02016-03-07 16:24:55 +0530499 interfaceIpAddresses1
500 .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"), IpPrefix.valueOf("192.168.10.0/24")));
501 Interface sw1Eth1 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH1, interfaceIpAddresses1,
502 MacAddress.valueOf("00:00:00:00:00:01"), VlanId.NONE);
503 interfaces.add(sw1Eth1);
504
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700505 List<InterfaceIpAddress> interfaceIpAddresses2 = new ArrayList<>();
kishoredb79dc02016-03-07 16:24:55 +0530506 interfaceIpAddresses2
507 .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"), IpPrefix.valueOf("192.168.20.0/24")));
508 Interface sw1Eth2 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH2, interfaceIpAddresses2,
509 MacAddress.valueOf("00:00:00:00:00:02"), VlanId.NONE);
510 interfaces.add(sw1Eth2);
511
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700512 List<InterfaceIpAddress> interfaceIpAddresses3 = new ArrayList<>();
kishoredb79dc02016-03-07 16:24:55 +0530513 interfaceIpAddresses3
514 .add(new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"), IpPrefix.valueOf("192.168.30.0/24")));
515 Interface sw1Eth3 = new Interface(SW1_ETH1.deviceId().toString(), SW1_ETH3, interfaceIpAddresses3,
516 MacAddress.valueOf("00:00:00:00:00:03"), VlanId.NONE);
517 interfaces.add(sw1Eth3);
518
kishoredb79dc02016-03-07 16:24:55 +0530519 }
520
kishoredb79dc02016-03-07 16:24:55 +0530521 private ForwardingObjective buildForwardingObjective(TrafficSelector selector, TrafficTreatment treatment,
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530522 int nextId, boolean add, int priority) {
kishoredb79dc02016-03-07 16:24:55 +0530523 DefaultForwardingObjective.Builder fobBuilder = DefaultForwardingObjective.builder();
524 fobBuilder.withSelector(selector);
525 if (treatment != null) {
526 fobBuilder.withTreatment(treatment);
527 }
528 if (nextId != -1) {
529 fobBuilder.nextStep(nextId);
530 }
Vinayak Tejankar3a409c62017-01-12 02:20:53 +0530531 fobBuilder.fromApp(APPID).withPriority(priority).withFlag(ForwardingObjective.Flag.VERSATILE);
kishoredb79dc02016-03-07 16:24:55 +0530532
533 return add ? fobBuilder.add() : fobBuilder.remove();
534 }
535
kishoredb79dc02016-03-07 16:24:55 +0530536 private class TestCoreService extends CoreServiceAdapter {
kishore71a27532016-03-16 20:23:49 +0530537
kishoredb79dc02016-03-07 16:24:55 +0530538 @Override
539 public ApplicationId getAppId(String name) {
540 return APPID;
541 }
542
543 @Override
544 public ApplicationId registerApplication(String name) {
kishoredb79dc02016-03-07 16:24:55 +0530545 return new TestApplicationId(name);
546 }
547
548 }
549
550 private class TestDeviceService extends DeviceServiceAdapter {
551
552 @Override
553 public boolean isAvailable(DeviceId deviceId) {
kishoredb79dc02016-03-07 16:24:55 +0530554 boolean flag = false;
555 if (deviceId.equals(controlPlaneConnectPoint.deviceId())) {
556 flag = true;
557 }
558 return flag;
559 }
560
561 @Override
562 public void addListener(DeviceListener listener) {
kishoredb79dc02016-03-07 16:24:55 +0530563 ControlPlaneRedirectManagerTest.this.deviceListener = listener;
564 }
565
566 }
567
kishoredb79dc02016-03-07 16:24:55 +0530568 private class TestRouterConfig extends RouterConfig {
569
570 @Override
571 public ConnectPoint getControlPlaneConnectPoint() {
kishoredb79dc02016-03-07 16:24:55 +0530572 return controlPlaneConnectPoint;
573 }
574
575 @Override
576 public boolean getOspfEnabled() {
kishoredb79dc02016-03-07 16:24:55 +0530577 return true;
578 }
579
580 @Override
581 public List<String> getInterfaces() {
kishoredb79dc02016-03-07 16:24:55 +0530582 ArrayList<String> interfaces = new ArrayList<>();
583 interfaces.add("of:0000000000000001");
584 interfaces.add("of:0000000000000001/2");
585 interfaces.add("of:0000000000000001/3");
586 return interfaces;
587 }
588
589 }
590
591 private class TestNetworkConfigService extends NetworkConfigServiceAdapter {
592
593 @Override
594 public void addListener(NetworkConfigListener listener) {
kishoredb79dc02016-03-07 16:24:55 +0530595 ControlPlaneRedirectManagerTest.this.networkConfigListener = listener;
596 }
597
598 @Override
599 public <S, C extends Config<S>> C getConfig(S subject, Class<C> configClass) {
kishoredb79dc02016-03-07 16:24:55 +0530600 return (C) ControlPlaneRedirectManagerTest.this.routerConfig;
601 }
602
603 }
604
605 private static class TestApplicationId implements ApplicationId {
606
607 private final String name;
608 private final short id;
609
610 public TestApplicationId(String name) {
611 this.name = name;
612 this.id = (short) Objects.hash(name);
613 }
614
615 public static ApplicationId create(String name) {
616 return new TestApplicationId(name);
617 }
618
619 @Override
620 public short id() {
621 return id;
622 }
623
624 @Override
625 public String name() {
626 return name;
627 }
628
629 @Override
630 public int hashCode() {
631 final int prime = 31;
632 int result = 1;
633 result = prime * result + id;
634 result = prime * result + ((name == null) ? 0 : name.hashCode());
635 return result;
636 }
637
638 @Override
639 public boolean equals(Object obj) {
640 if (this == obj) {
641 return true;
642 }
643 if (obj == null) {
644 return false;
645 }
646 if (getClass() != obj.getClass()) {
647 return false;
648 }
649 TestApplicationId other = (TestApplicationId) obj;
650 if (id != other.id) {
651 return false;
652 }
653 if (name == null) {
654 if (other.name != null) {
655 return false;
kishore71a27532016-03-16 20:23:49 +0530656 }
kishoredb79dc02016-03-07 16:24:55 +0530657 } else if (!name.equals(other.name)) {
658 return false;
659 }
660 return true;
661 }
662 }
663
664 private class InternalMastershipServiceTest extends MastershipServiceAdapter {
665
666 @Override
667 public boolean isLocalMaster(DeviceId deviceId) {
kishoredb79dc02016-03-07 16:24:55 +0530668 boolean flag = deviceId.equals(controlPlaneConnectPoint.deviceId());
669 return flag;
670 }
671
672 }
kishore71a27532016-03-16 20:23:49 +0530673
674 private class InternalInterfaceService extends InterfaceServiceAdapter {
675
676 @Override
677 public void addListener(InterfaceListener listener) {
678 ControlPlaneRedirectManagerTest.this.interfaceListener = listener;
679 }
680
681 @Override
682 public Set<Interface> getInterfaces() {
683 return interfaces;
684 }
685
686 @Override
687 public Set<Interface> getInterfacesByPort(ConnectPoint port) {
688 Set<Interface> setIntf = new HashSet<Interface>();
689 for (Interface intf : interfaces) {
690 if (intf.connectPoint().equals(port)) {
691 setIntf.add(intf);
692 }
693 }
694 return setIntf;
695 }
696
697 @Override
698 public Interface getMatchingInterface(IpAddress ip) {
699 Interface intff = null;
700 for (Interface intf : interfaces) {
Ray Milkey048bf9a2017-05-12 14:31:50 -0700701 for (InterfaceIpAddress address : intf.ipAddressesList()) {
kishore71a27532016-03-16 20:23:49 +0530702 if (address.ipAddress().equals(ip)) {
703 intff = intf;
704 break;
705 }
706 }
707 }
708
709 return intff;
710 }
711
712 }
kishoredb79dc02016-03-07 16:24:55 +0530713}