Committed by
Gerrit Code Review
Generalize IntentSynchronizer and separate reactive routing code
* IntentSynchronizer can now handle any intent rather than having use case specific APIs * IntentSynchronizer does not generate or store intents anymore, it only perform synchronization * SdnIpFib generates and manages the procative route-based intents * ReactiveRoutingFib generates and manages the reactive intents * Unit tests have been tightned up to only test single components, rather than multiple components together * PeerConnectivityManager uses meaningful keys when creating intents Change-Id: I4bb036ec8d056f43ece46f7dfc71d5e5a136b77d
Showing
21 changed files
with
771 additions
and
362 deletions
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * 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 | ||
| 7 | + * | ||
| 8 | + * 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. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.reactive.routing; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Specifies the type of an IP address or an IP prefix location. | ||
| 21 | + */ | ||
| 22 | +enum LocationType { | ||
| 23 | + /** | ||
| 24 | + * The location of an IP address or an IP prefix is in local SDN network. | ||
| 25 | + */ | ||
| 26 | + LOCAL, | ||
| 27 | + /** | ||
| 28 | + * The location of an IP address or an IP prefix is outside local SDN network. | ||
| 29 | + */ | ||
| 30 | + INTERNET, | ||
| 31 | + /** | ||
| 32 | + * There is no route for this IP address or IP prefix. | ||
| 33 | + */ | ||
| 34 | + NO_ROUTE | ||
| 35 | +} |
apps/reactive-routing/src/main/java/org/onosproject/reactive/routing/ReactiveRoutingFib.java
0 → 100644
This diff is collapsed. Click to expand it.
| ... | @@ -25,27 +25,39 @@ import org.onlab.packet.EthType; | ... | @@ -25,27 +25,39 @@ import org.onlab.packet.EthType; |
| 25 | import org.onlab.packet.Ethernet; | 25 | import org.onlab.packet.Ethernet; |
| 26 | import org.onlab.packet.IPv4; | 26 | import org.onlab.packet.IPv4; |
| 27 | import org.onlab.packet.Ip4Address; | 27 | import org.onlab.packet.Ip4Address; |
| 28 | +import org.onlab.packet.Ip6Address; | ||
| 28 | import org.onlab.packet.IpAddress; | 29 | import org.onlab.packet.IpAddress; |
| 30 | +import org.onlab.packet.IpPrefix; | ||
| 29 | import org.onlab.packet.MacAddress; | 31 | import org.onlab.packet.MacAddress; |
| 30 | import org.onosproject.core.ApplicationId; | 32 | import org.onosproject.core.ApplicationId; |
| 31 | import org.onosproject.core.CoreService; | 33 | import org.onosproject.core.CoreService; |
| 34 | +import org.onosproject.incubator.net.intf.Interface; | ||
| 35 | +import org.onosproject.incubator.net.intf.InterfaceService; | ||
| 32 | import org.onosproject.net.ConnectPoint; | 36 | import org.onosproject.net.ConnectPoint; |
| 37 | +import org.onosproject.net.Host; | ||
| 33 | import org.onosproject.net.flow.DefaultTrafficSelector; | 38 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 34 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 39 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 35 | import org.onosproject.net.flow.TrafficSelector; | 40 | import org.onosproject.net.flow.TrafficSelector; |
| 36 | import org.onosproject.net.flow.TrafficTreatment; | 41 | import org.onosproject.net.flow.TrafficTreatment; |
| 42 | +import org.onosproject.net.host.HostService; | ||
| 37 | import org.onosproject.net.packet.DefaultOutboundPacket; | 43 | import org.onosproject.net.packet.DefaultOutboundPacket; |
| 38 | import org.onosproject.net.packet.InboundPacket; | 44 | import org.onosproject.net.packet.InboundPacket; |
| 39 | import org.onosproject.net.packet.OutboundPacket; | 45 | import org.onosproject.net.packet.OutboundPacket; |
| 40 | import org.onosproject.net.packet.PacketContext; | 46 | import org.onosproject.net.packet.PacketContext; |
| 41 | import org.onosproject.net.packet.PacketProcessor; | 47 | import org.onosproject.net.packet.PacketProcessor; |
| 42 | import org.onosproject.net.packet.PacketService; | 48 | import org.onosproject.net.packet.PacketService; |
| 49 | +import org.onosproject.routing.IntentRequestListener; | ||
| 50 | +import org.onosproject.routing.RouteEntry; | ||
| 43 | import org.onosproject.routing.RoutingService; | 51 | import org.onosproject.routing.RoutingService; |
| 52 | +import org.onosproject.routing.SdnIpService; | ||
| 44 | import org.onosproject.routing.config.RoutingConfigurationService; | 53 | import org.onosproject.routing.config.RoutingConfigurationService; |
| 45 | import org.slf4j.Logger; | 54 | import org.slf4j.Logger; |
| 46 | 55 | ||
| 47 | import java.nio.ByteBuffer; | 56 | import java.nio.ByteBuffer; |
| 57 | +import java.util.Optional; | ||
| 58 | +import java.util.Set; | ||
| 48 | 59 | ||
| 60 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
| 49 | import static org.onlab.packet.Ethernet.TYPE_ARP; | 61 | import static org.onlab.packet.Ethernet.TYPE_ARP; |
| 50 | import static org.onlab.packet.Ethernet.TYPE_IPV4; | 62 | import static org.onlab.packet.Ethernet.TYPE_IPV4; |
| 51 | import static org.onosproject.net.packet.PacketPriority.REACTIVE; | 63 | import static org.onosproject.net.packet.PacketPriority.REACTIVE; |
| ... | @@ -74,16 +86,32 @@ public class SdnIpReactiveRouting { | ... | @@ -74,16 +86,32 @@ public class SdnIpReactiveRouting { |
| 74 | protected RoutingService routingService; | 86 | protected RoutingService routingService; |
| 75 | 87 | ||
| 76 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 88 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 89 | + protected SdnIpService sdnIpService; | ||
| 90 | + | ||
| 91 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 77 | protected RoutingConfigurationService config; | 92 | protected RoutingConfigurationService config; |
| 78 | 93 | ||
| 94 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 95 | + protected InterfaceService interfaceService; | ||
| 96 | + | ||
| 97 | + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | ||
| 98 | + protected HostService hostService; | ||
| 99 | + | ||
| 79 | private ApplicationId appId; | 100 | private ApplicationId appId; |
| 80 | 101 | ||
| 102 | + private IntentRequestListener intentRequestListener; | ||
| 103 | + | ||
| 81 | private ReactiveRoutingProcessor processor = | 104 | private ReactiveRoutingProcessor processor = |
| 82 | new ReactiveRoutingProcessor(); | 105 | new ReactiveRoutingProcessor(); |
| 83 | 106 | ||
| 84 | @Activate | 107 | @Activate |
| 85 | public void activate() { | 108 | public void activate() { |
| 86 | appId = coreService.registerApplication(APP_NAME); | 109 | appId = coreService.registerApplication(APP_NAME); |
| 110 | + | ||
| 111 | + intentRequestListener = new ReactiveRoutingFib(appId, hostService, | ||
| 112 | + config, interfaceService, | ||
| 113 | + sdnIpService.getIntentSynchronizationService()); | ||
| 114 | + | ||
| 87 | packetService.addProcessor(processor, PacketProcessor.director(2)); | 115 | packetService.addProcessor(processor, PacketProcessor.director(2)); |
| 88 | requestIntercepts(); | 116 | requestIntercepts(); |
| 89 | log.info("SDN-IP Reactive Routing Started"); | 117 | log.info("SDN-IP Reactive Routing Started"); |
| ... | @@ -168,12 +196,11 @@ public class SdnIpReactiveRouting { | ... | @@ -168,12 +196,11 @@ public class SdnIpReactiveRouting { |
| 168 | IpAddress srcIp = | 196 | IpAddress srcIp = |
| 169 | IpAddress.valueOf(ipv4Packet.getSourceAddress()); | 197 | IpAddress.valueOf(ipv4Packet.getSourceAddress()); |
| 170 | MacAddress srcMac = ethPkt.getSourceMAC(); | 198 | MacAddress srcMac = ethPkt.getSourceMAC(); |
| 171 | - routingService.packetReactiveProcessor(dstIp, srcIp, | 199 | + packetReactiveProcessor(dstIp, srcIp, srcConnectPoint, srcMac); |
| 172 | - srcConnectPoint, srcMac); | ||
| 173 | 200 | ||
| 174 | // TODO emit packet first or packetReactiveProcessor first | 201 | // TODO emit packet first or packetReactiveProcessor first |
| 175 | ConnectPoint egressConnectPoint = null; | 202 | ConnectPoint egressConnectPoint = null; |
| 176 | - egressConnectPoint = routingService.getEgressConnectPoint(dstIp); | 203 | + egressConnectPoint = getEgressConnectPoint(dstIp); |
| 177 | if (egressConnectPoint != null) { | 204 | if (egressConnectPoint != null) { |
| 178 | forwardPacketToDst(context, egressConnectPoint); | 205 | forwardPacketToDst(context, egressConnectPoint); |
| 179 | } | 206 | } |
| ... | @@ -185,6 +212,170 @@ public class SdnIpReactiveRouting { | ... | @@ -185,6 +212,170 @@ public class SdnIpReactiveRouting { |
| 185 | } | 212 | } |
| 186 | 213 | ||
| 187 | /** | 214 | /** |
| 215 | + * Routes packet reactively. | ||
| 216 | + * | ||
| 217 | + * @param dstIpAddress the destination IP address of a packet | ||
| 218 | + * @param srcIpAddress the source IP address of a packet | ||
| 219 | + * @param srcConnectPoint the connect point where a packet comes from | ||
| 220 | + * @param srcMacAddress the source MAC address of a packet | ||
| 221 | + */ | ||
| 222 | + private void packetReactiveProcessor(IpAddress dstIpAddress, | ||
| 223 | + IpAddress srcIpAddress, | ||
| 224 | + ConnectPoint srcConnectPoint, | ||
| 225 | + MacAddress srcMacAddress) { | ||
| 226 | + checkNotNull(dstIpAddress); | ||
| 227 | + checkNotNull(srcIpAddress); | ||
| 228 | + checkNotNull(srcConnectPoint); | ||
| 229 | + checkNotNull(srcMacAddress); | ||
| 230 | + | ||
| 231 | + // | ||
| 232 | + // Step1: Try to update the existing intent first if it exists. | ||
| 233 | + // | ||
| 234 | + IpPrefix ipPrefix = null; | ||
| 235 | + RouteEntry routeEntry = null; | ||
| 236 | + if (config.isIpAddressLocal(dstIpAddress)) { | ||
| 237 | + if (dstIpAddress.isIp4()) { | ||
| 238 | + ipPrefix = IpPrefix.valueOf(dstIpAddress, | ||
| 239 | + Ip4Address.BIT_LENGTH); | ||
| 240 | + } else { | ||
| 241 | + ipPrefix = IpPrefix.valueOf(dstIpAddress, | ||
| 242 | + Ip6Address.BIT_LENGTH); | ||
| 243 | + } | ||
| 244 | + } else { | ||
| 245 | + // Get IP prefix from BGP route table | ||
| 246 | + routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress); | ||
| 247 | + if (routeEntry != null) { | ||
| 248 | + ipPrefix = routeEntry.prefix(); | ||
| 249 | + } | ||
| 250 | + } | ||
| 251 | + if (ipPrefix != null | ||
| 252 | + && intentRequestListener.mp2pIntentExists(ipPrefix)) { | ||
| 253 | + intentRequestListener.updateExistingMp2pIntent(ipPrefix, | ||
| 254 | + srcConnectPoint); | ||
| 255 | + return; | ||
| 256 | + } | ||
| 257 | + | ||
| 258 | + // | ||
| 259 | + // Step2: There is no existing intent for the destination IP address. | ||
| 260 | + // Check whether it is necessary to create a new one. If necessary then | ||
| 261 | + // create a new one. | ||
| 262 | + // | ||
| 263 | + TrafficType trafficType = | ||
| 264 | + trafficTypeClassifier(srcConnectPoint, dstIpAddress); | ||
| 265 | + | ||
| 266 | + switch (trafficType) { | ||
| 267 | + case HOST_TO_INTERNET: | ||
| 268 | + // If the destination IP address is outside the local SDN network. | ||
| 269 | + // The Step 1 has already handled it. We do not need to do anything here. | ||
| 270 | + intentRequestListener.setUpConnectivityHostToInternet(srcIpAddress, | ||
| 271 | + ipPrefix, routeEntry.nextHop()); | ||
| 272 | + break; | ||
| 273 | + case INTERNET_TO_HOST: | ||
| 274 | + intentRequestListener.setUpConnectivityInternetToHost(dstIpAddress); | ||
| 275 | + break; | ||
| 276 | + case HOST_TO_HOST: | ||
| 277 | + intentRequestListener.setUpConnectivityHostToHost(dstIpAddress, | ||
| 278 | + srcIpAddress, srcMacAddress, srcConnectPoint); | ||
| 279 | + break; | ||
| 280 | + case INTERNET_TO_INTERNET: | ||
| 281 | + log.trace("This is transit traffic, " | ||
| 282 | + + "the intent should be preinstalled already"); | ||
| 283 | + break; | ||
| 284 | + case DROP: | ||
| 285 | + // TODO here should setUpDropPacketIntent(...); | ||
| 286 | + // We need a new type of intent here. | ||
| 287 | + break; | ||
| 288 | + case UNKNOWN: | ||
| 289 | + log.trace("This is unknown traffic, so we do nothing"); | ||
| 290 | + break; | ||
| 291 | + default: | ||
| 292 | + break; | ||
| 293 | + } | ||
| 294 | + } | ||
| 295 | + | ||
| 296 | + /** | ||
| 297 | + * Classifies the traffic and return the traffic type. | ||
| 298 | + * | ||
| 299 | + * @param srcConnectPoint the connect point where the packet comes from | ||
| 300 | + * @param dstIp the destination IP address in packet | ||
| 301 | + * @return the traffic type which this packet belongs to | ||
| 302 | + */ | ||
| 303 | + private TrafficType trafficTypeClassifier(ConnectPoint srcConnectPoint, | ||
| 304 | + IpAddress dstIp) { | ||
| 305 | + LocationType dstIpLocationType = getLocationType(dstIp); | ||
| 306 | + Optional<Interface> srcInterface = | ||
| 307 | + interfaceService.getInterfacesByPort(srcConnectPoint).stream().findFirst(); | ||
| 308 | + | ||
| 309 | + switch (dstIpLocationType) { | ||
| 310 | + case INTERNET: | ||
| 311 | + if (!srcInterface.isPresent()) { | ||
| 312 | + return TrafficType.HOST_TO_INTERNET; | ||
| 313 | + } else { | ||
| 314 | + return TrafficType.INTERNET_TO_INTERNET; | ||
| 315 | + } | ||
| 316 | + case LOCAL: | ||
| 317 | + if (!srcInterface.isPresent()) { | ||
| 318 | + return TrafficType.HOST_TO_HOST; | ||
| 319 | + } else { | ||
| 320 | + // TODO Currently we only consider local public prefixes. | ||
| 321 | + // In the future, we will consider the local private prefixes. | ||
| 322 | + // If dstIpLocationType is a local private, we should return | ||
| 323 | + // TrafficType.DROP. | ||
| 324 | + return TrafficType.INTERNET_TO_HOST; | ||
| 325 | + } | ||
| 326 | + case NO_ROUTE: | ||
| 327 | + return TrafficType.DROP; | ||
| 328 | + default: | ||
| 329 | + return TrafficType.UNKNOWN; | ||
| 330 | + } | ||
| 331 | + } | ||
| 332 | + | ||
| 333 | + /** | ||
| 334 | + * Evaluates the location of an IP address and returns the location type. | ||
| 335 | + * | ||
| 336 | + * @param ipAddress the IP address to evaluate | ||
| 337 | + * @return the IP address location type | ||
| 338 | + */ | ||
| 339 | + private LocationType getLocationType(IpAddress ipAddress) { | ||
| 340 | + if (config.isIpAddressLocal(ipAddress)) { | ||
| 341 | + return LocationType.LOCAL; | ||
| 342 | + } else if (routingService.getLongestMatchableRouteEntry(ipAddress) != null) { | ||
| 343 | + return LocationType.INTERNET; | ||
| 344 | + } else { | ||
| 345 | + return LocationType.NO_ROUTE; | ||
| 346 | + } | ||
| 347 | + } | ||
| 348 | + | ||
| 349 | + public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) { | ||
| 350 | + LocationType type = getLocationType(dstIpAddress); | ||
| 351 | + if (type == LocationType.LOCAL) { | ||
| 352 | + Set<Host> hosts = hostService.getHostsByIp(dstIpAddress); | ||
| 353 | + if (!hosts.isEmpty()) { | ||
| 354 | + return hosts.iterator().next().location(); | ||
| 355 | + } else { | ||
| 356 | + hostService.startMonitoringIp(dstIpAddress); | ||
| 357 | + return null; | ||
| 358 | + } | ||
| 359 | + } else if (type == LocationType.INTERNET) { | ||
| 360 | + IpAddress nextHopIpAddress = null; | ||
| 361 | + RouteEntry routeEntry = routingService.getLongestMatchableRouteEntry(dstIpAddress); | ||
| 362 | + if (routeEntry != null) { | ||
| 363 | + nextHopIpAddress = routeEntry.nextHop(); | ||
| 364 | + Interface it = interfaceService.getMatchingInterface(nextHopIpAddress); | ||
| 365 | + if (it != null) { | ||
| 366 | + return it.connectPoint(); | ||
| 367 | + } else { | ||
| 368 | + return null; | ||
| 369 | + } | ||
| 370 | + } else { | ||
| 371 | + return null; | ||
| 372 | + } | ||
| 373 | + } else { | ||
| 374 | + return null; | ||
| 375 | + } | ||
| 376 | + } | ||
| 377 | + | ||
| 378 | + /** | ||
| 188 | * Emits the specified packet onto the network. | 379 | * Emits the specified packet onto the network. |
| 189 | * | 380 | * |
| 190 | * @param context the packet context | 381 | * @param context the packet context | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * 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 | ||
| 7 | + * | ||
| 8 | + * 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. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.reactive.routing; | ||
| 18 | + | ||
| 19 | +/** | ||
| 20 | + * Specifies the type of traffic. | ||
| 21 | + * <p> | ||
| 22 | + * We classify traffic by the first packet of each traffic. | ||
| 23 | + * </p> | ||
| 24 | + */ | ||
| 25 | +enum TrafficType { | ||
| 26 | + /** | ||
| 27 | + * Traffic from a host located in local SDN network wants to | ||
| 28 | + * communicate with destination host located in Internet (outside | ||
| 29 | + * local SDN network). | ||
| 30 | + */ | ||
| 31 | + HOST_TO_INTERNET, | ||
| 32 | + /** | ||
| 33 | + * Traffic from Internet wants to communicate with a host located | ||
| 34 | + * in local SDN network. | ||
| 35 | + */ | ||
| 36 | + INTERNET_TO_HOST, | ||
| 37 | + /** | ||
| 38 | + * Both the source host and destination host of a traffic are in | ||
| 39 | + * local SDN network. | ||
| 40 | + */ | ||
| 41 | + HOST_TO_HOST, | ||
| 42 | + /** | ||
| 43 | + * Traffic from Internet wants to traverse local SDN network. | ||
| 44 | + */ | ||
| 45 | + INTERNET_TO_INTERNET, | ||
| 46 | + /** | ||
| 47 | + * Any traffic wants to communicate with a destination which has | ||
| 48 | + * no route, or traffic from Internet wants to access a local private | ||
| 49 | + * IP address. | ||
| 50 | + */ | ||
| 51 | + DROP, | ||
| 52 | + /** | ||
| 53 | + * Traffic does not belong to the types above. | ||
| 54 | + */ | ||
| 55 | + UNKNOWN | ||
| 56 | +} |
| ... | @@ -47,6 +47,16 @@ public interface IntentRequestListener { | ... | @@ -47,6 +47,16 @@ public interface IntentRequestListener { |
| 47 | ConnectPoint srcConnectPoint); | 47 | ConnectPoint srcConnectPoint); |
| 48 | 48 | ||
| 49 | /** | 49 | /** |
| 50 | + * Sets up connectivity for packet from a local host to the Internet. | ||
| 51 | + * | ||
| 52 | + * @param hostIp IP address of the local host | ||
| 53 | + * @param prefix external IP prefix that the host is talking to | ||
| 54 | + * @param nextHopIpAddress IP address of the next hop router for the prefix | ||
| 55 | + */ | ||
| 56 | + void setUpConnectivityHostToInternet(IpAddress hostIp, IpPrefix prefix, | ||
| 57 | + IpAddress nextHopIpAddress); | ||
| 58 | + | ||
| 59 | + /** | ||
| 50 | * Adds one new ingress connect point into ingress points of an existing | 60 | * Adds one new ingress connect point into ingress points of an existing |
| 51 | * intent and resubmits the new intent. | 61 | * intent and resubmits the new intent. |
| 52 | * <p> | 62 | * <p> | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * 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 | ||
| 7 | + * | ||
| 8 | + * 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. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.routing; | ||
| 18 | + | ||
| 19 | +import org.onosproject.net.intent.Intent; | ||
| 20 | + | ||
| 21 | +/** | ||
| 22 | + * Submits and withdraws intents to the IntentService from a single point in | ||
| 23 | + * the cluster at any one time. The provided intents will be synchronized with | ||
| 24 | + * the IntentService on leadership change. | ||
| 25 | + */ | ||
| 26 | +public interface IntentSynchronizationService { | ||
| 27 | + | ||
| 28 | + /** | ||
| 29 | + * Submits and intent to the synchronizer. | ||
| 30 | + * <p> | ||
| 31 | + * The intent will be submitted directly to the IntentService if this node | ||
| 32 | + * is the leader, otherwise it will be stored in the synchronizer for | ||
| 33 | + * synchronization if this node becomes the leader. | ||
| 34 | + * </p> | ||
| 35 | + * | ||
| 36 | + * @param intent intent to submit | ||
| 37 | + */ | ||
| 38 | + void submit(Intent intent); | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Withdraws an intent from the synchronizer. | ||
| 42 | + * <p> | ||
| 43 | + * The intent will be withdrawn directly from the IntentService if this node | ||
| 44 | + * is the leader. The intent will be removed from the synchronizer's | ||
| 45 | + * in-memory storage. | ||
| 46 | + * </p> | ||
| 47 | + * | ||
| 48 | + * @param intent intent to withdraw | ||
| 49 | + */ | ||
| 50 | + void withdraw(Intent intent); | ||
| 51 | +} |
| ... | @@ -16,8 +16,6 @@ | ... | @@ -16,8 +16,6 @@ |
| 16 | package org.onosproject.routing; | 16 | package org.onosproject.routing; |
| 17 | 17 | ||
| 18 | import org.onlab.packet.IpAddress; | 18 | import org.onlab.packet.IpAddress; |
| 19 | -import org.onlab.packet.MacAddress; | ||
| 20 | -import org.onosproject.net.ConnectPoint; | ||
| 21 | import org.onosproject.routing.config.BgpConfig; | 19 | import org.onosproject.routing.config.BgpConfig; |
| 22 | 20 | ||
| 23 | import java.util.Collection; | 21 | import java.util.Collection; |
| ... | @@ -32,63 +30,6 @@ public interface RoutingService { | ... | @@ -32,63 +30,6 @@ public interface RoutingService { |
| 32 | Class<BgpConfig> CONFIG_CLASS = BgpConfig.class; | 30 | Class<BgpConfig> CONFIG_CLASS = BgpConfig.class; |
| 33 | 31 | ||
| 34 | /** | 32 | /** |
| 35 | - * Specifies the type of an IP address or an IP prefix location. | ||
| 36 | - */ | ||
| 37 | - enum LocationType { | ||
| 38 | - /** | ||
| 39 | - * The location of an IP address or an IP prefix is in local SDN network. | ||
| 40 | - */ | ||
| 41 | - LOCAL, | ||
| 42 | - /** | ||
| 43 | - * The location of an IP address or an IP prefix is outside local SDN network. | ||
| 44 | - */ | ||
| 45 | - INTERNET, | ||
| 46 | - /** | ||
| 47 | - * There is no route for this IP address or IP prefix. | ||
| 48 | - */ | ||
| 49 | - NO_ROUTE | ||
| 50 | - } | ||
| 51 | - | ||
| 52 | - /** | ||
| 53 | - * Specifies the type of traffic. | ||
| 54 | - * <p> | ||
| 55 | - * We classify traffic by the first packet of each traffic. | ||
| 56 | - * </p> | ||
| 57 | - */ | ||
| 58 | - enum TrafficType { | ||
| 59 | - /** | ||
| 60 | - * Traffic from a host located in local SDN network wants to | ||
| 61 | - * communicate with destination host located in Internet (outside | ||
| 62 | - * local SDN network). | ||
| 63 | - */ | ||
| 64 | - HOST_TO_INTERNET, | ||
| 65 | - /** | ||
| 66 | - * Traffic from Internet wants to communicate with a host located | ||
| 67 | - * in local SDN network. | ||
| 68 | - */ | ||
| 69 | - INTERNET_TO_HOST, | ||
| 70 | - /** | ||
| 71 | - * Both the source host and destination host of a traffic are in | ||
| 72 | - * local SDN network. | ||
| 73 | - */ | ||
| 74 | - HOST_TO_HOST, | ||
| 75 | - /** | ||
| 76 | - * Traffic from Internet wants to traverse local SDN network. | ||
| 77 | - */ | ||
| 78 | - INTERNET_TO_INTERNET, | ||
| 79 | - /** | ||
| 80 | - * Any traffic wants to communicate with a destination which has | ||
| 81 | - * no route, or traffic from Internet wants to access a local private | ||
| 82 | - * IP address. | ||
| 83 | - */ | ||
| 84 | - DROP, | ||
| 85 | - /** | ||
| 86 | - * Traffic does not belong to the types above. | ||
| 87 | - */ | ||
| 88 | - UNKNOWN | ||
| 89 | - } | ||
| 90 | - | ||
| 91 | - /** | ||
| 92 | * Starts the routing service. | 33 | * Starts the routing service. |
| 93 | */ | 34 | */ |
| 94 | void start(); | 35 | void start(); |
| ... | @@ -101,15 +42,6 @@ public interface RoutingService { | ... | @@ -101,15 +42,6 @@ public interface RoutingService { |
| 101 | void addFibListener(FibListener fibListener); | 42 | void addFibListener(FibListener fibListener); |
| 102 | 43 | ||
| 103 | /** | 44 | /** |
| 104 | - * Adds intent creation and submission listener. | ||
| 105 | - * | ||
| 106 | - * @param intentRequestListener listener to send intent creation and | ||
| 107 | - * submission request to | ||
| 108 | - */ | ||
| 109 | - void addIntentRequestListener(IntentRequestListener | ||
| 110 | - intentRequestListener); | ||
| 111 | - | ||
| 112 | - /** | ||
| 113 | * Stops the routing service. | 45 | * Stops the routing service. |
| 114 | */ | 46 | */ |
| 115 | void stop(); | 47 | void stop(); |
| ... | @@ -129,14 +61,6 @@ public interface RoutingService { | ... | @@ -129,14 +61,6 @@ public interface RoutingService { |
| 129 | Collection<RouteEntry> getRoutes6(); | 61 | Collection<RouteEntry> getRoutes6(); |
| 130 | 62 | ||
| 131 | /** | 63 | /** |
| 132 | - * Evaluates the location of an IP address and returns the location type. | ||
| 133 | - * | ||
| 134 | - * @param ipAddress the IP address to evaluate | ||
| 135 | - * @return the IP address location type | ||
| 136 | - */ | ||
| 137 | - LocationType getLocationType(IpAddress ipAddress); | ||
| 138 | - | ||
| 139 | - /** | ||
| 140 | * Finds out the route entry which has the longest matchable IP prefix. | 64 | * Finds out the route entry which has the longest matchable IP prefix. |
| 141 | * | 65 | * |
| 142 | * @param ipAddress IP address used to find out longest matchable IP prefix | 66 | * @param ipAddress IP address used to find out longest matchable IP prefix |
| ... | @@ -145,25 +69,4 @@ public interface RoutingService { | ... | @@ -145,25 +69,4 @@ public interface RoutingService { |
| 145 | */ | 69 | */ |
| 146 | RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress); | 70 | RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress); |
| 147 | 71 | ||
| 148 | - /** | ||
| 149 | - * Finds out the egress connect point where to emit the first packet | ||
| 150 | - * based on destination IP address. | ||
| 151 | - * | ||
| 152 | - * @param dstIpAddress the destination IP address | ||
| 153 | - * @return the egress connect point if found, otherwise null | ||
| 154 | - */ | ||
| 155 | - ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress); | ||
| 156 | - | ||
| 157 | - /** | ||
| 158 | - * Routes packet reactively. | ||
| 159 | - * | ||
| 160 | - * @param dstIpAddress the destination IP address of a packet | ||
| 161 | - * @param srcIpAddress the source IP address of a packet | ||
| 162 | - * @param srcConnectPoint the connect point where a packet comes from | ||
| 163 | - * @param srcMacAddress the source MAC address of a packet | ||
| 164 | - */ | ||
| 165 | - void packetReactiveProcessor(IpAddress dstIpAddress, | ||
| 166 | - IpAddress srcIpAddress, | ||
| 167 | - ConnectPoint srcConnectPoint, | ||
| 168 | - MacAddress srcMacAddress); | ||
| 169 | } | 72 | } | ... | ... |
| ... | @@ -13,7 +13,7 @@ | ... | @@ -13,7 +13,7 @@ |
| 13 | * See the License for the specific language governing permissions and | 13 | * See the License for the specific language governing permissions and |
| 14 | * limitations under the License. | 14 | * limitations under the License. |
| 15 | */ | 15 | */ |
| 16 | -package org.onosproject.sdnip; | 16 | +package org.onosproject.routing; |
| 17 | 17 | ||
| 18 | /** | 18 | /** |
| 19 | * Service interface exported by SDN-IP. | 19 | * Service interface exported by SDN-IP. |
| ... | @@ -28,4 +28,12 @@ public interface SdnIpService { | ... | @@ -28,4 +28,12 @@ public interface SdnIpService { |
| 28 | */ | 28 | */ |
| 29 | void modifyPrimary(boolean isPrimary); | 29 | void modifyPrimary(boolean isPrimary); |
| 30 | 30 | ||
| 31 | + /** | ||
| 32 | + * Gets the intent synchronization service. | ||
| 33 | + * | ||
| 34 | + * @return intent synchronization service | ||
| 35 | + */ | ||
| 36 | + // TODO fix service resolution in SDN-IP | ||
| 37 | + IntentSynchronizationService getIntentSynchronizationService(); | ||
| 38 | + | ||
| 31 | } | 39 | } | ... | ... |
| ... | @@ -35,9 +35,7 @@ import org.onlab.packet.IpAddress; | ... | @@ -35,9 +35,7 @@ import org.onlab.packet.IpAddress; |
| 35 | import org.onlab.packet.IpPrefix; | 35 | import org.onlab.packet.IpPrefix; |
| 36 | import org.onlab.packet.MacAddress; | 36 | import org.onlab.packet.MacAddress; |
| 37 | import org.onosproject.core.CoreService; | 37 | import org.onosproject.core.CoreService; |
| 38 | -import org.onosproject.incubator.net.intf.Interface; | ||
| 39 | import org.onosproject.incubator.net.intf.InterfaceService; | 38 | import org.onosproject.incubator.net.intf.InterfaceService; |
| 40 | -import org.onosproject.net.ConnectPoint; | ||
| 41 | import org.onosproject.net.Host; | 39 | import org.onosproject.net.Host; |
| 42 | import org.onosproject.net.host.HostEvent; | 40 | import org.onosproject.net.host.HostEvent; |
| 43 | import org.onosproject.net.host.HostListener; | 41 | import org.onosproject.net.host.HostListener; |
| ... | @@ -46,7 +44,6 @@ import org.onosproject.routing.BgpService; | ... | @@ -46,7 +44,6 @@ import org.onosproject.routing.BgpService; |
| 46 | import org.onosproject.routing.FibEntry; | 44 | import org.onosproject.routing.FibEntry; |
| 47 | import org.onosproject.routing.FibListener; | 45 | import org.onosproject.routing.FibListener; |
| 48 | import org.onosproject.routing.FibUpdate; | 46 | import org.onosproject.routing.FibUpdate; |
| 49 | -import org.onosproject.routing.IntentRequestListener; | ||
| 50 | import org.onosproject.routing.RouteEntry; | 47 | import org.onosproject.routing.RouteEntry; |
| 51 | import org.onosproject.routing.RouteListener; | 48 | import org.onosproject.routing.RouteListener; |
| 52 | import org.onosproject.routing.RouteUpdate; | 49 | import org.onosproject.routing.RouteUpdate; |
| ... | @@ -61,7 +58,6 @@ import java.util.Iterator; | ... | @@ -61,7 +58,6 @@ import java.util.Iterator; |
| 61 | import java.util.LinkedList; | 58 | import java.util.LinkedList; |
| 62 | import java.util.List; | 59 | import java.util.List; |
| 63 | import java.util.Map; | 60 | import java.util.Map; |
| 64 | -import java.util.Optional; | ||
| 65 | import java.util.Set; | 61 | import java.util.Set; |
| 66 | import java.util.concurrent.BlockingQueue; | 62 | import java.util.concurrent.BlockingQueue; |
| 67 | import java.util.concurrent.ConcurrentHashMap; | 63 | import java.util.concurrent.ConcurrentHashMap; |
| ... | @@ -100,7 +96,6 @@ public class Router implements RoutingService { | ... | @@ -100,7 +96,6 @@ public class Router implements RoutingService { |
| 100 | private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>(); | 96 | private final Map<IpAddress, MacAddress> ip2Mac = new ConcurrentHashMap<>(); |
| 101 | 97 | ||
| 102 | private FibListener fibComponent; | 98 | private FibListener fibComponent; |
| 103 | - private IntentRequestListener intentRequestListener; | ||
| 104 | 99 | ||
| 105 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 100 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
| 106 | protected CoreService coreService; | 101 | protected CoreService coreService; |
| ... | @@ -145,12 +140,6 @@ public class Router implements RoutingService { | ... | @@ -145,12 +140,6 @@ public class Router implements RoutingService { |
| 145 | @Override | 140 | @Override |
| 146 | public void addFibListener(FibListener fibListener) { | 141 | public void addFibListener(FibListener fibListener) { |
| 147 | this.fibComponent = checkNotNull(fibListener); | 142 | this.fibComponent = checkNotNull(fibListener); |
| 148 | - | ||
| 149 | - } | ||
| 150 | - | ||
| 151 | - @Override | ||
| 152 | - public void addIntentRequestListener(IntentRequestListener intentRequestListener) { | ||
| 153 | - this.intentRequestListener = checkNotNull(intentRequestListener); | ||
| 154 | } | 143 | } |
| 155 | 144 | ||
| 156 | @Override | 145 | @Override |
| ... | @@ -287,12 +276,10 @@ public class Router implements RoutingService { | ... | @@ -287,12 +276,10 @@ public class Router implements RoutingService { |
| 287 | void addRibRoute(RouteEntry routeEntry) { | 276 | void addRibRoute(RouteEntry routeEntry) { |
| 288 | if (routeEntry.isIp4()) { | 277 | if (routeEntry.isIp4()) { |
| 289 | // IPv4 | 278 | // IPv4 |
| 290 | - ribTable4.put(createBinaryString(routeEntry.prefix()), | 279 | + ribTable4.put(createBinaryString(routeEntry.prefix()), routeEntry); |
| 291 | - routeEntry); | ||
| 292 | } else { | 280 | } else { |
| 293 | // IPv6 | 281 | // IPv6 |
| 294 | - ribTable6.put(createBinaryString(routeEntry.prefix()), | 282 | + ribTable6.put(createBinaryString(routeEntry.prefix()), routeEntry); |
| 295 | - routeEntry); | ||
| 296 | } | 283 | } |
| 297 | } | 284 | } |
| 298 | 285 | ||
| ... | @@ -553,17 +540,6 @@ public class Router implements RoutingService { | ... | @@ -553,17 +540,6 @@ public class Router implements RoutingService { |
| 553 | } | 540 | } |
| 554 | 541 | ||
| 555 | @Override | 542 | @Override |
| 556 | - public LocationType getLocationType(IpAddress ipAddress) { | ||
| 557 | - if (routingConfigurationService.isIpAddressLocal(ipAddress)) { | ||
| 558 | - return LocationType.LOCAL; | ||
| 559 | - } else if (getLongestMatchableRouteEntry(ipAddress) != null) { | ||
| 560 | - return LocationType.INTERNET; | ||
| 561 | - } else { | ||
| 562 | - return LocationType.NO_ROUTE; | ||
| 563 | - } | ||
| 564 | - } | ||
| 565 | - | ||
| 566 | - @Override | ||
| 567 | public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { | 543 | public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { |
| 568 | RouteEntry routeEntry = null; | 544 | RouteEntry routeEntry = null; |
| 569 | Iterable<RouteEntry> routeEntries; | 545 | Iterable<RouteEntry> routeEntries; |
| ... | @@ -587,142 +563,4 @@ public class Router implements RoutingService { | ... | @@ -587,142 +563,4 @@ public class Router implements RoutingService { |
| 587 | return routeEntry; | 563 | return routeEntry; |
| 588 | } | 564 | } |
| 589 | 565 | ||
| 590 | - @Override | ||
| 591 | - public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) { | ||
| 592 | - LocationType type = getLocationType(dstIpAddress); | ||
| 593 | - if (type == LocationType.LOCAL) { | ||
| 594 | - Set<Host> hosts = hostService.getHostsByIp(dstIpAddress); | ||
| 595 | - if (!hosts.isEmpty()) { | ||
| 596 | - return hosts.iterator().next().location(); | ||
| 597 | - } else { | ||
| 598 | - hostService.startMonitoringIp(dstIpAddress); | ||
| 599 | - return null; | ||
| 600 | - } | ||
| 601 | - } else if (type == LocationType.INTERNET) { | ||
| 602 | - IpAddress nextHopIpAddress = null; | ||
| 603 | - RouteEntry routeEntry = getLongestMatchableRouteEntry(dstIpAddress); | ||
| 604 | - if (routeEntry != null) { | ||
| 605 | - nextHopIpAddress = routeEntry.nextHop(); | ||
| 606 | - Interface it = interfaceService.getMatchingInterface(nextHopIpAddress); | ||
| 607 | - if (it != null) { | ||
| 608 | - return it.connectPoint(); | ||
| 609 | - } else { | ||
| 610 | - return null; | ||
| 611 | - } | ||
| 612 | - } else { | ||
| 613 | - return null; | ||
| 614 | - } | ||
| 615 | - } else { | ||
| 616 | - return null; | ||
| 617 | - } | ||
| 618 | - } | ||
| 619 | - | ||
| 620 | - @Override | ||
| 621 | - public void packetReactiveProcessor(IpAddress dstIpAddress, | ||
| 622 | - IpAddress srcIpAddress, | ||
| 623 | - ConnectPoint srcConnectPoint, | ||
| 624 | - MacAddress srcMacAddress) { | ||
| 625 | - checkNotNull(dstIpAddress); | ||
| 626 | - checkNotNull(srcIpAddress); | ||
| 627 | - checkNotNull(srcConnectPoint); | ||
| 628 | - checkNotNull(srcMacAddress); | ||
| 629 | - | ||
| 630 | - // | ||
| 631 | - // Step1: Try to update the existing intent first if it exists. | ||
| 632 | - // | ||
| 633 | - IpPrefix ipPrefix = null; | ||
| 634 | - if (routingConfigurationService.isIpAddressLocal(dstIpAddress)) { | ||
| 635 | - if (dstIpAddress.isIp4()) { | ||
| 636 | - ipPrefix = IpPrefix.valueOf(dstIpAddress, | ||
| 637 | - Ip4Address.BIT_LENGTH); | ||
| 638 | - } else { | ||
| 639 | - ipPrefix = IpPrefix.valueOf(dstIpAddress, | ||
| 640 | - Ip6Address.BIT_LENGTH); | ||
| 641 | - } | ||
| 642 | - } else { | ||
| 643 | - // Get IP prefix from BGP route table | ||
| 644 | - RouteEntry routeEntry = getLongestMatchableRouteEntry(dstIpAddress); | ||
| 645 | - if (routeEntry != null) { | ||
| 646 | - ipPrefix = routeEntry.prefix(); | ||
| 647 | - } | ||
| 648 | - } | ||
| 649 | - if (ipPrefix != null | ||
| 650 | - && intentRequestListener.mp2pIntentExists(ipPrefix)) { | ||
| 651 | - intentRequestListener.updateExistingMp2pIntent(ipPrefix, | ||
| 652 | - srcConnectPoint); | ||
| 653 | - return; | ||
| 654 | - } | ||
| 655 | - | ||
| 656 | - // | ||
| 657 | - // Step2: There is no existing intent for the destination IP address. | ||
| 658 | - // Check whether it is necessary to create a new one. If necessary then | ||
| 659 | - // create a new one. | ||
| 660 | - // | ||
| 661 | - TrafficType trafficType = | ||
| 662 | - trafficTypeClassifier(srcConnectPoint, dstIpAddress); | ||
| 663 | - | ||
| 664 | - switch (trafficType) { | ||
| 665 | - case HOST_TO_INTERNET: | ||
| 666 | - // If the destination IP address is outside the local SDN network. | ||
| 667 | - // The Step 1 has already handled it. We do not need to do anything here. | ||
| 668 | - break; | ||
| 669 | - case INTERNET_TO_HOST: | ||
| 670 | - intentRequestListener.setUpConnectivityInternetToHost(dstIpAddress); | ||
| 671 | - break; | ||
| 672 | - case HOST_TO_HOST: | ||
| 673 | - intentRequestListener.setUpConnectivityHostToHost(dstIpAddress, | ||
| 674 | - srcIpAddress, srcMacAddress, srcConnectPoint); | ||
| 675 | - break; | ||
| 676 | - case INTERNET_TO_INTERNET: | ||
| 677 | - log.trace("This is transit traffic, " | ||
| 678 | - + "the intent should be preinstalled already"); | ||
| 679 | - break; | ||
| 680 | - case DROP: | ||
| 681 | - // TODO here should setUpDropPaccketIntent(...); | ||
| 682 | - // We need a new type of intent here. | ||
| 683 | - break; | ||
| 684 | - case UNKNOWN: | ||
| 685 | - log.trace("This is unknown traffic, so we do nothing"); | ||
| 686 | - break; | ||
| 687 | - default: | ||
| 688 | - break; | ||
| 689 | - } | ||
| 690 | - } | ||
| 691 | - | ||
| 692 | - /** | ||
| 693 | - * Classifies the traffic and return the traffic type. | ||
| 694 | - * | ||
| 695 | - * @param srcConnectPoint the connect point where the packet comes from | ||
| 696 | - * @param dstIp the destination IP address in packet | ||
| 697 | - * @return the traffic type which this packet belongs to | ||
| 698 | - */ | ||
| 699 | - private TrafficType trafficTypeClassifier(ConnectPoint srcConnectPoint, | ||
| 700 | - IpAddress dstIp) { | ||
| 701 | - LocationType dstIpLocationType = getLocationType(dstIp); | ||
| 702 | - Optional<Interface> srcInterface = | ||
| 703 | - interfaceService.getInterfacesByPort(srcConnectPoint).stream().findFirst(); | ||
| 704 | - | ||
| 705 | - switch (dstIpLocationType) { | ||
| 706 | - case INTERNET: | ||
| 707 | - if (!srcInterface.isPresent()) { | ||
| 708 | - return TrafficType.HOST_TO_INTERNET; | ||
| 709 | - } else { | ||
| 710 | - return TrafficType.INTERNET_TO_INTERNET; | ||
| 711 | - } | ||
| 712 | - case LOCAL: | ||
| 713 | - if (!srcInterface.isPresent()) { | ||
| 714 | - return TrafficType.HOST_TO_HOST; | ||
| 715 | - } else { | ||
| 716 | - // TODO Currently we only consider local public prefixes. | ||
| 717 | - // In the future, we will consider the local private prefixes. | ||
| 718 | - // If dstIpLocationType is a local private, we should return | ||
| 719 | - // TrafficType.DROP. | ||
| 720 | - return TrafficType.INTERNET_TO_HOST; | ||
| 721 | - } | ||
| 722 | - case NO_ROUTE: | ||
| 723 | - return TrafficType.DROP; | ||
| 724 | - default: | ||
| 725 | - return TrafficType.UNKNOWN; | ||
| 726 | - } | ||
| 727 | - } | ||
| 728 | } | 566 | } | ... | ... |
| ... | @@ -18,10 +18,7 @@ package org.onosproject.routing.impl; | ... | @@ -18,10 +18,7 @@ package org.onosproject.routing.impl; |
| 18 | import org.apache.felix.scr.annotations.Component; | 18 | import org.apache.felix.scr.annotations.Component; |
| 19 | import org.apache.felix.scr.annotations.Service; | 19 | import org.apache.felix.scr.annotations.Service; |
| 20 | import org.onlab.packet.IpAddress; | 20 | import org.onlab.packet.IpAddress; |
| 21 | -import org.onlab.packet.MacAddress; | ||
| 22 | -import org.onosproject.net.ConnectPoint; | ||
| 23 | import org.onosproject.routing.FibListener; | 21 | import org.onosproject.routing.FibListener; |
| 24 | -import org.onosproject.routing.IntentRequestListener; | ||
| 25 | import org.onosproject.routing.RouteEntry; | 22 | import org.onosproject.routing.RouteEntry; |
| 26 | import org.onosproject.routing.RoutingService; | 23 | import org.onosproject.routing.RoutingService; |
| 27 | import org.onosproject.routing.StaticRoutingService; | 24 | import org.onosproject.routing.StaticRoutingService; |
| ... | @@ -49,11 +46,6 @@ public class StaticRouter implements RoutingService, StaticRoutingService { | ... | @@ -49,11 +46,6 @@ public class StaticRouter implements RoutingService, StaticRoutingService { |
| 49 | } | 46 | } |
| 50 | 47 | ||
| 51 | @Override | 48 | @Override |
| 52 | - public void addIntentRequestListener(IntentRequestListener intentRequestListener) { | ||
| 53 | - | ||
| 54 | - } | ||
| 55 | - | ||
| 56 | - @Override | ||
| 57 | public void stop() { | 49 | public void stop() { |
| 58 | 50 | ||
| 59 | } | 51 | } |
| ... | @@ -69,27 +61,11 @@ public class StaticRouter implements RoutingService, StaticRoutingService { | ... | @@ -69,27 +61,11 @@ public class StaticRouter implements RoutingService, StaticRoutingService { |
| 69 | } | 61 | } |
| 70 | 62 | ||
| 71 | @Override | 63 | @Override |
| 72 | - public LocationType getLocationType(IpAddress ipAddress) { | ||
| 73 | - return null; | ||
| 74 | - } | ||
| 75 | - | ||
| 76 | - @Override | ||
| 77 | public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { | 64 | public RouteEntry getLongestMatchableRouteEntry(IpAddress ipAddress) { |
| 78 | return null; | 65 | return null; |
| 79 | } | 66 | } |
| 80 | 67 | ||
| 81 | @Override | 68 | @Override |
| 82 | - public ConnectPoint getEgressConnectPoint(IpAddress dstIpAddress) { | ||
| 83 | - return null; | ||
| 84 | - } | ||
| 85 | - | ||
| 86 | - @Override | ||
| 87 | - public void packetReactiveProcessor(IpAddress dstIpAddress, IpAddress srcIpAddress, | ||
| 88 | - ConnectPoint srcConnectPoint, MacAddress srcMacAddress) { | ||
| 89 | - | ||
| 90 | - } | ||
| 91 | - | ||
| 92 | - @Override | ||
| 93 | public FibListener getFibListener() { | 69 | public FibListener getFibListener() { |
| 94 | return fibListener; | 70 | return fibListener; |
| 95 | } | 71 | } | ... | ... |
This diff is collapsed. Click to expand it.
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * 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 | ||
| 7 | + * | ||
| 8 | + * 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. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.sdnip; | ||
| 18 | + | ||
| 19 | +import org.onosproject.net.intent.Intent; | ||
| 20 | +import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
| 21 | +import org.onosproject.net.intent.PointToPointIntent; | ||
| 22 | +import org.slf4j.Logger; | ||
| 23 | +import org.slf4j.LoggerFactory; | ||
| 24 | + | ||
| 25 | +import java.util.Objects; | ||
| 26 | + | ||
| 27 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 28 | + | ||
| 29 | +/** | ||
| 30 | + * Utilities for dealing with intents. | ||
| 31 | + */ | ||
| 32 | +public final class IntentUtils { | ||
| 33 | + | ||
| 34 | + private static final Logger log = LoggerFactory.getLogger(IntentUtils.class); | ||
| 35 | + | ||
| 36 | + private IntentUtils() { | ||
| 37 | + | ||
| 38 | + } | ||
| 39 | + | ||
| 40 | + /** | ||
| 41 | + * Checks if two intents represent the same value. | ||
| 42 | + * | ||
| 43 | + * <p>({@link Intent#equals(Object)} only checks ID equality)</p> | ||
| 44 | + * | ||
| 45 | + * <p>Both intents must be of the same type.</p> | ||
| 46 | + * | ||
| 47 | + * @param one first intent | ||
| 48 | + * @param two second intent | ||
| 49 | + * @return true if the two intents represent the same value, otherwise false | ||
| 50 | + */ | ||
| 51 | + public static boolean equals(Intent one, Intent two) { | ||
| 52 | + checkArgument(one.getClass() == two.getClass(), | ||
| 53 | + "Intents are not the same type"); | ||
| 54 | + | ||
| 55 | + if (!(Objects.equals(one.appId(), two.appId()) && | ||
| 56 | + Objects.equals(one.key(), two.key()))) { | ||
| 57 | + return false; | ||
| 58 | + } | ||
| 59 | + | ||
| 60 | + if (one instanceof MultiPointToSinglePointIntent) { | ||
| 61 | + MultiPointToSinglePointIntent intent1 = (MultiPointToSinglePointIntent) one; | ||
| 62 | + MultiPointToSinglePointIntent intent2 = (MultiPointToSinglePointIntent) two; | ||
| 63 | + | ||
| 64 | + return Objects.equals(intent1.selector(), intent2.selector()) && | ||
| 65 | + Objects.equals(intent1.treatment(), intent2.treatment()) && | ||
| 66 | + Objects.equals(intent1.ingressPoints(), intent2.ingressPoints()) && | ||
| 67 | + Objects.equals(intent1.egressPoint(), intent2.egressPoint()); | ||
| 68 | + } else if (one instanceof PointToPointIntent) { | ||
| 69 | + PointToPointIntent intent1 = (PointToPointIntent) one; | ||
| 70 | + PointToPointIntent intent2 = (PointToPointIntent) two; | ||
| 71 | + | ||
| 72 | + return Objects.equals(intent1.selector(), intent2.selector()) && | ||
| 73 | + Objects.equals(intent1.treatment(), intent2.treatment()) && | ||
| 74 | + Objects.equals(intent1.ingressPoint(), intent2.ingressPoint()) && | ||
| 75 | + Objects.equals(intent1.egressPoint(), intent2.egressPoint()); | ||
| 76 | + } else { | ||
| 77 | + log.error("Unimplemented intent type"); | ||
| 78 | + return false; | ||
| 79 | + } | ||
| 80 | + } | ||
| 81 | +} |
| ... | @@ -15,6 +15,8 @@ | ... | @@ -15,6 +15,8 @@ |
| 15 | */ | 15 | */ |
| 16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
| 17 | 17 | ||
| 18 | +import com.google.common.collect.HashMultimap; | ||
| 19 | +import com.google.common.collect.Multimap; | ||
| 18 | import org.onlab.packet.Ethernet; | 20 | import org.onlab.packet.Ethernet; |
| 19 | import org.onlab.packet.IPv4; | 21 | import org.onlab.packet.IPv4; |
| 20 | import org.onlab.packet.IPv6; | 22 | import org.onlab.packet.IPv6; |
| ... | @@ -22,16 +24,18 @@ import org.onlab.packet.IpAddress; | ... | @@ -22,16 +24,18 @@ import org.onlab.packet.IpAddress; |
| 22 | import org.onlab.packet.IpPrefix; | 24 | import org.onlab.packet.IpPrefix; |
| 23 | import org.onlab.packet.TpPort; | 25 | import org.onlab.packet.TpPort; |
| 24 | import org.onosproject.core.ApplicationId; | 26 | import org.onosproject.core.ApplicationId; |
| 25 | -import org.onosproject.net.config.NetworkConfigService; | ||
| 26 | import org.onosproject.incubator.net.intf.Interface; | 27 | import org.onosproject.incubator.net.intf.Interface; |
| 27 | import org.onosproject.incubator.net.intf.InterfaceService; | 28 | import org.onosproject.incubator.net.intf.InterfaceService; |
| 28 | import org.onosproject.net.ConnectPoint; | 29 | import org.onosproject.net.ConnectPoint; |
| 30 | +import org.onosproject.net.config.NetworkConfigService; | ||
| 29 | import org.onosproject.net.flow.DefaultTrafficSelector; | 31 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 30 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 32 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 31 | import org.onosproject.net.flow.TrafficSelector; | 33 | import org.onosproject.net.flow.TrafficSelector; |
| 32 | import org.onosproject.net.flow.TrafficTreatment; | 34 | import org.onosproject.net.flow.TrafficTreatment; |
| 33 | import org.onosproject.net.host.InterfaceIpAddress; | 35 | import org.onosproject.net.host.InterfaceIpAddress; |
| 36 | +import org.onosproject.net.intent.Key; | ||
| 34 | import org.onosproject.net.intent.PointToPointIntent; | 37 | import org.onosproject.net.intent.PointToPointIntent; |
| 38 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 35 | import org.onosproject.routing.RoutingService; | 39 | import org.onosproject.routing.RoutingService; |
| 36 | import org.onosproject.routing.config.BgpConfig; | 40 | import org.onosproject.routing.config.BgpConfig; |
| 37 | import org.slf4j.Logger; | 41 | import org.slf4j.Logger; |
| ... | @@ -49,18 +53,26 @@ import static com.google.common.base.Preconditions.checkNotNull; | ... | @@ -49,18 +53,26 @@ import static com.google.common.base.Preconditions.checkNotNull; |
| 49 | public class PeerConnectivityManager { | 53 | public class PeerConnectivityManager { |
| 50 | private static final int PRIORITY_OFFSET = 1000; | 54 | private static final int PRIORITY_OFFSET = 1000; |
| 51 | 55 | ||
| 56 | + private static final String SUFFIX_DST = "dst"; | ||
| 57 | + private static final String SUFFIX_SRC = "src"; | ||
| 58 | + private static final String SUFFIX_ICMP = "icmp"; | ||
| 59 | + | ||
| 52 | private static final Logger log = LoggerFactory.getLogger( | 60 | private static final Logger log = LoggerFactory.getLogger( |
| 53 | PeerConnectivityManager.class); | 61 | PeerConnectivityManager.class); |
| 54 | 62 | ||
| 55 | private static final short BGP_PORT = 179; | 63 | private static final short BGP_PORT = 179; |
| 56 | 64 | ||
| 57 | - private final IntentSynchronizer intentSynchronizer; | 65 | + private final IntentSynchronizationService intentSynchronizer; |
| 58 | private final NetworkConfigService configService; | 66 | private final NetworkConfigService configService; |
| 59 | private final InterfaceService interfaceService; | 67 | private final InterfaceService interfaceService; |
| 60 | 68 | ||
| 61 | private final ApplicationId appId; | 69 | private final ApplicationId appId; |
| 62 | private final ApplicationId routerAppId; | 70 | private final ApplicationId routerAppId; |
| 63 | 71 | ||
| 72 | + // Just putting something random here for now. Figure out exactly what | ||
| 73 | + // indexes we need when we start making use of them. | ||
| 74 | + private final Multimap<BgpConfig.BgpSpeakerConfig, PointToPointIntent> peerIntents; | ||
| 75 | + | ||
| 64 | /** | 76 | /** |
| 65 | * Creates a new PeerConnectivityManager. | 77 | * Creates a new PeerConnectivityManager. |
| 66 | * | 78 | * |
| ... | @@ -71,7 +83,7 @@ public class PeerConnectivityManager { | ... | @@ -71,7 +83,7 @@ public class PeerConnectivityManager { |
| 71 | * @param routerAppId application ID | 83 | * @param routerAppId application ID |
| 72 | */ | 84 | */ |
| 73 | public PeerConnectivityManager(ApplicationId appId, | 85 | public PeerConnectivityManager(ApplicationId appId, |
| 74 | - IntentSynchronizer intentSynchronizer, | 86 | + IntentSynchronizationService intentSynchronizer, |
| 75 | NetworkConfigService configService, | 87 | NetworkConfigService configService, |
| 76 | ApplicationId routerAppId, | 88 | ApplicationId routerAppId, |
| 77 | InterfaceService interfaceService) { | 89 | InterfaceService interfaceService) { |
| ... | @@ -80,6 +92,8 @@ public class PeerConnectivityManager { | ... | @@ -80,6 +92,8 @@ public class PeerConnectivityManager { |
| 80 | this.configService = configService; | 92 | this.configService = configService; |
| 81 | this.routerAppId = routerAppId; | 93 | this.routerAppId = routerAppId; |
| 82 | this.interfaceService = interfaceService; | 94 | this.interfaceService = interfaceService; |
| 95 | + | ||
| 96 | + peerIntents = HashMultimap.create(); | ||
| 83 | } | 97 | } |
| 84 | 98 | ||
| 85 | /** | 99 | /** |
| ... | @@ -100,8 +114,6 @@ public class PeerConnectivityManager { | ... | @@ -100,8 +114,6 @@ public class PeerConnectivityManager { |
| 100 | * BGP speakers and external BGP peers. | 114 | * BGP speakers and external BGP peers. |
| 101 | */ | 115 | */ |
| 102 | private void setUpConnectivity() { | 116 | private void setUpConnectivity() { |
| 103 | - List<PointToPointIntent> intents = new ArrayList<>(); | ||
| 104 | - | ||
| 105 | BgpConfig config = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS); | 117 | BgpConfig config = configService.getConfig(routerAppId, RoutingService.CONFIG_CLASS); |
| 106 | 118 | ||
| 107 | if (config == null) { | 119 | if (config == null) { |
| ... | @@ -113,11 +125,12 @@ public class PeerConnectivityManager { | ... | @@ -113,11 +125,12 @@ public class PeerConnectivityManager { |
| 113 | log.debug("Start to set up BGP paths for BGP speaker: {}", | 125 | log.debug("Start to set up BGP paths for BGP speaker: {}", |
| 114 | bgpSpeaker); | 126 | bgpSpeaker); |
| 115 | 127 | ||
| 116 | - intents.addAll(buildSpeakerIntents(bgpSpeaker)); | 128 | + buildSpeakerIntents(bgpSpeaker).forEach(i -> { |
| 117 | - } | 129 | + peerIntents.put(bgpSpeaker, i); |
| 130 | + intentSynchronizer.submit(i); | ||
| 131 | + }); | ||
| 118 | 132 | ||
| 119 | - // Submit all the intents. | 133 | + } |
| 120 | - intentSynchronizer.submitPeerIntents(intents); | ||
| 121 | } | 134 | } |
| 122 | 135 | ||
| 123 | private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) { | 136 | private Collection<PointToPointIntent> buildSpeakerIntents(BgpConfig.BgpSpeakerConfig speaker) { |
| ... | @@ -167,8 +180,8 @@ public class PeerConnectivityManager { | ... | @@ -167,8 +180,8 @@ public class PeerConnectivityManager { |
| 167 | List<PointToPointIntent> intents = new ArrayList<>(); | 180 | List<PointToPointIntent> intents = new ArrayList<>(); |
| 168 | 181 | ||
| 169 | TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); | 182 | TrafficTreatment treatment = DefaultTrafficTreatment.emptyTreatment(); |
| 170 | - | ||
| 171 | TrafficSelector selector; | 183 | TrafficSelector selector; |
| 184 | + Key key; | ||
| 172 | 185 | ||
| 173 | byte tcpProtocol; | 186 | byte tcpProtocol; |
| 174 | byte icmpProtocol; | 187 | byte icmpProtocol; |
| ... | @@ -188,8 +201,11 @@ public class PeerConnectivityManager { | ... | @@ -188,8 +201,11 @@ public class PeerConnectivityManager { |
| 188 | null, | 201 | null, |
| 189 | BGP_PORT); | 202 | BGP_PORT); |
| 190 | 203 | ||
| 204 | + key = buildKey(ipOne, ipTwo, SUFFIX_DST); | ||
| 205 | + | ||
| 191 | intents.add(PointToPointIntent.builder() | 206 | intents.add(PointToPointIntent.builder() |
| 192 | .appId(appId) | 207 | .appId(appId) |
| 208 | + .key(key) | ||
| 193 | .selector(selector) | 209 | .selector(selector) |
| 194 | .treatment(treatment) | 210 | .treatment(treatment) |
| 195 | .ingressPoint(portOne) | 211 | .ingressPoint(portOne) |
| ... | @@ -204,8 +220,11 @@ public class PeerConnectivityManager { | ... | @@ -204,8 +220,11 @@ public class PeerConnectivityManager { |
| 204 | BGP_PORT, | 220 | BGP_PORT, |
| 205 | null); | 221 | null); |
| 206 | 222 | ||
| 223 | + key = buildKey(ipOne, ipTwo, SUFFIX_SRC); | ||
| 224 | + | ||
| 207 | intents.add(PointToPointIntent.builder() | 225 | intents.add(PointToPointIntent.builder() |
| 208 | .appId(appId) | 226 | .appId(appId) |
| 227 | + .key(key) | ||
| 209 | .selector(selector) | 228 | .selector(selector) |
| 210 | .treatment(treatment) | 229 | .treatment(treatment) |
| 211 | .ingressPoint(portOne) | 230 | .ingressPoint(portOne) |
| ... | @@ -220,8 +239,11 @@ public class PeerConnectivityManager { | ... | @@ -220,8 +239,11 @@ public class PeerConnectivityManager { |
| 220 | null, | 239 | null, |
| 221 | BGP_PORT); | 240 | BGP_PORT); |
| 222 | 241 | ||
| 242 | + key = buildKey(ipTwo, ipOne, SUFFIX_DST); | ||
| 243 | + | ||
| 223 | intents.add(PointToPointIntent.builder() | 244 | intents.add(PointToPointIntent.builder() |
| 224 | .appId(appId) | 245 | .appId(appId) |
| 246 | + .key(key) | ||
| 225 | .selector(selector) | 247 | .selector(selector) |
| 226 | .treatment(treatment) | 248 | .treatment(treatment) |
| 227 | .ingressPoint(portTwo) | 249 | .ingressPoint(portTwo) |
| ... | @@ -236,8 +258,11 @@ public class PeerConnectivityManager { | ... | @@ -236,8 +258,11 @@ public class PeerConnectivityManager { |
| 236 | BGP_PORT, | 258 | BGP_PORT, |
| 237 | null); | 259 | null); |
| 238 | 260 | ||
| 261 | + key = buildKey(ipTwo, ipOne, SUFFIX_SRC); | ||
| 262 | + | ||
| 239 | intents.add(PointToPointIntent.builder() | 263 | intents.add(PointToPointIntent.builder() |
| 240 | .appId(appId) | 264 | .appId(appId) |
| 265 | + .key(key) | ||
| 241 | .selector(selector) | 266 | .selector(selector) |
| 242 | .treatment(treatment) | 267 | .treatment(treatment) |
| 243 | .ingressPoint(portTwo) | 268 | .ingressPoint(portTwo) |
| ... | @@ -252,8 +277,11 @@ public class PeerConnectivityManager { | ... | @@ -252,8 +277,11 @@ public class PeerConnectivityManager { |
| 252 | null, | 277 | null, |
| 253 | null); | 278 | null); |
| 254 | 279 | ||
| 280 | + key = buildKey(ipOne, ipTwo, SUFFIX_ICMP); | ||
| 281 | + | ||
| 255 | intents.add(PointToPointIntent.builder() | 282 | intents.add(PointToPointIntent.builder() |
| 256 | .appId(appId) | 283 | .appId(appId) |
| 284 | + .key(key) | ||
| 257 | .selector(selector) | 285 | .selector(selector) |
| 258 | .treatment(treatment) | 286 | .treatment(treatment) |
| 259 | .ingressPoint(portOne) | 287 | .ingressPoint(portOne) |
| ... | @@ -268,8 +296,11 @@ public class PeerConnectivityManager { | ... | @@ -268,8 +296,11 @@ public class PeerConnectivityManager { |
| 268 | null, | 296 | null, |
| 269 | null); | 297 | null); |
| 270 | 298 | ||
| 299 | + key = buildKey(ipTwo, ipOne, SUFFIX_ICMP); | ||
| 300 | + | ||
| 271 | intents.add(PointToPointIntent.builder() | 301 | intents.add(PointToPointIntent.builder() |
| 272 | .appId(appId) | 302 | .appId(appId) |
| 303 | + .key(key) | ||
| 273 | .selector(selector) | 304 | .selector(selector) |
| 274 | .treatment(treatment) | 305 | .treatment(treatment) |
| 275 | .ingressPoint(portTwo) | 306 | .ingressPoint(portTwo) |
| ... | @@ -316,4 +347,27 @@ public class PeerConnectivityManager { | ... | @@ -316,4 +347,27 @@ public class PeerConnectivityManager { |
| 316 | return builder.build(); | 347 | return builder.build(); |
| 317 | } | 348 | } |
| 318 | 349 | ||
| 350 | + /** | ||
| 351 | + * Builds an intent Key for a point-to-point intent based off the source | ||
| 352 | + * and destination IP address, as well as a suffix String to distinguish | ||
| 353 | + * between different types of intents between the same source and | ||
| 354 | + * destination. | ||
| 355 | + * | ||
| 356 | + * @param srcIp source IP address | ||
| 357 | + * @param dstIp destination IP address | ||
| 358 | + * @param suffix suffix string | ||
| 359 | + * @return | ||
| 360 | + */ | ||
| 361 | + private Key buildKey(IpAddress srcIp, IpAddress dstIp, String suffix) { | ||
| 362 | + String keyString = new StringBuilder() | ||
| 363 | + .append(srcIp.toString()) | ||
| 364 | + .append("-") | ||
| 365 | + .append(dstIp.toString()) | ||
| 366 | + .append("-") | ||
| 367 | + .append(suffix) | ||
| 368 | + .toString(); | ||
| 369 | + | ||
| 370 | + return Key.of(keyString, appId); | ||
| 371 | + } | ||
| 372 | + | ||
| 319 | } | 373 | } | ... | ... |
| ... | @@ -32,7 +32,9 @@ import org.onosproject.net.config.NetworkConfigService; | ... | @@ -32,7 +32,9 @@ import org.onosproject.net.config.NetworkConfigService; |
| 32 | import org.onosproject.incubator.net.intf.InterfaceService; | 32 | import org.onosproject.incubator.net.intf.InterfaceService; |
| 33 | import org.onosproject.net.host.HostService; | 33 | import org.onosproject.net.host.HostService; |
| 34 | import org.onosproject.net.intent.IntentService; | 34 | import org.onosproject.net.intent.IntentService; |
| 35 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 35 | import org.onosproject.routing.RoutingService; | 36 | import org.onosproject.routing.RoutingService; |
| 37 | +import org.onosproject.routing.SdnIpService; | ||
| 36 | import org.onosproject.routing.config.RoutingConfigurationService; | 38 | import org.onosproject.routing.config.RoutingConfigurationService; |
| 37 | import org.slf4j.Logger; | 39 | import org.slf4j.Logger; |
| 38 | 40 | ||
| ... | @@ -79,6 +81,7 @@ public class SdnIp implements SdnIpService { | ... | @@ -79,6 +81,7 @@ public class SdnIp implements SdnIpService { |
| 79 | 81 | ||
| 80 | private IntentSynchronizer intentSynchronizer; | 82 | private IntentSynchronizer intentSynchronizer; |
| 81 | private PeerConnectivityManager peerConnectivity; | 83 | private PeerConnectivityManager peerConnectivity; |
| 84 | + private SdnIpFib fib; | ||
| 82 | 85 | ||
| 83 | private LeadershipEventListener leadershipEventListener = | 86 | private LeadershipEventListener leadershipEventListener = |
| 84 | new InnerLeadershipEventListener(); | 87 | new InnerLeadershipEventListener(); |
| ... | @@ -93,10 +96,7 @@ public class SdnIp implements SdnIpService { | ... | @@ -93,10 +96,7 @@ public class SdnIp implements SdnIpService { |
| 93 | 96 | ||
| 94 | localControllerNode = clusterService.getLocalNode(); | 97 | localControllerNode = clusterService.getLocalNode(); |
| 95 | 98 | ||
| 96 | - intentSynchronizer = new IntentSynchronizer(appId, intentService, | 99 | + intentSynchronizer = new IntentSynchronizer(appId, intentService); |
| 97 | - hostService, | ||
| 98 | - config, | ||
| 99 | - interfaceService); | ||
| 100 | intentSynchronizer.start(); | 100 | intentSynchronizer.start(); |
| 101 | 101 | ||
| 102 | peerConnectivity = new PeerConnectivityManager(appId, | 102 | peerConnectivity = new PeerConnectivityManager(appId, |
| ... | @@ -106,8 +106,9 @@ public class SdnIp implements SdnIpService { | ... | @@ -106,8 +106,9 @@ public class SdnIp implements SdnIpService { |
| 106 | interfaceService); | 106 | interfaceService); |
| 107 | peerConnectivity.start(); | 107 | peerConnectivity.start(); |
| 108 | 108 | ||
| 109 | - routingService.addFibListener(intentSynchronizer); | 109 | + fib = new SdnIpFib(appId, interfaceService, intentSynchronizer); |
| 110 | - routingService.addIntentRequestListener(intentSynchronizer); | 110 | + |
| 111 | + routingService.addFibListener(fib); | ||
| 111 | routingService.start(); | 112 | routingService.start(); |
| 112 | 113 | ||
| 113 | leadershipService.addListener(leadershipEventListener); | 114 | leadershipService.addListener(leadershipEventListener); |
| ... | @@ -131,6 +132,11 @@ public class SdnIp implements SdnIpService { | ... | @@ -131,6 +132,11 @@ public class SdnIp implements SdnIpService { |
| 131 | intentSynchronizer.leaderChanged(isPrimary); | 132 | intentSynchronizer.leaderChanged(isPrimary); |
| 132 | } | 133 | } |
| 133 | 134 | ||
| 135 | + @Override | ||
| 136 | + public IntentSynchronizationService getIntentSynchronizationService() { | ||
| 137 | + return intentSynchronizer; | ||
| 138 | + } | ||
| 139 | + | ||
| 134 | /** | 140 | /** |
| 135 | * Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider | 141 | * Converts DPIDs of the form xx:xx:xx:xx:xx:xx:xx to OpenFlow provider |
| 136 | * device URIs. | 142 | * device URIs. | ... | ... |
| 1 | +/* | ||
| 2 | + * Copyright 2015 Open Networking Laboratory | ||
| 3 | + * | ||
| 4 | + * 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 | ||
| 7 | + * | ||
| 8 | + * 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. | ||
| 15 | + */ | ||
| 16 | + | ||
| 17 | +package org.onosproject.sdnip; | ||
| 18 | + | ||
| 19 | +import com.google.common.collect.ImmutableList; | ||
| 20 | +import org.onlab.packet.Ethernet; | ||
| 21 | +import org.onlab.packet.IpAddress; | ||
| 22 | +import org.onlab.packet.IpPrefix; | ||
| 23 | +import org.onlab.packet.MacAddress; | ||
| 24 | +import org.onlab.packet.VlanId; | ||
| 25 | +import org.onosproject.core.ApplicationId; | ||
| 26 | +import org.onosproject.incubator.net.intf.Interface; | ||
| 27 | +import org.onosproject.incubator.net.intf.InterfaceService; | ||
| 28 | +import org.onosproject.net.ConnectPoint; | ||
| 29 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
| 30 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
| 31 | +import org.onosproject.net.flow.TrafficSelector; | ||
| 32 | +import org.onosproject.net.flow.TrafficTreatment; | ||
| 33 | +import org.onosproject.net.intent.Constraint; | ||
| 34 | +import org.onosproject.net.intent.Key; | ||
| 35 | +import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
| 36 | +import org.onosproject.net.intent.constraint.PartialFailureConstraint; | ||
| 37 | +import org.onosproject.routing.FibListener; | ||
| 38 | +import org.onosproject.routing.FibUpdate; | ||
| 39 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 40 | +import org.slf4j.Logger; | ||
| 41 | +import org.slf4j.LoggerFactory; | ||
| 42 | + | ||
| 43 | +import java.util.Collection; | ||
| 44 | +import java.util.HashSet; | ||
| 45 | +import java.util.Map; | ||
| 46 | +import java.util.Set; | ||
| 47 | +import java.util.concurrent.ConcurrentHashMap; | ||
| 48 | + | ||
| 49 | +import static com.google.common.base.Preconditions.checkArgument; | ||
| 50 | + | ||
| 51 | +/** | ||
| 52 | + * FIB component of SDN-IP. | ||
| 53 | + */ | ||
| 54 | +public class SdnIpFib implements FibListener { | ||
| 55 | + private Logger log = LoggerFactory.getLogger(getClass()); | ||
| 56 | + | ||
| 57 | + private static final int PRIORITY_OFFSET = 100; | ||
| 58 | + private static final int PRIORITY_MULTIPLIER = 5; | ||
| 59 | + protected static final ImmutableList<Constraint> CONSTRAINTS | ||
| 60 | + = ImmutableList.of(new PartialFailureConstraint()); | ||
| 61 | + | ||
| 62 | + private final Map<IpPrefix, MultiPointToSinglePointIntent> routeIntents; | ||
| 63 | + | ||
| 64 | + private final ApplicationId appId; | ||
| 65 | + private final InterfaceService interfaceService; | ||
| 66 | + private final IntentSynchronizationService intentSynchronizer; | ||
| 67 | + | ||
| 68 | + /** | ||
| 69 | + * Class constructor. | ||
| 70 | + * | ||
| 71 | + * @param appId application ID to use when generating intents | ||
| 72 | + * @param interfaceService interface service | ||
| 73 | + * @param intentSynchronizer intent synchronizer | ||
| 74 | + */ | ||
| 75 | + public SdnIpFib(ApplicationId appId, InterfaceService interfaceService, | ||
| 76 | + IntentSynchronizationService intentSynchronizer) { | ||
| 77 | + routeIntents = new ConcurrentHashMap<>(); | ||
| 78 | + | ||
| 79 | + this.appId = appId; | ||
| 80 | + this.interfaceService = interfaceService; | ||
| 81 | + this.intentSynchronizer = intentSynchronizer; | ||
| 82 | + } | ||
| 83 | + | ||
| 84 | + | ||
| 85 | + @Override | ||
| 86 | + public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) { | ||
| 87 | + int submitCount = 0, withdrawCount = 0; | ||
| 88 | + // | ||
| 89 | + // NOTE: Semantically, we MUST withdraw existing intents before | ||
| 90 | + // submitting new intents. | ||
| 91 | + // | ||
| 92 | + synchronized (this) { | ||
| 93 | + MultiPointToSinglePointIntent intent; | ||
| 94 | + | ||
| 95 | + // | ||
| 96 | + // Prepare the Intent batch operations for the intents to withdraw | ||
| 97 | + // | ||
| 98 | + for (FibUpdate withdraw : withdraws) { | ||
| 99 | + checkArgument(withdraw.type() == FibUpdate.Type.DELETE, | ||
| 100 | + "FibUpdate with wrong type in withdraws list"); | ||
| 101 | + | ||
| 102 | + IpPrefix prefix = withdraw.entry().prefix(); | ||
| 103 | + intent = routeIntents.remove(prefix); | ||
| 104 | + if (intent == null) { | ||
| 105 | + log.trace("SDN-IP No intent in routeIntents to delete " + | ||
| 106 | + "for prefix: {}", prefix); | ||
| 107 | + continue; | ||
| 108 | + } | ||
| 109 | + intentSynchronizer.withdraw(intent); | ||
| 110 | + withdrawCount++; | ||
| 111 | + } | ||
| 112 | + | ||
| 113 | + // | ||
| 114 | + // Prepare the Intent batch operations for the intents to submit | ||
| 115 | + // | ||
| 116 | + for (FibUpdate update : updates) { | ||
| 117 | + checkArgument(update.type() == FibUpdate.Type.UPDATE, | ||
| 118 | + "FibUpdate with wrong type in updates list"); | ||
| 119 | + | ||
| 120 | + IpPrefix prefix = update.entry().prefix(); | ||
| 121 | + intent = generateRouteIntent(prefix, update.entry().nextHopIp(), | ||
| 122 | + update.entry().nextHopMac()); | ||
| 123 | + | ||
| 124 | + if (intent == null) { | ||
| 125 | + // This preserves the old semantics - if an intent can't be | ||
| 126 | + // generated, we don't do anything with that prefix. But | ||
| 127 | + // perhaps we should withdraw the old intent anyway? | ||
| 128 | + continue; | ||
| 129 | + } | ||
| 130 | + | ||
| 131 | + routeIntents.put(prefix, intent); | ||
| 132 | + intentSynchronizer.submit(intent); | ||
| 133 | + submitCount++; | ||
| 134 | + } | ||
| 135 | + | ||
| 136 | + log.debug("SDN-IP submitted {}/{}, withdrew = {}/{}", submitCount, | ||
| 137 | + updates.size(), withdrawCount, withdraws.size()); | ||
| 138 | + } | ||
| 139 | + } | ||
| 140 | + | ||
| 141 | + /** | ||
| 142 | + * Generates a route intent for a prefix, the next hop IP address, and | ||
| 143 | + * the next hop MAC address. | ||
| 144 | + * <p/> | ||
| 145 | + * This method will find the egress interface for the intent. | ||
| 146 | + * Intent will match dst IP prefix and rewrite dst MAC address at all other | ||
| 147 | + * border switches, then forward packets according to dst MAC address. | ||
| 148 | + * | ||
| 149 | + * @param prefix IP prefix of the route to add | ||
| 150 | + * @param nextHopIpAddress IP address of the next hop | ||
| 151 | + * @param nextHopMacAddress MAC address of the next hop | ||
| 152 | + * @return the generated intent, or null if no intent should be submitted | ||
| 153 | + */ | ||
| 154 | + private MultiPointToSinglePointIntent generateRouteIntent( | ||
| 155 | + IpPrefix prefix, | ||
| 156 | + IpAddress nextHopIpAddress, | ||
| 157 | + MacAddress nextHopMacAddress) { | ||
| 158 | + | ||
| 159 | + // Find the attachment point (egress interface) of the next hop | ||
| 160 | + Interface egressInterface = interfaceService.getMatchingInterface(nextHopIpAddress); | ||
| 161 | + if (egressInterface == null) { | ||
| 162 | + log.warn("No outgoing interface found for {}", | ||
| 163 | + nextHopIpAddress); | ||
| 164 | + return null; | ||
| 165 | + } | ||
| 166 | + | ||
| 167 | + // Generate the intent itself | ||
| 168 | + Set<ConnectPoint> ingressPorts = new HashSet<>(); | ||
| 169 | + ConnectPoint egressPort = egressInterface.connectPoint(); | ||
| 170 | + log.debug("Generating intent for prefix {}, next hop mac {}", | ||
| 171 | + prefix, nextHopMacAddress); | ||
| 172 | + | ||
| 173 | + for (Interface intf : interfaceService.getInterfaces()) { | ||
| 174 | + // TODO this should be only peering interfaces | ||
| 175 | + if (!intf.connectPoint().equals(egressInterface.connectPoint())) { | ||
| 176 | + ConnectPoint srcPort = intf.connectPoint(); | ||
| 177 | + ingressPorts.add(srcPort); | ||
| 178 | + } | ||
| 179 | + } | ||
| 180 | + | ||
| 181 | + // Match the destination IP prefix at the first hop | ||
| 182 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
| 183 | + if (prefix.isIp4()) { | ||
| 184 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
| 185 | + selector.matchIPDst(prefix); | ||
| 186 | + } else { | ||
| 187 | + selector.matchEthType(Ethernet.TYPE_IPV6); | ||
| 188 | + selector.matchIPv6Dst(prefix); | ||
| 189 | + } | ||
| 190 | + | ||
| 191 | + // Rewrite the destination MAC address | ||
| 192 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
| 193 | + .setEthDst(nextHopMacAddress); | ||
| 194 | + if (!egressInterface.vlan().equals(VlanId.NONE)) { | ||
| 195 | + treatment.setVlanId(egressInterface.vlan()); | ||
| 196 | + // If we set VLAN ID, we have to make sure a VLAN tag exists. | ||
| 197 | + // TODO support no VLAN -> VLAN routing | ||
| 198 | + selector.matchVlanId(VlanId.ANY); | ||
| 199 | + } | ||
| 200 | + | ||
| 201 | + int priority = | ||
| 202 | + prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET; | ||
| 203 | + Key key = Key.of(prefix.toString(), appId); | ||
| 204 | + return MultiPointToSinglePointIntent.builder() | ||
| 205 | + .appId(appId) | ||
| 206 | + .key(key) | ||
| 207 | + .selector(selector.build()) | ||
| 208 | + .treatment(treatment.build()) | ||
| 209 | + .ingressPoints(ingressPorts) | ||
| 210 | + .egressPoint(egressPort) | ||
| 211 | + .priority(priority) | ||
| 212 | + .constraints(CONSTRAINTS) | ||
| 213 | + .build(); | ||
| 214 | + } | ||
| 215 | + | ||
| 216 | +} |
| ... | @@ -18,7 +18,7 @@ package org.onosproject.sdnip.cli; | ... | @@ -18,7 +18,7 @@ package org.onosproject.sdnip.cli; |
| 18 | import org.apache.karaf.shell.commands.Argument; | 18 | import org.apache.karaf.shell.commands.Argument; |
| 19 | import org.apache.karaf.shell.commands.Command; | 19 | import org.apache.karaf.shell.commands.Command; |
| 20 | import org.onosproject.cli.AbstractShellCommand; | 20 | import org.onosproject.cli.AbstractShellCommand; |
| 21 | -import org.onosproject.sdnip.SdnIpService; | 21 | +import org.onosproject.routing.SdnIpService; |
| 22 | 22 | ||
| 23 | /** | 23 | /** |
| 24 | * Command to change whether this SDNIP instance is primary or not. | 24 | * Command to change whether this SDNIP instance is primary or not. | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -19,7 +19,6 @@ import com.google.common.collect.Sets; | ... | @@ -19,7 +19,6 @@ import com.google.common.collect.Sets; |
| 19 | import org.junit.Before; | 19 | import org.junit.Before; |
| 20 | import org.junit.Ignore; | 20 | import org.junit.Ignore; |
| 21 | import org.junit.Test; | 21 | import org.junit.Test; |
| 22 | -import org.onlab.junit.TestUtils; | ||
| 23 | import org.onlab.junit.TestUtils.TestUtilsException; | 22 | import org.onlab.junit.TestUtils.TestUtilsException; |
| 24 | import org.onlab.packet.Ethernet; | 23 | import org.onlab.packet.Ethernet; |
| 25 | import org.onlab.packet.IPv4; | 24 | import org.onlab.packet.IPv4; |
| ... | @@ -28,13 +27,14 @@ import org.onlab.packet.IpPrefix; | ... | @@ -28,13 +27,14 @@ import org.onlab.packet.IpPrefix; |
| 28 | import org.onlab.packet.MacAddress; | 27 | import org.onlab.packet.MacAddress; |
| 29 | import org.onlab.packet.TpPort; | 28 | import org.onlab.packet.TpPort; |
| 30 | import org.onlab.packet.VlanId; | 29 | import org.onlab.packet.VlanId; |
| 30 | +import org.onosproject.TestApplicationId; | ||
| 31 | import org.onosproject.core.ApplicationId; | 31 | import org.onosproject.core.ApplicationId; |
| 32 | -import org.onosproject.net.config.NetworkConfigService; | ||
| 33 | import org.onosproject.incubator.net.intf.Interface; | 32 | import org.onosproject.incubator.net.intf.Interface; |
| 34 | import org.onosproject.incubator.net.intf.InterfaceService; | 33 | import org.onosproject.incubator.net.intf.InterfaceService; |
| 35 | import org.onosproject.net.ConnectPoint; | 34 | import org.onosproject.net.ConnectPoint; |
| 36 | import org.onosproject.net.DeviceId; | 35 | import org.onosproject.net.DeviceId; |
| 37 | import org.onosproject.net.PortNumber; | 36 | import org.onosproject.net.PortNumber; |
| 37 | +import org.onosproject.net.config.NetworkConfigService; | ||
| 38 | import org.onosproject.net.flow.DefaultTrafficSelector; | 38 | import org.onosproject.net.flow.DefaultTrafficSelector; |
| 39 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 39 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
| 40 | import org.onosproject.net.flow.TrafficSelector; | 40 | import org.onosproject.net.flow.TrafficSelector; |
| ... | @@ -42,8 +42,9 @@ import org.onosproject.net.flow.TrafficTreatment; | ... | @@ -42,8 +42,9 @@ import org.onosproject.net.flow.TrafficTreatment; |
| 42 | import org.onosproject.net.host.InterfaceIpAddress; | 42 | import org.onosproject.net.host.InterfaceIpAddress; |
| 43 | import org.onosproject.net.intent.AbstractIntentTest; | 43 | import org.onosproject.net.intent.AbstractIntentTest; |
| 44 | import org.onosproject.net.intent.Intent; | 44 | import org.onosproject.net.intent.Intent; |
| 45 | -import org.onosproject.net.intent.IntentService; | 45 | +import org.onosproject.net.intent.Key; |
| 46 | import org.onosproject.net.intent.PointToPointIntent; | 46 | import org.onosproject.net.intent.PointToPointIntent; |
| 47 | +import org.onosproject.routing.IntentSynchronizationService; | ||
| 47 | import org.onosproject.routing.config.BgpConfig; | 48 | import org.onosproject.routing.config.BgpConfig; |
| 48 | import org.onosproject.routing.config.BgpPeer; | 49 | import org.onosproject.routing.config.BgpPeer; |
| 49 | import org.onosproject.routing.config.BgpSpeaker; | 50 | import org.onosproject.routing.config.BgpSpeaker; |
| ... | @@ -71,26 +72,15 @@ import static org.onosproject.sdnip.TestIntentServiceHelper.eqExceptId; | ... | @@ -71,26 +72,15 @@ import static org.onosproject.sdnip.TestIntentServiceHelper.eqExceptId; |
| 71 | */ | 72 | */ |
| 72 | public class PeerConnectivityManagerTest extends AbstractIntentTest { | 73 | public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 73 | 74 | ||
| 74 | - private static final ApplicationId APPID = new ApplicationId() { | 75 | + private static final ApplicationId APPID = TestApplicationId.create("foo"); |
| 75 | - @Override | ||
| 76 | - public short id() { | ||
| 77 | - return 0; | ||
| 78 | - } | ||
| 79 | - | ||
| 80 | - @Override | ||
| 81 | - public String name() { | ||
| 82 | - return "foo"; | ||
| 83 | - } | ||
| 84 | - }; | ||
| 85 | 76 | ||
| 86 | private static final ApplicationId CONFIG_APP_ID = APPID; | 77 | private static final ApplicationId CONFIG_APP_ID = APPID; |
| 87 | 78 | ||
| 88 | private PeerConnectivityManager peerConnectivityManager; | 79 | private PeerConnectivityManager peerConnectivityManager; |
| 89 | - private IntentSynchronizer intentSynchronizer; | 80 | + private IntentSynchronizationService intentSynchronizer; |
| 90 | private RoutingConfigurationService routingConfig; | 81 | private RoutingConfigurationService routingConfig; |
| 91 | private InterfaceService interfaceService; | 82 | private InterfaceService interfaceService; |
| 92 | private NetworkConfigService networkConfigService; | 83 | private NetworkConfigService networkConfigService; |
| 93 | - private IntentService intentService; | ||
| 94 | 84 | ||
| 95 | private Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers; | 85 | private Set<BgpConfig.BgpSpeakerConfig> bgpSpeakers; |
| 96 | private Map<String, Interface> interfaces; | 86 | private Map<String, Interface> interfaces; |
| ... | @@ -98,8 +88,6 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -98,8 +88,6 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 98 | 88 | ||
| 99 | private BgpConfig bgpConfig; | 89 | private BgpConfig bgpConfig; |
| 100 | 90 | ||
| 101 | - private Map<String, Interface> configuredInterfaces; | ||
| 102 | - private Map<IpAddress, BgpPeer> configuredPeers; | ||
| 103 | private List<PointToPointIntent> intentList; | 91 | private List<PointToPointIntent> intentList; |
| 104 | 92 | ||
| 105 | private final String dpid1 = "00:00:00:00:00:00:00:01"; | 93 | private final String dpid1 = "00:00:00:00:00:00:00:01"; |
| ... | @@ -136,7 +124,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -136,7 +124,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 136 | // These will set expectations on routingConfig and interfaceService | 124 | // These will set expectations on routingConfig and interfaceService |
| 137 | bgpSpeakers = setUpBgpSpeakers(); | 125 | bgpSpeakers = setUpBgpSpeakers(); |
| 138 | interfaces = Collections.unmodifiableMap(setUpInterfaces()); | 126 | interfaces = Collections.unmodifiableMap(setUpInterfaces()); |
| 139 | - peers = Collections.unmodifiableMap(setUpPeers()); | 127 | + peers = setUpPeers(); |
| 140 | 128 | ||
| 141 | initPeerConnectivity(); | 129 | initPeerConnectivity(); |
| 142 | intentList = setUpIntentList(); | 130 | intentList = setUpIntentList(); |
| ... | @@ -169,11 +157,11 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -169,11 +157,11 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 169 | * Sets up logical interfaces, which emulate the configured interfaces | 157 | * Sets up logical interfaces, which emulate the configured interfaces |
| 170 | * in SDN-IP application. | 158 | * in SDN-IP application. |
| 171 | * | 159 | * |
| 172 | - * @return configured interfaces as a MAP from Interface name to Interface | 160 | + * @return configured interfaces as a map from interface name to Interface |
| 173 | */ | 161 | */ |
| 174 | private Map<String, Interface> setUpInterfaces() { | 162 | private Map<String, Interface> setUpInterfaces() { |
| 175 | 163 | ||
| 176 | - configuredInterfaces = new HashMap<>(); | 164 | + Map<String, Interface> configuredInterfaces = new HashMap<>(); |
| 177 | 165 | ||
| 178 | String interfaceSw1Eth1 = "s1-eth1"; | 166 | String interfaceSw1Eth1 = "s1-eth1"; |
| 179 | InterfaceIpAddress ia1 = | 167 | InterfaceIpAddress ia1 = |
| ... | @@ -242,7 +230,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -242,7 +230,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 242 | */ | 230 | */ |
| 243 | private Map<IpAddress, BgpPeer> setUpPeers() { | 231 | private Map<IpAddress, BgpPeer> setUpPeers() { |
| 244 | 232 | ||
| 245 | - configuredPeers = new HashMap<>(); | 233 | + Map<IpAddress, BgpPeer> configuredPeers = new HashMap<>(); |
| 246 | 234 | ||
| 247 | String peerSw1Eth1 = "192.168.10.1"; | 235 | String peerSw1Eth1 = "192.168.10.1"; |
| 248 | configuredPeers.put(IpAddress.valueOf(peerSw1Eth1), | 236 | configuredPeers.put(IpAddress.valueOf(peerSw1Eth1), |
| ... | @@ -266,14 +254,12 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -266,14 +254,12 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 266 | * @return point to point intent list | 254 | * @return point to point intent list |
| 267 | */ | 255 | */ |
| 268 | private List<PointToPointIntent> setUpIntentList() { | 256 | private List<PointToPointIntent> setUpIntentList() { |
| 269 | - | ||
| 270 | intentList = new ArrayList<>(); | 257 | intentList = new ArrayList<>(); |
| 271 | 258 | ||
| 272 | setUpBgpIntents(); | 259 | setUpBgpIntents(); |
| 273 | setUpIcmpIntents(); | 260 | setUpIcmpIntents(); |
| 274 | 261 | ||
| 275 | return intentList; | 262 | return intentList; |
| 276 | - | ||
| 277 | } | 263 | } |
| 278 | 264 | ||
| 279 | /** | 265 | /** |
| ... | @@ -306,8 +292,12 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -306,8 +292,12 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 306 | builder.matchTcpDst(TpPort.tpPort(dstTcpPort)); | 292 | builder.matchTcpDst(TpPort.tpPort(dstTcpPort)); |
| 307 | } | 293 | } |
| 308 | 294 | ||
| 295 | + Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0] | ||
| 296 | + + "-" + ((srcTcpPort == null) ? "dst" : "src"), APPID); | ||
| 297 | + | ||
| 309 | PointToPointIntent intent = PointToPointIntent.builder() | 298 | PointToPointIntent intent = PointToPointIntent.builder() |
| 310 | .appId(APPID) | 299 | .appId(APPID) |
| 300 | + .key(key) | ||
| 311 | .selector(builder.build()) | 301 | .selector(builder.build()) |
| 312 | .treatment(noTreatment) | 302 | .treatment(noTreatment) |
| 313 | .ingressPoint(srcConnectPoint) | 303 | .ingressPoint(srcConnectPoint) |
| ... | @@ -392,8 +382,12 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -392,8 +382,12 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 392 | .matchIPDst(IpPrefix.valueOf(dstPrefix)) | 382 | .matchIPDst(IpPrefix.valueOf(dstPrefix)) |
| 393 | .build(); | 383 | .build(); |
| 394 | 384 | ||
| 385 | + Key key = Key.of(srcPrefix.split("/")[0] + "-" + dstPrefix.split("/")[0] | ||
| 386 | + + "-" + "icmp", APPID); | ||
| 387 | + | ||
| 395 | PointToPointIntent intent = PointToPointIntent.builder() | 388 | PointToPointIntent intent = PointToPointIntent.builder() |
| 396 | .appId(APPID) | 389 | .appId(APPID) |
| 390 | + .key(key) | ||
| 397 | .selector(selector) | 391 | .selector(selector) |
| 398 | .treatment(noTreatment) | 392 | .treatment(noTreatment) |
| 399 | .ingressPoint(srcConnectPoint) | 393 | .ingressPoint(srcConnectPoint) |
| ... | @@ -434,19 +428,14 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -434,19 +428,14 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 434 | expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes(); | 428 | expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes(); |
| 435 | expect(bgpConfig.bgpSpeakers()).andReturn(bgpSpeakers).anyTimes(); | 429 | expect(bgpConfig.bgpSpeakers()).andReturn(bgpSpeakers).anyTimes(); |
| 436 | replay(bgpConfig); | 430 | replay(bgpConfig); |
| 437 | - expect(networkConfigService.getConfig(APPID, BgpConfig.class)).andReturn(bgpConfig).anyTimes(); | 431 | + expect(networkConfigService.getConfig(APPID, BgpConfig.class)) |
| 432 | + .andReturn(bgpConfig).anyTimes(); | ||
| 438 | replay(networkConfigService); | 433 | replay(networkConfigService); |
| 439 | replay(routingConfig); | 434 | replay(routingConfig); |
| 440 | replay(interfaceService); | 435 | replay(interfaceService); |
| 441 | 436 | ||
| 442 | - intentService = createMock(IntentService.class); | 437 | + intentSynchronizer = createMock(IntentSynchronizationService.class); |
| 443 | - replay(intentService); | 438 | + replay(intentSynchronizer); |
| 444 | - | ||
| 445 | - intentSynchronizer = new IntentSynchronizer(APPID, intentService, | ||
| 446 | - null, routingConfig, | ||
| 447 | - interfaceService); | ||
| 448 | - intentSynchronizer.leaderChanged(true); | ||
| 449 | - TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | ||
| 450 | 439 | ||
| 451 | peerConnectivityManager = | 440 | peerConnectivityManager = |
| 452 | new PeerConnectivityManager(APPID, intentSynchronizer, | 441 | new PeerConnectivityManager(APPID, intentSynchronizer, |
| ... | @@ -464,20 +453,18 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -464,20 +453,18 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 464 | */ | 453 | */ |
| 465 | @Test | 454 | @Test |
| 466 | public void testConnectionSetup() { | 455 | public void testConnectionSetup() { |
| 467 | - | 456 | + reset(intentSynchronizer); |
| 468 | - reset(intentService); | ||
| 469 | 457 | ||
| 470 | // Setup the expected intents | 458 | // Setup the expected intents |
| 471 | for (Intent intent : intentList) { | 459 | for (Intent intent : intentList) { |
| 472 | - intentService.submit(eqExceptId(intent)); | 460 | + intentSynchronizer.submit(eqExceptId(intent)); |
| 473 | } | 461 | } |
| 474 | - replay(intentService); | 462 | + replay(intentSynchronizer); |
| 475 | 463 | ||
| 476 | // Running the interface to be tested. | 464 | // Running the interface to be tested. |
| 477 | peerConnectivityManager.start(); | 465 | peerConnectivityManager.start(); |
| 478 | 466 | ||
| 479 | - verify(intentService); | 467 | + verify(intentSynchronizer); |
| 480 | - | ||
| 481 | } | 468 | } |
| 482 | 469 | ||
| 483 | /** | 470 | /** |
| ... | @@ -488,7 +475,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -488,7 +475,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 488 | reset(interfaceService); | 475 | reset(interfaceService); |
| 489 | 476 | ||
| 490 | expect(interfaceService.getInterfaces()).andReturn( | 477 | expect(interfaceService.getInterfaces()).andReturn( |
| 491 | - Sets.<Interface>newHashSet()).anyTimes(); | 478 | + Sets.newHashSet()).anyTimes(); |
| 492 | expect(interfaceService.getInterfacesByPort(s2Eth1)) | 479 | expect(interfaceService.getInterfacesByPort(s2Eth1)) |
| 493 | .andReturn(Collections.emptySet()).anyTimes(); | 480 | .andReturn(Collections.emptySet()).anyTimes(); |
| 494 | expect(interfaceService.getInterfacesByPort(s1Eth1)) | 481 | expect(interfaceService.getInterfacesByPort(s1Eth1)) |
| ... | @@ -508,10 +495,10 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -508,10 +495,10 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 508 | 495 | ||
| 509 | replay(interfaceService); | 496 | replay(interfaceService); |
| 510 | 497 | ||
| 511 | - reset(intentService); | 498 | + reset(intentSynchronizer); |
| 512 | - replay(intentService); | 499 | + replay(intentSynchronizer); |
| 513 | peerConnectivityManager.start(); | 500 | peerConnectivityManager.start(); |
| 514 | - verify(intentService); | 501 | + verify(intentSynchronizer); |
| 515 | } | 502 | } |
| 516 | 503 | ||
| 517 | /** | 504 | /** |
| ... | @@ -527,10 +514,10 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -527,10 +514,10 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 527 | expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes(); | 514 | expect(routingConfig.getBgpPeers()).andReturn(peers).anyTimes(); |
| 528 | replay(routingConfig); | 515 | replay(routingConfig); |
| 529 | 516 | ||
| 530 | - reset(intentService); | 517 | + reset(intentSynchronizer); |
| 531 | - replay(intentService); | 518 | + replay(intentSynchronizer); |
| 532 | peerConnectivityManager.start(); | 519 | peerConnectivityManager.start(); |
| 533 | - verify(intentService); | 520 | + verify(intentSynchronizer); |
| 534 | } | 521 | } |
| 535 | 522 | ||
| 536 | /** | 523 | /** |
| ... | @@ -540,7 +527,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -540,7 +527,7 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
| 540 | @Test | 527 | @Test |
| 541 | public void testNoPeerInterface() { | 528 | public void testNoPeerInterface() { |
| 542 | String peerSw100Eth1 = "192.168.200.1"; | 529 | String peerSw100Eth1 = "192.168.200.1"; |
| 543 | - configuredPeers.put(IpAddress.valueOf(peerSw100Eth1), | 530 | + peers.put(IpAddress.valueOf(peerSw100Eth1), |
| 544 | new BgpPeer("00:00:00:00:00:00:01:00", 1, peerSw100Eth1)); | 531 | new BgpPeer("00:00:00:00:00:00:01:00", 1, peerSw100Eth1)); |
| 545 | testConnectionSetup(); | 532 | testConnectionSetup(); |
| 546 | } | 533 | } | ... | ... |
This diff is collapsed. Click to expand it.
| ... | @@ -17,7 +17,6 @@ package org.onosproject.sdnip; | ... | @@ -17,7 +17,6 @@ package org.onosproject.sdnip; |
| 17 | 17 | ||
| 18 | import org.easymock.IArgumentMatcher; | 18 | import org.easymock.IArgumentMatcher; |
| 19 | import org.onosproject.net.intent.Intent; | 19 | import org.onosproject.net.intent.Intent; |
| 20 | -import org.onosproject.sdnip.IntentSynchronizer.IntentKey; | ||
| 21 | 20 | ||
| 22 | import static org.easymock.EasyMock.reportMatcher; | 21 | import static org.easymock.EasyMock.reportMatcher; |
| 23 | 22 | ||
| ... | @@ -53,8 +52,6 @@ public final class TestIntentServiceHelper { | ... | @@ -53,8 +52,6 @@ public final class TestIntentServiceHelper { |
| 53 | * the solution is to use an EasyMock matcher that verifies that all the | 52 | * the solution is to use an EasyMock matcher that verifies that all the |
| 54 | * value properties of the provided intent match the expected values, but | 53 | * value properties of the provided intent match the expected values, but |
| 55 | * ignores the intent ID when testing equality. | 54 | * ignores the intent ID when testing equality. |
| 56 | - * | ||
| 57 | - * FIXME this currently does not take key into account | ||
| 58 | */ | 55 | */ |
| 59 | private static final class IdAgnosticIntentMatcher implements | 56 | private static final class IdAgnosticIntentMatcher implements |
| 60 | IArgumentMatcher { | 57 | IArgumentMatcher { |
| ... | @@ -86,9 +83,7 @@ public final class TestIntentServiceHelper { | ... | @@ -86,9 +83,7 @@ public final class TestIntentServiceHelper { |
| 86 | Intent providedIntent = (Intent) object; | 83 | Intent providedIntent = (Intent) object; |
| 87 | providedString = providedIntent.toString(); | 84 | providedString = providedIntent.toString(); |
| 88 | 85 | ||
| 89 | - IntentKey thisIntentKey = new IntentKey(intent); | 86 | + return IntentUtils.equals(intent, providedIntent); |
| 90 | - IntentKey providedIntentKey = new IntentKey(providedIntent); | ||
| 91 | - return thisIntentKey.equals(providedIntentKey); | ||
| 92 | } | 87 | } |
| 93 | } | 88 | } |
| 94 | 89 | ... | ... |
| ... | @@ -521,7 +521,7 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -521,7 +521,7 @@ public class EventuallyConsistentMapImpl<K, V> |
| 521 | return; | 521 | return; |
| 522 | } | 522 | } |
| 523 | peers.forEach(node -> | 523 | peers.forEach(node -> |
| 524 | - senderPending.computeIfAbsent(node, unusedKey -> new EventAccumulator(node)).add(event) | 524 | + senderPending.computeIfAbsent(node, unusedKey -> new EventAccumulator(node)).add(event) |
| 525 | ); | 525 | ); |
| 526 | } | 526 | } |
| 527 | 527 | ||
| ... | @@ -574,8 +574,10 @@ public class EventuallyConsistentMapImpl<K, V> | ... | @@ -574,8 +574,10 @@ public class EventuallyConsistentMapImpl<K, V> |
| 574 | return; | 574 | return; |
| 575 | } | 575 | } |
| 576 | try { | 576 | try { |
| 577 | - log.debug("Received anti-entropy advertisement from {} for {} with {} entries in it", | 577 | + if (log.isTraceEnabled()) { |
| 578 | - mapName, ad.sender(), ad.digest().size()); | 578 | + log.trace("Received anti-entropy advertisement from {} for {} with {} entries in it", |
| 579 | + mapName, ad.sender(), ad.digest().size()); | ||
| 580 | + } | ||
| 579 | antiEntropyCheckLocalItems(ad).forEach(this::notifyListeners); | 581 | antiEntropyCheckLocalItems(ad).forEach(this::notifyListeners); |
| 580 | 582 | ||
| 581 | if (!lightweightAntiEntropy) { | 583 | if (!lightweightAntiEntropy) { | ... | ... |
-
Please register or login to post a comment