blob: 32f77fe68c141e1c7cbf084857e0ef218357410c [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070019package org.onlab.onos.sdnip;
20
Jonathan Hart31582d12014-10-22 13:52:41 -070021import java.util.List;
22
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070023import org.onlab.onos.core.ApplicationId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070024import org.onlab.onos.net.ConnectPoint;
25import org.onlab.onos.net.flow.DefaultTrafficSelector;
26import org.onlab.onos.net.flow.DefaultTrafficTreatment;
27import org.onlab.onos.net.flow.TrafficSelector;
28import org.onlab.onos.net.flow.TrafficTreatment;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070029import org.onlab.onos.net.intent.IntentService;
30import org.onlab.onos.net.intent.PointToPointIntent;
Jonathan Hart31582d12014-10-22 13:52:41 -070031import org.onlab.onos.sdnip.bgp.BgpConstants;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070032import org.onlab.onos.sdnip.config.BgpPeer;
33import org.onlab.onos.sdnip.config.BgpSpeaker;
34import org.onlab.onos.sdnip.config.Interface;
35import org.onlab.onos.sdnip.config.InterfaceAddress;
36import org.onlab.onos.sdnip.config.SdnIpConfigService;
37import org.onlab.packet.Ethernet;
38import org.onlab.packet.IPv4;
39import org.onlab.packet.IpAddress;
40import org.onlab.packet.IpPrefix;
41import org.slf4j.Logger;
42import org.slf4j.LoggerFactory;
43
44/**
45 * Manages the connectivity requirements between peers.
46 */
Jonathan Hartce430a42014-10-16 20:44:29 -070047public class PeerConnectivityManager {
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 Hart31582d12014-10-22 13:52:41 -070052 private final SdnIpConfigService configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070053 private final InterfaceService interfaceService;
54 private final IntentService intentService;
55
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 *
61 * @param appId the application ID
62 * @param configService the SDN-IP config service
63 * @param interfaceService the interface service
64 * @param intentService the intent service
65 */
Thomas Vachuskab97cf282014-10-20 23:31:12 -070066 public PeerConnectivityManager(ApplicationId appId,
Jonathan Hart31582d12014-10-22 13:52:41 -070067 SdnIpConfigService configService,
Thomas Vachuskab97cf282014-10-20 23:31:12 -070068 InterfaceService interfaceService,
69 IntentService intentService) {
70 this.appId = appId;
Jonathan Hart31582d12014-10-22 13:52:41 -070071 this.configService = configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070072 this.interfaceService = interfaceService;
73 this.intentService = intentService;
74 }
75
Jonathan Hart31582d12014-10-22 13:52:41 -070076 /**
77 * Starts the peer connectivity manager.
78 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070079 public void start() {
80 // TODO are any of these errors?
81 if (interfaceService.getInterfaces().isEmpty()) {
82
83 log.warn("The interface in configuration file is empty. "
Thomas Vachuskab97cf282014-10-20 23:31:12 -070084 + "Thus, the SDN-IP application can not be started.");
Jonathan Hart31582d12014-10-22 13:52:41 -070085 } else if (configService.getBgpPeers().isEmpty()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -070086
87 log.warn("The BGP peer in configuration file is empty."
Thomas Vachuskab97cf282014-10-20 23:31:12 -070088 + "Thus, the SDN-IP application can not be started.");
Jonathan Hart31582d12014-10-22 13:52:41 -070089 } else if (configService.getBgpSpeakers() == null) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -070090
91 log.error("The BGP speaker in configuration file is empty. "
Thomas Vachuskab97cf282014-10-20 23:31:12 -070092 + "Thus, the SDN-IP application can not be started.");
Jonathan Hartdc711bd2014-10-15 11:24:23 -070093 return;
94 }
95
96 setupBgpPaths();
97 setupIcmpPaths();
98 }
99
100 /**
101 * Sets up paths for all {@link BgpSpeaker}s and all external peers.
102 * <p/>
103 * Run a loop for all BGP speakers and a loop for all BGP peers outside.
104 * Push intents for paths from each BGP speaker to all peers. Push intents
105 * for paths from all peers to each BGP speaker.
106 */
107 private void setupBgpPaths() {
Jonathan Hart31582d12014-10-22 13:52:41 -0700108 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700109 .values()) {
110 log.debug("Start to set up BGP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700111 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700112 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
113
114 List<InterfaceAddress> interfaceAddresses =
115 bgpSpeaker.interfaceAddresses();
116
Jonathan Hart31582d12014-10-22 13:52:41 -0700117 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700118
119 log.debug("Start to set up BGP paths between BGP speaker: {} "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700120 + "to BGP peer: {}", bgpSpeaker, bgpPeer);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700121
122 Interface peerInterface = interfaceService.getInterface(
123 bgpPeer.connectPoint());
124 if (peerInterface == null) {
125 log.error("Can not find the corresponding Interface from "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700126 + "configuration for BGP peer {}",
127 bgpPeer.ipAddress());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700128 continue;
129 }
130
131 IpAddress bgpdAddress = null;
132 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
133 if (interfaceAddress.connectPoint().equals(
134 peerInterface.connectPoint())) {
135 bgpdAddress = interfaceAddress.ipAddress();
136 break;
137 }
138 }
139 if (bgpdAddress == null) {
140 log.debug("There is no interface IP address for bgpPeer: {}"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700141 + " on interface {}", bgpPeer, bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700142 return;
143 }
144
145 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
146 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
147
148 // install intent for BGP path from BGPd to BGP peer matching
149 // destination TCP port 179
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700150 TrafficSelector selector = DefaultTrafficSelector.builder()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700151 .matchEthType(Ethernet.TYPE_IPV4)
152 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700153 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
154 IpAddress.MAX_INET_MASK))
155 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
156 IpAddress.MAX_INET_MASK))
157 .matchTcpDst((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700158 .build();
159
160 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
161 .build();
162
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700163 PointToPointIntent intentMatchDstTcpPort =
164 new PointToPointIntent(appId, selector, treatment,
165 bgpdConnectPoint, bgpdPeerConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700166 intentService.submit(intentMatchDstTcpPort);
167 log.debug("Submitted BGP path intent matching dst TCP port 179 "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700168 + "from BGPd {} to peer {}: {}",
169 bgpdAddress, bgpdPeerAddress, intentMatchDstTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700170
171 // install intent for BGP path from BGPd to BGP peer matching
172 // source TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700173 selector = DefaultTrafficSelector.builder()
174 .matchEthType(Ethernet.TYPE_IPV4)
175 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700176 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
177 IpAddress.MAX_INET_MASK))
178 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
179 IpAddress.MAX_INET_MASK))
180 .matchTcpSrc((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700181 .build();
182
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700183 PointToPointIntent intentMatchSrcTcpPort =
184 new PointToPointIntent(appId, selector, treatment,
185 bgpdConnectPoint, bgpdPeerConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700186 intentService.submit(intentMatchSrcTcpPort);
187 log.debug("Submitted BGP path intent matching src TCP port 179"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700188 + "from BGPd {} to peer {}: {}",
189 bgpdAddress, bgpdPeerAddress, intentMatchSrcTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700190
191 // install intent for reversed BGP path from BGP peer to BGPd
192 // matching destination TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700193 selector = DefaultTrafficSelector.builder()
194 .matchEthType(Ethernet.TYPE_IPV4)
195 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700196 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
197 IpAddress.MAX_INET_MASK))
198 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
199 IpAddress.MAX_INET_MASK))
200 .matchTcpDst((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700201 .build();
202
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700203 PointToPointIntent reversedIntentMatchDstTcpPort =
204 new PointToPointIntent(appId, selector, treatment,
205 bgpdPeerConnectPoint, bgpdConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700206 intentService.submit(reversedIntentMatchDstTcpPort);
207 log.debug("Submitted BGP path intent matching dst TCP port 179"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700208 + "from BGP peer {} to BGPd {} : {}",
209 bgpdPeerAddress, bgpdAddress, reversedIntentMatchDstTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700210
211 // install intent for reversed BGP path from BGP peer to BGPd
212 // matching source TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700213 selector = DefaultTrafficSelector.builder()
214 .matchEthType(Ethernet.TYPE_IPV4)
215 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700216 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
217 IpAddress.MAX_INET_MASK))
218 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
219 IpAddress.MAX_INET_MASK))
220 .matchTcpSrc((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700221 .build();
222
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700223 PointToPointIntent reversedIntentMatchSrcTcpPort =
224 new PointToPointIntent(appId, selector, treatment,
225 bgpdPeerConnectPoint, bgpdConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700226 intentService.submit(reversedIntentMatchSrcTcpPort);
227 log.debug("Submitted BGP path intent matching src TCP port 179"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700228 + "from BGP peer {} to BGPd {} : {}",
229 bgpdPeerAddress, bgpdAddress, reversedIntentMatchSrcTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700230
231 }
232 }
233 }
234
235 /**
236 * Sets up ICMP paths between each {@link BgpSpeaker} and all BGP peers
237 * located in other external networks.
238 * <p/>
239 * Run a loop for all BGP speakers and a loop for all BGP Peers. Push
240 * intents for paths from each BGP speaker to all peers. Push intents
241 * for paths from all peers to each BGP speaker.
242 */
243 private void setupIcmpPaths() {
Jonathan Hart31582d12014-10-22 13:52:41 -0700244 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700245 .values()) {
246 log.debug("Start to set up ICMP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700247 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700248 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
249 List<InterfaceAddress> interfaceAddresses = bgpSpeaker
250 .interfaceAddresses();
251
Jonathan Hart31582d12014-10-22 13:52:41 -0700252 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700253
254 Interface peerInterface = interfaceService.getInterface(
255 bgpPeer.connectPoint());
256
257 if (peerInterface == null) {
258 log.error("Can not find the corresponding Interface from "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700259 + "configuration for BGP peer {}",
260 bgpPeer.ipAddress());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700261 continue;
262 }
263 IpAddress bgpdAddress = null;
264 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
265 if (interfaceAddress.connectPoint().equals(
266 peerInterface.connectPoint())) {
267 bgpdAddress = interfaceAddress.ipAddress();
268 break;
269 }
270
271 }
272 if (bgpdAddress == null) {
273 log.debug("There is no IP address for bgpPeer: {} on "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700274 + "interface port: {}", bgpPeer,
275 bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700276 return;
277 }
278
279 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
280 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
281
282 // install intent for ICMP path from BGPd to BGP peer
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700283 TrafficSelector selector = DefaultTrafficSelector.builder()
284 .matchEthType(Ethernet.TYPE_IPV4)
285 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700286 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
287 IpAddress.MAX_INET_MASK))
288 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
289 IpAddress.MAX_INET_MASK))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700290 .build();
291
292 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
293 .build();
294
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700295 PointToPointIntent intent =
296 new PointToPointIntent(appId, selector, treatment,
297 bgpdConnectPoint, bgpdPeerConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700298 intentService.submit(intent);
299 log.debug("Submitted ICMP path intent from BGPd {} to peer {} :"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700300 + " {}", bgpdAddress, bgpdPeerAddress, intent);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700301
302 // install intent for reversed ICMP path from BGP peer to BGPd
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700303 selector = DefaultTrafficSelector.builder()
304 .matchEthType(Ethernet.TYPE_IPV4)
305 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700306 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
307 IpAddress.MAX_INET_MASK))
308 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
309 IpAddress.MAX_INET_MASK))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700310 .build();
311
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700312 PointToPointIntent reversedIntent =
313 new PointToPointIntent(appId, selector, treatment,
314 bgpdPeerConnectPoint, bgpdConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700315 intentService.submit(reversedIntent);
316 log.debug("Submitted ICMP path intent from BGP peer {} to BGPd"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700317 + " {} : {}",
318 bgpdPeerAddress, bgpdAddress, reversedIntent);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700319 }
320 }
321 }
322
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700323}