blob: b5bc25baa2ccf919f2f2865ccbcaa47dcf252f06 [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;
40import java.util.List;
41
Jonathan Hartdc711bd2014-10-15 11:24:23 -070042/**
43 * Manages the connectivity requirements between peers.
44 */
Jonathan Hartce430a42014-10-16 20:44:29 -070045public class PeerConnectivityManager {
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -070046 private static final int PRIORITY_OFFSET = 1000;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070047
48 private static final Logger log = LoggerFactory.getLogger(
Jonathan Hartce430a42014-10-16 20:44:29 -070049 PeerConnectivityManager.class);
Jonathan Hartdc711bd2014-10-15 11:24:23 -070050
Jonathan Hart41349e92015-02-09 14:14:02 -080051 private static final short BGP_PORT = 179;
52
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080053 private final IntentSynchronizer intentSynchronizer;
Jonathan Hart90a02c22015-02-13 11:52:07 -080054 private final RoutingConfigurationService configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070055
Thomas Vachuskab97cf282014-10-20 23:31:12 -070056 private final ApplicationId appId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070057
Jonathan Hart31582d12014-10-22 13:52:41 -070058 /**
59 * Creates a new PeerConnectivityManager.
60 *
Jonathan Hart51372182014-12-03 21:32:34 -080061 * @param appId the application ID
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080062 * @param intentSynchronizer the intent synchronizer
Jonathan Hart51372182014-12-03 21:32:34 -080063 * @param configService the SDN-IP config service
Jonathan Hart31582d12014-10-22 13:52:41 -070064 */
Thomas Vachuskab97cf282014-10-20 23:31:12 -070065 public PeerConnectivityManager(ApplicationId appId,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080066 IntentSynchronizer intentSynchronizer,
Jonathan Hart90a02c22015-02-13 11:52:07 -080067 RoutingConfigurationService configService) {
Thomas Vachuskab97cf282014-10-20 23:31:12 -070068 this.appId = appId;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080069 this.intentSynchronizer = intentSynchronizer;
Jonathan Hart31582d12014-10-22 13:52:41 -070070 this.configService = configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070071 }
72
Jonathan Hart31582d12014-10-22 13:52:41 -070073 /**
74 * Starts the peer connectivity manager.
75 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070076 public void start() {
Jonathan Hart90a02c22015-02-13 11:52:07 -080077 if (configService.getInterfaces().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080078 log.warn("No interfaces found in configuration file");
Jonathan Hartde089122014-12-03 22:33:14 -080079 }
80
81 if (configService.getBgpPeers().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080082 log.warn("No BGP peers found in configuration file");
Jonathan Hartde089122014-12-03 22:33:14 -080083 }
84
85 if (configService.getBgpSpeakers().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080086 log.error("No BGP speakers found in configuration file");
Jonathan Hartdc711bd2014-10-15 11:24:23 -070087 }
88
Jonathan Hart6ec68292014-11-14 15:09:30 -080089 setUpConnectivity();
Jonathan Hartdc711bd2014-10-15 11:24:23 -070090 }
91
92 /**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080093 * Stops the peer connectivity manager.
94 */
95 public void stop() {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080096 }
97
98 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -080099 * Sets up paths to establish connectivity between all internal
100 * {@link BgpSpeaker}s and all external {@link BgpPeer}s.
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700101 */
Jonathan Hart6ec68292014-11-14 15:09:30 -0800102 private void setUpConnectivity() {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800103 List<PointToPointIntent> intents = new ArrayList<>();
104
Jonathan Hart31582d12014-10-22 13:52:41 -0700105 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700106 .values()) {
107 log.debug("Start to set up BGP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700108 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700109
Jonathan Hart31582d12014-10-22 13:52:41 -0700110 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700111
112 log.debug("Start to set up BGP paths between BGP speaker: {} "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700113 + "to BGP peer: {}", bgpSpeaker, bgpPeer);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700114
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800115 intents.addAll(buildPeerIntents(bgpSpeaker, bgpPeer));
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700116 }
117 }
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800118
119 // Submit all the intents.
120 intentSynchronizer.submitPeerIntents(intents);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700121 }
122
123 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -0800124 * Builds the required intents between a given internal BGP speaker and
125 * external BGP peer.
126 *
127 * @param bgpSpeaker the BGP speaker
128 * @param bgpPeer the BGP peer
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800129 * @return the intents to install
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700130 */
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800131 private Collection<PointToPointIntent> buildPeerIntents(
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700132 BgpSpeaker bgpSpeaker,
133 BgpPeer bgpPeer) {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800134 List<PointToPointIntent> intents = new ArrayList<>();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700135
Jonathan Hart6ec68292014-11-14 15:09:30 -0800136 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700137
Jonathan Hart6ec68292014-11-14 15:09:30 -0800138 List<InterfaceAddress> interfaceAddresses =
139 bgpSpeaker.interfaceAddresses();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700140
Jonathan Hart90a02c22015-02-13 11:52:07 -0800141 Interface peerInterface = configService.getInterface(
Jonathan Hart6ec68292014-11-14 15:09:30 -0800142 bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700143
Jonathan Hart6ec68292014-11-14 15:09:30 -0800144 if (peerInterface == null) {
145 log.error("No interface found for peer {}", bgpPeer.ipAddress());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800146 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800147 }
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700148
Jonathan Hart6ec68292014-11-14 15:09:30 -0800149 IpAddress bgpdAddress = null;
150 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
151 if (interfaceAddress.connectPoint().equals(
152 peerInterface.connectPoint())) {
153 bgpdAddress = interfaceAddress.ipAddress();
154 break;
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700155 }
156 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800157 if (bgpdAddress == null) {
158 log.debug("No IP address found for peer {} on interface {}",
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700159 bgpPeer, bgpPeer.connectPoint());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800160 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800161 }
162
163 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
164 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
165
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800166 if (bgpdAddress.version() != bgpdPeerAddress.version()) {
167 return intents;
168 }
169
Brian O'Connor6b528132015-03-10 16:39:52 -0700170 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
Jonathan Hart6ec68292014-11-14 15:09:30 -0800171
172 TrafficSelector selector;
173
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800174 byte tcpProtocol;
175 byte icmpProtocol;
176
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700177 if (bgpdAddress.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800178 tcpProtocol = IPv4.PROTOCOL_TCP;
179 icmpProtocol = IPv4.PROTOCOL_ICMP;
180 } else {
181 tcpProtocol = IPv6.PROTOCOL_TCP;
182 icmpProtocol = IPv6.PROTOCOL_ICMP6;
183 }
184
Jonathan Hart51372182014-12-03 21:32:34 -0800185 // Path from BGP speaker to BGP peer matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800186 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700187 bgpdAddress,
188 bgpdPeerAddress,
189 null,
190 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800191
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -0700192 int priority = PRIORITY_OFFSET;
193
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700194 intents.add(PointToPointIntent.builder()
195 .appId(appId)
196 .selector(selector)
197 .treatment(treatment)
198 .ingressPoint(bgpdConnectPoint)
199 .egressPoint(bgpdPeerConnectPoint)
200 .priority(priority)
201 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800202
Jonathan Hart51372182014-12-03 21:32:34 -0800203 // Path from BGP speaker to BGP peer matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800204 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700205 bgpdAddress,
206 bgpdPeerAddress,
207 BGP_PORT,
208 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800209
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700210 intents.add(PointToPointIntent.builder()
211 .appId(appId)
212 .selector(selector)
213 .treatment(treatment)
214 .ingressPoint(bgpdConnectPoint)
215 .egressPoint(bgpdPeerConnectPoint)
216 .priority(priority)
217 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800218
Jonathan Hart51372182014-12-03 21:32:34 -0800219 // Path from BGP peer to BGP speaker matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800220 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700221 bgpdPeerAddress,
222 bgpdAddress,
223 null,
224 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800225
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700226 intents.add(PointToPointIntent.builder()
227 .appId(appId)
228 .selector(selector)
229 .treatment(treatment)
230 .ingressPoint(bgpdPeerConnectPoint)
231 .egressPoint(bgpdConnectPoint)
232 .priority(priority)
233 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800234
Jonathan Hart51372182014-12-03 21:32:34 -0800235 // Path from BGP peer to BGP speaker matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800236 selector = buildSelector(tcpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700237 bgpdPeerAddress,
238 bgpdAddress,
239 BGP_PORT,
240 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800241
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700242 intents.add(PointToPointIntent.builder()
243 .appId(appId)
244 .selector(selector)
245 .treatment(treatment)
246 .ingressPoint(bgpdPeerConnectPoint)
247 .egressPoint(bgpdConnectPoint)
248 .priority(priority)
249 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800250
Jonathan Hart51372182014-12-03 21:32:34 -0800251 // ICMP path from BGP speaker to BGP peer
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800252 selector = buildSelector(icmpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700253 bgpdAddress,
254 bgpdPeerAddress,
255 null,
256 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800257
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700258 intents.add(PointToPointIntent.builder()
259 .appId(appId)
260 .selector(selector)
261 .treatment(treatment)
262 .ingressPoint(bgpdConnectPoint)
263 .egressPoint(bgpdPeerConnectPoint)
264 .priority(priority)
265 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800266
Jonathan Hart51372182014-12-03 21:32:34 -0800267 // ICMP path from BGP peer to BGP speaker
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800268 selector = buildSelector(icmpProtocol,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700269 bgpdPeerAddress,
270 bgpdAddress,
271 null,
272 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800273
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700274 intents.add(PointToPointIntent.builder()
275 .appId(appId)
276 .selector(selector)
277 .treatment(treatment)
278 .ingressPoint(bgpdPeerConnectPoint)
279 .egressPoint(bgpdConnectPoint)
280 .priority(priority)
281 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800282
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800283 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800284 }
285
286 /**
287 * Builds a traffic selector based on the set of input parameters.
288 *
289 * @param ipProto IP protocol
290 * @param srcIp source IP address
291 * @param dstIp destination IP address
292 * @param srcTcpPort source TCP port, or null if shouldn't be set
293 * @param dstTcpPort destination TCP port, or null if shouldn't be set
294 * @return the new traffic selector
295 */
296 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800297 IpAddress dstIp, Short srcTcpPort,
298 Short dstTcpPort) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800299 TrafficSelector.Builder builder = null;
300
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700301 if (dstIp.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800302 builder = DefaultTrafficSelector.builder()
303 .matchEthType(Ethernet.TYPE_IPV4)
304 .matchIPProtocol(ipProto)
305 .matchIPSrc(IpPrefix.valueOf(srcIp,
306 IpPrefix.MAX_INET_MASK_LENGTH))
307 .matchIPDst(IpPrefix.valueOf(dstIp,
308 IpPrefix.MAX_INET_MASK_LENGTH));
309 } else {
310 builder = DefaultTrafficSelector.builder()
311 .matchEthType(Ethernet.TYPE_IPV6)
312 .matchIPProtocol(ipProto)
313 .matchIPv6Src(IpPrefix.valueOf(srcIp,
314 IpPrefix.MAX_INET6_MASK_LENGTH))
315 .matchIPv6Dst(IpPrefix.valueOf(dstIp,
316 IpPrefix.MAX_INET6_MASK_LENGTH));
317 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800318
319 if (srcTcpPort != null) {
320 builder.matchTcpSrc(srcTcpPort);
321 }
322
323 if (dstTcpPort != null) {
324 builder.matchTcpDst(dstTcpPort);
325 }
326
327 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700328 }
329
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700330}