blob: f9ee791f3c6f4963f26691cc43d6a37e8bde46fc [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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;
Jonathan Hart2a9ea492015-07-30 15:53:04 -070029import org.onosproject.net.host.InterfaceIpAddress;
Brian O'Connorabafb502014-12-02 22:26:20 -080030import org.onosproject.net.intent.PointToPointIntent;
Jonathan Hart2da1e602015-02-18 19:09:24 -080031import org.onosproject.routing.config.BgpPeer;
32import org.onosproject.routing.config.BgpSpeaker;
33import org.onosproject.routing.config.Interface;
34import org.onosproject.routing.config.InterfaceAddress;
35import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070036import org.slf4j.Logger;
37import org.slf4j.LoggerFactory;
38
Jonathan Hart41349e92015-02-09 14:14:02 -080039import java.util.ArrayList;
40import java.util.Collection;
41import 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(
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700133 BgpSpeaker bgpSpeaker,
134 BgpPeer bgpPeer) {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800135 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) {
Jonathan Hart2a9ea492015-07-30 15:53:04 -0700152 if (interfaceAddress.connectPoint().equals(peerInterface.connectPoint())) {
153 for (InterfaceIpAddress interfaceIpAddress : peerInterface.ipAddresses()) {
154 // Only add intents where the peer and ONOS's addresses are
155 // in the same subnet
156 if (interfaceIpAddress.subnetAddress().contains(bgpPeer.ipAddress())) {
157 bgpdAddress = interfaceAddress.ipAddress();
158 }
159 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800160 break;
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700161 }
162 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800163 if (bgpdAddress == null) {
164 log.debug("No IP address found for peer {} on interface {}",
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700165 bgpPeer, bgpPeer.connectPoint());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800166 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800167 }
168
169 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
170 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
171
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800172 if (bgpdAddress.version() != bgpdPeerAddress.version()) {
173 return intents;
174 }
175
Brian O'Connor6b528132015-03-10 16:39:52 -0700176 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
Jonathan Hart6ec68292014-11-14 15:09:30 -0800177
178 TrafficSelector selector;
179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800180 byte tcpProtocol;
181 byte icmpProtocol;
182
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700183 if (bgpdAddress.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800184 tcpProtocol = IPv4.PROTOCOL_TCP;
185 icmpProtocol = IPv4.PROTOCOL_ICMP;
186 } else {
187 tcpProtocol = IPv6.PROTOCOL_TCP;
188 icmpProtocol = IPv6.PROTOCOL_ICMP6;
189 }
190
Jonathan Hart51372182014-12-03 21:32:34 -0800191 // Path from BGP speaker to BGP peer matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800192 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700193 bgpdAddress,
194 bgpdPeerAddress,
195 null,
196 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800197
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700198 int priority = PRIORITY_OFFSET;
199
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700200 intents.add(PointToPointIntent.builder()
201 .appId(appId)
202 .selector(selector)
203 .treatment(treatment)
204 .ingressPoint(bgpdConnectPoint)
205 .egressPoint(bgpdPeerConnectPoint)
206 .priority(priority)
207 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800208
Jonathan Hart51372182014-12-03 21:32:34 -0800209 // Path from BGP speaker to BGP peer matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800210 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700211 bgpdAddress,
212 bgpdPeerAddress,
213 BGP_PORT,
214 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800215
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700216 intents.add(PointToPointIntent.builder()
217 .appId(appId)
218 .selector(selector)
219 .treatment(treatment)
220 .ingressPoint(bgpdConnectPoint)
221 .egressPoint(bgpdPeerConnectPoint)
222 .priority(priority)
223 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800224
Jonathan Hart51372182014-12-03 21:32:34 -0800225 // Path from BGP peer to BGP speaker matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800226 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700227 bgpdPeerAddress,
228 bgpdAddress,
229 null,
230 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800231
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700232 intents.add(PointToPointIntent.builder()
233 .appId(appId)
234 .selector(selector)
235 .treatment(treatment)
236 .ingressPoint(bgpdPeerConnectPoint)
237 .egressPoint(bgpdConnectPoint)
238 .priority(priority)
239 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800240
Jonathan Hart51372182014-12-03 21:32:34 -0800241 // Path from BGP peer to BGP speaker matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800242 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700243 bgpdPeerAddress,
244 bgpdAddress,
245 BGP_PORT,
246 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800247
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700248 intents.add(PointToPointIntent.builder()
249 .appId(appId)
250 .selector(selector)
251 .treatment(treatment)
252 .ingressPoint(bgpdPeerConnectPoint)
253 .egressPoint(bgpdConnectPoint)
254 .priority(priority)
255 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800256
Jonathan Hart51372182014-12-03 21:32:34 -0800257 // ICMP path from BGP speaker to BGP peer
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800258 selector = buildSelector(icmpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700259 bgpdAddress,
260 bgpdPeerAddress,
261 null,
262 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800263
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700264 intents.add(PointToPointIntent.builder()
265 .appId(appId)
266 .selector(selector)
267 .treatment(treatment)
268 .ingressPoint(bgpdConnectPoint)
269 .egressPoint(bgpdPeerConnectPoint)
270 .priority(priority)
271 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800272
Jonathan Hart51372182014-12-03 21:32:34 -0800273 // ICMP path from BGP peer to BGP speaker
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800274 selector = buildSelector(icmpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700275 bgpdPeerAddress,
276 bgpdAddress,
277 null,
278 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800279
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700280 intents.add(PointToPointIntent.builder()
281 .appId(appId)
282 .selector(selector)
283 .treatment(treatment)
284 .ingressPoint(bgpdPeerConnectPoint)
285 .egressPoint(bgpdConnectPoint)
286 .priority(priority)
287 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800288
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800289 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800290 }
291
292 /**
293 * Builds a traffic selector based on the set of input parameters.
294 *
295 * @param ipProto IP protocol
296 * @param srcIp source IP address
297 * @param dstIp destination IP address
298 * @param srcTcpPort source TCP port, or null if shouldn't be set
299 * @param dstTcpPort destination TCP port, or null if shouldn't be set
300 * @return the new traffic selector
301 */
302 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800303 IpAddress dstIp, Short srcTcpPort,
304 Short dstTcpPort) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800305 TrafficSelector.Builder builder = null;
306
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700307 if (dstIp.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800308 builder = DefaultTrafficSelector.builder()
309 .matchEthType(Ethernet.TYPE_IPV4)
310 .matchIPProtocol(ipProto)
311 .matchIPSrc(IpPrefix.valueOf(srcIp,
312 IpPrefix.MAX_INET_MASK_LENGTH))
313 .matchIPDst(IpPrefix.valueOf(dstIp,
314 IpPrefix.MAX_INET_MASK_LENGTH));
315 } else {
316 builder = DefaultTrafficSelector.builder()
317 .matchEthType(Ethernet.TYPE_IPV6)
318 .matchIPProtocol(ipProto)
319 .matchIPv6Src(IpPrefix.valueOf(srcIp,
320 IpPrefix.MAX_INET6_MASK_LENGTH))
321 .matchIPv6Dst(IpPrefix.valueOf(dstIp,
322 IpPrefix.MAX_INET6_MASK_LENGTH));
323 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800324
325 if (srcTcpPort != null) {
326 builder.matchTcpSrc(srcTcpPort);
327 }
328
329 if (dstTcpPort != null) {
330 builder.matchTcpDst(dstTcpPort);
331 }
332
333 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700334 }
335
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700336}