blob: 44366b05e4255598832d97bf145bf273ec842b62 [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 Hart6ec68292014-11-14 15:09:30 -080018import java.util.ArrayList;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080019import java.util.Collection;
Jonathan Hart31582d12014-10-22 13:52:41 -070020import java.util.List;
21
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;
Brian O'Connorabafb502014-12-02 22:26:20 -080026import org.onosproject.core.ApplicationId;
27import org.onosproject.net.ConnectPoint;
28import org.onosproject.net.flow.DefaultTrafficSelector;
29import org.onosproject.net.flow.DefaultTrafficTreatment;
30import org.onosproject.net.flow.TrafficSelector;
31import org.onosproject.net.flow.TrafficTreatment;
32import org.onosproject.net.intent.PointToPointIntent;
33import org.onosproject.sdnip.bgp.BgpConstants;
34import org.onosproject.sdnip.config.BgpPeer;
35import org.onosproject.sdnip.config.BgpSpeaker;
36import org.onosproject.sdnip.config.Interface;
37import org.onosproject.sdnip.config.InterfaceAddress;
38import org.onosproject.sdnip.config.SdnIpConfigurationService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070039import org.slf4j.Logger;
40import org.slf4j.LoggerFactory;
41
42/**
43 * Manages the connectivity requirements between peers.
44 */
Jonathan Hartce430a42014-10-16 20:44:29 -070045public class PeerConnectivityManager {
Jonathan Hartdc711bd2014-10-15 11:24:23 -070046
47 private static final Logger log = LoggerFactory.getLogger(
Jonathan Hartce430a42014-10-16 20:44:29 -070048 PeerConnectivityManager.class);
Jonathan Hartdc711bd2014-10-15 11:24:23 -070049
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080050 private final IntentSynchronizer intentSynchronizer;
Jonathan Hart9965d772014-12-02 10:28:34 -080051 private final SdnIpConfigurationService configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070052 private final InterfaceService interfaceService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070053
Thomas Vachuskab97cf282014-10-20 23:31:12 -070054 private final ApplicationId appId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070055
Jonathan Hart31582d12014-10-22 13:52:41 -070056 /**
57 * Creates a new PeerConnectivityManager.
58 *
Jonathan Hart51372182014-12-03 21:32:34 -080059 * @param appId the application ID
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080060 * @param intentSynchronizer the intent synchronizer
Jonathan Hart51372182014-12-03 21:32:34 -080061 * @param configService the SDN-IP config service
62 * @param interfaceService the interface service
Jonathan Hart31582d12014-10-22 13:52:41 -070063 */
Thomas Vachuskab97cf282014-10-20 23:31:12 -070064 public PeerConnectivityManager(ApplicationId appId,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080065 IntentSynchronizer intentSynchronizer,
Jonathan Hart9965d772014-12-02 10:28:34 -080066 SdnIpConfigurationService configService,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080067 InterfaceService interfaceService) {
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 this.interfaceService = interfaceService;
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 Hartdc711bd2014-10-15 11:24:23 -070078 if (interfaceService.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() {
97 // TODO: Implement it
98 }
99
100 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -0800101 * Sets up paths to establish connectivity between all internal
102 * {@link BgpSpeaker}s and all external {@link BgpPeer}s.
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700103 */
Jonathan Hart6ec68292014-11-14 15:09:30 -0800104 private void setUpConnectivity() {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800105 List<PointToPointIntent> intents = new ArrayList<>();
106
Jonathan Hart31582d12014-10-22 13:52:41 -0700107 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700108 .values()) {
109 log.debug("Start to set up BGP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700110 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700111
Jonathan Hart31582d12014-10-22 13:52:41 -0700112 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700113
114 log.debug("Start to set up BGP paths between BGP speaker: {} "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700115 + "to BGP peer: {}", bgpSpeaker, bgpPeer);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700116
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800117 intents.addAll(buildPeerIntents(bgpSpeaker, bgpPeer));
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700118 }
119 }
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800120
121 // Submit all the intents.
122 intentSynchronizer.submitPeerIntents(intents);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700123 }
124
125 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -0800126 * Builds the required intents between a given internal BGP speaker and
127 * external BGP peer.
128 *
129 * @param bgpSpeaker the BGP speaker
130 * @param bgpPeer the BGP peer
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800131 * @return the intents to install
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700132 */
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800133 private Collection<PointToPointIntent> buildPeerIntents(
134 BgpSpeaker bgpSpeaker,
135 BgpPeer bgpPeer) {
136 List<PointToPointIntent> intents = new ArrayList<>();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700137
Jonathan Hart6ec68292014-11-14 15:09:30 -0800138 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700139
Jonathan Hart6ec68292014-11-14 15:09:30 -0800140 List<InterfaceAddress> interfaceAddresses =
141 bgpSpeaker.interfaceAddresses();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700142
Jonathan Hart6ec68292014-11-14 15:09:30 -0800143 Interface peerInterface = interfaceService.getInterface(
144 bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700145
Jonathan Hart6ec68292014-11-14 15:09:30 -0800146 if (peerInterface == null) {
147 log.error("No interface found for peer {}", bgpPeer.ipAddress());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800148 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800149 }
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700150
Jonathan Hart6ec68292014-11-14 15:09:30 -0800151 IpAddress bgpdAddress = null;
152 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
153 if (interfaceAddress.connectPoint().equals(
154 peerInterface.connectPoint())) {
155 bgpdAddress = interfaceAddress.ipAddress();
156 break;
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700157 }
158 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800159 if (bgpdAddress == null) {
160 log.debug("No IP address found for peer {} on interface {}",
161 bgpPeer, bgpPeer.connectPoint());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800162 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800163 }
164
165 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
166 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
167
168 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
169 .build();
170
171 TrafficSelector selector;
172
Jonathan Hart51372182014-12-03 21:32:34 -0800173 // Path from BGP speaker to BGP peer matching destination TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800174 selector = buildSelector(IPv4.PROTOCOL_TCP,
175 bgpdAddress,
176 bgpdPeerAddress,
177 null,
178 (short) BgpConstants.BGP_PORT);
179
180 intents.add(new PointToPointIntent(appId, selector, treatment,
181 bgpdConnectPoint, bgpdPeerConnectPoint));
182
Jonathan Hart51372182014-12-03 21:32:34 -0800183 // Path from BGP speaker to BGP peer matching source TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800184 selector = buildSelector(IPv4.PROTOCOL_TCP,
185 bgpdAddress,
186 bgpdPeerAddress,
187 (short) BgpConstants.BGP_PORT,
188 null);
189
190 intents.add(new PointToPointIntent(appId, selector, treatment,
191 bgpdConnectPoint, bgpdPeerConnectPoint));
192
Jonathan Hart51372182014-12-03 21:32:34 -0800193 // Path from BGP peer to BGP speaker matching destination TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800194 selector = buildSelector(IPv4.PROTOCOL_TCP,
195 bgpdPeerAddress,
196 bgpdAddress,
197 null,
198 (short) BgpConstants.BGP_PORT);
199
200 intents.add(new PointToPointIntent(appId, selector, treatment,
201 bgpdPeerConnectPoint, bgpdConnectPoint));
202
Jonathan Hart51372182014-12-03 21:32:34 -0800203 // Path from BGP peer to BGP speaker matching source TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800204 selector = buildSelector(IPv4.PROTOCOL_TCP,
205 bgpdPeerAddress,
206 bgpdAddress,
207 (short) BgpConstants.BGP_PORT,
208 null);
209
210 intents.add(new PointToPointIntent(appId, selector, treatment,
211 bgpdPeerConnectPoint, bgpdConnectPoint));
212
Jonathan Hart51372182014-12-03 21:32:34 -0800213 // ICMP path from BGP speaker to BGP peer
Jonathan Hart6ec68292014-11-14 15:09:30 -0800214 selector = buildSelector(IPv4.PROTOCOL_ICMP,
215 bgpdAddress,
216 bgpdPeerAddress,
217 null,
218 null);
219
220 intents.add(new PointToPointIntent(appId, selector, treatment,
221 bgpdConnectPoint, bgpdPeerConnectPoint));
222
Jonathan Hart51372182014-12-03 21:32:34 -0800223 // ICMP path from BGP peer to BGP speaker
Jonathan Hart6ec68292014-11-14 15:09:30 -0800224 selector = buildSelector(IPv4.PROTOCOL_ICMP,
225 bgpdPeerAddress,
226 bgpdAddress,
227 null,
228 null);
229
230 intents.add(new PointToPointIntent(appId, selector, treatment,
231 bgpdPeerConnectPoint, bgpdConnectPoint));
232
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800233 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800234 }
235
236 /**
237 * Builds a traffic selector based on the set of input parameters.
238 *
239 * @param ipProto IP protocol
240 * @param srcIp source IP address
241 * @param dstIp destination IP address
242 * @param srcTcpPort source TCP port, or null if shouldn't be set
243 * @param dstTcpPort destination TCP port, or null if shouldn't be set
244 * @return the new traffic selector
245 */
246 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800247 IpAddress dstIp, Short srcTcpPort,
248 Short dstTcpPort) {
Jonathan Hart6ec68292014-11-14 15:09:30 -0800249 TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
250 .matchEthType(Ethernet.TYPE_IPV4)
251 .matchIPProtocol(ipProto)
252 .matchIPSrc(IpPrefix.valueOf(srcIp,
253 IpPrefix.MAX_INET_MASK_LENGTH))
254 .matchIPDst(IpPrefix.valueOf(dstIp,
255 IpPrefix.MAX_INET_MASK_LENGTH));
256
257 if (srcTcpPort != null) {
258 builder.matchTcpSrc(srcTcpPort);
259 }
260
261 if (dstTcpPort != null) {
262 builder.matchTcpDst(dstTcpPort);
263 }
264
265 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700266 }
267
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700268}