blob: 459db2b76cd3b507a0300098dc04e0ed8d449fb8 [file] [log] [blame]
Thomas Vachuska781d18b2014-10-27 10:31:25 -07001/*
Ray Milkey34c95902015-04-15 09:47:53 -07002 * Copyright 2014-2015 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;
Hyunsun Mooncf732fb2015-08-22 21:04:23 -070023import org.onlab.packet.TpPort;
Brian O'Connorabafb502014-12-02 22:26:20 -080024import org.onosproject.core.ApplicationId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040025import org.onosproject.net.config.NetworkConfigService;
26import org.onosproject.incubator.net.intf.Interface;
27import org.onosproject.incubator.net.intf.InterfaceService;
Brian O'Connorabafb502014-12-02 22:26:20 -080028import org.onosproject.net.ConnectPoint;
29import org.onosproject.net.flow.DefaultTrafficSelector;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
31import org.onosproject.net.flow.TrafficSelector;
32import org.onosproject.net.flow.TrafficTreatment;
Jonathan Hart2a9ea492015-07-30 15:53:04 -070033import org.onosproject.net.host.InterfaceIpAddress;
Brian O'Connorabafb502014-12-02 22:26:20 -080034import org.onosproject.net.intent.PointToPointIntent;
Jonathan Hart4cb39882015-08-12 23:50:55 -040035import org.onosproject.routing.RoutingService;
36import org.onosproject.routing.config.BgpConfig;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070037import org.slf4j.Logger;
38import org.slf4j.LoggerFactory;
39
Jonathan Hart41349e92015-02-09 14:14:02 -080040import java.util.ArrayList;
41import java.util.Collection;
42import java.util.List;
43
Jonathan Hart4cb39882015-08-12 23:50:55 -040044import static com.google.common.base.Preconditions.checkNotNull;
45
Jonathan Hartdc711bd2014-10-15 11:24:23 -070046/**
47 * Manages the connectivity requirements between peers.
48 */
Jonathan Hartce430a42014-10-16 20:44:29 -070049public class PeerConnectivityManager {
Pavlin Radoslavov2aa1f322015-03-11 17:59:44 -070050 private static final int PRIORITY_OFFSET = 1000;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070051
52 private static final Logger log = LoggerFactory.getLogger(
Jonathan Hartce430a42014-10-16 20:44:29 -070053 PeerConnectivityManager.class);
Jonathan Hartdc711bd2014-10-15 11:24:23 -070054
Jonathan Hart41349e92015-02-09 14:14:02 -080055 private static final short BGP_PORT = 179;
56
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080057 private final IntentSynchronizer intentSynchronizer;
Jonathan Hart4cb39882015-08-12 23:50:55 -040058 private final NetworkConfigService configService;
59 private final InterfaceService interfaceService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070060
Thomas Vachuskab97cf282014-10-20 23:31:12 -070061 private final ApplicationId appId;
Jonathan Hart4cb39882015-08-12 23:50:55 -040062 private final ApplicationId routerAppId;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070063
Jonathan Hart31582d12014-10-22 13:52:41 -070064 /**
65 * Creates a new PeerConnectivityManager.
66 *
Jonathan Hart51372182014-12-03 21:32:34 -080067 * @param appId the application ID
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080068 * @param intentSynchronizer the intent synchronizer
Jonathan Hart51372182014-12-03 21:32:34 -080069 * @param configService the SDN-IP config service
Ray Milkey9b36d812015-09-09 15:24:54 -070070 * @param interfaceService the interface service
71 * @param routerAppId application ID
Jonathan Hart31582d12014-10-22 13:52:41 -070072 */
Thomas Vachuskab97cf282014-10-20 23:31:12 -070073 public PeerConnectivityManager(ApplicationId appId,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080074 IntentSynchronizer intentSynchronizer,
Jonathan Hart4cb39882015-08-12 23:50:55 -040075 NetworkConfigService configService,
76 ApplicationId routerAppId,
77 InterfaceService interfaceService) {
Thomas Vachuskab97cf282014-10-20 23:31:12 -070078 this.appId = appId;
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -080079 this.intentSynchronizer = intentSynchronizer;
Jonathan Hart31582d12014-10-22 13:52:41 -070080 this.configService = configService;
Jonathan Hart4cb39882015-08-12 23:50:55 -040081 this.routerAppId = routerAppId;
82 this.interfaceService = interfaceService;
Jonathan Hartdc711bd2014-10-15 11:24:23 -070083 }
84
Jonathan Hart31582d12014-10-22 13:52:41 -070085 /**
86 * Starts the peer connectivity manager.
87 */
Jonathan Hartdc711bd2014-10-15 11:24:23 -070088 public void start() {
Jonathan Hart6ec68292014-11-14 15:09:30 -080089 setUpConnectivity();
Jonathan Hartdc711bd2014-10-15 11:24:23 -070090 }
91
92 /**
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080093 * Stops the peer connectivity manager.
94 */
95 public void stop() {
Pavlin Radoslavova071b1e2014-11-17 13:37:57 -080096 }
97
98 /**
Jonathan Hart6ec68292014-11-14 15:09:30 -080099 * Sets up paths to establish connectivity between all internal
Jonathan Hart4cb39882015-08-12 23:50:55 -0400100 * BGP speakers and external BGP peers.
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700101 */
Jonathan Hart6ec68292014-11-14 15:09:30 -0800102 private void setUpConnectivity() {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800103 List<PointToPointIntent> intents = new ArrayList<>();
104
Jonathan Hart4cb39882015-08-12 23:50:55 -0400105 BgpConfig config = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
106
107 if (config == null) {
108 log.warn("No BgpConfig found");
109 return;
110 }
111
112 for (BgpConfig.BgpSpeakerConfig bgpSpeaker : config.bgpSpeakers()) {
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700113 log.debug("Start to set up BGP paths for BGP speaker: {}",
Jonathan Hart4cb39882015-08-12 23:50:55 -0400114 bgpSpeaker);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700115
Jonathan Hart4cb39882015-08-12 23:50:55 -0400116 intents.addAll(buildSpeakerIntents(bgpSpeaker));
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700117 }
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800118
119 // Submit all the intents.
120 intentSynchronizer.submitPeerIntents(intents);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700121 }
122
Jonathan Hart4cb39882015-08-12 23:50:55 -0400123 private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) {
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800124 List<PointToPointIntent> intents = new ArrayList<>();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700125
Jonathan Hart4cb39882015-08-12 23:50:55 -0400126 for (IpAddress peerAddress : speaker.peers()) {
127 Interface peeringInterface = interfaceService.getMatchingInterface(peerAddress);
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700128
Jonathan Hart4cb39882015-08-12 23:50:55 -0400129 if (peeringInterface == null) {
130 log.debug("No peering interface found for peer {} on speaker {}",
131 peerAddress, speaker);
Jonathan Harte30fcda2015-08-06 16:22:34 -0700132 continue;
133 }
134
Jonathan Hart4cb39882015-08-12 23:50:55 -0400135 IpAddress peeringAddress = null;
136 for (InterfaceIpAddress address : peeringInterface.ipAddresses()) {
137 if (address.subnetAddress().contains(peerAddress)) {
138 peeringAddress = address.ipAddress();
Jonathan Harte30fcda2015-08-06 16:22:34 -0700139 break;
Jonathan Hart2a9ea492015-07-30 15:53:04 -0700140 }
Jonathan Harte30fcda2015-08-06 16:22:34 -0700141 }
Jonathan Hart4cb39882015-08-12 23:50:55 -0400142
143 checkNotNull(peeringAddress);
144
145 intents.addAll(buildIntents(speaker.connectPoint(), peeringAddress,
146 peeringInterface.connectPoint(), peerAddress));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800147 }
148
Jonathan Hart4cb39882015-08-12 23:50:55 -0400149 return intents;
150 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800151
Jonathan Hart4cb39882015-08-12 23:50:55 -0400152 /**
153 * Builds the required intents between the two pairs of connect points and
154 * IP addresses.
155 *
156 * @param portOne the first connect point
157 * @param ipOne the first IP address
158 * @param portTwo the second connect point
159 * @param ipTwo the second IP address
160 * @return the intents to install
161 */
162 private Collection<PointToPointIntent> buildIntents(ConnectPoint portOne,
163 IpAddress ipOne,
164 ConnectPoint portTwo,
165 IpAddress ipTwo) {
166
167 List<PointToPointIntent> intents = new ArrayList<>();
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800168
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
Jonathan Hart4cb39882015-08-12 23:50:55 -0400176 if (ipOne.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 Hart4cb39882015-08-12 23:50:55 -0400186 ipOne,
187 ipTwo,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700188 null,
189 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800190
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700191 intents.add(PointToPointIntent.builder()
192 .appId(appId)
193 .selector(selector)
194 .treatment(treatment)
Jonathan Hart4cb39882015-08-12 23:50:55 -0400195 .ingressPoint(portOne)
196 .egressPoint(portTwo)
197 .priority(PRIORITY_OFFSET)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700198 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800199
Jonathan Hart51372182014-12-03 21:32:34 -0800200 // Path from BGP speaker to BGP peer matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800201 selector = buildSelector(tcpProtocol,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400202 ipOne,
203 ipTwo,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700204 BGP_PORT,
205 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800206
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700207 intents.add(PointToPointIntent.builder()
208 .appId(appId)
209 .selector(selector)
210 .treatment(treatment)
Jonathan Hart4cb39882015-08-12 23:50:55 -0400211 .ingressPoint(portOne)
212 .egressPoint(portTwo)
213 .priority(PRIORITY_OFFSET)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700214 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800215
Jonathan Hart51372182014-12-03 21:32:34 -0800216 // Path from BGP peer to BGP speaker matching destination TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800217 selector = buildSelector(tcpProtocol,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400218 ipTwo,
219 ipOne,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700220 null,
221 BGP_PORT);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800222
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700223 intents.add(PointToPointIntent.builder()
224 .appId(appId)
225 .selector(selector)
226 .treatment(treatment)
Jonathan Hart4cb39882015-08-12 23:50:55 -0400227 .ingressPoint(portTwo)
228 .egressPoint(portOne)
229 .priority(PRIORITY_OFFSET)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700230 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800231
Jonathan Hart51372182014-12-03 21:32:34 -0800232 // Path from BGP peer to BGP speaker matching source TCP port 179
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800233 selector = buildSelector(tcpProtocol,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400234 ipTwo,
235 ipOne,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700236 BGP_PORT,
237 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800238
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700239 intents.add(PointToPointIntent.builder()
240 .appId(appId)
241 .selector(selector)
242 .treatment(treatment)
Jonathan Hart4cb39882015-08-12 23:50:55 -0400243 .ingressPoint(portTwo)
244 .egressPoint(portOne)
245 .priority(PRIORITY_OFFSET)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700246 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800247
Jonathan Hart51372182014-12-03 21:32:34 -0800248 // ICMP path from BGP speaker to BGP peer
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800249 selector = buildSelector(icmpProtocol,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400250 ipOne,
251 ipTwo,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700252 null,
253 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800254
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700255 intents.add(PointToPointIntent.builder()
256 .appId(appId)
257 .selector(selector)
258 .treatment(treatment)
Jonathan Hart4cb39882015-08-12 23:50:55 -0400259 .ingressPoint(portOne)
260 .egressPoint(portTwo)
261 .priority(PRIORITY_OFFSET)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700262 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800263
Jonathan Hart51372182014-12-03 21:32:34 -0800264 // ICMP path from BGP peer to BGP speaker
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800265 selector = buildSelector(icmpProtocol,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400266 ipTwo,
267 ipOne,
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700268 null,
269 null);
Jonathan Hart6ec68292014-11-14 15:09:30 -0800270
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700271 intents.add(PointToPointIntent.builder()
272 .appId(appId)
273 .selector(selector)
274 .treatment(treatment)
Jonathan Hart4cb39882015-08-12 23:50:55 -0400275 .ingressPoint(portTwo)
276 .egressPoint(portOne)
277 .priority(PRIORITY_OFFSET)
Ray Milkey3e3ec5f2015-03-17 17:00:38 -0700278 .build());
Jonathan Hart6ec68292014-11-14 15:09:30 -0800279
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800280 return intents;
Jonathan Hart6ec68292014-11-14 15:09:30 -0800281 }
282
283 /**
284 * Builds a traffic selector based on the set of input parameters.
285 *
286 * @param ipProto IP protocol
287 * @param srcIp source IP address
288 * @param dstIp destination IP address
289 * @param srcTcpPort source TCP port, or null if shouldn't be set
290 * @param dstTcpPort destination TCP port, or null if shouldn't be set
291 * @return the new traffic selector
292 */
293 private TrafficSelector buildSelector(byte ipProto, IpAddress srcIp,
Pavlin Radoslavova7243cc2014-11-22 21:38:02 -0800294 IpAddress dstIp, Short srcTcpPort,
295 Short dstTcpPort) {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400296 TrafficSelector.Builder builder = DefaultTrafficSelector.builder()
297 .matchEthType(Ethernet.TYPE_IPV4)
298 .matchIPProtocol(ipProto);
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800299
Pavlin Radoslavov87dd9302015-03-10 13:53:24 -0700300 if (dstIp.isIp4()) {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400301 builder.matchIPSrc(IpPrefix.valueOf(srcIp, IpPrefix.MAX_INET_MASK_LENGTH))
302 .matchIPDst(IpPrefix.valueOf(dstIp, IpPrefix.MAX_INET_MASK_LENGTH));
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800303 } else {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400304 builder.matchIPv6Src(IpPrefix.valueOf(srcIp, IpPrefix.MAX_INET6_MASK_LENGTH))
305 .matchIPv6Dst(IpPrefix.valueOf(dstIp, IpPrefix.MAX_INET6_MASK_LENGTH));
Kunihiro Ishiguro6e2ee152015-01-20 16:57:54 -0800306 }
Jonathan Hart6ec68292014-11-14 15:09:30 -0800307
308 if (srcTcpPort != null) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700309 builder.matchTcpSrc(TpPort.tpPort(srcTcpPort));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800310 }
311
312 if (dstTcpPort != null) {
Hyunsun Mooncf732fb2015-08-22 21:04:23 -0700313 builder.matchTcpDst(TpPort.tpPort(dstTcpPort));
Jonathan Hart6ec68292014-11-14 15:09:30 -0800314 }
315
316 return builder.build();
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700317 }
318
Jonathan Hartdc711bd2014-10-15 11:24:23 -0700319}