blob: 6e4de1246322324fc7974b4ec730d144d5d8a6b0 [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;
Saurav Das7c305372015-10-28 12:39:42 -070028import org.onosproject.net.Port;
sangho80f11cb2015-04-01 13:05:26 -070029import org.onosproject.net.PortNumber;
sangho80f11cb2015-04-01 13:05:26 -070030import org.onosproject.net.flow.DefaultTrafficSelector;
31import org.onosproject.net.flow.DefaultTrafficTreatment;
sangho80f11cb2015-04-01 13:05:26 -070032import org.onosproject.net.flow.TrafficSelector;
33import org.onosproject.net.flow.TrafficTreatment;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070034import org.onosproject.net.flow.criteria.Criteria;
35import org.onosproject.net.flowobjective.DefaultFilteringObjective;
36import org.onosproject.net.flowobjective.DefaultForwardingObjective;
37import org.onosproject.net.flowobjective.FilteringObjective;
38import org.onosproject.net.flowobjective.ForwardingObjective;
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -070039import org.onosproject.net.flowobjective.Objective;
40import org.onosproject.net.flowobjective.ObjectiveError;
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070041import org.onosproject.net.flowobjective.ForwardingObjective.Builder;
Saurav Das9f1c42e2015-10-23 10:51:11 -070042import org.onosproject.net.flowobjective.ForwardingObjective.Flag;
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -070043import org.onosproject.net.flowobjective.ObjectiveContext;
sangho80f11cb2015-04-01 13:05:26 -070044import org.slf4j.Logger;
45import org.slf4j.LoggerFactory;
46
47import java.util.ArrayList;
sangho80f11cb2015-04-01 13:05:26 -070048import java.util.List;
49import java.util.Set;
sanghofb7c7292015-04-13 15:15:58 -070050import java.util.concurrent.atomic.AtomicLong;
sangho80f11cb2015-04-01 13:05:26 -070051
52import static com.google.common.base.Preconditions.checkNotNull;
53
54public class RoutingRulePopulator {
55
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070056 private static final Logger log = LoggerFactory
57 .getLogger(RoutingRulePopulator.class);
sangho80f11cb2015-04-01 13:05:26 -070058
sanghofb7c7292015-04-13 15:15:58 -070059 private AtomicLong rulePopulationCounter;
sangho9b169e32015-04-14 16:27:13 -070060 private SegmentRoutingManager srManager;
61 private DeviceConfiguration config;
Saurav Das9f1c42e2015-10-23 10:51:11 -070062
63 private static final int HIGHEST_PRIORITY = 0xffff;
Saurav Das7c305372015-10-28 12:39:42 -070064 private static final long OFPP_MAX = 0xffffff00L;
65
Saurav Das9f1c42e2015-10-23 10:51:11 -070066
sangho80f11cb2015-04-01 13:05:26 -070067 /**
68 * Creates a RoutingRulePopulator object.
69 *
Thomas Vachuska8a075092015-04-15 18:20:08 -070070 * @param srManager segment routing manager reference
sangho80f11cb2015-04-01 13:05:26 -070071 */
72 public RoutingRulePopulator(SegmentRoutingManager srManager) {
73 this.srManager = srManager;
sangho9b169e32015-04-14 16:27:13 -070074 this.config = checkNotNull(srManager.deviceConfiguration);
sanghofb7c7292015-04-13 15:15:58 -070075 this.rulePopulationCounter = new AtomicLong(0);
76 }
77
78 /**
79 * Resets the population counter.
80 */
81 public void resetCounter() {
82 rulePopulationCounter.set(0);
83 }
84
85 /**
86 * Returns the number of rules populated.
Thomas Vachuska7cfc6202015-04-30 18:13:25 -070087 *
88 * @return number of rules
sanghofb7c7292015-04-13 15:15:58 -070089 */
90 public long getCounter() {
91 return rulePopulationCounter.get();
sangho80f11cb2015-04-01 13:05:26 -070092 }
93
94 /**
Srikanth Vavilapalli64505482015-04-21 13:04:13 -070095 * Populates IP flow rules for specific hosts directly connected to the
96 * switch.
sangho80f11cb2015-04-01 13:05:26 -070097 *
98 * @param deviceId switch ID to set the rules
99 * @param hostIp host IP address
100 * @param hostMac host MAC address
101 * @param outPort port where the host is connected
102 */
103 public void populateIpRuleForHost(DeviceId deviceId, Ip4Address hostIp,
104 MacAddress hostMac, PortNumber outPort) {
105 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
106 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
107
Saurav Das9f1c42e2015-10-23 10:51:11 -0700108 sbuilder.matchIPDst(IpPrefix.valueOf(hostIp, IpPrefix.MAX_INET_MASK_LENGTH));
sangho80f11cb2015-04-01 13:05:26 -0700109 sbuilder.matchEthType(Ethernet.TYPE_IPV4);
110
sangho27462c62015-05-14 00:39:53 -0700111 tbuilder.deferred()
112 .setEthDst(hostMac)
sangho9b169e32015-04-14 16:27:13 -0700113 .setEthSrc(config.getDeviceMac(deviceId))
sangho80f11cb2015-04-01 13:05:26 -0700114 .setOutput(outPort);
115
116 TrafficTreatment treatment = tbuilder.build();
117 TrafficSelector selector = sbuilder.build();
118
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700119 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
120 .builder().fromApp(srManager.appId).makePermanent()
121 .withSelector(selector).withTreatment(treatment)
122 .withPriority(100).withFlag(ForwardingObjective.Flag.SPECIFIC);
sangho80f11cb2015-04-01 13:05:26 -0700123
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700124 log.debug("Installing IPv4 forwarding objective "
125 + "for host {} in switch {}", hostIp, deviceId);
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700126 srManager.flowObjectiveService.
127 forward(deviceId,
128 fwdBuilder.
129 add(new SRObjectiveContext(deviceId,
130 SRObjectiveContext.ObjectiveType.FORWARDING)));
sanghofb7c7292015-04-13 15:15:58 -0700131 rulePopulationCounter.incrementAndGet();
sangho80f11cb2015-04-01 13:05:26 -0700132 }
133
134 /**
135 * Populates IP flow rules for the subnets of the destination router.
136 *
137 * @param deviceId switch ID to set the rules
Srikanth Vavilapalli37a461b2015-04-07 15:12:32 -0700138 * @param subnets subnet information
sangho80f11cb2015-04-01 13:05:26 -0700139 * @param destSw destination switch ID
140 * @param nextHops next hop switch ID list
141 * @return true if all rules are set successfully, false otherwise
142 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700143 public boolean populateIpRuleForSubnet(DeviceId deviceId,
144 List<Ip4Prefix> subnets,
145 DeviceId destSw,
146 Set<DeviceId> nextHops) {
sangho80f11cb2015-04-01 13:05:26 -0700147
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700148 for (IpPrefix subnet : subnets) {
sangho80f11cb2015-04-01 13:05:26 -0700149 if (!populateIpRuleForRouter(deviceId, subnet, destSw, nextHops)) {
150 return false;
151 }
152 }
153
154 return true;
155 }
156
157 /**
158 * Populates IP flow rules for the router IP address.
159 *
Saurav Das88979182015-10-19 14:37:36 -0700160 * @param deviceId target device ID to set the rules
sangho80f11cb2015-04-01 13:05:26 -0700161 * @param ipPrefix the IP address of the destination router
162 * @param destSw device ID of the destination router
163 * @param nextHops next hop switch ID list
164 * @return true if all rules are set successfully, false otherwise
165 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700166 public boolean populateIpRuleForRouter(DeviceId deviceId,
167 IpPrefix ipPrefix, DeviceId destSw,
168 Set<DeviceId> nextHops) {
sangho80f11cb2015-04-01 13:05:26 -0700169
170 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
171 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
172
173 sbuilder.matchIPDst(ipPrefix);
174 sbuilder.matchEthType(Ethernet.TYPE_IPV4);
175
176 NeighborSet ns = null;
177
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700178 // If the next hop is the same as the final destination, then MPLS label
179 // is not set.
sangho80f11cb2015-04-01 13:05:26 -0700180 if (nextHops.size() == 1 && nextHops.toArray()[0].equals(destSw)) {
sangho27462c62015-05-14 00:39:53 -0700181 tbuilder.deferred().decNwTtl();
sangho80f11cb2015-04-01 13:05:26 -0700182 ns = new NeighborSet(nextHops);
183 } else {
sangho27462c62015-05-14 00:39:53 -0700184 tbuilder.deferred().copyTtlOut();
sangho9b169e32015-04-14 16:27:13 -0700185 ns = new NeighborSet(nextHops, config.getSegmentId(destSw));
sangho80f11cb2015-04-01 13:05:26 -0700186 }
187
sangho80f11cb2015-04-01 13:05:26 -0700188 TrafficTreatment treatment = tbuilder.build();
189 TrafficSelector selector = sbuilder.build();
190
sangho2165d222015-05-01 09:38:25 -0700191 if (srManager.getNextObjectiveId(deviceId, ns) <= 0) {
192 log.warn("No next objective in {} for ns: {}", deviceId, ns);
193 return false;
194 }
195
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700196 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
197 .builder()
198 .fromApp(srManager.appId)
199 .makePermanent()
200 .nextStep(srManager.getNextObjectiveId(deviceId, ns))
201 .withTreatment(treatment)
202 .withSelector(selector)
203 .withPriority(100)
204 .withFlag(ForwardingObjective.Flag.SPECIFIC);
205 log.debug("Installing IPv4 forwarding objective "
sangho2165d222015-05-01 09:38:25 -0700206 + "for router IP/subnet {} in switch {}",
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700207 ipPrefix,
208 deviceId);
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700209 srManager.flowObjectiveService.
210 forward(deviceId,
211 fwdBuilder.
212 add(new SRObjectiveContext(deviceId,
213 SRObjectiveContext.ObjectiveType.FORWARDING)));
sanghofb7c7292015-04-13 15:15:58 -0700214 rulePopulationCounter.incrementAndGet();
sangho80f11cb2015-04-01 13:05:26 -0700215
216 return true;
217 }
218
sangho80f11cb2015-04-01 13:05:26 -0700219 /**
Saurav Das88979182015-10-19 14:37:36 -0700220 * Populates MPLS flow rules to all routers.
sangho80f11cb2015-04-01 13:05:26 -0700221 *
Saurav Das88979182015-10-19 14:37:36 -0700222 * @param deviceId target device ID of the switch to set the rules
sangho80f11cb2015-04-01 13:05:26 -0700223 * @param destSwId destination switch device ID
224 * @param nextHops next hops switch ID list
225 * @return true if all rules are set successfully, false otherwise
226 */
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700227 public boolean populateMplsRule(DeviceId deviceId, DeviceId destSwId,
228 Set<DeviceId> nextHops) {
sangho80f11cb2015-04-01 13:05:26 -0700229
230 TrafficSelector.Builder sbuilder = DefaultTrafficSelector.builder();
Sho SHIMIZU47b8aa22015-09-11 11:19:11 -0700231 List<ForwardingObjective.Builder> fwdObjBuilders = new ArrayList<>();
sangho80f11cb2015-04-01 13:05:26 -0700232
233 // TODO Handle the case of Bos == false
sangho9b169e32015-04-14 16:27:13 -0700234 sbuilder.matchMplsLabel(MplsLabel.mplsLabel(config.getSegmentId(destSwId)));
sangho80f11cb2015-04-01 13:05:26 -0700235 sbuilder.matchEthType(Ethernet.MPLS_UNICAST);
236
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700237 // If the next hop is the destination router, do PHP
sangho80f11cb2015-04-01 13:05:26 -0700238 if (nextHops.size() == 1 && destSwId.equals(nextHops.toArray()[0])) {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700239 log.debug("populateMplsRule: Installing MPLS forwarding objective for "
240 + "label {} in switch {} with PHP",
241 config.getSegmentId(destSwId),
242 deviceId);
243
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700244 ForwardingObjective.Builder fwdObjBosBuilder =
245 getMplsForwardingObjective(deviceId,
246 destSwId,
247 nextHops,
248 true,
249 true);
250 // TODO: Check with Sangho on why we need this
251 ForwardingObjective.Builder fwdObjNoBosBuilder =
252 getMplsForwardingObjective(deviceId,
253 destSwId,
254 nextHops,
255 true,
256 false);
257 if (fwdObjBosBuilder != null) {
258 fwdObjBuilders.add(fwdObjBosBuilder);
sangho80f11cb2015-04-01 13:05:26 -0700259 } else {
260 log.warn("Failed to set MPLS rules.");
261 return false;
262 }
263 } else {
Srikanth Vavilapalli7cd16712015-05-04 09:48:09 -0700264 log.debug("Installing MPLS forwarding objective for "
265 + "label {} in switch {} without PHP",
266 config.getSegmentId(destSwId),
267 deviceId);
268
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700269 ForwardingObjective.Builder fwdObjBosBuilder =
270 getMplsForwardingObjective(deviceId,
271 destSwId,
272 nextHops,
273 false,
274 true);
275 // TODO: Check with Sangho on why we need this
276 ForwardingObjective.Builder fwdObjNoBosBuilder =
277 getMplsForwardingObjective(deviceId,
278 destSwId,
279 nextHops,
280 false,
281 false);
282 if (fwdObjBosBuilder != null) {
283 fwdObjBuilders.add(fwdObjBosBuilder);
sangho80f11cb2015-04-01 13:05:26 -0700284 } else {
285 log.warn("Failed to set MPLS rules.");
286 return false;
287 }
288 }
289
290 TrafficSelector selector = sbuilder.build();
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700291 for (ForwardingObjective.Builder fwdObjBuilder : fwdObjBuilders) {
292 ((Builder) ((Builder) fwdObjBuilder.fromApp(srManager.appId)
293 .makePermanent()).withSelector(selector)
294 .withPriority(100))
295 .withFlag(ForwardingObjective.Flag.SPECIFIC);
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700296 srManager.flowObjectiveService.
297 forward(deviceId,
298 fwdObjBuilder.
299 add(new SRObjectiveContext(deviceId,
300 SRObjectiveContext.ObjectiveType.FORWARDING)));
sanghofb7c7292015-04-13 15:15:58 -0700301 rulePopulationCounter.incrementAndGet();
sangho80f11cb2015-04-01 13:05:26 -0700302 }
303
304 return true;
305 }
306
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700307 private ForwardingObjective.Builder getMplsForwardingObjective(DeviceId deviceId,
308 DeviceId destSw,
309 Set<DeviceId> nextHops,
310 boolean phpRequired,
311 boolean isBos) {
sangho80f11cb2015-04-01 13:05:26 -0700312
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700313 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective
314 .builder().withFlag(ForwardingObjective.Flag.SPECIFIC);
sangho80f11cb2015-04-01 13:05:26 -0700315
316 TrafficTreatment.Builder tbuilder = DefaultTrafficTreatment.builder();
317
318 if (phpRequired) {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700319 log.debug("getMplsForwardingObjective: php required");
sangho27462c62015-05-14 00:39:53 -0700320 tbuilder.deferred().copyTtlIn();
sangho80f11cb2015-04-01 13:05:26 -0700321 if (isBos) {
sangho27462c62015-05-14 00:39:53 -0700322 tbuilder.deferred().popMpls(Ethernet.TYPE_IPV4).decNwTtl();
sangho80f11cb2015-04-01 13:05:26 -0700323 } else {
sangho27462c62015-05-14 00:39:53 -0700324 tbuilder.deferred().popMpls(Ethernet.MPLS_UNICAST).decMplsTtl();
sangho80f11cb2015-04-01 13:05:26 -0700325 }
326 } else {
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700327 log.debug("getMplsForwardingObjective: php not required");
sangho27462c62015-05-14 00:39:53 -0700328 tbuilder.deferred().decMplsTtl();
sangho80f11cb2015-04-01 13:05:26 -0700329 }
330
sangho9b169e32015-04-14 16:27:13 -0700331 if (!isECMPSupportedInTransitRouter() && !config.isEdgeDevice(deviceId)) {
sangho28d0b6d2015-05-07 13:30:57 -0700332 PortNumber port = selectOnePort(deviceId, nextHops);
sangho9b169e32015-04-14 16:27:13 -0700333 DeviceId nextHop = (DeviceId) nextHops.toArray()[0];
sangho28d0b6d2015-05-07 13:30:57 -0700334 if (port == null) {
sangho80f11cb2015-04-01 13:05:26 -0700335 log.warn("No link from {} to {}", deviceId, nextHops);
336 return null;
337 }
sangho27462c62015-05-14 00:39:53 -0700338 tbuilder.deferred()
339 .setEthSrc(config.getDeviceMac(deviceId))
sangho9b169e32015-04-14 16:27:13 -0700340 .setEthDst(config.getDeviceMac(nextHop))
sangho28d0b6d2015-05-07 13:30:57 -0700341 .setOutput(port);
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700342 fwdBuilder.withTreatment(tbuilder.build());
sangho80f11cb2015-04-01 13:05:26 -0700343 } else {
344 NeighborSet ns = new NeighborSet(nextHops);
sangho3cd8db62015-05-06 11:42:31 -0700345 fwdBuilder.withTreatment(tbuilder.build());
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700346 fwdBuilder.nextStep(srManager
347 .getNextObjectiveId(deviceId, ns));
sangho80f11cb2015-04-01 13:05:26 -0700348 }
349
Srikanth Vavilapalli64505482015-04-21 13:04:13 -0700350 return fwdBuilder;
sangho80f11cb2015-04-01 13:05:26 -0700351 }
352
sangho9b169e32015-04-14 16:27:13 -0700353 private boolean isECMPSupportedInTransitRouter() {
354
355 // TODO: remove this function when objectives subsystem is supported.
356 return false;
357 }
358
sangho80f11cb2015-04-01 13:05:26 -0700359 /**
Saurav Das9f1c42e2015-10-23 10:51:11 -0700360 * Creates a filtering objective to permit all untagged packets with a
Saurav Das7c305372015-10-28 12:39:42 -0700361 * dstMac corresponding to the router's MAC address. For those pipelines
362 * that need to internally assign vlans to untagged packets, this method
363 * provides per-subnet vlan-ids as metadata.
sangho80f11cb2015-04-01 13:05:26 -0700364 *
Saurav Das9f1c42e2015-10-23 10:51:11 -0700365 * @param deviceId the switch dpid for the router
sangho80f11cb2015-04-01 13:05:26 -0700366 */
Saurav Das9f1c42e2015-10-23 10:51:11 -0700367 public void populateRouterMacVlanFilters(DeviceId deviceId) {
Saurav Das7c305372015-10-28 12:39:42 -0700368 log.debug("Installing per-port filtering objective for untagged "
369 + "packets in device {}", deviceId);
370 for (Port port : srManager.deviceService.getPorts(deviceId)) {
371 if (port.number().toLong() > 0 && port.number().toLong() < OFPP_MAX) {
372 Ip4Prefix portSubnet = config.getPortSubnet(deviceId, port.number());
373 VlanId assignedVlan = (portSubnet == null)
374 ? VlanId.vlanId(SegmentRoutingManager.ASSIGNED_VLAN_NO_SUBNET)
375 : srManager.getSubnetAssignedVlanId(deviceId, portSubnet);
376 TrafficTreatment tt = DefaultTrafficTreatment.builder()
377 .pushVlan().setVlanId(assignedVlan).build();
378 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
379 fob.withKey(Criteria.matchInPort(port.number()))
Saurav Das9f1c42e2015-10-23 10:51:11 -0700380 .addCondition(Criteria.matchEthDst(config.getDeviceMac(deviceId)))
381 .addCondition(Criteria.matchVlanId(VlanId.NONE))
Saurav Das7c305372015-10-28 12:39:42 -0700382 .setMeta(tt)
383 .addCondition(Criteria.matchIPDst(IpPrefix.valueOf(
384 config.getRouterIp(deviceId),
385 IpPrefix.MAX_INET_MASK_LENGTH)));
386 fob.permit().fromApp(srManager.appId);
387 srManager.flowObjectiveService.
388 filter(deviceId, fob.add(new SRObjectiveContext(deviceId,
389 SRObjectiveContext.ObjectiveType.FILTER)));
390 }
391 }
sangho80f11cb2015-04-01 13:05:26 -0700392 }
393
394 /**
Saurav Das9f1c42e2015-10-23 10:51:11 -0700395 * Creates a forwarding objective to punt all IP packets, destined to the
396 * router's port IP addresses, to the controller. Note that it the input
397 * port should not be matched on, as these packets can come from any input.
sangho80f11cb2015-04-01 13:05:26 -0700398 *
Saurav Das9f1c42e2015-10-23 10:51:11 -0700399 * @param deviceId the switch dpid for the router
sangho80f11cb2015-04-01 13:05:26 -0700400 */
Saurav Das9f1c42e2015-10-23 10:51:11 -0700401 public void populateRouterIpPunts(DeviceId deviceId) {
402 ForwardingObjective.Builder puntIp = DefaultForwardingObjective.builder();
sangho80f11cb2015-04-01 13:05:26 -0700403
Saurav Das9f1c42e2015-10-23 10:51:11 -0700404 List<Ip4Address> gws = config.getPortIPs(deviceId);
405 for (Ip4Address ipaddr : gws) {
406 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
407 TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
408 selector.matchEthType(Ethernet.TYPE_IPV4);
409 selector.matchIPDst(IpPrefix.valueOf(ipaddr,
410 IpPrefix.MAX_INET_MASK_LENGTH));
411 treatment.setOutput(PortNumber.CONTROLLER);
412 puntIp.withSelector(selector.build());
413 puntIp.withTreatment(treatment.build());
414 puntIp.withFlag(Flag.VERSATILE)
415 .withPriority(HIGHEST_PRIORITY)
416 .makePermanent()
417 .fromApp(srManager.appId);
418 log.debug("Installing forwarding objective to punt port IP addresses");
419 srManager.flowObjectiveService.
420 forward(deviceId,
421 puntIp.add(new SRObjectiveContext(deviceId,
422 SRObjectiveContext.ObjectiveType.FORWARDING)));
423 }
sangho80f11cb2015-04-01 13:05:26 -0700424 }
425
sangho28d0b6d2015-05-07 13:30:57 -0700426 private PortNumber selectOnePort(DeviceId srcId, Set<DeviceId> destIds) {
sangho80f11cb2015-04-01 13:05:26 -0700427
sangho28d0b6d2015-05-07 13:30:57 -0700428 Set<Link> links = srManager.linkService.getDeviceLinks(srcId);
429 for (DeviceId destId: destIds) {
430 for (Link link : links) {
431 if (link.dst().deviceId().equals(destId)) {
432 return link.src().port();
433 } else if (link.src().deviceId().equals(destId)) {
434 return link.dst().port();
435 }
sangho80f11cb2015-04-01 13:05:26 -0700436 }
437 }
438
439 return null;
440 }
441
Srikanth Vavilapalli8c83f1d2015-05-22 13:47:31 -0700442 private static class SRObjectiveContext implements ObjectiveContext {
443 enum ObjectiveType {
444 FILTER,
445 FORWARDING
446 }
447 final DeviceId deviceId;
448 final ObjectiveType type;
449
450 SRObjectiveContext(DeviceId deviceId, ObjectiveType type) {
451 this.deviceId = deviceId;
452 this.type = type;
453 }
454 @Override
455 public void onSuccess(Objective objective) {
456 log.debug("{} objective operation successful in device {}",
457 type.name(), deviceId);
458 }
459
460 @Override
461 public void onError(Objective objective, ObjectiveError error) {
462 log.warn("{} objective {} operation failed with error: {} in device {}",
463 type.name(), objective, error, deviceId);
464 }
465 }
466
sangho80f11cb2015-04-01 13:05:26 -0700467}