Jonathan Hart
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 +}
...@@ -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 }
......
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.
......
...@@ -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) {
......