blob: 9a6680e047f836a6626a81fa776ee2e29d46a34d [file] [log] [blame]
Jonathan Hartf5829202015-02-12 09:37:02 -08001/*
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.bgprouter;
17
alshabib910aff12015-04-09 16:55:57 -070018import com.google.common.collect.ConcurrentHashMultiset;
19import com.google.common.collect.HashMultimap;
20import com.google.common.collect.Maps;
21import com.google.common.collect.Multimap;
22import com.google.common.collect.Multiset;
Saurav Dasbd7f7422015-04-23 16:31:47 -070023
Jonathan Hartf5829202015-02-12 09:37:02 -080024import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
29import org.onlab.packet.Ethernet;
Jonathan Hart7baba072015-02-23 14:27:59 -080030import org.onlab.packet.IpAddress;
31import org.onlab.packet.IpPrefix;
Jonathan Hart54b406b2015-03-06 16:24:14 -080032import org.onosproject.config.NetworkConfigService;
Jonathan Hartf5829202015-02-12 09:37:02 -080033import org.onosproject.core.ApplicationId;
34import org.onosproject.core.CoreService;
35import org.onosproject.net.DeviceId;
Saurav Dasbd7f7422015-04-23 16:31:47 -070036import org.onosproject.net.device.DeviceEvent;
37import org.onosproject.net.device.DeviceListener;
38import org.onosproject.net.device.DeviceService;
Jonathan Hartf5829202015-02-12 09:37:02 -080039import org.onosproject.net.flow.DefaultTrafficSelector;
40import org.onosproject.net.flow.DefaultTrafficTreatment;
Jonathan Hartf5829202015-02-12 09:37:02 -080041import org.onosproject.net.flow.TrafficSelector;
42import org.onosproject.net.flow.TrafficTreatment;
alshabib910aff12015-04-09 16:55:57 -070043import org.onosproject.net.flow.criteria.Criteria;
44import org.onosproject.net.flowobjective.DefaultFilteringObjective;
alshabib2a441c62015-04-13 18:39:38 -070045import org.onosproject.net.flowobjective.DefaultForwardingObjective;
46import org.onosproject.net.flowobjective.DefaultNextObjective;
alshabib910aff12015-04-09 16:55:57 -070047import org.onosproject.net.flowobjective.FilteringObjective;
48import org.onosproject.net.flowobjective.FlowObjectiveService;
alshabib2a441c62015-04-13 18:39:38 -070049import org.onosproject.net.flowobjective.ForwardingObjective;
50import org.onosproject.net.flowobjective.NextObjective;
Saurav Dasbd7f7422015-04-23 16:31:47 -070051import org.onosproject.net.flowobjective.Objective;
52import org.onosproject.net.flowobjective.ObjectiveContext;
53import org.onosproject.net.flowobjective.ObjectiveError;
Jonathan Hartf5829202015-02-12 09:37:02 -080054import org.onosproject.net.packet.PacketService;
Jonathan Hart7baba072015-02-23 14:27:59 -080055import org.onosproject.routing.FibEntry;
Jonathan Hart2da1e602015-02-18 19:09:24 -080056import org.onosproject.routing.FibListener;
57import org.onosproject.routing.FibUpdate;
58import org.onosproject.routing.RoutingService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080059import org.onosproject.routing.config.BgpSpeaker;
Jonathan Hart2da1e602015-02-18 19:09:24 -080060import org.onosproject.routing.config.Interface;
61import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hartf5829202015-02-12 09:37:02 -080062import org.slf4j.Logger;
63import org.slf4j.LoggerFactory;
64
alshabib910aff12015-04-09 16:55:57 -070065import java.util.Collection;
alshabib910aff12015-04-09 16:55:57 -070066import java.util.HashMap;
alshabib910aff12015-04-09 16:55:57 -070067import java.util.Map;
68import java.util.Set;
alshabib2a441c62015-04-13 18:39:38 -070069
Saurav Dasdfc639e2015-04-30 11:48:16 -070070/* For test only - will be removed before Cardinal release
71import org.onlab.packet.Ip4Address;
72import org.onlab.packet.Ip4Prefix;
73import org.onlab.packet.MacAddress;
74import java.util.Collections;
75import static org.onlab.util.Tools.delay;
76*/
77
Jonathan Hartf5829202015-02-12 09:37:02 -080078/**
79 * BgpRouter component.
80 */
81@Component(immediate = true)
82public class BgpRouter {
83
84 private static final Logger log = LoggerFactory.getLogger(BgpRouter.class);
85
86 private static final String BGP_ROUTER_APP = "org.onosproject.bgprouter";
87
Jonathan Hart12ef2052015-03-10 13:58:13 -070088 private static final int PRIORITY_OFFSET = 100;
89 private static final int PRIORITY_MULTIPLIER = 5;
Jonathan Hartf5829202015-02-12 09:37:02 -080090
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected CoreService coreService;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
Jonathan Hartf5829202015-02-12 09:37:02 -080095 protected RoutingService routingService;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected RoutingConfigurationService configService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected PacketService packetService;
102
Saurav Dasbd7f7422015-04-23 16:31:47 -0700103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected FlowObjectiveService flowObjectiveService;
105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected DeviceService deviceService;
108
Saurav Dasfbe25c52015-03-04 11:12:00 -0800109 //
110 // NOTE: Unused reference - needed to guarantee that the
111 // NetworkConfigReader component is activated and the network configuration
112 // is read.
113 //
114 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
115 protected NetworkConfigService networkConfigService;
116
Jonathan Hartf5829202015-02-12 09:37:02 -0800117 private ApplicationId appId;
118
Jonathan Hart7baba072015-02-23 14:27:59 -0800119 // Reference count for how many times a next hop is used by a route
120 private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
121
122 // Mapping from prefix to its current next hop
123 private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
124
125 // Mapping from next hop IP to next hop object containing group info
alshabib2a441c62015-04-13 18:39:38 -0700126 private final Map<IpAddress, Integer> nextHops = Maps.newHashMap();
Jonathan Hart7baba072015-02-23 14:27:59 -0800127
128 // Stores FIB updates that are waiting for groups to be set up
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700129 private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
Jonathan Hartf5829202015-02-12 09:37:02 -0800130
Saurav Dasfbe25c52015-03-04 11:12:00 -0800131 // Device id of data-plane switch - should be learned from config
132 private DeviceId deviceId;
133
134 // Device id of control-plane switch (OVS) connected to BGP Speaker - should be
135 // learned from config
136 private DeviceId ctrlDeviceId;
Jonathan Hartf5829202015-02-12 09:37:02 -0800137
Saurav Dasbd7f7422015-04-23 16:31:47 -0700138 // Responsible for handling BGP traffic (encapsulated within OF messages)
139 // between the data-plane switch and the Quagga VM using a control plane OVS.
Jonathan Hartf5829202015-02-12 09:37:02 -0800140 private TunnellingConnectivityManager connectivityManager;
141
Saurav Dasbd7f7422015-04-23 16:31:47 -0700142 private DeviceListener deviceListener;
sangho5eaf0332015-03-09 15:08:12 -0700143 private IcmpHandler icmpHandler;
144
Jonathan Hartf5829202015-02-12 09:37:02 -0800145 @Activate
146 protected void activate() {
Jonathan Hartf5829202015-02-12 09:37:02 -0800147 appId = coreService.registerApplication(BGP_ROUTER_APP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800148 getDeviceConfiguration(configService.getBgpSpeakers());
Jonathan Hartf5829202015-02-12 09:37:02 -0800149
150 connectivityManager = new TunnellingConnectivityManager(appId,
151 configService,
Jonathan Hart936a7292015-03-06 18:02:57 -0800152 packetService,
Saurav Das3d038262015-04-23 12:36:58 -0700153 flowObjectiveService);
Jonathan Hartf5829202015-02-12 09:37:02 -0800154
sangho5eaf0332015-03-09 15:08:12 -0700155 icmpHandler = new IcmpHandler(configService, packetService);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700156 deviceListener = new InnerDeviceListener();
Pingping Line28ae4c2015-03-13 11:37:03 -0700157 routingService.addFibListener(new InternalFibListener());
158 routingService.start();
Saurav Dasbd7f7422015-04-23 16:31:47 -0700159 deviceService.addListener(deviceListener);
Jonathan Hartf5829202015-02-12 09:37:02 -0800160 connectivityManager.start();
sangho5eaf0332015-03-09 15:08:12 -0700161 icmpHandler.start();
162
Jonathan Hart49bcae92015-06-04 15:33:15 -0700163 // Initialize devices now if they are already connected
164 if (deviceService.isAvailable(deviceId)) {
165 processIntfFilters(true, configService.getInterfaces());
166 }
167
168 if (deviceService.isAvailable(ctrlDeviceId)) {
169 connectivityManager.notifySwitchAvailable();
170 }
171
Jonathan Hartf5829202015-02-12 09:37:02 -0800172 log.info("BgpRouter started");
173 }
174
175 @Deactivate
176 protected void deactivate() {
177 routingService.stop();
178 connectivityManager.stop();
sangho5eaf0332015-03-09 15:08:12 -0700179 icmpHandler.stop();
Saurav Dasbd7f7422015-04-23 16:31:47 -0700180 deviceService.removeListener(deviceListener);
181 //processIntfFilters(false, configService.getInterfaces()); //TODO necessary?
Jonathan Hartf5829202015-02-12 09:37:02 -0800182 log.info("BgpRouter stopped");
183 }
184
Saurav Dasfbe25c52015-03-04 11:12:00 -0800185 private void getDeviceConfiguration(Map<String, BgpSpeaker> bgps) {
186 if (bgps == null || bgps.values().isEmpty()) {
187 log.error("BGP speakers configuration is missing");
188 return;
189 }
190 for (BgpSpeaker s : bgps.values()) {
191 ctrlDeviceId = s.connectPoint().deviceId();
192 if (s.interfaceAddresses() == null || s.interfaceAddresses().isEmpty()) {
193 log.error("BGP Router must have interfaces configured");
194 return;
195 }
196 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
197 break;
198 }
sangho5eaf0332015-03-09 15:08:12 -0700199
Saurav Dasfbe25c52015-03-04 11:12:00 -0800200 log.info("Router dpid: {}", deviceId);
201 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
202 }
203
Jonathan Hartf5829202015-02-12 09:37:02 -0800204 private void updateFibEntry(Collection<FibUpdate> updates) {
alshabib2a441c62015-04-13 18:39:38 -0700205 Map<FibEntry, Integer> toInstall = new HashMap<>(updates.size());
Jonathan Hart5b141422015-03-06 12:59:09 -0800206
Jonathan Hartf5829202015-02-12 09:37:02 -0800207 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800208 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800209
Jonathan Hart7baba072015-02-23 14:27:59 -0800210 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800211
alshabib2a441c62015-04-13 18:39:38 -0700212 Integer nextId;
Jonathan Hart7baba072015-02-23 14:27:59 -0800213 synchronized (pendingUpdates) {
alshabib2a441c62015-04-13 18:39:38 -0700214 nextId = nextHops.get(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800215 }
216
alshabib2a441c62015-04-13 18:39:38 -0700217 toInstall.put(update.entry(), nextId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800218 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800219
220 installFlows(toInstall);
Jonathan Hartf5829202015-02-12 09:37:02 -0800221 }
222
alshabib2a441c62015-04-13 18:39:38 -0700223 private void installFlows(Map<FibEntry, Integer> entriesToInstall) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800224
alshabib2a441c62015-04-13 18:39:38 -0700225 for (Map.Entry<FibEntry, Integer> entry : entriesToInstall.entrySet()) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800226 FibEntry fibEntry = entry.getKey();
alshabib2a441c62015-04-13 18:39:38 -0700227 Integer nextId = entry.getValue();
Jonathan Hart5b141422015-03-06 12:59:09 -0800228
alshabib2a441c62015-04-13 18:39:38 -0700229 flowObjectiveService.forward(deviceId,
Saurav Dasbd7f7422015-04-23 16:31:47 -0700230 generateRibForwardingObj(fibEntry.prefix(), nextId).add());
Saurav Das3d038262015-04-23 12:36:58 -0700231 log.trace("Sending forwarding objective {} -> nextId:{}", fibEntry, nextId);
Jonathan Hart5b141422015-03-06 12:59:09 -0800232 }
233
Jonathan Hart7baba072015-02-23 14:27:59 -0800234 }
235
236 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800237
Jonathan Hart7baba072015-02-23 14:27:59 -0800238 for (FibUpdate update : withdraws) {
239 FibEntry entry = update.entry();
sanghodde53d12015-04-30 10:34:41 -0700240 //Integer nextId = nextHops.get(entry.nextHopIp());
Jonathan Hart7baba072015-02-23 14:27:59 -0800241
Saurav Dasbd7f7422015-04-23 16:31:47 -0700242 /* Group group = deleteNextHop(entry.prefix());
Jonathan Hart37d659c2015-03-08 19:20:38 -0700243 if (group == null) {
244 log.warn("Group not found when deleting {}", entry);
245 return;
alshabib2a441c62015-04-13 18:39:38 -0700246 }*/
Jonathan Hartf5829202015-02-12 09:37:02 -0800247
alshabib2a441c62015-04-13 18:39:38 -0700248 flowObjectiveService.forward(deviceId,
sanghodde53d12015-04-30 10:34:41 -0700249 generateRibForwardingObj(entry.prefix(), null).remove());
Jonathan Hartf5829202015-02-12 09:37:02 -0800250
Jonathan Hartf5829202015-02-12 09:37:02 -0800251 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800252
Jonathan Hartf5829202015-02-12 09:37:02 -0800253 }
254
Saurav Dasbd7f7422015-04-23 16:31:47 -0700255 private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
256 Integer nextId) {
Jonathan Hart37d659c2015-03-08 19:20:38 -0700257 TrafficSelector selector = DefaultTrafficSelector.builder()
258 .matchEthType(Ethernet.TYPE_IPV4)
259 .matchIPDst(prefix)
260 .build();
261
Jonathan Hart12ef2052015-03-10 13:58:13 -0700262 int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
263
alshabib2a441c62015-04-13 18:39:38 -0700264 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
265 .fromApp(appId)
266 .makePermanent()
alshabib2a441c62015-04-13 18:39:38 -0700267 .withSelector(selector)
268 .withPriority(priority)
269 .withFlag(ForwardingObjective.Flag.SPECIFIC);
270
sanghodde53d12015-04-30 10:34:41 -0700271 if (nextId == null) {
Saurav Das100e3b82015-04-30 11:12:10 -0700272 // Route withdraws are not specified with next hops. Generating
273 // dummy treatment as there is no equivalent nextId info.
sanghodde53d12015-04-30 10:34:41 -0700274 fwdBuilder.withTreatment(DefaultTrafficTreatment.builder().build());
275 } else {
276 fwdBuilder.nextStep(nextId);
277 }
alshabib2a441c62015-04-13 18:39:38 -0700278 return fwdBuilder;
Jonathan Hart37d659c2015-03-08 19:20:38 -0700279 }
280
Jonathan Hart7baba072015-02-23 14:27:59 -0800281 private synchronized void addNextHop(FibEntry entry) {
282 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
283 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800284 // There was no next hop in the multiset
285
Jonathan Hart7baba072015-02-23 14:27:59 -0800286 Interface egressIntf = configService.getMatchingInterface(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800287 if (egressIntf == null) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800288 log.warn("no egress interface found for {}", entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800289 return;
290 }
291
Jonathan Hart7baba072015-02-23 14:27:59 -0800292 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
293
294 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
Jonathan Hartf5829202015-02-12 09:37:02 -0800295
296 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
297 .setEthSrc(egressIntf.mac())
298 .setEthDst(nextHop.mac())
Jonathan Hart54b406b2015-03-06 16:24:14 -0800299 .pushVlan()
Jonathan Hartf5829202015-02-12 09:37:02 -0800300 .setVlanId(egressIntf.vlan())
alshabibda1644e2015-03-13 14:01:35 -0700301 .setVlanPcp((byte) 0)
Jonathan Hartf5829202015-02-12 09:37:02 -0800302 .setOutput(egressIntf.connectPoint().port())
303 .build();
304
Saurav Das3ea46622015-04-22 14:01:34 -0700305 int nextId = flowObjectiveService.allocateNextId();
306
alshabib2a441c62015-04-13 18:39:38 -0700307 NextObjective nextObjective = DefaultNextObjective.builder()
Saurav Das3ea46622015-04-22 14:01:34 -0700308 .withId(nextId)
alshabib2a441c62015-04-13 18:39:38 -0700309 .addTreatment(treatment)
310 .withType(NextObjective.Type.SIMPLE)
311 .fromApp(appId)
Saurav Dasbd7f7422015-04-23 16:31:47 -0700312 .add(); // TODO add callbacks
alshabib2a441c62015-04-13 18:39:38 -0700313
314 flowObjectiveService.next(deviceId, nextObjective);
315
Saurav Das3ea46622015-04-22 14:01:34 -0700316 nextHops.put(nextHop.ip(), nextId);
Jonathan Hart7baba072015-02-23 14:27:59 -0800317
Jonathan Hartf5829202015-02-12 09:37:02 -0800318 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800319
320 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800321 }
322
alshabib2a441c62015-04-13 18:39:38 -0700323 /*private synchronized Group deleteNextHop(IpPrefix prefix) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800324 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
325 NextHop nextHop = nextHops.get(nextHopIp);
326 if (nextHop == null) {
327 log.warn("No next hop found when removing prefix {}", prefix);
Jonathan Hart37d659c2015-03-08 19:20:38 -0700328 return null;
Jonathan Hart7baba072015-02-23 14:27:59 -0800329 }
330
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700331 Group group = groupService.getGroup(deviceId,
332 new DefaultGroupKey(appKryo.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700333 serialize(nextHop.group())));
Jonathan Hart37d659c2015-03-08 19:20:38 -0700334
Jonathan Hartf9f2cbb2015-03-12 17:44:03 -0700335 // FIXME disabling group deletes for now until we verify the logic is OK
Saurav Dasbd7f7422015-04-23 16:31:47 -0700336 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800337 // There was one or less next hops, so there are now none
338
Jonathan Hart7baba072015-02-23 14:27:59 -0800339 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800340
Jonathan Hart7baba072015-02-23 14:27:59 -0800341 nextHops.remove(nextHopIp);
342
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700343 groupService.removeGroup(deviceId,
344 new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
345 appId);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700346 }
Jonathan Hart37d659c2015-03-08 19:20:38 -0700347
348 return group;
alshabib2a441c62015-04-13 18:39:38 -0700349 }*/
Jonathan Hartf5829202015-02-12 09:37:02 -0800350
351 private class InternalFibListener implements FibListener {
352
353 @Override
354 public void update(Collection<FibUpdate> updates,
355 Collection<FibUpdate> withdraws) {
356 BgpRouter.this.deleteFibEntry(withdraws);
357 BgpRouter.this.updateFibEntry(updates);
358 }
359 }
alshabib10580802015-02-18 18:30:33 -0800360
Saurav Dascfd63d22015-04-13 16:08:24 -0700361 private void processIntfFilters(boolean install, Set<Interface> intfs) {
362 log.info("Processing {} router interfaces", intfs.size());
363 for (Interface intf : intfs) {
Jonathan Hart49bcae92015-06-04 15:33:15 -0700364 if (!intf.connectPoint().deviceId().equals(deviceId)) {
365 // Ignore interfaces if they are not on the router switch
366 continue;
367 }
368
Saurav Dascfd63d22015-04-13 16:08:24 -0700369 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
370 fob.withKey(Criteria.matchInPort(intf.connectPoint().port()))
371 .addCondition(Criteria.matchEthDst(intf.mac()))
372 .addCondition(Criteria.matchVlanId(intf.vlan()));
373 intf.ipAddresses().stream()
374 .forEach(ipaddr -> fob.addCondition(
Saurav Dasc39f6032015-05-14 17:12:47 -0700375 Criteria.matchIPDst(
376 IpPrefix.valueOf(ipaddr.ipAddress(), 32))));
Saurav Dascfd63d22015-04-13 16:08:24 -0700377 fob.permit().fromApp(appId);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700378 flowObjectiveService.filter(
379 deviceId,
380 fob.add(new ObjectiveContext() {
381 @Override
382 public void onSuccess(Objective objective) {
383 log.info("Successfully installed interface based "
Saurav Dasc39f6032015-05-14 17:12:47 -0700384 + "filtering objectives for intf {}", intf);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700385 }
386
387 @Override
388 public void onError(Objective objective,
389 ObjectiveError error) {
Saurav Dasf9ba4222015-05-07 17:13:59 -0700390 log.error("Failed to install interface filters for intf {}: {}",
391 intf, error);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700392 // TODO something more than just logging
393 }
394 }));
alshabib10580802015-02-18 18:30:33 -0800395 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800396 }
alshabib10580802015-02-18 18:30:33 -0800397
Saurav Dasbd7f7422015-04-23 16:31:47 -0700398 // Triggers driver setup when a device is (re)detected.
399 private class InnerDeviceListener implements DeviceListener {
Jonathan Hart7baba072015-02-23 14:27:59 -0800400 @Override
Saurav Dasbd7f7422015-04-23 16:31:47 -0700401 public void event(DeviceEvent event) {
402 switch (event.type()) {
403 case DEVICE_ADDED:
404 case DEVICE_AVAILABILITY_CHANGED:
405 if (deviceService.isAvailable(event.subject().id())) {
406 log.info("Device connected {}", event.subject().id());
sanghof22fb402015-04-27 23:55:10 -0700407 if (event.subject().id().equals(deviceId)) {
408 processIntfFilters(true, configService.getInterfaces());
Jonathan Hart7baba072015-02-23 14:27:59 -0800409
sanghodde53d12015-04-30 10:34:41 -0700410 /* For test only - will be removed before Cardinal release
sanghof22fb402015-04-27 23:55:10 -0700411 delay(1000);
412 FibEntry fibEntry = new FibEntry(Ip4Prefix.valueOf("10.1.0.0/16"),
413 Ip4Address.valueOf("192.168.10.1"),
414 MacAddress.valueOf("DE:AD:BE:EF:FE:ED"));
415 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
416 updateFibEntry(Collections.singletonList(fibUpdate));
sanghodde53d12015-04-30 10:34:41 -0700417 */
sanghof22fb402015-04-27 23:55:10 -0700418 }
419
420 if (event.subject().id().equals(ctrlDeviceId)) {
421 connectivityManager.notifySwitchAvailable();
422 }
Saurav Dasbd7f7422015-04-23 16:31:47 -0700423 }
424 break;
Jonathan Hart5b141422015-03-06 12:59:09 -0800425
Saurav Dasbd7f7422015-04-23 16:31:47 -0700426 // TODO other cases
427 case DEVICE_UPDATED:
428 break;
429 case DEVICE_REMOVED:
430 break;
431 case DEVICE_SUSPENDED:
432 break;
433 case PORT_ADDED:
434 break;
435 case PORT_UPDATED:
436 break;
437 case PORT_REMOVED:
438 break;
439 default:
440 break;
Jonathan Hart7baba072015-02-23 14:27:59 -0800441 }
442 }
Saurav Dasbd7f7422015-04-23 16:31:47 -0700443 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800444}