blob: 9f3494577701fa3c899d967db3a718475db985b0 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Thomas Vachuska4f1a60c2014-10-28 13:39:07 -07002 * Copyright 2014 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 Hartdc711bd2014-10-15 11:24:23 -070017
Jonathan Hart51372182014-12-03 21:32:34 -080018import org.onlab.packet.Ethernet;
19import org.onlab.packet.IPv4;
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -080020import org.onlab.packet.IPv6;
Jonathan Hart41349e92015-02-09 14:14:02 -080021import org.onlab.packet.IpAddress;
Jonathan Hart51372182014-12-03 21:32:34 -080022import org.onlab.packet.IpPrefix;
Brian O'Connorabafb502014-12-02 22:26:20 -080023import org.onosproject.core.ApplicationId;
24import org.onosproject.net.ConnectPoint;
25import org.onosproject.net.flow.DefaultTrafficSelector;
26import org.onosproject.net.flow.DefaultTrafficTreatment;
27import org.onosproject.net.flow.TrafficSelector;
28import org.onosproject.net.flow.TrafficTreatment;
29import org.onosproject.net.intent.PointToPointIntent;
Jonathan Hart2da1e602015-02-18 19:09:24 -080030import org.onosproject.routing.config.BgpPeer;
31import org.onosproject.routing.config.BgpSpeaker;
32import org.onosproject.routing.config.Interface;
33import org.onosproject.routing.config.InterfaceAddress;
34import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070035import org.slf4j.Logger;
36import org.slf4j.LoggerFactory;
37
Jonathan Hart41349e92015-02-09 14:14:02 -080038import java.util.ArrayList;
39import java.util.Collection;
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -070040import java.util.Collections;
Jonathan Hart41349e92015-02-09 14:14:02 -080041import java.util.List;
42
Jonathan Hartdc711bd2014-10-15 11:24:23 -070043/**
44 * Manages the connectivity requirements between peers.
45 */
Jonathan Hartce430a42014-10-16 20:44:29 -070046public class PeerConnectivityManager {
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -070047 private static final int PRIORITY_OFFSET = 1000;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070048
49 private static final Logger log = LoggerFactory.getLogger(
Jonathan Hartce430a42014-10-16 20:44:29 -070050 PeerConnectivityManager.class);
Jonathan Hartdc711bd2014-10-15 11:24:23 -070051
Jonathan Hart41349e92015-02-09 14:14:02 -080052 private static final short BGP_PORT = 179;
53
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080054 private final IntentSynchronizer intentSynchronizer;
Jonathan Hart90a02c22015-02-13 11:52:07 -080055 private final RoutingConfigurationService configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070056
Thomas Vachuskab97cf282014-10-20 23:31:12 -070057 private final ApplicationId appId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070058
Jonathan Hart31582d12014-10-22 13:52:41 -070059 /**
60 * Creates a new PeerConnectivityManager.
61 *
Jonathan Hart51372182014-12-03 21:32:34 -080062 * @param appId the application ID
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080063 * @param intentSynchronizer the intent synchronizer
Jonathan Hart51372182014-12-03 21:32:34 -080064 * @param configService the SDN-IP config service
Jonathan Hart31582d12014-10-22 13:52:41 -070065 */
Thomas Vachuskab97cf282014-10-20 23:31:12 -070066 public PeerConnectivityManager(ApplicationId appId,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080067 IntentSynchronizer intentSynchronizer,
Jonathan Hart90a02c22015-02-13 11:52:07 -080068 RoutingConfigurationService configService) {
Thomas Vachuskab97cf282014-10-20 23:31:12 -070069 this.appId = appId;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080070 this.intentSynchronizer = intentSynchronizer;
Jonathan Hart31582d12014-10-22 13:52:41 -070071 this.configService = configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070072 }
73
Jonathan Hart31582d12014-10-22 13:52:41 -070074 /**
75 * Starts the peer connectivity manager.
76 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070077 public void start() {
Jonathan Hart90a02c22015-02-13 11:52:07 -080078 if (configService.getInterfaces().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080079 log.warn("No interfaces found in configuration file");
Jonathan Hartde089122014-12-03 22:33:14 -080080 }
81
82 if (configService.getBgpPeers().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080083 log.warn("No BGP peers found in configuration file");
Jonathan Hartde089122014-12-03 22:33:14 -080084 }
85
86 if (configService.getBgpSpeakers().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080087 log.error("No BGP speakers found in configuration file");
Jonathan Hartdc711bd2014-10-15 11:24:23 -070088 }
89
Jonathan Hart6ec68292014-11-14 15:09:30 -080090 setUpConnectivity();
Jonathan Hartdc711bd2014-10-15 11:24:23 -070091 }
92
93 /**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080094 * Stops the peer connectivity manager.
95 */
96 public void stop() {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080097 }
98
99 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -0800100 * Sets up paths to establish connectivity between all internal
101 * {@link BgpSpeaker}s and all external {@link BgpPeer}s.
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700102 */
Jonathan Hart6ec68292014-11-14 15:09:30 -0800103 private void setUpConnectivity() {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800104 List<PointToPointIntent> intents = new ArrayList<>();
105
Jonathan Hart31582d12014-10-22 13:52:41 -0700106 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700107 .values()) {
108 log.debug("Start to set up BGP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700109 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700110
Jonathan Hart31582d12014-10-22 13:52:41 -0700111 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700112
113 log.debug("Start to set up BGP paths between BGP speaker: {} "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700114 + "to BGP peer: {}", bgpSpeaker, bgpPeer);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700115
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800116 intents.addAll(buildPeerIntents(bgpSpeaker, bgpPeer));
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700117 }
118 }
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800119
120 // Submit all the intents.
121 intentSynchronizer.submitPeerIntents(intents);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700122 }
123
124 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -0800125 * Builds the required intents between a given internal BGP speaker and
126 * external BGP peer.
127 *
128 * @param bgpSpeaker the BGP speaker
129 * @param bgpPeer the BGP peer
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800130 * @return the intents to install
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700131 */
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800132 private Collection<PointToPointIntent> buildPeerIntents(
133 BgpSpeaker bgpSpeaker,
134 BgpPeer bgpPeer) {
135 List<PointToPointIntent> intents = new ArrayList<>();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700136
Jonathan Hart6ec68292014-11-14 15:09:30 -0800137 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700138
Jonathan Hart6ec68292014-11-14 15:09:30 -0800139 List<InterfaceAddress> interfaceAddresses =
140 bgpSpeaker.interfaceAddresses();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700141
Jonathan Hart90a02c22015-02-13 11:52:07 -0800142 Interface peerInterface = configService.getInterface(
Jonathan Hart6ec68292014-11-14 15:09:30 -0800143 bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700144
Jonathan Hart6ec68292014-11-14 15:09:30 -0800145 if (peerInterface == null) {
146 log.error("No interface found for peer {}", bgpPeer.ipAddress());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800147 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800148 }
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700149
Jonathan Hart6ec68292014-11-14 15:09:30 -0800150 IpAddress bgpdAddress = null;
151 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
152 if (interfaceAddress.connectPoint().equals(
153 peerInterface.connectPoint())) {
154 bgpdAddress = interfaceAddress.ipAddress();
155 break;
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700156 }
157 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800158 if (bgpdAddress == null) {
159 log.debug("No IP address found for peer {} on interface {}",
160 bgpPeer, bgpPeer.connectPoint());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800161 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800162 }
163
164 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
165 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
166
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800167 if (bgpdAddress.version() != bgpdPeerAddress.version()) {
168 return intents;
169 }
170
Brian O'Connor6b528132015-03-10 16:39:52 -0700171 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
Jonathan Hart6ec68292014-11-14 15:09:30 -0800172
173 TrafficSelector selector;
174
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800175 byte tcpProtocol;
176 byte icmpProtocol;
177
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700178 if (bgpdAddress.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800179 tcpProtocol = IPv4.PROTOCOL_TCP;
180 icmpProtocol = IPv4.PROTOCOL_ICMP;
181 } else {
182 tcpProtocol = IPv6.PROTOCOL_TCP;
183 icmpProtocol = IPv6.PROTOCOL_ICMP6;
184 }
185
Jonathan Hart51372182014-12-03 21:32:34 -0800186 // Path from BGP speaker to BGP peer matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800187 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800188 bgpdAddress,
189 bgpdPeerAddress,
190 null,
Jonathan Hart41349e92015-02-09 14:14:02 -0800191 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800192
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700193 int priority = PRIORITY_OFFSET;
194
Jonathan Hart6ec68292014-11-14 15:09:30 -0800195 intents.add(new PointToPointIntent(appId, selector, treatment,
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700196 bgpdConnectPoint,
197 bgpdPeerConnectPoint,
198 Collections.emptyList(),
199 priority));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800200
Jonathan Hart51372182014-12-03 21:32:34 -0800201 // Path from BGP speaker to BGP peer matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800202 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800203 bgpdAddress,
204 bgpdPeerAddress,
Jonathan Hart41349e92015-02-09 14:14:02 -0800205 BGP_PORT,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800206 null);
207
208 intents.add(new PointToPointIntent(appId, selector, treatment,
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700209 bgpdConnectPoint,
210 bgpdPeerConnectPoint,
211 Collections.emptyList(),
212 priority));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800213
Jonathan Hart51372182014-12-03 21:32:34 -0800214 // Path from BGP peer to BGP speaker matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800215 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800216 bgpdPeerAddress,
217 bgpdAddress,
218 null,
Jonathan Hart41349e92015-02-09 14:14:02 -0800219 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800220
221 intents.add(new PointToPointIntent(appId, selector, treatment,
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700222 bgpdPeerConnectPoint,
223 bgpdConnectPoint,
224 Collections.emptyList(),
225 priority));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800226
Jonathan Hart51372182014-12-03 21:32:34 -0800227 // Path from BGP peer to BGP speaker matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800228 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800229 bgpdPeerAddress,
230 bgpdAddress,
Jonathan Hart41349e92015-02-09 14:14:02 -0800231 BGP_PORT,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800232 null);
233
234 intents.add(new PointToPointIntent(appId, selector, treatment,
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700235 bgpdPeerConnectPoint,
236 bgpdConnectPoint,
237 Collections.emptyList(),
238 priority));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800239
Jonathan Hart51372182014-12-03 21:32:34 -0800240 // ICMP path from BGP speaker to BGP peer
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800241 selector = buildSelector(icmpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800242 bgpdAddress,
243 bgpdPeerAddress,
244 null,
245 null);
246
247 intents.add(new PointToPointIntent(appId, selector, treatment,
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700248 bgpdConnectPoint,
249 bgpdPeerConnectPoint,
250 Collections.emptyList(),
251 priority));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800252
Jonathan Hart51372182014-12-03 21:32:34 -0800253 // ICMP path from BGP peer to BGP speaker
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800254 selector = buildSelector(icmpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800255 bgpdPeerAddress,
256 bgpdAddress,
257 null,
258 null);
259
260 intents.add(new PointToPointIntent(appId, selector, treatment,
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700261 bgpdPeerConnectPoint,
262 bgpdConnectPoint,
263 Collections.emptyList(),
264 priority));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800265
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800266 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800267 }
268
269 /**
270 * Builds a traffic selector based on the set of input parameters.
271 *
272 * @param ipProto IP protocol
273 * @param srcIp source IP address
274 * @param dstIp destination IP address
275 * @param srcTcpPort source TCP port, or null if shouldn't be set
276 * @param dstTcpPort destination TCP port, or null if shouldn't be set
277 * @return the new traffic selector
278 */
279 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800280 IpAddress dstIp, Short srcTcpPort,
281 Short dstTcpPort) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800282 TrafficSelector.Builder builder = null;
283
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700284 if (dstIp.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800285 builder = DefaultTrafficSelector.builder()
286 .matchEthType(Ethernet.TYPE_IPV4)
287 .matchIPProtocol(ipProto)
288 .matchIPSrc(IpPrefix.valueOf(srcIp,
289 IpPrefix.MAX_INET_MASK_LENGTH))
290 .matchIPDst(IpPrefix.valueOf(dstIp,
291 IpPrefix.MAX_INET_MASK_LENGTH));
292 } else {
293 builder = DefaultTrafficSelector.builder()
294 .matchEthType(Ethernet.TYPE_IPV6)
295 .matchIPProtocol(ipProto)
296 .matchIPv6Src(IpPrefix.valueOf(srcIp,
297 IpPrefix.MAX_INET6_MASK_LENGTH))
298 .matchIPv6Dst(IpPrefix.valueOf(dstIp,
299 IpPrefix.MAX_INET6_MASK_LENGTH));
300 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800301
302 if (srcTcpPort != null) {
303 builder.matchTcpSrc(srcTcpPort);
304 }
305
306 if (dstTcpPort != null) {
307 builder.matchTcpDst(dstTcpPort);
308 }
309
310 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700311 }
312
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700313}