blob: 32bae1489263d1b23666a12e9e99be058391f2db [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Brian O'Connor5ab426f2016-04-09 01:19:45 -07002 * Copyright 2014-present Open Networking Laboratory
Thomas Vachuska781d18b2014-10-27 10:31:25 -07003 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07004 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
Thomas Vachuska781d18b2014-10-27 10:31:25 -07007 *
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07008 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
Thomas Vachuska781d18b2014-10-27 10:31:25 -070015 */
Brian O'Connorabafb502014-12-02 22:26:20 -080016package org.onosproject.sdnip;
Jonathan Hartce430a42014-10-16 20:44:29 -070017
Sho SHIMIZU891162b2016-06-06 16:32:01 -070018import com.google.common.collect.ImmutableList;
Jonathan Harte30fcda2015-08-06 16:22:34 -070019import com.google.common.collect.Sets;
Jonathan Hartce430a42014-10-16 20:44:29 -070020import org.junit.Before;
Jonathan Hartce430a42014-10-16 20:44:29 -070021import org.junit.Test;
Jonathan Hart51372182014-12-03 21:32:34 -080022import org.onlab.packet.Ethernet;
23import org.onlab.packet.IPv4;
24import org.onlab.packet.IpAddress;
25import org.onlab.packet.IpPrefix;
26import org.onlab.packet.MacAddress;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -070027import org.onlab.packet.TpPort;
Jonathan Hart6cd2f352015-01-13 17:44:45 -080028import org.onlab.packet.VlanId;
Jonathan Hart9a426f82015-09-03 15:43:13 +020029import org.onosproject.TestApplicationId;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.core.ApplicationId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040031import org.onosproject.incubator.net.intf.Interface;
Jonathan Hartb14221c2016-03-07 09:55:50 -080032import org.onosproject.incubator.net.intf.InterfaceListener;
Jonathan Hart4cb39882015-08-12 23:50:55 -040033import org.onosproject.incubator.net.intf.InterfaceService;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.ConnectPoint;
35import org.onosproject.net.DeviceId;
36import org.onosproject.net.PortNumber;
Jonathan Hart08105be2015-10-10 18:31:06 -070037import org.onosproject.net.config.NetworkConfigListener;
Jonathan Hart9a426f82015-09-03 15:43:13 +020038import org.onosproject.net.config.NetworkConfigService;
Brian O'Connorabafb502014-12-02 22:26:20 -080039import org.onosproject.net.flow.DefaultTrafficSelector;
40import org.onosproject.net.flow.DefaultTrafficTreatment;
41import org.onosproject.net.flow.TrafficSelector;
42import org.onosproject.net.flow.TrafficTreatment;
43import org.onosproject.net.host.InterfaceIpAddress;
44import org.onosproject.net.intent.AbstractIntentTest;
45import org.onosproject.net.intent.Intent;
Jonathan Hart9a426f82015-09-03 15:43:13 +020046import org.onosproject.net.intent.Key;
Brian O'Connorabafb502014-12-02 22:26:20 -080047import org.onosproject.net.intent.PointToPointIntent;
Jonathan Hart9a426f82015-09-03 15:43:13 +020048import org.onosproject.routing.IntentSynchronizationService;
Jonathan Hart4cb39882015-08-12 23:50:55 -040049import org.onosproject.routing.config.BgpConfig;
Jonathan Hartce430a42014-10-16 20:44:29 -070050
Jonathan Harte30fcda2015-08-06 16:22:34 -070051import java.util.ArrayList;
52import java.util.Collections;
53import java.util.HashMap;
Jonathan Harte30fcda2015-08-06 16:22:34 -070054import java.util.List;
55import java.util.Map;
Jonathan Harta8625482015-09-08 16:14:56 -070056import java.util.Optional;
Jonathan Hart4cb39882015-08-12 23:50:55 -040057import java.util.Set;
Jonathan Hart552e31f2015-02-06 11:11:59 -080058
Jonathan Hart08105be2015-10-10 18:31:06 -070059import static org.easymock.EasyMock.anyObject;
Ray Milkey3e3ec5f2015-03-17 17:00:38 -070060import static org.easymock.EasyMock.createMock;
61import static org.easymock.EasyMock.expect;
Jonathan Hart08105be2015-10-10 18:31:06 -070062import static org.easymock.EasyMock.expectLastCall;
Ray Milkey3e3ec5f2015-03-17 17:00:38 -070063import static org.easymock.EasyMock.replay;
64import static org.easymock.EasyMock.reset;
65import static org.easymock.EasyMock.verify;
Jonathan Hart33b81f22016-02-05 09:25:50 -080066import static org.onosproject.routing.TestIntentServiceHelper.eqExceptId;
Jonathan Hartce430a42014-10-16 20:44:29 -070067
68/**
Jonathan Hart51372182014-12-03 21:32:34 -080069 * Unit tests for PeerConnectivityManager.
Jonathan Hartce430a42014-10-16 20:44:29 -070070 */
Brian O'Connor520c0522014-11-23 23:50:47 -080071public class PeerConnectivityManagerTest extends AbstractIntentTest {
Jonathan Hartce430a42014-10-16 20:44:29 -070072
Jonathan Hart9a426f82015-09-03 15:43:13 +020073 private static final ApplicationId APPID = TestApplicationId.create("foo");
Thomas Vachuskab97cf282014-10-20 23:31:12 -070074
Jonathan Hart4cb39882015-08-12 23:50:55 -040075 private static final ApplicationId CONFIG_APP_ID = APPID;
76
Jonathan Hartce430a42014-10-16 20:44:29 -070077 private PeerConnectivityManager peerConnectivityManager;
Jonathan Hart9a426f82015-09-03 15:43:13 +020078 private IntentSynchronizationService intentSynchronizer;
Jonathan Hart4cb39882015-08-12 23:50:55 -040079 private InterfaceService interfaceService;
80 private NetworkConfigService networkConfigService;
Jonathan Hartce430a42014-10-16 20:44:29 -070081
Jonathan Hart4cb39882015-08-12 23:50:55 -040082 private Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers;
Jonathan Hartce430a42014-10-16 20:44:29 -070083 private Map<String, Interface> interfaces;
Jonathan Hartce430a42014-10-16 20:44:29 -070084
Jonathan Hart4cb39882015-08-12 23:50:55 -040085 private BgpConfig bgpConfig;
86
Jonathan Hartce430a42014-10-16 20:44:29 -070087 private List<PointToPointIntent> intentList;
88
89 private final String dpid1 = "00:00:00:00:00:00:00:01";
90 private final String dpid2 = "00:00:00:00:00:00:00:02";
Luca Prete8f2a3ce2016-03-29 16:13:01 -070091 private final String dpid3 = "00:00:00:00:00:00:00:03";
Jonathan Hartce430a42014-10-16 20:44:29 -070092
93 private final DeviceId deviceId1 =
94 DeviceId.deviceId(SdnIp.dpidToUri(dpid1));
95 private final DeviceId deviceId2 =
96 DeviceId.deviceId(SdnIp.dpidToUri(dpid2));
Luca Prete8f2a3ce2016-03-29 16:13:01 -070097 private final DeviceId deviceId3 =
98 DeviceId.deviceId(SdnIp.dpidToUri(dpid3));
Jonathan Hartce430a42014-10-16 20:44:29 -070099
100 // Interfaces connected to BGP speakers
101 private final ConnectPoint s1Eth100 =
102 new ConnectPoint(deviceId1, PortNumber.portNumber(100));
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700103 private final ConnectPoint s2Eth100 =
104 new ConnectPoint(deviceId2, PortNumber.portNumber(100));
105 private final ConnectPoint s3Eth100 =
106 new ConnectPoint(deviceId3, PortNumber.portNumber(100));
Jonathan Hartce430a42014-10-16 20:44:29 -0700107
108 // Interfaces connected to BGP peers
109 private final ConnectPoint s1Eth1 =
110 new ConnectPoint(deviceId1, PortNumber.portNumber(1));
111 private final ConnectPoint s2Eth1 =
112 new ConnectPoint(deviceId2, PortNumber.portNumber(1));
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700113 private final ConnectPoint s3Eth1 =
114 new ConnectPoint(deviceId3, PortNumber.portNumber(1));
Jonathan Hartce430a42014-10-16 20:44:29 -0700115
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700116 private static final VlanId NO_VLAN = VlanId.NONE;
117 private static final VlanId VLAN10 = VlanId.vlanId(Short.valueOf("10"));
118 private static final VlanId VLAN20 = VlanId.vlanId(Short.valueOf("20"));
119 private static final VlanId VLAN30 = VlanId.vlanId(Short.valueOf("30"));
Jonathan Hartce430a42014-10-16 20:44:29 -0700120
121 @Before
122 public void setUp() throws Exception {
Brian O'Connor520c0522014-11-23 23:50:47 -0800123 super.setUp();
Jonathan Hartb14221c2016-03-07 09:55:50 -0800124
Jonathan Hart4cb39882015-08-12 23:50:55 -0400125 interfaceService = createMock(InterfaceService.class);
Jonathan Hartb14221c2016-03-07 09:55:50 -0800126 interfaceService.addListener(anyObject(InterfaceListener.class));
127 expectLastCall().anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400128 networkConfigService = createMock(NetworkConfigService.class);
Jonathan Hart08105be2015-10-10 18:31:06 -0700129 networkConfigService.addListener(anyObject(NetworkConfigListener.class));
130 expectLastCall().anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400131 bgpConfig = createMock(BgpConfig.class);
Jonathan Hart90a02c22015-02-13 11:52:07 -0800132
Jonathan Hart4cb39882015-08-12 23:50:55 -0400133 // These will set expectations on routingConfig and interfaceService
134 bgpSpeakers = setUpBgpSpeakers();
Jonathan Hartce430a42014-10-16 20:44:29 -0700135 interfaces = Collections.unmodifiableMap(setUpInterfaces());
Jonathan Hartce430a42014-10-16 20:44:29 -0700136
137 initPeerConnectivity();
138 intentList = setUpIntentList();
139 }
140
141 /**
142 * Sets up BGP speakers.
143 *
144 * @return configured BGP speakers as a map from speaker name to speaker
145 */
Jonathan Hart4cb39882015-08-12 23:50:55 -0400146 private Set<BgpConfig.BgpSpeakerConfig> setUpBgpSpeakers() {
Jonathan Hartce430a42014-10-16 20:44:29 -0700147
Jonathan Hart4cb39882015-08-12 23:50:55 -0400148 BgpConfig.BgpSpeakerConfig speaker1 = new BgpConfig.BgpSpeakerConfig(
Jonathan Harta8625482015-09-08 16:14:56 -0700149 Optional.empty(),
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700150 NO_VLAN, s1Eth100,
151 Collections.singleton(IpAddress.valueOf("192.168.10.1")));
Jonathan Hartce430a42014-10-16 20:44:29 -0700152
Jonathan Hart4cb39882015-08-12 23:50:55 -0400153 BgpConfig.BgpSpeakerConfig speaker2 = new BgpConfig.BgpSpeakerConfig(
Jonathan Harta8625482015-09-08 16:14:56 -0700154 Optional.empty(),
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700155 NO_VLAN, s1Eth100,
156 Sets.newHashSet(IpAddress.valueOf("192.168.20.1"),
Jonathan Hart4cb39882015-08-12 23:50:55 -0400157 IpAddress.valueOf("192.168.30.1")));
Jonathan Hartce430a42014-10-16 20:44:29 -0700158
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700159 BgpConfig.BgpSpeakerConfig speaker3 = new BgpConfig.BgpSpeakerConfig(
160 Optional.empty(),
161 VLAN30, s3Eth100,
162 Sets.newHashSet(IpAddress.valueOf("192.168.40.1"),
163 IpAddress.valueOf("192.168.50.1")));
164
Jonathan Hart4cb39882015-08-12 23:50:55 -0400165 Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers = Sets.newHashSet();
166 bgpSpeakers.add(speaker1);
167 bgpSpeakers.add(speaker2);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700168 bgpSpeakers.add(speaker3);
Jonathan Hartce430a42014-10-16 20:44:29 -0700169
Jonathan Hart4cb39882015-08-12 23:50:55 -0400170 return bgpSpeakers;
Jonathan Hartce430a42014-10-16 20:44:29 -0700171 }
172
173 /**
174 * Sets up logical interfaces, which emulate the configured interfaces
175 * in SDN-IP application.
176 *
Jonathan Hart9a426f82015-09-03 15:43:13 +0200177 * @return configured interfaces as a map from interface name to Interface
Jonathan Hartce430a42014-10-16 20:44:29 -0700178 */
179 private Map<String, Interface> setUpInterfaces() {
180
Jonathan Hart9a426f82015-09-03 15:43:13 +0200181 Map<String, Interface> configuredInterfaces = new HashMap<>();
Jonathan Hartce430a42014-10-16 20:44:29 -0700182
183 String interfaceSw1Eth1 = "s1-eth1";
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700184 InterfaceIpAddress ia1 =
Jonathan Harte30fcda2015-08-06 16:22:34 -0700185 new InterfaceIpAddress(IpAddress.valueOf("192.168.10.101"),
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700186 IpPrefix.valueOf("192.168.10.0/24"));
Jonathan Hartb14221c2016-03-07 09:55:50 -0800187 Interface intfsw1eth1 = new Interface(interfaceSw1Eth1, s1Eth1,
Jonathan Hart00cddda2016-02-16 10:30:37 -0800188 Collections.singletonList(ia1),
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800189 MacAddress.valueOf("00:00:00:00:00:01"),
190 VlanId.NONE);
Jonathan Hartce430a42014-10-16 20:44:29 -0700191
192 configuredInterfaces.put(interfaceSw1Eth1, intfsw1eth1);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700193
Jonathan Hartce430a42014-10-16 20:44:29 -0700194 String interfaceSw2Eth1 = "s2-eth1";
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700195 InterfaceIpAddress ia2 =
Jonathan Harte30fcda2015-08-06 16:22:34 -0700196 new InterfaceIpAddress(IpAddress.valueOf("192.168.20.101"),
Pavlin Radoslavov76b0ae22014-10-27 15:33:19 -0700197 IpPrefix.valueOf("192.168.20.0/24"));
Jonathan Hartb14221c2016-03-07 09:55:50 -0800198 Interface intfsw2eth1 = new Interface(interfaceSw2Eth1, s2Eth1,
Jonathan Hart00cddda2016-02-16 10:30:37 -0800199 Collections.singletonList(ia2),
Jonathan Hart6cd2f352015-01-13 17:44:45 -0800200 MacAddress.valueOf("00:00:00:00:00:02"),
201 VlanId.NONE);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700202
Jonathan Hartce430a42014-10-16 20:44:29 -0700203 configuredInterfaces.put(interfaceSw2Eth1, intfsw2eth1);
204
Jonathan Harte30fcda2015-08-06 16:22:34 -0700205 String interfaceSw2Eth1intf2 = "s2-eth1_2";
206 InterfaceIpAddress ia3 =
207 new InterfaceIpAddress(IpAddress.valueOf("192.168.30.101"),
208 IpPrefix.valueOf("192.168.30.0/24"));
Jonathan Hartb14221c2016-03-07 09:55:50 -0800209 Interface intfsw2eth1intf2 = new Interface(interfaceSw2Eth1intf2, s2Eth1,
Jonathan Hart00cddda2016-02-16 10:30:37 -0800210 Collections.singletonList(ia3),
Jonathan Harte30fcda2015-08-06 16:22:34 -0700211 MacAddress.valueOf("00:00:00:00:00:03"),
212 VlanId.NONE);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700213
Jonathan Harte30fcda2015-08-06 16:22:34 -0700214 configuredInterfaces.put(interfaceSw2Eth1intf2, intfsw2eth1intf2);
215
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700216 String interfaceSw3Eth1 = "s3-eth1";
217 InterfaceIpAddress ia4 =
218 new InterfaceIpAddress(IpAddress.valueOf("192.168.40.101"),
219 IpPrefix.valueOf("192.168.40.0/24"));
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700220 Interface intfsw3eth1 = new Interface(Interface.NO_INTERFACE_NAME,
221 s3Eth1,
222 ImmutableList.of(ia4),
223 MacAddress.valueOf("00:00:00:00:00:04"),
224 VLAN10);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700225
226 configuredInterfaces.put(interfaceSw3Eth1, intfsw3eth1);
227
228 String interfaceSw3Eth1intf2 = "s3-eth1_2";
229 InterfaceIpAddress ia5 =
230 new InterfaceIpAddress(IpAddress.valueOf("192.168.50.101"),
231 IpPrefix.valueOf("192.168.50.0/24"));
Sho SHIMIZU891162b2016-06-06 16:32:01 -0700232 Interface intfsw3eth1intf2 = new Interface(Interface.NO_INTERFACE_NAME,
233 s3Eth1,
234 ImmutableList.of(ia5),
235 MacAddress.valueOf("00:00:00:00:00:05"),
236 VLAN20);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700237
238 configuredInterfaces.put(interfaceSw3Eth1intf2, intfsw3eth1intf2);
239
Jonathan Hart4cb39882015-08-12 23:50:55 -0400240 expect(interfaceService.getInterfacesByPort(s1Eth1))
241 .andReturn(Collections.singleton(intfsw1eth1)).anyTimes();
242 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.10.101")))
243 .andReturn(Collections.singleton(intfsw1eth1)).anyTimes();
244 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.10.1")))
Jonathan Hartce430a42014-10-16 20:44:29 -0700245 .andReturn(intfsw1eth1).anyTimes();
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700246
Jonathan Hart4cb39882015-08-12 23:50:55 -0400247 expect(interfaceService.getInterfacesByPort(s2Eth1))
248 .andReturn(Collections.singleton(intfsw2eth1)).anyTimes();
249 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.20.101")))
250 .andReturn(Collections.singleton(intfsw2eth1)).anyTimes();
251 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.20.1")))
Jonathan Hartce430a42014-10-16 20:44:29 -0700252 .andReturn(intfsw2eth1).anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400253
254 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.30.101")))
255 .andReturn(Collections.singleton(intfsw2eth1intf2)).anyTimes();
256 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.30.1")))
Jonathan Harte30fcda2015-08-06 16:22:34 -0700257 .andReturn(intfsw2eth1intf2).anyTimes();
Jonathan Hartce430a42014-10-16 20:44:29 -0700258
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700259 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.40.101")))
260 .andReturn(Collections.singleton(intfsw3eth1)).anyTimes();
261 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.40.1")))
262 .andReturn(intfsw3eth1).anyTimes();
263
264 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.50.101")))
265 .andReturn(Collections.singleton(intfsw3eth1intf2)).anyTimes();
266 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.50.1")))
267 .andReturn(intfsw3eth1intf2).anyTimes();
268
Jonathan Hartce430a42014-10-16 20:44:29 -0700269 // Non-existent interface used during one of the tests
Jonathan Hart4cb39882015-08-12 23:50:55 -0400270 expect(interfaceService.getInterfacesByPort(new ConnectPoint(
271 DeviceId.deviceId(SdnIp.dpidToUri("00:00:00:00:00:00:01:00")),
272 PortNumber.portNumber(1))))
Jonathan Hartce430a42014-10-16 20:44:29 -0700273 .andReturn(null).anyTimes();
274
Jonathan Hart4cb39882015-08-12 23:50:55 -0400275 expect(interfaceService.getInterfaces()).andReturn(
Jonathan Hartce430a42014-10-16 20:44:29 -0700276 Sets.newHashSet(configuredInterfaces.values())).anyTimes();
Jonathan Hartce430a42014-10-16 20:44:29 -0700277
278 return configuredInterfaces;
279 }
280
281 /**
Jonathan Hartce430a42014-10-16 20:44:29 -0700282 * Sets up expected point to point intent list.
283 *
284 * @return point to point intent list
285 */
286 private List<PointToPointIntent> setUpIntentList() {
Jonathan Hart90a02c22015-02-13 11:52:07 -0800287 intentList = new ArrayList<>();
Jonathan Hartce430a42014-10-16 20:44:29 -0700288
289 setUpBgpIntents();
290 setUpIcmpIntents();
291
292 return intentList;
Jonathan Hartce430a42014-10-16 20:44:29 -0700293 }
294
295 /**
296 * Constructs a BGP intent and put it into the intentList.
297 * <p/>
298 * The purpose of this method is too simplify the setUpBgpIntents() method,
299 * and to make the setUpBgpIntents() easy to read.
300 *
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700301 * @param srcVlanId ingress VlanId
302 * @param dstVlanId egress VlanId
Jonathan Hartce430a42014-10-16 20:44:29 -0700303 * @param srcPrefix source IP prefix to match
304 * @param dstPrefix destination IP prefix to match
305 * @param srcTcpPort source TCP port to match
306 * @param dstTcpPort destination TCP port to match
307 * @param srcConnectPoint source connect point for PointToPointIntent
308 * @param dstConnectPoint destination connect point for PointToPointIntent
309 */
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700310 private void bgpPathintentConstructor(VlanId srcVlanId, VlanId dstVlanId,
311 String srcPrefix, String dstPrefix,
312 Short srcTcpPort, Short dstTcpPort,
313 ConnectPoint srcConnectPoint,
314 ConnectPoint dstConnectPoint) {
Jonathan Hartce430a42014-10-16 20:44:29 -0700315
316 TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
317 .matchEthType(Ethernet.TYPE_IPV4)
318 .matchIPProtocol(IPv4.PROTOCOL_TCP)
319 .matchIPSrc(IpPrefix.valueOf(srcPrefix))
320 .matchIPDst(IpPrefix.valueOf(dstPrefix));
321
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700322 if (!srcVlanId.equals(VlanId.NONE)) {
323 builder.matchVlanId(VlanId.ANY);
324 }
325
326 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
327
328 if (!dstVlanId.equals(VlanId.NONE)) {
329 treatment.setVlanId(dstVlanId);
330 }
331
Jonathan Hartce430a42014-10-16 20:44:29 -0700332 if (srcTcpPort != null) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700333 builder.matchTcpSrc(TpPort.tpPort(srcTcpPort));
Jonathan Hartce430a42014-10-16 20:44:29 -0700334 }
335 if (dstTcpPort != null) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700336 builder.matchTcpDst(TpPort.tpPort(dstTcpPort));
Jonathan Hartce430a42014-10-16 20:44:29 -0700337 }
338
Jonathan Hart9a426f82015-09-03 15:43:13 +0200339 Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0]
340 + "-" + ((srcTcpPort == null) ? "dst" : "src"), APPID);
341
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700342 PointToPointIntent intent = PointToPointIntent.builder()
343 .appId(APPID)
Jonathan Hart9a426f82015-09-03 15:43:13 +0200344 .key(key)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700345 .selector(builder.build())
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700346 .treatment(treatment.build())
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700347 .ingressPoint(srcConnectPoint)
348 .egressPoint(dstConnectPoint)
349 .build();
Jonathan Hartce430a42014-10-16 20:44:29 -0700350
351 intentList.add(intent);
352 }
353
354 /**
355 * Sets up intents for BGP paths.
356 */
357 private void setUpBgpIntents() {
358
Jonathan Hart41349e92015-02-09 14:14:02 -0800359 Short bgpPort = 179;
Jonathan Hartce430a42014-10-16 20:44:29 -0700360
361 // Start to build intents between BGP speaker1 and BGP peer1
362 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700363 NO_VLAN, NO_VLAN,
364 "192.168.10.101/32", "192.168.10.1/32",
365 null, bgpPort,
Jonathan Hartce430a42014-10-16 20:44:29 -0700366 s1Eth100, s1Eth1);
367 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700368 NO_VLAN, NO_VLAN,
369 "192.168.10.101/32", "192.168.10.1/32",
370 bgpPort, null,
Jonathan Hartce430a42014-10-16 20:44:29 -0700371 s1Eth100, s1Eth1);
372
373 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700374 NO_VLAN, NO_VLAN,
375 "192.168.10.1/32", "192.168.10.101/32",
376 null, bgpPort,
Jonathan Hartce430a42014-10-16 20:44:29 -0700377 s1Eth1, s1Eth100);
378 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700379 NO_VLAN, NO_VLAN,
380 "192.168.10.1/32", "192.168.10.101/32",
381 bgpPort, null,
Jonathan Hartce430a42014-10-16 20:44:29 -0700382 s1Eth1, s1Eth100);
383
384 // Start to build intents between BGP speaker1 and BGP peer2
385 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700386 NO_VLAN, NO_VLAN,
387 "192.168.20.101/32", "192.168.20.1/32",
388 null, bgpPort,
Jonathan Hartce430a42014-10-16 20:44:29 -0700389 s1Eth100, s2Eth1);
390 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700391 NO_VLAN, NO_VLAN,
392 "192.168.20.101/32", "192.168.20.1/32",
393 bgpPort, null,
Jonathan Hartce430a42014-10-16 20:44:29 -0700394 s1Eth100, s2Eth1);
395
396 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700397 NO_VLAN, NO_VLAN,
398 "192.168.20.1/32", "192.168.20.101/32",
399 null, bgpPort,
Jonathan Hartce430a42014-10-16 20:44:29 -0700400 s2Eth1, s1Eth100);
401 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700402 NO_VLAN, NO_VLAN,
403 "192.168.20.1/32", "192.168.20.101/32",
404 bgpPort, null,
Jonathan Hartce430a42014-10-16 20:44:29 -0700405 s2Eth1, s1Eth100);
406
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700407 // Start to build intents between BGP speaker2 and BGP peer1
Jonathan Hartce430a42014-10-16 20:44:29 -0700408 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700409 NO_VLAN, NO_VLAN,
410 "192.168.30.101/32", "192.168.30.1/32",
411 null, bgpPort,
Jonathan Harte30fcda2015-08-06 16:22:34 -0700412 s1Eth100, s2Eth1);
Jonathan Hartce430a42014-10-16 20:44:29 -0700413 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700414 NO_VLAN, NO_VLAN,
415 "192.168.30.101/32", "192.168.30.1/32",
416 bgpPort, null,
Jonathan Harte30fcda2015-08-06 16:22:34 -0700417 s1Eth100, s2Eth1);
Jonathan Hartce430a42014-10-16 20:44:29 -0700418
419 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700420 NO_VLAN, NO_VLAN,
421 "192.168.30.1/32", "192.168.30.101/32",
422 null, bgpPort,
Jonathan Harte30fcda2015-08-06 16:22:34 -0700423 s2Eth1, s1Eth100);
Jonathan Hartce430a42014-10-16 20:44:29 -0700424 bgpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700425 NO_VLAN, NO_VLAN,
426 "192.168.30.1/32", "192.168.30.101/32",
427 bgpPort, null,
Jonathan Harte30fcda2015-08-06 16:22:34 -0700428 s2Eth1, s1Eth100);
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700429
430 // Start to build intents between BGP speaker3 and BGP peer4
431 bgpPathintentConstructor(
432 VLAN30, VLAN10,
433 "192.168.40.101/32", "192.168.40.1/32",
434 null, bgpPort,
435 s3Eth100, s3Eth1);
436 bgpPathintentConstructor(
437 VLAN30, VLAN10,
438 "192.168.40.101/32", "192.168.40.1/32",
439 bgpPort, null,
440 s3Eth100, s3Eth1);
441
442 bgpPathintentConstructor(
443 VLAN10, VLAN30,
444 "192.168.40.1/32", "192.168.40.101/32",
445 null, bgpPort,
446 s3Eth1, s3Eth100);
447 bgpPathintentConstructor(
448 VLAN10, VLAN30,
449 "192.168.40.1/32", "192.168.40.101/32",
450 bgpPort, null,
451 s3Eth1, s3Eth100);
452
453 // Start to build intents between BGP speaker3 and BGP peer5
454 bgpPathintentConstructor(
455 VLAN30, VLAN20,
456 "192.168.50.101/32", "192.168.50.1/32",
457 null, bgpPort,
458 s3Eth100, s3Eth1);
459 bgpPathintentConstructor(
460 VLAN30, VLAN20,
461 "192.168.50.101/32", "192.168.50.1/32",
462 bgpPort, null,
463 s3Eth100, s3Eth1);
464
465 bgpPathintentConstructor(
466 VLAN20, VLAN30,
467 "192.168.50.1/32", "192.168.50.101/32",
468 null, bgpPort,
469 s3Eth1, s3Eth100);
470 bgpPathintentConstructor(
471 VLAN20, VLAN30,
472 "192.168.50.1/32", "192.168.50.101/32",
473 bgpPort, null,
474 s3Eth1, s3Eth100);
Jonathan Hartce430a42014-10-16 20:44:29 -0700475 }
476
477 /**
478 * Constructs a BGP intent and put it into the intentList.
479 * <p/>
480 * The purpose of this method is too simplify the setUpBgpIntents() method,
481 * and to make the setUpBgpIntents() easy to read.
482 *
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700483 * @param srcVlanId ingress VlanId
484 * @param dstVlanId egress VlanId
Jonathan Hartce430a42014-10-16 20:44:29 -0700485 * @param srcPrefix source IP prefix to match
486 * @param dstPrefix destination IP prefix to match
487 * @param srcConnectPoint source connect point for PointToPointIntent
488 * @param dstConnectPoint destination connect point for PointToPointIntent
489 */
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700490 private void icmpPathintentConstructor(VlanId srcVlanId, VlanId dstVlanId,
491 String srcPrefix, String dstPrefix,
492 ConnectPoint srcConnectPoint,
493 ConnectPoint dstConnectPoint) {
Jonathan Hartce430a42014-10-16 20:44:29 -0700494
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700495 TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
Jonathan Hartce430a42014-10-16 20:44:29 -0700496 .matchEthType(Ethernet.TYPE_IPV4)
497 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
498 .matchIPSrc(IpPrefix.valueOf(srcPrefix))
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700499 .matchIPDst(IpPrefix.valueOf(dstPrefix));
500
501 if (!srcVlanId.equals(VlanId.NONE)) {
502 builder.matchVlanId(VlanId.ANY);
503 }
504
505 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
506
507 if (!dstVlanId.equals(VlanId.NONE)) {
508 treatment.setVlanId(dstVlanId);
509 }
Jonathan Hartce430a42014-10-16 20:44:29 -0700510
Jonathan Hart9a426f82015-09-03 15:43:13 +0200511 Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0]
512 + "-" + "icmp", APPID);
513
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700514 PointToPointIntent intent = PointToPointIntent.builder()
515 .appId(APPID)
Jonathan Hart9a426f82015-09-03 15:43:13 +0200516 .key(key)
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700517 .selector(builder.build())
518 .treatment(treatment.build())
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700519 .ingressPoint(srcConnectPoint)
520 .egressPoint(dstConnectPoint)
521 .build();
Jonathan Hartce430a42014-10-16 20:44:29 -0700522
523 intentList.add(intent);
524 }
525
526 /**
527 * Sets up intents for ICMP paths.
528 */
529 private void setUpIcmpIntents() {
Jonathan Hartce430a42014-10-16 20:44:29 -0700530 // Start to build intents between BGP speaker1 and BGP peer1
531 icmpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700532 NO_VLAN, NO_VLAN,
533 "192.168.10.101/32", "192.168.10.1/32",
534 s1Eth100, s1Eth1);
Jonathan Hartce430a42014-10-16 20:44:29 -0700535 icmpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700536 NO_VLAN, NO_VLAN,
537 "192.168.10.1/32", "192.168.10.101/32",
538 s1Eth1, s1Eth100);
Jonathan Hartce430a42014-10-16 20:44:29 -0700539
540 // Start to build intents between BGP speaker1 and BGP peer2
541 icmpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700542 NO_VLAN, NO_VLAN,
543 "192.168.20.101/32", "192.168.20.1/32",
544 s1Eth100, s2Eth1);
Jonathan Hartce430a42014-10-16 20:44:29 -0700545 icmpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700546 NO_VLAN, NO_VLAN,
547 "192.168.20.1/32", "192.168.20.101/32",
548 s2Eth1, s1Eth100);
Jonathan Hartce430a42014-10-16 20:44:29 -0700549
Jonathan Hartce430a42014-10-16 20:44:29 -0700550 icmpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700551 NO_VLAN, NO_VLAN,
552 "192.168.30.101/32", "192.168.30.1/32",
553 s1Eth100, s2Eth1);
Jonathan Hartce430a42014-10-16 20:44:29 -0700554 icmpPathintentConstructor(
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700555 NO_VLAN, NO_VLAN,
556 "192.168.30.1/32", "192.168.30.101/32",
557 s2Eth1, s1Eth100);
558
559 // Start to build intents between BGP speaker3 and BGP peer 4
560 icmpPathintentConstructor(
561 VLAN10, VLAN30,
562 "192.168.40.1/32", "192.168.40.101/32",
563 s3Eth1, s3Eth100);
564 icmpPathintentConstructor(
565 VLAN30, VLAN10,
566 "192.168.40.101/32", "192.168.40.1/32",
567 s3Eth100, s3Eth1);
568
569 // Start to build intents between BGP speaker3 and BGP peer 5
570 icmpPathintentConstructor(
571 VLAN20, VLAN30,
572 "192.168.50.1/32", "192.168.50.101/32",
573 s3Eth1, s3Eth100);
574 icmpPathintentConstructor(
575 VLAN30, VLAN20,
576 "192.168.50.101/32", "192.168.50.1/32",
577 s3Eth100, s3Eth1);
Jonathan Hartce430a42014-10-16 20:44:29 -0700578 }
579
580 /**
581 * Initializes peer connectivity testing environment.
582 */
Jonathan Hartde6e2032016-04-15 13:28:02 -0700583 private void initPeerConnectivity() {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400584 expect(bgpConfig.bgpSpeakers()).andReturn(bgpSpeakers).anyTimes();
585 replay(bgpConfig);
Jonathan Hart9a426f82015-09-03 15:43:13 +0200586 expect(networkConfigService.getConfig(APPID, BgpConfig.class))
587 .andReturn(bgpConfig).anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400588 replay(networkConfigService);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400589 replay(interfaceService);
Jonathan Hartce430a42014-10-16 20:44:29 -0700590
Jonathan Hart9a426f82015-09-03 15:43:13 +0200591 intentSynchronizer = createMock(IntentSynchronizationService.class);
592 replay(intentSynchronizer);
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800593
594 peerConnectivityManager =
595 new PeerConnectivityManager(APPID, intentSynchronizer,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400596 networkConfigService,
597 CONFIG_APP_ID,
598 interfaceService);
Jonathan Hartce430a42014-10-16 20:44:29 -0700599 }
600
Jonathan Hartce430a42014-10-16 20:44:29 -0700601 /**
602 * Tests whether peer connectivity manager can set up correct BGP and
603 * ICMP intents according to specific configuration.
604 * <p/>
605 * Two tricky cases included in the configuration are: 2 peers on a same
606 * switch port, peer on the same switch with BGPd.
607 */
608 @Test
609 public void testConnectionSetup() {
Jonathan Hart9a426f82015-09-03 15:43:13 +0200610 reset(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700611
Pavlin Radoslavovdde22ae2014-11-24 11:47:17 -0800612 // Setup the expected intents
Pavlin Radoslavovdde22ae2014-11-24 11:47:17 -0800613 for (Intent intent : intentList) {
Jonathan Hart9a426f82015-09-03 15:43:13 +0200614 intentSynchronizer.submit(eqExceptId(intent));
Jonathan Hartce430a42014-10-16 20:44:29 -0700615 }
Jonathan Hart9a426f82015-09-03 15:43:13 +0200616 replay(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700617
618 // Running the interface to be tested.
619 peerConnectivityManager.start();
620
Jonathan Hart9a426f82015-09-03 15:43:13 +0200621 verify(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700622 }
623
624 /**
625 * Tests a corner case, when there are no interfaces in the configuration.
626 */
627 @Test
628 public void testNullInterfaces() {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400629 reset(interfaceService);
Jonathan Hartb14221c2016-03-07 09:55:50 -0800630 interfaceService.addListener(anyObject(InterfaceListener.class));
631 expectLastCall().anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400632
633 expect(interfaceService.getInterfaces()).andReturn(
Jonathan Hart9a426f82015-09-03 15:43:13 +0200634 Sets.newHashSet()).anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400635 expect(interfaceService.getInterfacesByPort(s2Eth1))
636 .andReturn(Collections.emptySet()).anyTimes();
637 expect(interfaceService.getInterfacesByPort(s1Eth1))
638 .andReturn(Collections.emptySet()).anyTimes();
639 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.10.101")))
640 .andReturn(Collections.emptySet()).anyTimes();
641 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.10.1")))
Jonathan Hartce430a42014-10-16 20:44:29 -0700642 .andReturn(null).anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400643 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.20.101")))
644 .andReturn(Collections.emptySet()).anyTimes();
645 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.20.1")))
Jonathan Harte30fcda2015-08-06 16:22:34 -0700646 .andReturn(null).anyTimes();
Jonathan Hart4cb39882015-08-12 23:50:55 -0400647 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.30.101")))
648 .andReturn(Collections.emptySet()).anyTimes();
649 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.30.1")))
Jonathan Harte30fcda2015-08-06 16:22:34 -0700650 .andReturn(null).anyTimes();
Luca Prete8f2a3ce2016-03-29 16:13:01 -0700651 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.40.101")))
652 .andReturn(Collections.emptySet()).anyTimes();
653 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.40.1")))
654 .andReturn(null).anyTimes();
655 expect(interfaceService.getInterfacesByIp(IpAddress.valueOf("192.168.50.101")))
656 .andReturn(Collections.emptySet()).anyTimes();
657 expect(interfaceService.getMatchingInterface(IpAddress.valueOf("192.168.50.1")))
658 .andReturn(null).anyTimes();
Jonathan Hartce430a42014-10-16 20:44:29 -0700659
Jonathan Hart4cb39882015-08-12 23:50:55 -0400660 replay(interfaceService);
Jonathan Hartce430a42014-10-16 20:44:29 -0700661
Jonathan Hart9a426f82015-09-03 15:43:13 +0200662 reset(intentSynchronizer);
663 replay(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700664 peerConnectivityManager.start();
Jonathan Hart9a426f82015-09-03 15:43:13 +0200665 verify(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700666 }
667
668 /**
669 * Tests a corner case, when there is no BGP speakers in the configuration.
670 */
671 @Test
672 public void testNullBgpSpeakers() {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400673 reset(bgpConfig);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400674 expect(bgpConfig.bgpSpeakers()).andReturn(Collections.emptySet()).anyTimes();
675 replay(bgpConfig);
Jonathan Hartce430a42014-10-16 20:44:29 -0700676
Jonathan Hartde6e2032016-04-15 13:28:02 -0700677 // We don't expect any intents in this case
Jonathan Hart9a426f82015-09-03 15:43:13 +0200678 reset(intentSynchronizer);
679 replay(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700680 peerConnectivityManager.start();
Jonathan Hart9a426f82015-09-03 15:43:13 +0200681 verify(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700682 }
683
684 /**
685 * Tests a corner case, when there is no Interface configured for one BGP
686 * peer.
687 */
688 @Test
689 public void testNoPeerInterface() {
Jonathan Hartde6e2032016-04-15 13:28:02 -0700690 IpAddress ip = IpAddress.valueOf("1.1.1.1");
691 bgpSpeakers.clear();
692 bgpSpeakers.add(new BgpConfig.BgpSpeakerConfig(Optional.of("foo"),
693 VlanId.NONE, s1Eth100, Collections.singleton(ip)));
694 reset(interfaceService);
695 interfaceService.addListener(anyObject(InterfaceListener.class));
696 expect(interfaceService.getMatchingInterface(ip)).andReturn(null).anyTimes();
697 replay(interfaceService);
698
699 // We don't expect any intents in this case
700 reset(intentSynchronizer);
701 replay(intentSynchronizer);
702 peerConnectivityManager.start();
703 verify(intentSynchronizer);
Jonathan Hartce430a42014-10-16 20:44:29 -0700704 }
705
Jonathan Hartce430a42014-10-16 20:44:29 -0700706}