blob: 5b1434256a748210fa23b8e01511a1bb501c5b12 [file] [log] [blame]
sangho80f11cb2015-04-01 13:05:26 -07001/*
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 */
16package org.onosproject.segmentrouting;
17
18import org.onlab.packet.Ethernet;
19import org.onlab.packet.Ip4Address;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070020import org.onlab.packet.Ip4Prefix;
sangho80f11cb2015-04-01 13:05:26 -070021import org.onlab.packet.IpPrefix;
22import org.onlab.packet.MacAddress;
sangho80f11cb2015-04-01 13:05:26 -070023import org.onlab.packet.MplsLabel;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070024import org.onlab.packet.VlanId;
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -070025import org.onosproject.segmentrouting.grouphandler.NeighborSet;
sangho80f11cb2015-04-01 13:05:26 -070026import org.onosproject.net.DeviceId;
27import org.onosproject.net.Link;
28import org.onosproject.net.PortNumber;
sangho80f11cb2015-04-01 13:05:26 -070029import org.onosproject.net.flow.DefaultTrafficSelector;
30import org.onosproject.net.flow.DefaultTrafficTreatment;
sangho80f11cb2015-04-01 13:05:26 -070031import org.onosproject.net.flow.TrafficSelector;
32import org.onosproject.net.flow.TrafficTreatment;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070033import org.onosproject.net.flow.criteria.Criteria;
34import org.onosproject.net.flowobjective.DefaultFilteringObjective;
35import org.onosproject.net.flowobjective.DefaultForwardingObjective;
36import org.onosproject.net.flowobjective.FilteringObjective;
37import org.onosproject.net.flowobjective.ForwardingObjective;
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -070038import org.onosproject.net.flowobjective.Objective;
39import org.onosproject.net.flowobjective.ObjectiveError;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070040import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
Saurav Das9f1c42e2015-10-23 10:51:11 -070041import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -070042import org.onosproject.net.flowobjective.ObjectiveContext;
sangho80f11cb2015-04-01 13:05:26 -070043import org.slf4j.Logger;
44import org.slf4j.LoggerFactory;
45
46import java.util.ArrayList;
sangho80f11cb2015-04-01 13:05:26 -070047import java.util.List;
48import java.util.Set;
sanghofb7c7292015-04-13 15:15:58 -070049import java.util.concurrent.atomic.AtomicLong;
sangho80f11cb2015-04-01 13:05:26 -070050
51import static com.google.common.base.Preconditions.checkNotNull;
52
53public class RoutingRulePopulator {
54
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070055 private static final Logger log = LoggerFactory
56 .getLogger(RoutingRulePopulator.class);
sangho80f11cb2015-04-01 13:05:26 -070057
sanghofb7c7292015-04-13 15:15:58 -070058 private AtomicLong rulePopulationCounter;
sangho9b169e32015-04-14 16:27:13 -070059 private SegmentRoutingManager srManager;
60 private DeviceConfiguration config;
Saurav Das9f1c42e2015-10-23 10:51:11 -070061
62 private static final int HIGHEST_PRIORITY = 0xffff;
63
sangho80f11cb2015-04-01 13:05:26 -070064 /**
65 * Creates a RoutingRulePopulator object.
66 *
Thomas Vachuska8a075092015-04-15 18:20:08 -070067 * @param srManager segment routing manager reference
sangho80f11cb2015-04-01 13:05:26 -070068 */
69 public RoutingRulePopulator(SegmentRoutingManager srManager) {
70 this.srManager = srManager;
sangho9b169e32015-04-14 16:27:13 -070071 this.config = checkNotNull(srManager.deviceConfiguration);
sanghofb7c7292015-04-13 15:15:58 -070072 this.rulePopulationCounter = new AtomicLong(0);
73 }
74
75 /**
76 * Resets the population counter.
77 */
78 public void resetCounter() {
79 rulePopulationCounter.set(0);
80 }
81
82 /**
83 * Returns the number of rules populated.
Thomas Vachuska7cfc6202015-04-30 18:13:25 -070084 *
85 * @return number of rules
sanghofb7c7292015-04-13 15:15:58 -070086 */
87 public long getCounter() {
88 return rulePopulationCounter.get();
sangho80f11cb2015-04-01 13:05:26 -070089 }
90
91 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070092 * Populates IP flow rules for specific hosts directly connected to the
93 * switch.
sangho80f11cb2015-04-01 13:05:26 -070094 *
95 * @param deviceId switch ID to set the rules
96 * @param hostIp host IP address
97 * @param hostMac host MAC address
98 * @param outPort port where the host is connected
99 */
100 public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
101 MacAddress hostMac, PortNumber outPort) {
102 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
103 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
104
Saurav Das9f1c42e2015-10-23 10:51:11 -0700105 sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH));
sangho80f11cb2015-04-01 13:05:26 -0700106 sbuilder.matchEthType(Ethernet.TYPE_IPV4);
107
sangho27462c62015-05-14 00:39:53 -0700108 tbuilder.deferred()
109 .setEthDst(hostMac)
sangho9b169e32015-04-14 16:27:13 -0700110 .setEthSrc(config.getDeviceMac(deviceId))
sangho80f11cb2015-04-01 13:05:26 -0700111 .setOutput(outPort);
112
113 TrafficTreatment treatment = tbuilder.build();
114 TrafficSelector selector = sbuilder.build();
115
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700116 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
117 .builder().fromApp(srManager.appId).makePermanent()
118 .withSelector(selector).withTreatment(treatment)
119 .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC);
sangho80f11cb2015-04-01 13:05:26 -0700120
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700121 log.debug("Installing IPv4 forwarding objective "
122 + "for host {} in switch {}", hostIp, deviceId);
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700123 srManager.flowObjectiveService.
124 forward(deviceId,
125 fwdBuilder.
126 add(new SRObjectiveContext(deviceId,
127 SRObjectiveContext.ObjectiveType.FORWARDING)));
sanghofb7c7292015-04-13 15:15:58 -0700128 rulePopulationCounter.incrementAndGet();
sangho80f11cb2015-04-01 13:05:26 -0700129 }
130
131 /**
132 * Populates IP flow rules for the subnets of the destination router.
133 *
134 * @param deviceId switch ID to set the rules
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700135 * @param subnets subnet information
sangho80f11cb2015-04-01 13:05:26 -0700136 * @param destSw destination switch ID
137 * @param nextHops next hop switch ID list
138 * @return true if all rules are set successfully, false otherwise
139 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700140 public boolean populateIpRuleForSubnet(DeviceId deviceId,
141 List<Ip4Prefix> subnets,
142 DeviceId destSw,
143 Set<DeviceId> nextHops) {
sangho80f11cb2015-04-01 13:05:26 -0700144
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700145 for (IpPrefix subnet : subnets) {
sangho80f11cb2015-04-01 13:05:26 -0700146 if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
147 return false;
148 }
149 }
150
151 return true;
152 }
153
154 /**
155 * Populates IP flow rules for the router IP address.
156 *
Saurav Das88979182015-10-19 14:37:36 -0700157 * @param deviceId target device ID to set the rules
sangho80f11cb2015-04-01 13:05:26 -0700158 * @param ipPrefix the IP address of the destination router
159 * @param destSw device ID of the destination router
160 * @param nextHops next hop switch ID list
161 * @return true if all rules are set successfully, false otherwise
162 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700163 public boolean populateIpRuleForRouter(DeviceId deviceId,
164 IpPrefix ipPrefix, DeviceId destSw,
165 Set<DeviceId> nextHops) {
sangho80f11cb2015-04-01 13:05:26 -0700166
167 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
168 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
169
170 sbuilder.matchIPDst(ipPrefix);
171 sbuilder.matchEthType(Ethernet.TYPE_IPV4);
172
173 NeighborSet ns = null;
174
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700175 // If the next hop is the same as the final destination, then MPLS label
176 // is not set.
sangho80f11cb2015-04-01 13:05:26 -0700177 if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
sangho27462c62015-05-14 00:39:53 -0700178 tbuilder.deferred().decNwTtl();
sangho80f11cb2015-04-01 13:05:26 -0700179 ns = new NeighborSet(nextHops);
180 } else {
sangho27462c62015-05-14 00:39:53 -0700181 tbuilder.deferred().copyTtlOut();
sangho9b169e32015-04-14 16:27:13 -0700182 ns = new NeighborSet(nextHops, config.getSegmentId(destSw));
sangho80f11cb2015-04-01 13:05:26 -0700183 }
184
sangho80f11cb2015-04-01 13:05:26 -0700185 TrafficTreatment treatment = tbuilder.build();
186 TrafficSelector selector = sbuilder.build();
187
sangho2165d222015-05-01 09:38:25 -0700188 if (srManager.getNextObjectiveId(deviceId, ns) <= 0) {
189 log.warn("No next objective in {} for ns: {}", deviceId, ns);
190 return false;
191 }
192
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700193 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
194 .builder()
195 .fromApp(srManager.appId)
196 .makePermanent()
197 .nextStep(srManager.getNextObjectiveId(deviceId, ns))
198 .withTreatment(treatment)
199 .withSelector(selector)
200 .withPriority(100)
201 .withFlag(ForwardingObjective.Flag.SPECIFIC);
202 log.debug("Installing IPv4 forwarding objective "
sangho2165d222015-05-01 09:38:25 -0700203 + "for router IP/subnet {} in switch {}",
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700204 ipPrefix,
205 deviceId);
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700206 srManager.flowObjectiveService.
207 forward(deviceId,
208 fwdBuilder.
209 add(new SRObjectiveContext(deviceId,
210 SRObjectiveContext.ObjectiveType.FORWARDING)));
sanghofb7c7292015-04-13 15:15:58 -0700211 rulePopulationCounter.incrementAndGet();
sangho80f11cb2015-04-01 13:05:26 -0700212
213 return true;
214 }
215
sangho80f11cb2015-04-01 13:05:26 -0700216 /**
Saurav Das88979182015-10-19 14:37:36 -0700217 * Populates MPLS flow rules to all routers.
sangho80f11cb2015-04-01 13:05:26 -0700218 *
Saurav Das88979182015-10-19 14:37:36 -0700219 * @param deviceId target device ID of the switch to set the rules
sangho80f11cb2015-04-01 13:05:26 -0700220 * @param destSwId destination switch device ID
221 * @param nextHops next hops switch ID list
222 * @return true if all rules are set successfully, false otherwise
223 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700224 public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId,
225 Set<DeviceId> nextHops) {
sangho80f11cb2015-04-01 13:05:26 -0700226
227 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
Sho SHIMIZU47b8aa22015-09-11 11:19:11 -0700228 List<ForwardingObjective.Builder> fwdObjBuilders = new ArrayList<>();
sangho80f11cb2015-04-01 13:05:26 -0700229
230 // TODO Handle the case of Bos == false
sangho9b169e32015-04-14 16:27:13 -0700231 sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId)));
sangho80f11cb2015-04-01 13:05:26 -0700232 sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
233
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700234 // If the next hop is the destination router, do PHP
sangho80f11cb2015-04-01 13:05:26 -0700235 if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700236 log.debug("populateMplsRule: Installing MPLS forwarding objective for "
237 + "label {} in switch {} with PHP",
238 config.getSegmentId(destSwId),
239 deviceId);
240
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700241 ForwardingObjective.Builder fwdObjBosBuilder =
242 getMplsForwardingObjective(deviceId,
243 destSwId,
244 nextHops,
245 true,
246 true);
247 // TODO: Check with Sangho on why we need this
248 ForwardingObjective.Builder fwdObjNoBosBuilder =
249 getMplsForwardingObjective(deviceId,
250 destSwId,
251 nextHops,
252 true,
253 false);
254 if (fwdObjBosBuilder != null) {
255 fwdObjBuilders.add(fwdObjBosBuilder);
sangho80f11cb2015-04-01 13:05:26 -0700256 } else {
257 log.warn("Failed to set MPLS rules.");
258 return false;
259 }
260 } else {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700261 log.debug("Installing MPLS forwarding objective for "
262 + "label {} in switch {} without PHP",
263 config.getSegmentId(destSwId),
264 deviceId);
265
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700266 ForwardingObjective.Builder fwdObjBosBuilder =
267 getMplsForwardingObjective(deviceId,
268 destSwId,
269 nextHops,
270 false,
271 true);
272 // TODO: Check with Sangho on why we need this
273 ForwardingObjective.Builder fwdObjNoBosBuilder =
274 getMplsForwardingObjective(deviceId,
275 destSwId,
276 nextHops,
277 false,
278 false);
279 if (fwdObjBosBuilder != null) {
280 fwdObjBuilders.add(fwdObjBosBuilder);
sangho80f11cb2015-04-01 13:05:26 -0700281 } else {
282 log.warn("Failed to set MPLS rules.");
283 return false;
284 }
285 }
286
287 TrafficSelector selector = sbuilder.build();
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700288 for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
289 ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId)
290 .makePermanent()).withSelector(selector)
291 .withPriority(100))
292 .withFlag(ForwardingObjective.Flag.SPECIFIC);
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700293 srManager.flowObjectiveService.
294 forward(deviceId,
295 fwdObjBuilder.
296 add(new SRObjectiveContext(deviceId,
297 SRObjectiveContext.ObjectiveType.FORWARDING)));
sanghofb7c7292015-04-13 15:15:58 -0700298 rulePopulationCounter.incrementAndGet();
sangho80f11cb2015-04-01 13:05:26 -0700299 }
300
301 return true;
302 }
303
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700304 private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId deviceId,
305 DeviceId destSw,
306 Set<DeviceId> nextHops,
307 boolean phpRequired,
308 boolean isBos) {
sangho80f11cb2015-04-01 13:05:26 -0700309
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700310 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
311 .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
sangho80f11cb2015-04-01 13:05:26 -0700312
313 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
314
315 if (phpRequired) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700316 log.debug("getMplsForwardingObjective: php required");
sangho27462c62015-05-14 00:39:53 -0700317 tbuilder.deferred().copyTtlIn();
sangho80f11cb2015-04-01 13:05:26 -0700318 if (isBos) {
sangho27462c62015-05-14 00:39:53 -0700319 tbuilder.deferred().popMpls(Ethernet.TYPE_IPV4).decNwTtl();
sangho80f11cb2015-04-01 13:05:26 -0700320 } else {
sangho27462c62015-05-14 00:39:53 -0700321 tbuilder.deferred().popMpls(Ethernet.MPLS_UNICAST).decMplsTtl();
sangho80f11cb2015-04-01 13:05:26 -0700322 }
323 } else {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700324 log.debug("getMplsForwardingObjective: php not required");
sangho27462c62015-05-14 00:39:53 -0700325 tbuilder.deferred().decMplsTtl();
sangho80f11cb2015-04-01 13:05:26 -0700326 }
327
sangho9b169e32015-04-14 16:27:13 -0700328 if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) {
sangho28d0b6d2015-05-07 13:30:57 -0700329 PortNumber port = selectOnePort(deviceId, nextHops);
sangho9b169e32015-04-14 16:27:13 -0700330 DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
sangho28d0b6d2015-05-07 13:30:57 -0700331 if (port == null) {
sangho80f11cb2015-04-01 13:05:26 -0700332 log.warn("No link from {} to {}", deviceId, nextHops);
333 return null;
334 }
sangho27462c62015-05-14 00:39:53 -0700335 tbuilder.deferred()
336 .setEthSrc(config.getDeviceMac(deviceId))
sangho9b169e32015-04-14 16:27:13 -0700337 .setEthDst(config.getDeviceMac(nextHop))
sangho28d0b6d2015-05-07 13:30:57 -0700338 .setOutput(port);
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700339 fwdBuilder.withTreatment(tbuilder.build());
sangho80f11cb2015-04-01 13:05:26 -0700340 } else {
341 NeighborSet ns = new NeighborSet(nextHops);
sangho3cd8db62015-05-06 11:42:31 -0700342 fwdBuilder.withTreatment(tbuilder.build());
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700343 fwdBuilder.nextStep(srManager
344 .getNextObjectiveId(deviceId, ns));
sangho80f11cb2015-04-01 13:05:26 -0700345 }
346
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700347 return fwdBuilder;
sangho80f11cb2015-04-01 13:05:26 -0700348 }
349
sangho9b169e32015-04-14 16:27:13 -0700350 private boolean isECMPSupportedInTransitRouter() {
351
352 // TODO: remove this function when objectives subsystem is supported.
353 return false;
354 }
355
sangho80f11cb2015-04-01 13:05:26 -0700356 /**
Saurav Das9f1c42e2015-10-23 10:51:11 -0700357 * Creates a filtering objective to permit all untagged packets with a
358 * dstMac corresponding to the router's MAC address.
sangho80f11cb2015-04-01 13:05:26 -0700359 *
Saurav Das9f1c42e2015-10-23 10:51:11 -0700360 * @param deviceId the switch dpid for the router
sangho80f11cb2015-04-01 13:05:26 -0700361 */
Saurav Das9f1c42e2015-10-23 10:51:11 -0700362 public void populateRouterMacVlanFilters(DeviceId deviceId) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700363 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
364 fob.withKey(Criteria.matchInPort(PortNumber.ALL))
Saurav Das9f1c42e2015-10-23 10:51:11 -0700365 .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId)))
366 .addCondition(Criteria.matchVlanId(VlanId.NONE))
367 .addCondition(Criteria.matchIPDst(
368 IpPrefix.valueOf(config.getRouterIp(deviceId),
369 IpPrefix.MAX_INET_MASK_LENGTH)));
370
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700371 fob.permit().fromApp(srManager.appId);
Saurav Das9f1c42e2015-10-23 10:51:11 -0700372 log.debug("Installing filtering objective for untagged packets");
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700373 srManager.flowObjectiveService.
374 filter(deviceId,
375 fob.add(new SRObjectiveContext(deviceId,
376 SRObjectiveContext.ObjectiveType.FILTER)));
sangho80f11cb2015-04-01 13:05:26 -0700377 }
378
379 /**
Saurav Das9f1c42e2015-10-23 10:51:11 -0700380 * Creates a forwarding objective to punt all IP packets, destined to the
381 * router's port IP addresses, to the controller. Note that it the input
382 * port should not be matched on, as these packets can come from any input.
sangho80f11cb2015-04-01 13:05:26 -0700383 *
Saurav Das9f1c42e2015-10-23 10:51:11 -0700384 * @param deviceId the switch dpid for the router
sangho80f11cb2015-04-01 13:05:26 -0700385 */
Saurav Das9f1c42e2015-10-23 10:51:11 -0700386 public void populateRouterIpPunts(DeviceId deviceId) {
387 ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
sangho80f11cb2015-04-01 13:05:26 -0700388
Saurav Das9f1c42e2015-10-23 10:51:11 -0700389 List<Ip4Address> gws = config.getPortIPs(deviceId);
390 for (Ip4Address ipaddr : gws) {
391 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
392 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
393 selector.matchEthType(Ethernet.TYPE_IPV4);
394 selector.matchIPDst(IpPrefix.valueOf(ipaddr,
395 IpPrefix.MAX_INET_MASK_LENGTH));
396 treatment.setOutput(PortNumber.CONTROLLER);
397 puntIp.withSelector(selector.build());
398 puntIp.withTreatment(treatment.build());
399 puntIp.withFlag(Flag.VERSATILE)
400 .withPriority(HIGHEST_PRIORITY)
401 .makePermanent()
402 .fromApp(srManager.appId);
403 log.debug("Installing forwarding objective to punt port IP addresses");
404 srManager.flowObjectiveService.
405 forward(deviceId,
406 puntIp.add(new SRObjectiveContext(deviceId,
407 SRObjectiveContext.ObjectiveType.FORWARDING)));
408 }
sangho80f11cb2015-04-01 13:05:26 -0700409 }
410
sangho28d0b6d2015-05-07 13:30:57 -0700411 private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) {
sangho80f11cb2015-04-01 13:05:26 -0700412
sangho28d0b6d2015-05-07 13:30:57 -0700413 Set<Link> links = srManager.linkService.getDeviceLinks(srcId);
414 for (DeviceId destId: destIds) {
415 for (Link link : links) {
416 if (link.dst().deviceId().equals(destId)) {
417 return link.src().port();
418 } else if (link.src().deviceId().equals(destId)) {
419 return link.dst().port();
420 }
sangho80f11cb2015-04-01 13:05:26 -0700421 }
422 }
423
424 return null;
425 }
426
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700427 private static class SRObjectiveContext implements ObjectiveContext {
428 enum ObjectiveType {
429 FILTER,
430 FORWARDING
431 }
432 final DeviceId deviceId;
433 final ObjectiveType type;
434
435 SRObjectiveContext(DeviceId deviceId, ObjectiveType type) {
436 this.deviceId = deviceId;
437 this.type = type;
438 }
439 @Override
440 public void onSuccess(Objective objective) {
441 log.debug("{} objective operation successful in device {}",
442 type.name(), deviceId);
443 }
444
445 @Override
446 public void onError(Objective objective, ObjectiveError error) {
447 log.warn("{} objective {} operation failed with error: {} in device {}",
448 type.name(), objective, error, deviceId);
449 }
450 }
451
sangho80f11cb2015-04-01 13:05:26 -0700452}