blob: aea6e06653cc915f8811940a91d84ab8c33314b7 [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 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070016package org.onlab.onos.sdnip;
17
Jonathan Hart31582d12014-10-22 13:52:41 -070018import java.util.List;
19
Thomas Vachuskae0f804a2014-10-27 23:40:48 -070020import org.onlab.onos.core.ApplicationId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070021import org.onlab.onos.net.ConnectPoint;
22import org.onlab.onos.net.flow.DefaultTrafficSelector;
23import org.onlab.onos.net.flow.DefaultTrafficTreatment;
24import org.onlab.onos.net.flow.TrafficSelector;
25import org.onlab.onos.net.flow.TrafficTreatment;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070026import org.onlab.onos.net.intent.IntentService;
27import org.onlab.onos.net.intent.PointToPointIntent;
Jonathan Hart31582d12014-10-22 13:52:41 -070028import org.onlab.onos.sdnip.bgp.BgpConstants;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070029import org.onlab.onos.sdnip.config.BgpPeer;
30import org.onlab.onos.sdnip.config.BgpSpeaker;
31import org.onlab.onos.sdnip.config.Interface;
32import org.onlab.onos.sdnip.config.InterfaceAddress;
33import org.onlab.onos.sdnip.config.SdnIpConfigService;
34import org.onlab.packet.Ethernet;
35import org.onlab.packet.IPv4;
36import org.onlab.packet.IpAddress;
37import org.onlab.packet.IpPrefix;
38import org.slf4j.Logger;
39import org.slf4j.LoggerFactory;
40
41/**
42 * Manages the connectivity requirements between peers.
43 */
Jonathan Hartce430a42014-10-16 20:44:29 -070044public class PeerConnectivityManager {
Jonathan Hartdc711bd2014-10-15 11:24:23 -070045
46 private static final Logger log = LoggerFactory.getLogger(
Jonathan Hartce430a42014-10-16 20:44:29 -070047 PeerConnectivityManager.class);
Jonathan Hartdc711bd2014-10-15 11:24:23 -070048
Jonathan Hart31582d12014-10-22 13:52:41 -070049 private final SdnIpConfigService configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070050 private final InterfaceService interfaceService;
51 private final IntentService intentService;
52
Thomas Vachuskab97cf282014-10-20 23:31:12 -070053 private final ApplicationId appId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070054
Jonathan Hart31582d12014-10-22 13:52:41 -070055 /**
56 * Creates a new PeerConnectivityManager.
57 *
58 * @param appId the application ID
59 * @param configService the SDN-IP config service
60 * @param interfaceService the interface service
61 * @param intentService the intent service
62 */
Thomas Vachuskab97cf282014-10-20 23:31:12 -070063 public PeerConnectivityManager(ApplicationId appId,
Jonathan Hart31582d12014-10-22 13:52:41 -070064 SdnIpConfigService configService,
Thomas Vachuskab97cf282014-10-20 23:31:12 -070065 InterfaceService interfaceService,
66 IntentService intentService) {
67 this.appId = appId;
Jonathan Hart31582d12014-10-22 13:52:41 -070068 this.configService = configService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070069 this.interfaceService = interfaceService;
70 this.intentService = intentService;
71 }
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() {
77 // TODO are any of these errors?
78 if (interfaceService.getInterfaces().isEmpty()) {
79
80 log.warn("The interface in configuration file is empty. "
Thomas Vachuskab97cf282014-10-20 23:31:12 -070081 + "Thus, the SDN-IP application can not be started.");
Jonathan Hart31582d12014-10-22 13:52:41 -070082 } else if (configService.getBgpPeers().isEmpty()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -070083
84 log.warn("The BGP peer in configuration file is empty."
Thomas Vachuskab97cf282014-10-20 23:31:12 -070085 + "Thus, the SDN-IP application can not be started.");
Jonathan Hart31582d12014-10-22 13:52:41 -070086 } else if (configService.getBgpSpeakers() == null) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -070087
88 log.error("The BGP speaker in configuration file is empty. "
Thomas Vachuskab97cf282014-10-20 23:31:12 -070089 + "Thus, the SDN-IP application can not be started.");
Jonathan Hartdc711bd2014-10-15 11:24:23 -070090 return;
91 }
92
93 setupBgpPaths();
94 setupIcmpPaths();
95 }
96
97 /**
98 * Sets up paths for all {@link BgpSpeaker}s and all external peers.
99 * <p/>
100 * Run a loop for all BGP speakers and a loop for all BGP peers outside.
101 * Push intents for paths from each BGP speaker to all peers. Push intents
102 * for paths from all peers to each BGP speaker.
103 */
104 private void setupBgpPaths() {
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 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
110
111 List<InterfaceAddress> interfaceAddresses =
112 bgpSpeaker.interfaceAddresses();
113
Jonathan Hart31582d12014-10-22 13:52:41 -0700114 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700115
116 log.debug("Start to set up BGP paths between BGP speaker: {} "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700117 + "to BGP peer: {}", bgpSpeaker, bgpPeer);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700118
119 Interface peerInterface = interfaceService.getInterface(
120 bgpPeer.connectPoint());
121 if (peerInterface == null) {
122 log.error("Can not find the corresponding Interface from "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700123 + "configuration for BGP peer {}",
124 bgpPeer.ipAddress());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700125 continue;
126 }
127
128 IpAddress bgpdAddress = null;
129 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
130 if (interfaceAddress.connectPoint().equals(
131 peerInterface.connectPoint())) {
132 bgpdAddress = interfaceAddress.ipAddress();
133 break;
134 }
135 }
136 if (bgpdAddress == null) {
137 log.debug("There is no interface IP address for bgpPeer: {}"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700138 + " on interface {}", bgpPeer, bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700139 return;
140 }
141
142 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
143 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
144
145 // install intent for BGP path from BGPd to BGP peer matching
146 // destination TCP port 179
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700147 TrafficSelector selector = DefaultTrafficSelector.builder()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700148 .matchEthType(Ethernet.TYPE_IPV4)
149 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700150 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
151 IpAddress.MAX_INET_MASK))
152 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
153 IpAddress.MAX_INET_MASK))
154 .matchTcpDst((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700155 .build();
156
157 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
158 .build();
159
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700160 PointToPointIntent intentMatchDstTcpPort =
161 new PointToPointIntent(appId, selector, treatment,
162 bgpdConnectPoint, bgpdPeerConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700163 intentService.submit(intentMatchDstTcpPort);
164 log.debug("Submitted BGP path intent matching dst TCP port 179 "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700165 + "from BGPd {} to peer {}: {}",
166 bgpdAddress, bgpdPeerAddress, intentMatchDstTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700167
168 // install intent for BGP path from BGPd to BGP peer matching
169 // source TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700170 selector = DefaultTrafficSelector.builder()
171 .matchEthType(Ethernet.TYPE_IPV4)
172 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700173 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
174 IpAddress.MAX_INET_MASK))
175 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
176 IpAddress.MAX_INET_MASK))
177 .matchTcpSrc((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700178 .build();
179
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700180 PointToPointIntent intentMatchSrcTcpPort =
181 new PointToPointIntent(appId, selector, treatment,
182 bgpdConnectPoint, bgpdPeerConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700183 intentService.submit(intentMatchSrcTcpPort);
184 log.debug("Submitted BGP path intent matching src TCP port 179"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700185 + "from BGPd {} to peer {}: {}",
186 bgpdAddress, bgpdPeerAddress, intentMatchSrcTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700187
188 // install intent for reversed BGP path from BGP peer to BGPd
189 // matching destination TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700190 selector = DefaultTrafficSelector.builder()
191 .matchEthType(Ethernet.TYPE_IPV4)
192 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700193 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
194 IpAddress.MAX_INET_MASK))
195 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
196 IpAddress.MAX_INET_MASK))
197 .matchTcpDst((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700198 .build();
199
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700200 PointToPointIntent reversedIntentMatchDstTcpPort =
201 new PointToPointIntent(appId, selector, treatment,
202 bgpdPeerConnectPoint, bgpdConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700203 intentService.submit(reversedIntentMatchDstTcpPort);
204 log.debug("Submitted BGP path intent matching dst TCP port 179"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700205 + "from BGP peer {} to BGPd {} : {}",
206 bgpdPeerAddress, bgpdAddress, reversedIntentMatchDstTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700207
208 // install intent for reversed BGP path from BGP peer to BGPd
209 // matching source TCP port 179
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700210 selector = DefaultTrafficSelector.builder()
211 .matchEthType(Ethernet.TYPE_IPV4)
212 .matchIPProtocol(IPv4.PROTOCOL_TCP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700213 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
214 IpAddress.MAX_INET_MASK))
215 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
216 IpAddress.MAX_INET_MASK))
217 .matchTcpSrc((short) BgpConstants.BGP_PORT)
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700218 .build();
219
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700220 PointToPointIntent reversedIntentMatchSrcTcpPort =
221 new PointToPointIntent(appId, selector, treatment,
222 bgpdPeerConnectPoint, bgpdConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700223 intentService.submit(reversedIntentMatchSrcTcpPort);
224 log.debug("Submitted BGP path intent matching src TCP port 179"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700225 + "from BGP peer {} to BGPd {} : {}",
226 bgpdPeerAddress, bgpdAddress, reversedIntentMatchSrcTcpPort);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700227
228 }
229 }
230 }
231
232 /**
233 * Sets up ICMP paths between each {@link BgpSpeaker} and all BGP peers
234 * located in other external networks.
235 * <p/>
236 * Run a loop for all BGP speakers and a loop for all BGP Peers. Push
237 * intents for paths from each BGP speaker to all peers. Push intents
238 * for paths from all peers to each BGP speaker.
239 */
240 private void setupIcmpPaths() {
Jonathan Hart31582d12014-10-22 13:52:41 -0700241 for (BgpSpeaker bgpSpeaker : configService.getBgpSpeakers()
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700242 .values()) {
243 log.debug("Start to set up ICMP paths for BGP speaker: {}",
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700244 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700245 ConnectPoint bgpdConnectPoint = bgpSpeaker.connectPoint();
246 List<InterfaceAddress> interfaceAddresses = bgpSpeaker
247 .interfaceAddresses();
248
Jonathan Hart31582d12014-10-22 13:52:41 -0700249 for (BgpPeer bgpPeer : configService.getBgpPeers().values()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700250
251 Interface peerInterface = interfaceService.getInterface(
252 bgpPeer.connectPoint());
253
254 if (peerInterface == null) {
255 log.error("Can not find the corresponding Interface from "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700256 + "configuration for BGP peer {}",
257 bgpPeer.ipAddress());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700258 continue;
259 }
260 IpAddress bgpdAddress = null;
261 for (InterfaceAddress interfaceAddress : interfaceAddresses) {
262 if (interfaceAddress.connectPoint().equals(
263 peerInterface.connectPoint())) {
264 bgpdAddress = interfaceAddress.ipAddress();
265 break;
266 }
267
268 }
269 if (bgpdAddress == null) {
270 log.debug("There is no IP address for bgpPeer: {} on "
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700271 + "interface port: {}", bgpPeer,
272 bgpPeer.connectPoint());
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700273 return;
274 }
275
276 IpAddress bgpdPeerAddress = bgpPeer.ipAddress();
277 ConnectPoint bgpdPeerConnectPoint = peerInterface.connectPoint();
278
279 // install intent for ICMP path from BGPd to BGP peer
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700280 TrafficSelector selector = DefaultTrafficSelector.builder()
281 .matchEthType(Ethernet.TYPE_IPV4)
282 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700283 .matchIPSrc(IpPrefix.valueOf(bgpdAddress.toInt(),
284 IpAddress.MAX_INET_MASK))
285 .matchIPDst(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
286 IpAddress.MAX_INET_MASK))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700287 .build();
288
289 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
290 .build();
291
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700292 PointToPointIntent intent =
293 new PointToPointIntent(appId, selector, treatment,
294 bgpdConnectPoint, bgpdPeerConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700295 intentService.submit(intent);
296 log.debug("Submitted ICMP path intent from BGPd {} to peer {} :"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700297 + " {}", bgpdAddress, bgpdPeerAddress, intent);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700298
299 // install intent for reversed ICMP path from BGP peer to BGPd
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700300 selector = DefaultTrafficSelector.builder()
301 .matchEthType(Ethernet.TYPE_IPV4)
302 .matchIPProtocol(IPv4.PROTOCOL_ICMP)
Jonathan Hart31582d12014-10-22 13:52:41 -0700303 .matchIPSrc(IpPrefix.valueOf(bgpdPeerAddress.toInt(),
304 IpAddress.MAX_INET_MASK))
305 .matchIPDst(IpPrefix.valueOf(bgpdAddress.toInt(),
306 IpAddress.MAX_INET_MASK))
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700307 .build();
308
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700309 PointToPointIntent reversedIntent =
310 new PointToPointIntent(appId, selector, treatment,
311 bgpdPeerConnectPoint, bgpdConnectPoint);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700312 intentService.submit(reversedIntent);
313 log.debug("Submitted ICMP path intent from BGP peer {} to BGPd"
Thomas Vachuskab97cf282014-10-20 23:31:12 -0700314 + " {} : {}",
315 bgpdPeerAddress, bgpdAddress, reversedIntent);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700316 }
317 }
318 }
319
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700320}