blob: 9491718bc28db9acc9ec93f3c4b75be6f495919e [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() {
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 Hart6ec68292014-11-14 15:09:30 -0800142 Interface peerInterface = interfaceService.getInterface(
143 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
167 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
168 .build();
169
170 TrafficSelector selector;
171
Jonathan Hart51372182014-12-03 21:32:34 -0800172 // Path from BGP speaker to BGP peer matching destination TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800173 selector = buildSelector(IPv4.PROTOCOL_TCP,
174 bgpdAddress,
175 bgpdPeerAddress,
176 null,
177 (short) BgpConstants.BGP_PORT);
178
179 intents.add(new PointToPointIntent(appId, selector, treatment,
180 bgpdConnectPoint, bgpdPeerConnectPoint));
181
Jonathan Hart51372182014-12-03 21:32:34 -0800182 // Path from BGP speaker to BGP peer matching source TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800183 selector = buildSelector(IPv4.PROTOCOL_TCP,
184 bgpdAddress,
185 bgpdPeerAddress,
186 (short) BgpConstants.BGP_PORT,
187 null);
188
189 intents.add(new PointToPointIntent(appId, selector, treatment,
190 bgpdConnectPoint, bgpdPeerConnectPoint));
191
Jonathan Hart51372182014-12-03 21:32:34 -0800192 // Path from BGP peer to BGP speaker matching destination TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800193 selector = buildSelector(IPv4.PROTOCOL_TCP,
194 bgpdPeerAddress,
195 bgpdAddress,
196 null,
197 (short) BgpConstants.BGP_PORT);
198
199 intents.add(new PointToPointIntent(appId, selector, treatment,
200 bgpdPeerConnectPoint, bgpdConnectPoint));
201
Jonathan Hart51372182014-12-03 21:32:34 -0800202 // Path from BGP peer to BGP speaker matching source TCP port 179
Jonathan Hart6ec68292014-11-14 15:09:30 -0800203 selector = buildSelector(IPv4.PROTOCOL_TCP,
204 bgpdPeerAddress,
205 bgpdAddress,
206 (short) BgpConstants.BGP_PORT,
207 null);
208
209 intents.add(new PointToPointIntent(appId, selector, treatment,
210 bgpdPeerConnectPoint, bgpdConnectPoint));
211
Jonathan Hart51372182014-12-03 21:32:34 -0800212 // ICMP path from BGP speaker to BGP peer
Jonathan Hart6ec68292014-11-14 15:09:30 -0800213 selector = buildSelector(IPv4.PROTOCOL_ICMP,
214 bgpdAddress,
215 bgpdPeerAddress,
216 null,
217 null);
218
219 intents.add(new PointToPointIntent(appId, selector, treatment,
220 bgpdConnectPoint, bgpdPeerConnectPoint));
221
Jonathan Hart51372182014-12-03 21:32:34 -0800222 // ICMP path from BGP peer to BGP speaker
Jonathan Hart6ec68292014-11-14 15:09:30 -0800223 selector = buildSelector(IPv4.PROTOCOL_ICMP,
224 bgpdPeerAddress,
225 bgpdAddress,
226 null,
227 null);
228
229 intents.add(new PointToPointIntent(appId, selector, treatment,
230 bgpdPeerConnectPoint, bgpdConnectPoint));
231
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800232 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800233 }
234
235 /**
236 * Builds a traffic selector based on the set of input parameters.
237 *
238 * @param ipProto IP protocol
239 * @param srcIp source IP address
240 * @param dstIp destination IP address
241 * @param srcTcpPort source TCP port, or null if shouldn't be set
242 * @param dstTcpPort destination TCP port, or null if shouldn't be set
243 * @return the new traffic selector
244 */
245 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800246 IpAddress dstIp, Short srcTcpPort,
247 Short dstTcpPort) {
Jonathan Hart6ec68292014-11-14 15:09:30 -0800248 TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
249 .matchEthType(Ethernet.TYPE_IPV4)
250 .matchIPProtocol(ipProto)
251 .matchIPSrc(IpPrefix.valueOf(srcIp,
252 IpPrefix.MAX_INET_MASK_LENGTH))
253 .matchIPDst(IpPrefix.valueOf(dstIp,
254 IpPrefix.MAX_INET_MASK_LENGTH));
255
256 if (srcTcpPort != null) {
257 builder.matchTcpSrc(srcTcpPort);
258 }
259
260 if (dstTcpPort != null) {
261 builder.matchTcpDst(dstTcpPort);
262 }
263
264 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700265 }
266
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700267}