blob: c9f9606af0b5a945c6a9e3dbac614d44a6bf5c64 [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 {
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
Jonathan Hart41349e92015-02-09 14:14:02 -080050 private static final short BGP_PORT = 179;
51
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080052 private final IntentSynchronizer intentSynchronizer;
Jonathan Hart90a02c22015-02-13 11:52:07 -080053 private final RoutingConfigurationService configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070054
Thomas Vachuskab97cf282014-10-20 23:31:12 -070055 private final ApplicationId appId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070056
Jonathan Hart31582d12014-10-22 13:52:41 -070057 /**
58 * Creates a new PeerConnectivityManager.
59 *
Jonathan Hart51372182014-12-03 21:32:34 -080060 * @param appId the application ID
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080061 * @param intentSynchronizer the intent synchronizer
Jonathan Hart51372182014-12-03 21:32:34 -080062 * @param configService the SDN-IP config 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 Hart90a02c22015-02-13 11:52:07 -080066 RoutingConfigurationService configService) {
Thomas Vachuskab97cf282014-10-20 23:31:12 -070067 this.appId = appId;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080068 this.intentSynchronizer = intentSynchronizer;
Jonathan Hart31582d12014-10-22 13:52:41 -070069 this.configService = configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070070 }
71
Jonathan Hart31582d12014-10-22 13:52:41 -070072 /**
73 * Starts the peer connectivity manager.
74 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070075 public void start() {
Jonathan Hart90a02c22015-02-13 11:52:07 -080076 if (configService.getInterfaces().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080077 log.warn("No interfaces found in configuration file");
Jonathan Hartde089122014-12-03 22:33:14 -080078 }
79
80 if (configService.getBgpPeers().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080081 log.warn("No BGP peers found in configuration file");
Jonathan Hartde089122014-12-03 22:33:14 -080082 }
83
84 if (configService.getBgpSpeakers().isEmpty()) {
Jonathan Hart51372182014-12-03 21:32:34 -080085 log.error("No BGP speakers found in configuration file");
Jonathan Hartdc711bd2014-10-15 11:24:23 -070086 }
87
Jonathan Hart6ec68292014-11-14 15:09:30 -080088 setUpConnectivity();
Jonathan Hartdc711bd2014-10-15 11:24:23 -070089 }
90
91 /**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080092 * Stops the peer connectivity manager.
93 */
94 public void stop() {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080095 }
96
97 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -080098 * Sets up paths to establish connectivity between all internal
99 * {@link BgpSpeaker}s and all external {@link BgpPeer}s.
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700100 */
Jonathan Hart6ec68292014-11-14 15:09:30 -0800101 private void setUpConnectivity() {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800102 List<PointToPointIntent> intents = new ArrayList<>();
103
Jonathan Hart31582d12014-10-22 13:52:41 -0700104 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700105 .values()) {
106 log.debug("Start to set up BGP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700107 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700108
Jonathan Hart31582d12014-10-22 13:52:41 -0700109 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700110
111 log.debug("Start to set up BGP paths between BGP speaker: {} "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700112 + "to BGP peer: {}", bgpSpeaker, bgpPeer);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700113
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800114 intents.addAll(buildPeerIntents(bgpSpeaker, bgpPeer));
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700115 }
116 }
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800117
118 // Submit all the intents.
119 intentSynchronizer.submitPeerIntents(intents);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700120 }
121
122 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -0800123 * Builds the required intents between a given internal BGP speaker and
124 * external BGP peer.
125 *
126 * @param bgpSpeaker the BGP speaker
127 * @param bgpPeer the BGP peer
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800128 * @return the intents to install
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700129 */
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800130 private Collection<PointToPointIntent> buildPeerIntents(
131 BgpSpeaker bgpSpeaker,
132 BgpPeer bgpPeer) {
133 List<PointToPointIntent> intents = new ArrayList<>();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700134
Jonathan Hart6ec68292014-11-14 15:09:30 -0800135 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700136
Jonathan Hart6ec68292014-11-14 15:09:30 -0800137 List<InterfaceAddress> interfaceAddresses =
138 bgpSpeaker.interfaceAddresses();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700139
Jonathan Hart90a02c22015-02-13 11:52:07 -0800140 Interface peerInterface = configService.getInterface(
Jonathan Hart6ec68292014-11-14 15:09:30 -0800141 bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700142
Jonathan Hart6ec68292014-11-14 15:09:30 -0800143 if (peerInterface == null) {
144 log.error("No interface found for peer {}", bgpPeer.ipAddress());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800145 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800146 }
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700147
Jonathan Hart6ec68292014-11-14 15:09:30 -0800148 IpAddress bgpdAddress = null;
149 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
150 if (interfaceAddress.connectPoint().equals(
151 peerInterface.connectPoint())) {
152 bgpdAddress = interfaceAddress.ipAddress();
153 break;
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700154 }
155 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800156 if (bgpdAddress == null) {
157 log.debug("No IP address found for peer {} on interface {}",
158 bgpPeer, bgpPeer.connectPoint());
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800159 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800160 }
161
162 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
163 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
164
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800165 if (bgpdAddress.version() != bgpdPeerAddress.version()) {
166 return intents;
167 }
168
Brian O'Connor6b528132015-03-10 16:39:52 -0700169 TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment();
Jonathan Hart6ec68292014-11-14 15:09:30 -0800170
171 TrafficSelector selector;
172
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800173 byte tcpProtocol;
174 byte icmpProtocol;
175
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700176 if (bgpdAddress.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800177 tcpProtocol = IPv4.PROTOCOL_TCP;
178 icmpProtocol = IPv4.PROTOCOL_ICMP;
179 } else {
180 tcpProtocol = IPv6.PROTOCOL_TCP;
181 icmpProtocol = IPv6.PROTOCOL_ICMP6;
182 }
183
Jonathan Hart51372182014-12-03 21:32:34 -0800184 // Path from BGP speaker to BGP peer matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800185 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800186 bgpdAddress,
187 bgpdPeerAddress,
188 null,
Jonathan Hart41349e92015-02-09 14:14:02 -0800189 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800190
191 intents.add(new PointToPointIntent(appId, selector, treatment,
192 bgpdConnectPoint, bgpdPeerConnectPoint));
193
Jonathan Hart51372182014-12-03 21:32:34 -0800194 // Path from BGP speaker to BGP peer matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800195 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800196 bgpdAddress,
197 bgpdPeerAddress,
Jonathan Hart41349e92015-02-09 14:14:02 -0800198 BGP_PORT,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800199 null);
200
201 intents.add(new PointToPointIntent(appId, selector, treatment,
202 bgpdConnectPoint, bgpdPeerConnectPoint));
203
Jonathan Hart51372182014-12-03 21:32:34 -0800204 // Path from BGP peer to BGP speaker matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800205 selector = buildSelector(tcpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800206 bgpdPeerAddress,
207 bgpdAddress,
208 null,
Jonathan Hart41349e92015-02-09 14:14:02 -0800209 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800210
211 intents.add(new PointToPointIntent(appId, selector, treatment,
212 bgpdPeerConnectPoint, bgpdConnectPoint));
213
Jonathan Hart51372182014-12-03 21:32:34 -0800214 // Path from BGP peer to BGP speaker matching source 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,
Jonathan Hart41349e92015-02-09 14:14:02 -0800218 BGP_PORT,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800219 null);
220
221 intents.add(new PointToPointIntent(appId, selector, treatment,
222 bgpdPeerConnectPoint, bgpdConnectPoint));
223
Jonathan Hart51372182014-12-03 21:32:34 -0800224 // ICMP path from BGP speaker to BGP peer
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800225 selector = buildSelector(icmpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800226 bgpdAddress,
227 bgpdPeerAddress,
228 null,
229 null);
230
231 intents.add(new PointToPointIntent(appId, selector, treatment,
232 bgpdConnectPoint, bgpdPeerConnectPoint));
233
Jonathan Hart51372182014-12-03 21:32:34 -0800234 // ICMP path from BGP peer to BGP speaker
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800235 selector = buildSelector(icmpProtocol,
Jonathan Hart6ec68292014-11-14 15:09:30 -0800236 bgpdPeerAddress,
237 bgpdAddress,
238 null,
239 null);
240
241 intents.add(new PointToPointIntent(appId, selector, treatment,
242 bgpdPeerConnectPoint, bgpdConnectPoint));
243
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800244 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800245 }
246
247 /**
248 * Builds a traffic selector based on the set of input parameters.
249 *
250 * @param ipProto IP protocol
251 * @param srcIp source IP address
252 * @param dstIp destination IP address
253 * @param srcTcpPort source TCP port, or null if shouldn't be set
254 * @param dstTcpPort destination TCP port, or null if shouldn't be set
255 * @return the new traffic selector
256 */
257 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800258 IpAddress dstIp, Short srcTcpPort,
259 Short dstTcpPort) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800260 TrafficSelector.Builder builder = null;
261
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700262 if (dstIp.isIp4()) {
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800263 builder = DefaultTrafficSelector.builder()
264 .matchEthType(Ethernet.TYPE_IPV4)
265 .matchIPProtocol(ipProto)
266 .matchIPSrc(IpPrefix.valueOf(srcIp,
267 IpPrefix.MAX_INET_MASK_LENGTH))
268 .matchIPDst(IpPrefix.valueOf(dstIp,
269 IpPrefix.MAX_INET_MASK_LENGTH));
270 } else {
271 builder = DefaultTrafficSelector.builder()
272 .matchEthType(Ethernet.TYPE_IPV6)
273 .matchIPProtocol(ipProto)
274 .matchIPv6Src(IpPrefix.valueOf(srcIp,
275 IpPrefix.MAX_INET6_MASK_LENGTH))
276 .matchIPv6Dst(IpPrefix.valueOf(dstIp,
277 IpPrefix.MAX_INET6_MASK_LENGTH));
278 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800279
280 if (srcTcpPort != null) {
281 builder.matchTcpSrc(srcTcpPort);
282 }
283
284 if (dstTcpPort != null) {
285 builder.matchTcpDst(dstTcpPort);
286 }
287
288 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700289 }
290
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700291}