Create a formal interface between the RIB and FIB.
* IntentSynchronizer implements a more generalized FibListener interface * Updates to the FIB are signalled with FibUpdate to any FibListeners * generateRouteIntent logic has been pushed down into the IntentSynchronizer Change-Id: I6f0ccfd52ee4e16ce9974af5ee549d4ede6c2d0e
Showing
11 changed files
with
452 additions
and
304 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 | +package org.onosproject.sdnip; | ||
17 | + | ||
18 | +import org.onlab.packet.IpAddress; | ||
19 | +import org.onlab.packet.IpPrefix; | ||
20 | +import org.onlab.packet.MacAddress; | ||
21 | + | ||
22 | +/** | ||
23 | + * An entry in the Forwarding Information Base (FIB). | ||
24 | + */ | ||
25 | +public class FibEntry { | ||
26 | + | ||
27 | + private final IpPrefix prefix; | ||
28 | + private final IpAddress nextHopIp; | ||
29 | + private final MacAddress nextHopMac; | ||
30 | + | ||
31 | + /** | ||
32 | + * Creates a new FIB entry. | ||
33 | + * | ||
34 | + * @param prefix IP prefix of the FIB entry | ||
35 | + * @param nextHopIp IP address of the next hop | ||
36 | + * @param nextHopMac MAC address of the next hop | ||
37 | + */ | ||
38 | + public FibEntry(IpPrefix prefix, IpAddress nextHopIp, MacAddress nextHopMac) { | ||
39 | + this.prefix = prefix; | ||
40 | + this.nextHopIp = nextHopIp; | ||
41 | + this.nextHopMac = nextHopMac; | ||
42 | + } | ||
43 | + | ||
44 | + /** | ||
45 | + * Returns the IP prefix of the FIB entry. | ||
46 | + * | ||
47 | + * @return the IP prefix | ||
48 | + */ | ||
49 | + public IpPrefix prefix() { | ||
50 | + return prefix; | ||
51 | + } | ||
52 | + | ||
53 | + /** | ||
54 | + * Returns the IP address of the next hop. | ||
55 | + * | ||
56 | + * @return the IP address | ||
57 | + */ | ||
58 | + public IpAddress nextHopIp() { | ||
59 | + return nextHopIp; | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * Returns the MAC address of the next hop. | ||
64 | + * | ||
65 | + * @return the MAC address | ||
66 | + */ | ||
67 | + public MacAddress nextHopMac() { | ||
68 | + return nextHopMac; | ||
69 | + } | ||
70 | +} |
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 | +package org.onosproject.sdnip; | ||
17 | + | ||
18 | +import java.util.Collection; | ||
19 | + | ||
20 | +/** | ||
21 | + * A component that is able to process Forwarding Information Base (FIB) updates. | ||
22 | + */ | ||
23 | +public interface FibListener { | ||
24 | + | ||
25 | + /** | ||
26 | + * Signals the FIB component of changes to the FIB. | ||
27 | + * | ||
28 | + * @param updates FIB updates of the UDPATE type | ||
29 | + * @param withdraws FIB updates of the WITHDRAW type | ||
30 | + */ | ||
31 | + // TODO this interface should use only one collection when we have the new | ||
32 | + // intent key API | ||
33 | + void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws); | ||
34 | + | ||
35 | +} |
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 | +package org.onosproject.sdnip; | ||
17 | + | ||
18 | +/** | ||
19 | + * Represents a change to the Forwarding Information Base (FIB). | ||
20 | + */ | ||
21 | +public class FibUpdate { | ||
22 | + | ||
23 | + /** | ||
24 | + * Specifies the type of the FIB update. | ||
25 | + */ | ||
26 | + public enum Type { | ||
27 | + /** | ||
28 | + * The update contains a new or updated FIB entry for a prefix. | ||
29 | + */ | ||
30 | + UPDATE, | ||
31 | + | ||
32 | + /** | ||
33 | + * The update signals that a prefix should be removed from the FIB. | ||
34 | + */ | ||
35 | + DELETE | ||
36 | + } | ||
37 | + | ||
38 | + private final Type type; | ||
39 | + private final FibEntry entry; | ||
40 | + | ||
41 | + /** | ||
42 | + * Creates a new FIB update. | ||
43 | + * | ||
44 | + * @param type type of the update | ||
45 | + * @param entry FIB entry describing the update | ||
46 | + */ | ||
47 | + public FibUpdate(Type type, FibEntry entry) { | ||
48 | + this.type = type; | ||
49 | + this.entry = entry; | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * Returns the type of the update. | ||
54 | + * | ||
55 | + * @return update type | ||
56 | + */ | ||
57 | + public Type type() { | ||
58 | + return type; | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Returns the FIB entry which contains update information. | ||
63 | + * | ||
64 | + * @return the FIB entry | ||
65 | + */ | ||
66 | + public FibEntry entry() { | ||
67 | + return entry; | ||
68 | + } | ||
69 | +} |
... | @@ -15,22 +15,19 @@ | ... | @@ -15,22 +15,19 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static com.google.common.base.Preconditions.checkArgument; | 18 | +import com.google.common.util.concurrent.ThreadFactoryBuilder; |
19 | - | 19 | +import org.onlab.packet.Ethernet; |
20 | -import java.util.Collection; | 20 | +import org.onlab.packet.Ip4Address; |
21 | -import java.util.HashMap; | 21 | +import org.onlab.packet.IpAddress; |
22 | -import java.util.LinkedList; | ||
23 | -import java.util.List; | ||
24 | -import java.util.Map; | ||
25 | -import java.util.Objects; | ||
26 | -import java.util.concurrent.ConcurrentHashMap; | ||
27 | -import java.util.concurrent.ExecutorService; | ||
28 | -import java.util.concurrent.Executors; | ||
29 | -import java.util.concurrent.Semaphore; | ||
30 | - | ||
31 | -import org.apache.commons.lang3.tuple.Pair; | ||
32 | import org.onlab.packet.IpPrefix; | 22 | import org.onlab.packet.IpPrefix; |
23 | +import org.onlab.packet.MacAddress; | ||
24 | +import org.onlab.packet.VlanId; | ||
33 | import org.onosproject.core.ApplicationId; | 25 | import org.onosproject.core.ApplicationId; |
26 | +import org.onosproject.net.ConnectPoint; | ||
27 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
28 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
29 | +import org.onosproject.net.flow.TrafficSelector; | ||
30 | +import org.onosproject.net.flow.TrafficTreatment; | ||
34 | import org.onosproject.net.flow.criteria.Criteria.IPCriterion; | 31 | import org.onosproject.net.flow.criteria.Criteria.IPCriterion; |
35 | import org.onosproject.net.flow.criteria.Criterion; | 32 | import org.onosproject.net.flow.criteria.Criterion; |
36 | import org.onosproject.net.intent.Intent; | 33 | import org.onosproject.net.intent.Intent; |
... | @@ -39,16 +36,32 @@ import org.onosproject.net.intent.IntentService; | ... | @@ -39,16 +36,32 @@ import org.onosproject.net.intent.IntentService; |
39 | import org.onosproject.net.intent.IntentState; | 36 | import org.onosproject.net.intent.IntentState; |
40 | import org.onosproject.net.intent.MultiPointToSinglePointIntent; | 37 | import org.onosproject.net.intent.MultiPointToSinglePointIntent; |
41 | import org.onosproject.net.intent.PointToPointIntent; | 38 | import org.onosproject.net.intent.PointToPointIntent; |
39 | +import org.onosproject.sdnip.config.BgpPeer; | ||
40 | +import org.onosproject.sdnip.config.Interface; | ||
41 | +import org.onosproject.sdnip.config.SdnIpConfigurationService; | ||
42 | import org.slf4j.Logger; | 42 | import org.slf4j.Logger; |
43 | import org.slf4j.LoggerFactory; | 43 | import org.slf4j.LoggerFactory; |
44 | 44 | ||
45 | -import com.google.common.util.concurrent.ThreadFactoryBuilder; | 45 | +import java.util.Collection; |
46 | +import java.util.HashMap; | ||
47 | +import java.util.HashSet; | ||
48 | +import java.util.LinkedList; | ||
49 | +import java.util.List; | ||
50 | +import java.util.Map; | ||
51 | +import java.util.Objects; | ||
52 | +import java.util.Set; | ||
53 | +import java.util.concurrent.ConcurrentHashMap; | ||
54 | +import java.util.concurrent.ExecutorService; | ||
55 | +import java.util.concurrent.Executors; | ||
56 | +import java.util.concurrent.Semaphore; | ||
57 | + | ||
58 | +import static com.google.common.base.Preconditions.checkArgument; | ||
46 | 59 | ||
47 | /** | 60 | /** |
48 | * Synchronizes intents between the in-memory intent store and the | 61 | * Synchronizes intents between the in-memory intent store and the |
49 | * IntentService. | 62 | * IntentService. |
50 | */ | 63 | */ |
51 | -public class IntentSynchronizer { | 64 | +public class IntentSynchronizer implements FibListener { |
52 | private static final Logger log = | 65 | private static final Logger log = |
53 | LoggerFactory.getLogger(IntentSynchronizer.class); | 66 | LoggerFactory.getLogger(IntentSynchronizer.class); |
54 | 67 | ||
... | @@ -65,18 +78,28 @@ public class IntentSynchronizer { | ... | @@ -65,18 +78,28 @@ public class IntentSynchronizer { |
65 | private volatile boolean isElectedLeader = false; | 78 | private volatile boolean isElectedLeader = false; |
66 | private volatile boolean isActivatedLeader = false; | 79 | private volatile boolean isActivatedLeader = false; |
67 | 80 | ||
81 | + private final SdnIpConfigurationService configService; | ||
82 | + private final InterfaceService interfaceService; | ||
83 | + | ||
68 | /** | 84 | /** |
69 | * Class constructor. | 85 | * Class constructor. |
70 | * | 86 | * |
71 | * @param appId the Application ID | 87 | * @param appId the Application ID |
72 | * @param intentService the intent service | 88 | * @param intentService the intent service |
89 | + * @param configService the SDN-IP configuration service | ||
90 | + * @param interfaceService the interface service | ||
73 | */ | 91 | */ |
74 | - IntentSynchronizer(ApplicationId appId, IntentService intentService) { | 92 | + IntentSynchronizer(ApplicationId appId, IntentService intentService, |
93 | + SdnIpConfigurationService configService, | ||
94 | + InterfaceService interfaceService) { | ||
75 | this.appId = appId; | 95 | this.appId = appId; |
76 | this.intentService = intentService; | 96 | this.intentService = intentService; |
77 | peerIntents = new ConcurrentHashMap<>(); | 97 | peerIntents = new ConcurrentHashMap<>(); |
78 | routeIntents = new ConcurrentHashMap<>(); | 98 | routeIntents = new ConcurrentHashMap<>(); |
79 | 99 | ||
100 | + this.configService = configService; | ||
101 | + this.interfaceService = interfaceService; | ||
102 | + | ||
80 | bgpIntentsSynchronizerExecutor = Executors.newSingleThreadExecutor( | 103 | bgpIntentsSynchronizerExecutor = Executors.newSingleThreadExecutor( |
81 | new ThreadFactoryBuilder() | 104 | new ThreadFactoryBuilder() |
82 | .setNameFormat("sdnip-intents-synchronizer-%d").build()); | 105 | .setNameFormat("sdnip-intents-synchronizer-%d").build()); |
... | @@ -244,17 +267,86 @@ public class IntentSynchronizer { | ... | @@ -244,17 +267,86 @@ public class IntentSynchronizer { |
244 | } | 267 | } |
245 | 268 | ||
246 | /** | 269 | /** |
247 | - * Updates multi-point-to-single-point route intents. | 270 | + * Generates a route intent for a prefix, the next hop IP address, and |
271 | + * the next hop MAC address. | ||
272 | + * <p/> | ||
273 | + * This method will find the egress interface for the intent. | ||
274 | + * Intent will match dst IP prefix and rewrite dst MAC address at all other | ||
275 | + * border switches, then forward packets according to dst MAC address. | ||
248 | * | 276 | * |
249 | - * @param submitIntents the intents to submit | 277 | + * @param prefix IP prefix of the route to add |
250 | - * @param withdrawPrefixes the IPv4 or IPv6 matching prefixes for the | 278 | + * @param nextHopIpAddress IP address of the next hop |
251 | - * intents to withdraw | 279 | + * @param nextHopMacAddress MAC address of the next hop |
280 | + * @return the generated intent, or null if no intent should be submitted | ||
252 | */ | 281 | */ |
253 | - void updateRouteIntents( | 282 | + private MultiPointToSinglePointIntent generateRouteIntent( |
254 | - Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>> submitIntents, | 283 | + IpPrefix prefix, |
255 | - Collection<IpPrefix> withdrawPrefixes) { | 284 | + IpAddress nextHopIpAddress, |
285 | + MacAddress nextHopMacAddress) { | ||
286 | + | ||
287 | + // Find the attachment point (egress interface) of the next hop | ||
288 | + Interface egressInterface; | ||
289 | + if (configService.getBgpPeers().containsKey(nextHopIpAddress)) { | ||
290 | + // Route to a peer | ||
291 | + log.debug("Route to peer {}", nextHopIpAddress); | ||
292 | + BgpPeer peer = | ||
293 | + configService.getBgpPeers().get(nextHopIpAddress); | ||
294 | + egressInterface = | ||
295 | + interfaceService.getInterface(peer.connectPoint()); | ||
296 | + } else { | ||
297 | + // Route to non-peer | ||
298 | + log.debug("Route to non-peer {}", nextHopIpAddress); | ||
299 | + egressInterface = | ||
300 | + interfaceService.getMatchingInterface(nextHopIpAddress); | ||
301 | + if (egressInterface == null) { | ||
302 | + log.warn("No outgoing interface found for {}", | ||
303 | + nextHopIpAddress); | ||
304 | + return null; | ||
305 | + } | ||
306 | + } | ||
256 | 307 | ||
257 | // | 308 | // |
309 | + // Generate the intent itself | ||
310 | + // | ||
311 | + Set<ConnectPoint> ingressPorts = new HashSet<>(); | ||
312 | + ConnectPoint egressPort = egressInterface.connectPoint(); | ||
313 | + log.debug("Generating intent for prefix {}, next hop mac {}", | ||
314 | + prefix, nextHopMacAddress); | ||
315 | + | ||
316 | + for (Interface intf : interfaceService.getInterfaces()) { | ||
317 | + if (!intf.connectPoint().equals(egressInterface.connectPoint())) { | ||
318 | + ConnectPoint srcPort = intf.connectPoint(); | ||
319 | + ingressPorts.add(srcPort); | ||
320 | + } | ||
321 | + } | ||
322 | + | ||
323 | + // Match the destination IP prefix at the first hop | ||
324 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
325 | + if (prefix.version() == Ip4Address.VERSION) { | ||
326 | + selector.matchEthType(Ethernet.TYPE_IPV4); | ||
327 | + } else { | ||
328 | + selector.matchEthType(Ethernet.TYPE_IPV6); | ||
329 | + } | ||
330 | + selector.matchIPDst(prefix); | ||
331 | + | ||
332 | + // Rewrite the destination MAC address | ||
333 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
334 | + .setEthDst(nextHopMacAddress); | ||
335 | + if (!egressInterface.vlan().equals(VlanId.NONE)) { | ||
336 | + treatment.setVlanId(egressInterface.vlan()); | ||
337 | + // If we set VLAN ID, we have to make sure a VLAN tag exists. | ||
338 | + // TODO support no VLAN -> VLAN routing | ||
339 | + selector.matchVlanId(VlanId.ANY); | ||
340 | + } | ||
341 | + | ||
342 | + return new MultiPointToSinglePointIntent(appId, selector.build(), | ||
343 | + treatment.build(), | ||
344 | + ingressPorts, egressPort); | ||
345 | + } | ||
346 | + | ||
347 | + @Override | ||
348 | + public void update(Collection<FibUpdate> updates, Collection<FibUpdate> withdraws) { | ||
349 | + // | ||
258 | // NOTE: Semantically, we MUST withdraw existing intents before | 350 | // NOTE: Semantically, we MUST withdraw existing intents before |
259 | // submitting new intents. | 351 | // submitting new intents. |
260 | // | 352 | // |
... | @@ -262,14 +354,19 @@ public class IntentSynchronizer { | ... | @@ -262,14 +354,19 @@ public class IntentSynchronizer { |
262 | MultiPointToSinglePointIntent intent; | 354 | MultiPointToSinglePointIntent intent; |
263 | 355 | ||
264 | log.debug("SDN-IP submitting intents = {} withdrawing = {}", | 356 | log.debug("SDN-IP submitting intents = {} withdrawing = {}", |
265 | - submitIntents.size(), withdrawPrefixes.size()); | 357 | + updates.size(), withdraws.size()); |
266 | 358 | ||
267 | // | 359 | // |
268 | // Prepare the Intent batch operations for the intents to withdraw | 360 | // Prepare the Intent batch operations for the intents to withdraw |
269 | // | 361 | // |
270 | IntentOperations.Builder withdrawBuilder = | 362 | IntentOperations.Builder withdrawBuilder = |
271 | IntentOperations.builder(appId); | 363 | IntentOperations.builder(appId); |
272 | - for (IpPrefix prefix : withdrawPrefixes) { | 364 | + for (FibUpdate withdraw : withdraws) { |
365 | + checkArgument(withdraw.type() == FibUpdate.Type.DELETE, | ||
366 | + "FibUpdate with wrong type in withdraws list"); | ||
367 | + | ||
368 | + IpPrefix prefix = withdraw.entry().prefix(); | ||
369 | + | ||
273 | intent = routeIntents.remove(prefix); | 370 | intent = routeIntents.remove(prefix); |
274 | if (intent == null) { | 371 | if (intent == null) { |
275 | log.trace("SDN-IP No intent in routeIntents to delete " + | 372 | log.trace("SDN-IP No intent in routeIntents to delete " + |
... | @@ -287,10 +384,21 @@ public class IntentSynchronizer { | ... | @@ -287,10 +384,21 @@ public class IntentSynchronizer { |
287 | // | 384 | // |
288 | IntentOperations.Builder submitBuilder = | 385 | IntentOperations.Builder submitBuilder = |
289 | IntentOperations.builder(appId); | 386 | IntentOperations.builder(appId); |
290 | - for (Pair<IpPrefix, MultiPointToSinglePointIntent> pair : | 387 | + for (FibUpdate update : updates) { |
291 | - submitIntents) { | 388 | + checkArgument(update.type() == FibUpdate.Type.UPDATE, |
292 | - IpPrefix prefix = pair.getLeft(); | 389 | + "FibUpdate with wrong type in updates list"); |
293 | - intent = pair.getRight(); | 390 | + |
391 | + IpPrefix prefix = update.entry().prefix(); | ||
392 | + intent = generateRouteIntent(prefix, update.entry().nextHopIp(), | ||
393 | + update.entry().nextHopMac()); | ||
394 | + | ||
395 | + if (intent == null) { | ||
396 | + // This preserves the old semantics - if an intent can't be | ||
397 | + // generated, we don't do anything with that prefix. But | ||
398 | + // perhaps we should withdraw the old intent anyway? | ||
399 | + continue; | ||
400 | + } | ||
401 | + | ||
294 | MultiPointToSinglePointIntent oldIntent = | 402 | MultiPointToSinglePointIntent oldIntent = |
295 | routeIntents.put(prefix, intent); | 403 | routeIntents.put(prefix, intent); |
296 | if (isElectedLeader && isActivatedLeader) { | 404 | if (isElectedLeader && isActivatedLeader) { | ... | ... |
... | @@ -15,61 +15,48 @@ | ... | @@ -15,61 +15,48 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import java.util.Collection; | 18 | +import com.google.common.collect.HashMultimap; |
19 | -import java.util.HashSet; | 19 | +import com.google.common.collect.Multimaps; |
20 | -import java.util.Iterator; | 20 | +import com.google.common.collect.SetMultimap; |
21 | -import java.util.LinkedList; | 21 | +import com.google.common.util.concurrent.ThreadFactoryBuilder; |
22 | -import java.util.List; | 22 | +import com.googlecode.concurrenttrees.common.KeyValuePair; |
23 | -import java.util.Map; | 23 | +import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; |
24 | -import java.util.Set; | 24 | +import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; |
25 | -import java.util.concurrent.BlockingQueue; | 25 | +import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; |
26 | -import java.util.concurrent.ConcurrentHashMap; | ||
27 | -import java.util.concurrent.ExecutorService; | ||
28 | -import java.util.concurrent.Executors; | ||
29 | -import java.util.concurrent.LinkedBlockingQueue; | ||
30 | - | ||
31 | -import org.apache.commons.lang3.tuple.Pair; | ||
32 | -import org.onlab.packet.Ethernet; | ||
33 | import org.onlab.packet.Ip4Address; | 26 | import org.onlab.packet.Ip4Address; |
34 | import org.onlab.packet.IpAddress; | 27 | import org.onlab.packet.IpAddress; |
35 | import org.onlab.packet.IpPrefix; | 28 | import org.onlab.packet.IpPrefix; |
36 | import org.onlab.packet.MacAddress; | 29 | import org.onlab.packet.MacAddress; |
37 | -import org.onlab.packet.VlanId; | ||
38 | -import org.onosproject.core.ApplicationId; | ||
39 | -import org.onosproject.net.ConnectPoint; | ||
40 | import org.onosproject.net.Host; | 30 | import org.onosproject.net.Host; |
41 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
42 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
43 | -import org.onosproject.net.flow.TrafficSelector; | ||
44 | -import org.onosproject.net.flow.TrafficTreatment; | ||
45 | import org.onosproject.net.host.HostEvent; | 31 | import org.onosproject.net.host.HostEvent; |
46 | import org.onosproject.net.host.HostListener; | 32 | import org.onosproject.net.host.HostListener; |
47 | import org.onosproject.net.host.HostService; | 33 | import org.onosproject.net.host.HostService; |
48 | -import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ||
49 | -import org.onosproject.sdnip.config.BgpPeer; | ||
50 | -import org.onosproject.sdnip.config.Interface; | ||
51 | -import org.onosproject.sdnip.config.SdnIpConfigurationService; | ||
52 | import org.slf4j.Logger; | 34 | import org.slf4j.Logger; |
53 | import org.slf4j.LoggerFactory; | 35 | import org.slf4j.LoggerFactory; |
54 | 36 | ||
55 | -import com.google.common.collect.HashMultimap; | 37 | +import java.util.Collection; |
56 | -import com.google.common.collect.Multimaps; | 38 | +import java.util.Collections; |
57 | -import com.google.common.collect.SetMultimap; | 39 | +import java.util.Iterator; |
58 | -import com.google.common.util.concurrent.ThreadFactoryBuilder; | 40 | +import java.util.LinkedList; |
59 | -import com.googlecode.concurrenttrees.common.KeyValuePair; | 41 | +import java.util.List; |
60 | -import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; | 42 | +import java.util.Map; |
61 | -import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; | 43 | +import java.util.Set; |
62 | -import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; | 44 | +import java.util.concurrent.BlockingQueue; |
45 | +import java.util.concurrent.ConcurrentHashMap; | ||
46 | +import java.util.concurrent.ExecutorService; | ||
47 | +import java.util.concurrent.Executors; | ||
48 | +import java.util.concurrent.LinkedBlockingQueue; | ||
63 | 49 | ||
64 | /** | 50 | /** |
65 | - * This class processes BGP route update, translates each update into a intent | 51 | + * This class processes route updates and maintains a Routing Information Base |
66 | - * and submits the intent. | 52 | + * (RIB). After route updates have been processed and next hops have been |
53 | + * resolved, FIB updates are sent to any listening FIB components. | ||
67 | */ | 54 | */ |
68 | public class Router implements RouteListener { | 55 | public class Router implements RouteListener { |
69 | 56 | ||
70 | private static final Logger log = LoggerFactory.getLogger(Router.class); | 57 | private static final Logger log = LoggerFactory.getLogger(Router.class); |
71 | 58 | ||
72 | - // Store all route updates in a radix tree. | 59 | + // Route entries are stored in a radix tree. |
73 | // The key in this tree is the binary string of prefix of the route. | 60 | // The key in this tree is the binary string of prefix of the route. |
74 | private InvertedRadixTree<RouteEntry> ribTable4; | 61 | private InvertedRadixTree<RouteEntry> ribTable4; |
75 | private InvertedRadixTree<RouteEntry> ribTable6; | 62 | private InvertedRadixTree<RouteEntry> ribTable6; |
... | @@ -77,37 +64,26 @@ public class Router implements RouteListener { | ... | @@ -77,37 +64,26 @@ public class Router implements RouteListener { |
77 | // Stores all incoming route updates in a queue. | 64 | // Stores all incoming route updates in a queue. |
78 | private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue; | 65 | private final BlockingQueue<Collection<RouteUpdate>> routeUpdatesQueue; |
79 | 66 | ||
80 | - // The IpAddress is the next hop address of each route update. | 67 | + // Next-hop IP address to route entry mapping for next hops pending MAC resolution |
81 | private final SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp; | 68 | private final SetMultimap<IpAddress, RouteEntry> routesWaitingOnArp; |
82 | 69 | ||
83 | // The IPv4 address to MAC address mapping | 70 | // The IPv4 address to MAC address mapping |
84 | private final Map<IpAddress, MacAddress> ip2Mac; | 71 | private final Map<IpAddress, MacAddress> ip2Mac; |
85 | 72 | ||
86 | - private final ApplicationId appId; | 73 | + private final FibListener fibComponent; |
87 | - private final IntentSynchronizer intentSynchronizer; | ||
88 | private final HostService hostService; | 74 | private final HostService hostService; |
89 | - private final SdnIpConfigurationService configService; | ||
90 | - private final InterfaceService interfaceService; | ||
91 | private final ExecutorService bgpUpdatesExecutor; | 75 | private final ExecutorService bgpUpdatesExecutor; |
92 | private final HostListener hostListener; | 76 | private final HostListener hostListener; |
93 | 77 | ||
94 | /** | 78 | /** |
95 | * Class constructor. | 79 | * Class constructor. |
96 | * | 80 | * |
97 | - * @param appId the application ID | 81 | + * @param fibComponent the intent synchronizer |
98 | - * @param intentSynchronizer the intent synchronizer | ||
99 | - * @param configService the configuration service | ||
100 | - * @param interfaceService the interface service | ||
101 | * @param hostService the host service | 82 | * @param hostService the host service |
102 | */ | 83 | */ |
103 | - public Router(ApplicationId appId, IntentSynchronizer intentSynchronizer, | 84 | + public Router(FibListener fibComponent, HostService hostService) { |
104 | - SdnIpConfigurationService configService, | 85 | + // TODO move to a listener model for adding fib listeners |
105 | - InterfaceService interfaceService, | 86 | + this.fibComponent = fibComponent; |
106 | - HostService hostService) { | ||
107 | - this.appId = appId; | ||
108 | - this.intentSynchronizer = intentSynchronizer; | ||
109 | - this.configService = configService; | ||
110 | - this.interfaceService = interfaceService; | ||
111 | this.hostService = hostService; | 87 | this.hostService = hostService; |
112 | 88 | ||
113 | this.hostListener = new InternalHostListener(); | 89 | this.hostListener = new InternalHostListener(); |
... | @@ -291,23 +267,23 @@ public class Router implements RouteListener { | ... | @@ -291,23 +267,23 @@ public class Router implements RouteListener { |
291 | */ | 267 | */ |
292 | void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { | 268 | void processRouteUpdates(Collection<RouteUpdate> routeUpdates) { |
293 | synchronized (this) { | 269 | synchronized (this) { |
294 | - Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>> | ||
295 | - submitIntents = new LinkedList<>(); | ||
296 | Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); | 270 | Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); |
297 | - MultiPointToSinglePointIntent intent; | 271 | + Collection<FibUpdate> fibUpdates = new LinkedList<>(); |
272 | + Collection<FibUpdate> fibWithdraws = new LinkedList<>(); | ||
298 | 273 | ||
299 | for (RouteUpdate update : routeUpdates) { | 274 | for (RouteUpdate update : routeUpdates) { |
300 | switch (update.type()) { | 275 | switch (update.type()) { |
301 | case UPDATE: | 276 | case UPDATE: |
302 | - intent = processRouteAdd(update.routeEntry(), | 277 | + FibEntry fib = processRouteAdd(update.routeEntry(), |
303 | withdrawPrefixes); | 278 | withdrawPrefixes); |
304 | - if (intent != null) { | 279 | + if (fib != null) { |
305 | - submitIntents.add(Pair.of(update.routeEntry().prefix(), | 280 | + fibUpdates.add(new FibUpdate(FibUpdate.Type.UPDATE, fib)); |
306 | - intent)); | ||
307 | } | 281 | } |
282 | + | ||
308 | break; | 283 | break; |
309 | case DELETE: | 284 | case DELETE: |
310 | processRouteDelete(update.routeEntry(), withdrawPrefixes); | 285 | processRouteDelete(update.routeEntry(), withdrawPrefixes); |
286 | + | ||
311 | break; | 287 | break; |
312 | default: | 288 | default: |
313 | log.error("Unknown update Type: {}", update.type()); | 289 | log.error("Unknown update Type: {}", update.type()); |
... | @@ -315,8 +291,10 @@ public class Router implements RouteListener { | ... | @@ -315,8 +291,10 @@ public class Router implements RouteListener { |
315 | } | 291 | } |
316 | } | 292 | } |
317 | 293 | ||
318 | - intentSynchronizer.updateRouteIntents(submitIntents, | 294 | + withdrawPrefixes.forEach(p -> fibWithdraws.add(new FibUpdate( |
319 | - withdrawPrefixes); | 295 | + FibUpdate.Type.DELETE, new FibEntry(p, null, null)))); |
296 | + | ||
297 | + fibComponent.update(fibUpdates, fibWithdraws); | ||
320 | } | 298 | } |
321 | } | 299 | } |
322 | 300 | ||
... | @@ -335,9 +313,9 @@ public class Router implements RouteListener { | ... | @@ -335,9 +313,9 @@ public class Router implements RouteListener { |
335 | * @param routeEntry the route entry to add | 313 | * @param routeEntry the route entry to add |
336 | * @param withdrawPrefixes the collection of accumulated prefixes whose | 314 | * @param withdrawPrefixes the collection of accumulated prefixes whose |
337 | * intents will be withdrawn | 315 | * intents will be withdrawn |
338 | - * @return the corresponding intent that should be submitted, or null | 316 | + * @return the corresponding FIB entry change, or null |
339 | */ | 317 | */ |
340 | - private MultiPointToSinglePointIntent processRouteAdd( | 318 | + private FibEntry processRouteAdd( |
341 | RouteEntry routeEntry, | 319 | RouteEntry routeEntry, |
342 | Collection<IpPrefix> withdrawPrefixes) { | 320 | Collection<IpPrefix> withdrawPrefixes) { |
343 | log.debug("Processing route add: {}", routeEntry); | 321 | log.debug("Processing route add: {}", routeEntry); |
... | @@ -397,89 +375,11 @@ public class Router implements RouteListener { | ... | @@ -397,89 +375,11 @@ public class Router implements RouteListener { |
397 | routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry); | 375 | routesWaitingOnArp.put(routeEntry.nextHop(), routeEntry); |
398 | return null; | 376 | return null; |
399 | } | 377 | } |
400 | - return generateRouteIntent(routeEntry.prefix(), routeEntry.nextHop(), | 378 | + return new FibEntry(routeEntry.prefix(), routeEntry.nextHop(), |
401 | nextHopMacAddress); | 379 | nextHopMacAddress); |
402 | } | 380 | } |
403 | 381 | ||
404 | /** | 382 | /** |
405 | - * Generates a route intent for a prefix, the next hop IP address, and | ||
406 | - * the next hop MAC address. | ||
407 | - * <p/> | ||
408 | - * This method will find the egress interface for the intent. | ||
409 | - * Intent will match dst IP prefix and rewrite dst MAC address at all other | ||
410 | - * border switches, then forward packets according to dst MAC address. | ||
411 | - * | ||
412 | - * @param prefix IP prefix of the route to add | ||
413 | - * @param nextHopIpAddress IP address of the next hop | ||
414 | - * @param nextHopMacAddress MAC address of the next hop | ||
415 | - * @return the generated intent, or null if no intent should be submitted | ||
416 | - */ | ||
417 | - private MultiPointToSinglePointIntent generateRouteIntent( | ||
418 | - IpPrefix prefix, | ||
419 | - IpAddress nextHopIpAddress, | ||
420 | - MacAddress nextHopMacAddress) { | ||
421 | - | ||
422 | - // Find the attachment point (egress interface) of the next hop | ||
423 | - Interface egressInterface; | ||
424 | - if (configService.getBgpPeers().containsKey(nextHopIpAddress)) { | ||
425 | - // Route to a peer | ||
426 | - log.debug("Route to peer {}", nextHopIpAddress); | ||
427 | - BgpPeer peer = | ||
428 | - configService.getBgpPeers().get(nextHopIpAddress); | ||
429 | - egressInterface = | ||
430 | - interfaceService.getInterface(peer.connectPoint()); | ||
431 | - } else { | ||
432 | - // Route to non-peer | ||
433 | - log.debug("Route to non-peer {}", nextHopIpAddress); | ||
434 | - egressInterface = | ||
435 | - interfaceService.getMatchingInterface(nextHopIpAddress); | ||
436 | - if (egressInterface == null) { | ||
437 | - log.warn("No outgoing interface found for {}", | ||
438 | - nextHopIpAddress); | ||
439 | - return null; | ||
440 | - } | ||
441 | - } | ||
442 | - | ||
443 | - // | ||
444 | - // Generate the intent itself | ||
445 | - // | ||
446 | - Set<ConnectPoint> ingressPorts = new HashSet<>(); | ||
447 | - ConnectPoint egressPort = egressInterface.connectPoint(); | ||
448 | - log.debug("Generating intent for prefix {}, next hop mac {}", | ||
449 | - prefix, nextHopMacAddress); | ||
450 | - | ||
451 | - for (Interface intf : interfaceService.getInterfaces()) { | ||
452 | - if (!intf.connectPoint().equals(egressInterface.connectPoint())) { | ||
453 | - ConnectPoint srcPort = intf.connectPoint(); | ||
454 | - ingressPorts.add(srcPort); | ||
455 | - } | ||
456 | - } | ||
457 | - | ||
458 | - // Match the destination IP prefix at the first hop | ||
459 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
460 | - if (prefix.version() == Ip4Address.VERSION) { | ||
461 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
462 | - } else { | ||
463 | - selector.matchEthType(Ethernet.TYPE_IPV6); | ||
464 | - } | ||
465 | - selector.matchIPDst(prefix); | ||
466 | - | ||
467 | - // Rewrite the destination MAC address | ||
468 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder() | ||
469 | - .setEthDst(nextHopMacAddress); | ||
470 | - if (!egressInterface.vlan().equals(VlanId.NONE)) { | ||
471 | - treatment.setVlanId(egressInterface.vlan()); | ||
472 | - // If we set VLAN ID, we have to make sure a VLAN tag exists. | ||
473 | - // TODO support no VLAN -> VLAN routing | ||
474 | - selector.matchVlanId(VlanId.ANY); | ||
475 | - } | ||
476 | - | ||
477 | - return new MultiPointToSinglePointIntent(appId, selector.build(), | ||
478 | - treatment.build(), | ||
479 | - ingressPorts, egressPort); | ||
480 | - } | ||
481 | - | ||
482 | - /** | ||
483 | * Processes the deletion of a route entry. | 383 | * Processes the deletion of a route entry. |
484 | * <p> | 384 | * <p> |
485 | * The prefix for the routing entry is removed from radix tree. | 385 | * The prefix for the routing entry is removed from radix tree. |
... | @@ -528,9 +428,7 @@ public class Router implements RouteListener { | ... | @@ -528,9 +428,7 @@ public class Router implements RouteListener { |
528 | // tree and the intents could get out of sync. | 428 | // tree and the intents could get out of sync. |
529 | // | 429 | // |
530 | synchronized (this) { | 430 | synchronized (this) { |
531 | - Collection<Pair<IpPrefix, MultiPointToSinglePointIntent>> | 431 | + Collection<FibUpdate> submitFibEntries = new LinkedList<>(); |
532 | - submitIntents = new LinkedList<>(); | ||
533 | - MultiPointToSinglePointIntent intent; | ||
534 | 432 | ||
535 | Set<RouteEntry> routesToPush = | 433 | Set<RouteEntry> routesToPush = |
536 | routesWaitingOnArp.removeAll(ipAddress); | 434 | routesWaitingOnArp.removeAll(ipAddress); |
... | @@ -540,27 +438,21 @@ public class Router implements RouteListener { | ... | @@ -540,27 +438,21 @@ public class Router implements RouteListener { |
540 | RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix()); | 438 | RouteEntry foundRouteEntry = findRibRoute(routeEntry.prefix()); |
541 | if (foundRouteEntry != null && | 439 | if (foundRouteEntry != null && |
542 | foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { | 440 | foundRouteEntry.nextHop().equals(routeEntry.nextHop())) { |
543 | - // We only push prefix flows if the prefix is still in the | 441 | + // We only push FIB updates if the prefix is still in the |
544 | - // radix tree and the next hop is the same as our | 442 | + // radix tree and the next hop is the same as our entry. |
545 | - // update. | ||
546 | // The prefix could have been removed while we were waiting | 443 | // The prefix could have been removed while we were waiting |
547 | // for the ARP, or the next hop could have changed. | 444 | // for the ARP, or the next hop could have changed. |
548 | - intent = generateRouteIntent(routeEntry.prefix(), | 445 | + submitFibEntries.add(new FibUpdate(FibUpdate.Type.UPDATE, |
549 | - ipAddress, macAddress); | 446 | + new FibEntry(routeEntry.prefix(), |
550 | - if (intent != null) { | 447 | + ipAddress, macAddress))); |
551 | - submitIntents.add(Pair.of(routeEntry.prefix(), | ||
552 | - intent)); | ||
553 | - } | ||
554 | } else { | 448 | } else { |
555 | log.debug("{} has been revoked before the MAC was resolved", | 449 | log.debug("{} has been revoked before the MAC was resolved", |
556 | routeEntry); | 450 | routeEntry); |
557 | } | 451 | } |
558 | } | 452 | } |
559 | 453 | ||
560 | - if (!submitIntents.isEmpty()) { | 454 | + if (!submitFibEntries.isEmpty()) { |
561 | - Collection<IpPrefix> withdrawPrefixes = new LinkedList<>(); | 455 | + fibComponent.update(submitFibEntries, Collections.emptyList()); |
562 | - intentSynchronizer.updateRouteIntents(submitIntents, | ||
563 | - withdrawPrefixes); | ||
564 | } | 456 | } |
565 | 457 | ||
566 | ip2Mac.put(ipAddress, macAddress); | 458 | ip2Mac.put(ipAddress, macAddress); | ... | ... |
... | @@ -15,11 +15,6 @@ | ... | @@ -15,11 +15,6 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static org.slf4j.LoggerFactory.getLogger; | ||
19 | - | ||
20 | -import java.util.Collection; | ||
21 | -import java.util.Dictionary; | ||
22 | - | ||
23 | import org.apache.felix.scr.annotations.Activate; | 18 | import org.apache.felix.scr.annotations.Activate; |
24 | import org.apache.felix.scr.annotations.Component; | 19 | import org.apache.felix.scr.annotations.Component; |
25 | import org.apache.felix.scr.annotations.Deactivate; | 20 | import org.apache.felix.scr.annotations.Deactivate; |
... | @@ -44,6 +39,11 @@ import org.onosproject.sdnip.config.SdnIpConfigurationReader; | ... | @@ -44,6 +39,11 @@ import org.onosproject.sdnip.config.SdnIpConfigurationReader; |
44 | import org.osgi.service.component.ComponentContext; | 39 | import org.osgi.service.component.ComponentContext; |
45 | import org.slf4j.Logger; | 40 | import org.slf4j.Logger; |
46 | 41 | ||
42 | +import java.util.Collection; | ||
43 | +import java.util.Dictionary; | ||
44 | + | ||
45 | +import static org.slf4j.LoggerFactory.getLogger; | ||
46 | + | ||
47 | /** | 47 | /** |
48 | * Component for the SDN-IP peering application. | 48 | * Component for the SDN-IP peering application. |
49 | */ | 49 | */ |
... | @@ -104,7 +104,8 @@ public class SdnIp implements SdnIpService { | ... | @@ -104,7 +104,8 @@ public class SdnIp implements SdnIpService { |
104 | InterfaceService interfaceService = | 104 | InterfaceService interfaceService = |
105 | new HostToInterfaceAdaptor(hostService); | 105 | new HostToInterfaceAdaptor(hostService); |
106 | 106 | ||
107 | - intentSynchronizer = new IntentSynchronizer(appId, intentService); | 107 | + intentSynchronizer = new IntentSynchronizer(appId, intentService, |
108 | + config, interfaceService); | ||
108 | intentSynchronizer.start(); | 109 | intentSynchronizer.start(); |
109 | 110 | ||
110 | peerConnectivity = new PeerConnectivityManager(appId, | 111 | peerConnectivity = new PeerConnectivityManager(appId, |
... | @@ -113,8 +114,7 @@ public class SdnIp implements SdnIpService { | ... | @@ -113,8 +114,7 @@ public class SdnIp implements SdnIpService { |
113 | interfaceService); | 114 | interfaceService); |
114 | peerConnectivity.start(); | 115 | peerConnectivity.start(); |
115 | 116 | ||
116 | - router = new Router(appId, intentSynchronizer, config, | 117 | + router = new Router(intentSynchronizer, hostService); |
117 | - interfaceService, hostService); | ||
118 | router.start(); | 118 | router.start(); |
119 | 119 | ||
120 | leadershipService.addListener(leadershipEventListener); | 120 | leadershipService.addListener(leadershipEventListener); | ... | ... |
... | @@ -15,23 +15,10 @@ | ... | @@ -15,23 +15,10 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static org.easymock.EasyMock.anyObject; | 18 | +import com.google.common.collect.Sets; |
19 | -import static org.easymock.EasyMock.createMock; | 19 | +import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; |
20 | -import static org.easymock.EasyMock.expect; | 20 | +import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; |
21 | -import static org.easymock.EasyMock.expectLastCall; | 21 | +import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; |
22 | -import static org.easymock.EasyMock.replay; | ||
23 | -import static org.easymock.EasyMock.reset; | ||
24 | -import static org.easymock.EasyMock.verify; | ||
25 | -import static org.hamcrest.Matchers.is; | ||
26 | -import static org.junit.Assert.assertEquals; | ||
27 | -import static org.junit.Assert.assertFalse; | ||
28 | -import static org.junit.Assert.assertThat; | ||
29 | -import static org.junit.Assert.assertTrue; | ||
30 | - | ||
31 | -import java.util.HashSet; | ||
32 | -import java.util.Set; | ||
33 | -import java.util.concurrent.ConcurrentHashMap; | ||
34 | - | ||
35 | import org.junit.Before; | 22 | import org.junit.Before; |
36 | import org.junit.Test; | 23 | import org.junit.Test; |
37 | import org.onlab.junit.TestUtils; | 24 | import org.onlab.junit.TestUtils; |
... | @@ -67,10 +54,16 @@ import org.onosproject.net.intent.MultiPointToSinglePointIntent; | ... | @@ -67,10 +54,16 @@ import org.onosproject.net.intent.MultiPointToSinglePointIntent; |
67 | import org.onosproject.net.provider.ProviderId; | 54 | import org.onosproject.net.provider.ProviderId; |
68 | import org.onosproject.sdnip.config.Interface; | 55 | import org.onosproject.sdnip.config.Interface; |
69 | 56 | ||
70 | -import com.google.common.collect.Sets; | 57 | +import java.util.HashSet; |
71 | -import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; | 58 | +import java.util.Set; |
72 | -import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; | 59 | +import java.util.concurrent.ConcurrentHashMap; |
73 | -import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; | 60 | + |
61 | +import static org.easymock.EasyMock.*; | ||
62 | +import static org.hamcrest.Matchers.is; | ||
63 | +import static org.junit.Assert.assertEquals; | ||
64 | +import static org.junit.Assert.assertFalse; | ||
65 | +import static org.junit.Assert.assertThat; | ||
66 | +import static org.junit.Assert.assertTrue; | ||
74 | 67 | ||
75 | /** | 68 | /** |
76 | * This class tests the intent synchronization function in the | 69 | * This class tests the intent synchronization function in the |
... | @@ -116,9 +109,9 @@ public class IntentSyncTest extends AbstractIntentTest { | ... | @@ -116,9 +109,9 @@ public class IntentSyncTest extends AbstractIntentTest { |
116 | setUpHostService(); | 109 | setUpHostService(); |
117 | intentService = createMock(IntentService.class); | 110 | intentService = createMock(IntentService.class); |
118 | 111 | ||
119 | - intentSynchronizer = new IntentSynchronizer(APPID, intentService); | 112 | + intentSynchronizer = new IntentSynchronizer(APPID, intentService, |
120 | - router = new Router(APPID, intentSynchronizer, null, interfaceService, | 113 | + null, interfaceService); |
121 | - hostService); | 114 | + router = new Router(intentSynchronizer, hostService); |
122 | } | 115 | } |
123 | 116 | ||
124 | /** | 117 | /** | ... | ... |
... | @@ -15,19 +15,7 @@ | ... | @@ -15,19 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static org.easymock.EasyMock.createMock; | 18 | +import com.google.common.collect.Sets; |
19 | -import static org.easymock.EasyMock.expect; | ||
20 | -import static org.easymock.EasyMock.replay; | ||
21 | -import static org.easymock.EasyMock.reset; | ||
22 | -import static org.easymock.EasyMock.verify; | ||
23 | - | ||
24 | -import java.util.ArrayList; | ||
25 | -import java.util.Collections; | ||
26 | -import java.util.HashMap; | ||
27 | -import java.util.LinkedList; | ||
28 | -import java.util.List; | ||
29 | -import java.util.Map; | ||
30 | - | ||
31 | import org.junit.Before; | 19 | import org.junit.Before; |
32 | import org.junit.Ignore; | 20 | import org.junit.Ignore; |
33 | import org.junit.Test; | 21 | import org.junit.Test; |
... | @@ -60,7 +48,14 @@ import org.onosproject.sdnip.config.Interface; | ... | @@ -60,7 +48,14 @@ import org.onosproject.sdnip.config.Interface; |
60 | import org.onosproject.sdnip.config.InterfaceAddress; | 48 | import org.onosproject.sdnip.config.InterfaceAddress; |
61 | import org.onosproject.sdnip.config.SdnIpConfigurationService; | 49 | import org.onosproject.sdnip.config.SdnIpConfigurationService; |
62 | 50 | ||
63 | -import com.google.common.collect.Sets; | 51 | +import java.util.ArrayList; |
52 | +import java.util.Collections; | ||
53 | +import java.util.HashMap; | ||
54 | +import java.util.LinkedList; | ||
55 | +import java.util.List; | ||
56 | +import java.util.Map; | ||
57 | + | ||
58 | +import static org.easymock.EasyMock.*; | ||
64 | 59 | ||
65 | /** | 60 | /** |
66 | * Unit tests for PeerConnectivityManager. | 61 | * Unit tests for PeerConnectivityManager. |
... | @@ -552,7 +547,9 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { | ... | @@ -552,7 +547,9 @@ public class PeerConnectivityManagerTest extends AbstractIntentTest { |
552 | intentService = createMock(IntentService.class); | 547 | intentService = createMock(IntentService.class); |
553 | replay(intentService); | 548 | replay(intentService); |
554 | 549 | ||
555 | - intentSynchronizer = new IntentSynchronizer(APPID, intentService); | 550 | + intentSynchronizer = new IntentSynchronizer(APPID, intentService, |
551 | + configInfoService, | ||
552 | + interfaceService); | ||
556 | intentSynchronizer.leaderChanged(true); | 553 | intentSynchronizer.leaderChanged(true); |
557 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); | 554 | TestUtils.setField(intentSynchronizer, "isActivatedLeader", true); |
558 | 555 | ... | ... |
... | @@ -15,22 +15,10 @@ | ... | @@ -15,22 +15,10 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static org.easymock.EasyMock.anyObject; | 18 | +import com.google.common.collect.Sets; |
19 | -import static org.easymock.EasyMock.createMock; | 19 | +import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; |
20 | -import static org.easymock.EasyMock.expect; | 20 | +import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; |
21 | -import static org.easymock.EasyMock.replay; | 21 | +import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; |
22 | -import static org.easymock.EasyMock.reset; | ||
23 | -import static org.easymock.EasyMock.verify; | ||
24 | -import static org.junit.Assert.assertEquals; | ||
25 | -import static org.junit.Assert.assertTrue; | ||
26 | - | ||
27 | -import java.util.Collections; | ||
28 | -import java.util.HashMap; | ||
29 | -import java.util.HashSet; | ||
30 | -import java.util.Map; | ||
31 | -import java.util.Set; | ||
32 | -import java.util.concurrent.ConcurrentHashMap; | ||
33 | - | ||
34 | import org.junit.Before; | 22 | import org.junit.Before; |
35 | import org.junit.Test; | 23 | import org.junit.Test; |
36 | import org.onlab.junit.TestUtils; | 24 | import org.onlab.junit.TestUtils; |
... | @@ -69,10 +57,16 @@ import org.onosproject.sdnip.config.BgpPeer; | ... | @@ -69,10 +57,16 @@ import org.onosproject.sdnip.config.BgpPeer; |
69 | import org.onosproject.sdnip.config.Interface; | 57 | import org.onosproject.sdnip.config.Interface; |
70 | import org.onosproject.sdnip.config.SdnIpConfigurationService; | 58 | import org.onosproject.sdnip.config.SdnIpConfigurationService; |
71 | 59 | ||
72 | -import com.google.common.collect.Sets; | 60 | +import java.util.Collections; |
73 | -import com.googlecode.concurrenttrees.radix.node.concrete.DefaultByteArrayNodeFactory; | 61 | +import java.util.HashMap; |
74 | -import com.googlecode.concurrenttrees.radixinverted.ConcurrentInvertedRadixTree; | 62 | +import java.util.HashSet; |
75 | -import com.googlecode.concurrenttrees.radixinverted.InvertedRadixTree; | 63 | +import java.util.Map; |
64 | +import java.util.Set; | ||
65 | +import java.util.concurrent.ConcurrentHashMap; | ||
66 | + | ||
67 | +import static org.easymock.EasyMock.*; | ||
68 | +import static org.junit.Assert.assertEquals; | ||
69 | +import static org.junit.Assert.assertTrue; | ||
76 | 70 | ||
77 | /** | 71 | /** |
78 | * This class tests adding a route, updating a route, deleting a route, and | 72 | * This class tests adding a route, updating a route, deleting a route, and |
... | @@ -122,9 +116,10 @@ public class RouterAsyncArpTest extends AbstractIntentTest { | ... | @@ -122,9 +116,10 @@ public class RouterAsyncArpTest extends AbstractIntentTest { |
122 | hostService = createMock(HostService.class); | 116 | hostService = createMock(HostService.class); |
123 | intentService = createMock(IntentService.class); | 117 | intentService = createMock(IntentService.class); |
124 | 118 | ||
125 | - intentSynchronizer = new IntentSynchronizer(APPID, intentService); | 119 | + intentSynchronizer = new IntentSynchronizer(APPID, intentService, |
126 | - router = new Router(APPID, intentSynchronizer, | 120 | + sdnIpConfigService, |
127 | - sdnIpConfigService, interfaceService, hostService); | 121 | + interfaceService); |
122 | + router = new Router(intentSynchronizer, hostService); | ||
128 | internalHostListener = router.new InternalHostListener(); | 123 | internalHostListener = router.new InternalHostListener(); |
129 | } | 124 | } |
130 | 125 | ... | ... |
... | @@ -15,22 +15,7 @@ | ... | @@ -15,22 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static org.easymock.EasyMock.anyObject; | 18 | +import com.google.common.collect.Sets; |
19 | -import static org.easymock.EasyMock.createMock; | ||
20 | -import static org.easymock.EasyMock.expect; | ||
21 | -import static org.easymock.EasyMock.expectLastCall; | ||
22 | -import static org.easymock.EasyMock.replay; | ||
23 | -import static org.easymock.EasyMock.reset; | ||
24 | -import static org.easymock.EasyMock.verify; | ||
25 | -import static org.junit.Assert.assertEquals; | ||
26 | -import static org.junit.Assert.assertTrue; | ||
27 | - | ||
28 | -import java.util.Collections; | ||
29 | -import java.util.HashMap; | ||
30 | -import java.util.HashSet; | ||
31 | -import java.util.Map; | ||
32 | -import java.util.Set; | ||
33 | - | ||
34 | import org.junit.Before; | 19 | import org.junit.Before; |
35 | import org.junit.Test; | 20 | import org.junit.Test; |
36 | import org.onlab.junit.TestUtils; | 21 | import org.onlab.junit.TestUtils; |
... | @@ -68,7 +53,15 @@ import org.onosproject.sdnip.config.BgpPeer; | ... | @@ -68,7 +53,15 @@ import org.onosproject.sdnip.config.BgpPeer; |
68 | import org.onosproject.sdnip.config.Interface; | 53 | import org.onosproject.sdnip.config.Interface; |
69 | import org.onosproject.sdnip.config.SdnIpConfigurationService; | 54 | import org.onosproject.sdnip.config.SdnIpConfigurationService; |
70 | 55 | ||
71 | -import com.google.common.collect.Sets; | 56 | +import java.util.Collections; |
57 | +import java.util.HashMap; | ||
58 | +import java.util.HashSet; | ||
59 | +import java.util.Map; | ||
60 | +import java.util.Set; | ||
61 | + | ||
62 | +import static org.easymock.EasyMock.*; | ||
63 | +import static org.junit.Assert.assertEquals; | ||
64 | +import static org.junit.Assert.assertTrue; | ||
72 | 65 | ||
73 | /** | 66 | /** |
74 | * This class tests adding a route, updating a route, deleting a route, | 67 | * This class tests adding a route, updating a route, deleting a route, |
... | @@ -125,9 +118,10 @@ public class RouterTest extends AbstractIntentTest { | ... | @@ -125,9 +118,10 @@ public class RouterTest extends AbstractIntentTest { |
125 | 118 | ||
126 | intentService = createMock(IntentService.class); | 119 | intentService = createMock(IntentService.class); |
127 | 120 | ||
128 | - intentSynchronizer = new IntentSynchronizer(APPID, intentService); | 121 | + intentSynchronizer = new IntentSynchronizer(APPID, intentService, |
129 | - router = new Router(APPID, intentSynchronizer, sdnIpConfigService, | 122 | + sdnIpConfigService, |
130 | - interfaceService, hostService); | 123 | + interfaceService); |
124 | + router = new Router(intentSynchronizer, hostService); | ||
131 | } | 125 | } |
132 | 126 | ||
133 | /** | 127 | /** | ... | ... |
... | @@ -15,26 +15,7 @@ | ... | @@ -15,26 +15,7 @@ |
15 | */ | 15 | */ |
16 | package org.onosproject.sdnip; | 16 | package org.onosproject.sdnip; |
17 | 17 | ||
18 | -import static org.easymock.EasyMock.createMock; | 18 | +import com.google.common.collect.Sets; |
19 | -import static org.easymock.EasyMock.expect; | ||
20 | -import static org.easymock.EasyMock.expectLastCall; | ||
21 | -import static org.easymock.EasyMock.replay; | ||
22 | -import static org.easymock.EasyMock.reset; | ||
23 | -import static org.easymock.EasyMock.verify; | ||
24 | -import static org.junit.Assert.assertEquals; | ||
25 | -import static org.junit.Assert.assertNotNull; | ||
26 | - | ||
27 | -import java.nio.ByteBuffer; | ||
28 | -import java.util.ArrayList; | ||
29 | -import java.util.HashMap; | ||
30 | -import java.util.HashSet; | ||
31 | -import java.util.List; | ||
32 | -import java.util.Map; | ||
33 | -import java.util.Random; | ||
34 | -import java.util.Set; | ||
35 | -import java.util.concurrent.CountDownLatch; | ||
36 | -import java.util.concurrent.TimeUnit; | ||
37 | - | ||
38 | import org.easymock.IAnswer; | 19 | import org.easymock.IAnswer; |
39 | import org.junit.Before; | 20 | import org.junit.Before; |
40 | import org.junit.Test; | 21 | import org.junit.Test; |
... | @@ -66,7 +47,20 @@ import org.onosproject.sdnip.config.BgpPeer; | ... | @@ -66,7 +47,20 @@ import org.onosproject.sdnip.config.BgpPeer; |
66 | import org.onosproject.sdnip.config.Interface; | 47 | import org.onosproject.sdnip.config.Interface; |
67 | import org.onosproject.sdnip.config.SdnIpConfigurationService; | 48 | import org.onosproject.sdnip.config.SdnIpConfigurationService; |
68 | 49 | ||
69 | -import com.google.common.collect.Sets; | 50 | +import java.nio.ByteBuffer; |
51 | +import java.util.ArrayList; | ||
52 | +import java.util.HashMap; | ||
53 | +import java.util.HashSet; | ||
54 | +import java.util.List; | ||
55 | +import java.util.Map; | ||
56 | +import java.util.Random; | ||
57 | +import java.util.Set; | ||
58 | +import java.util.concurrent.CountDownLatch; | ||
59 | +import java.util.concurrent.TimeUnit; | ||
60 | + | ||
61 | +import static org.easymock.EasyMock.*; | ||
62 | +import static org.junit.Assert.assertEquals; | ||
63 | +import static org.junit.Assert.assertNotNull; | ||
70 | 64 | ||
71 | /** | 65 | /** |
72 | * Integration tests for the SDN-IP application. | 66 | * Integration tests for the SDN-IP application. |
... | @@ -130,9 +124,10 @@ public class SdnIpTest extends AbstractIntentTest { | ... | @@ -130,9 +124,10 @@ public class SdnIpTest extends AbstractIntentTest { |
130 | intentService = createMock(IntentService.class); | 124 | intentService = createMock(IntentService.class); |
131 | random = new Random(); | 125 | random = new Random(); |
132 | 126 | ||
133 | - intentSynchronizer = new IntentSynchronizer(APPID, intentService); | 127 | + intentSynchronizer = new IntentSynchronizer(APPID, intentService, |
134 | - router = new Router(APPID, intentSynchronizer, sdnIpConfigService, | 128 | + sdnIpConfigService, |
135 | - interfaceService, hostService); | 129 | + interfaceService); |
130 | + router = new Router(intentSynchronizer, hostService); | ||
136 | } | 131 | } |
137 | 132 | ||
138 | /** | 133 | /** | ... | ... |
-
Please register or login to post a comment