blob: e5388d2896da49b603454d92a6d7d5c353af1e07 [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;
Jonathan Hartf5829202015-02-12 09:37:02 -080023import org.apache.felix.scr.annotations.Activate;
24import org.apache.felix.scr.annotations.Component;
25import org.apache.felix.scr.annotations.Deactivate;
26import org.apache.felix.scr.annotations.Reference;
27import org.apache.felix.scr.annotations.ReferenceCardinality;
28import org.onlab.packet.Ethernet;
Jonathan Hart7baba072015-02-23 14:27:59 -080029import org.onlab.packet.IpAddress;
30import org.onlab.packet.IpPrefix;
Jonathan Hartf5829202015-02-12 09:37:02 -080031import org.onosproject.core.ApplicationId;
32import org.onosproject.core.CoreService;
Jonathan Hart4cb39882015-08-12 23:50:55 -040033import org.onosproject.net.config.NetworkConfigService;
34import org.onosproject.incubator.net.intf.Interface;
35import org.onosproject.incubator.net.intf.InterfaceService;
Jonathan Hartf5829202015-02-12 09:37:02 -080036import org.onosproject.net.DeviceId;
Saurav Dasbd7f7422015-04-23 16:31:47 -070037import org.onosproject.net.device.DeviceEvent;
38import org.onosproject.net.device.DeviceListener;
39import org.onosproject.net.device.DeviceService;
Jonathan Hartf5829202015-02-12 09:37:02 -080040import org.onosproject.net.flow.DefaultTrafficSelector;
41import org.onosproject.net.flow.DefaultTrafficTreatment;
Jonathan Hartf5829202015-02-12 09:37:02 -080042import org.onosproject.net.flow.TrafficSelector;
43import org.onosproject.net.flow.TrafficTreatment;
alshabib910aff12015-04-09 16:55:57 -070044import org.onosproject.net.flow.criteria.Criteria;
45import org.onosproject.net.flowobjective.DefaultFilteringObjective;
alshabib2a441c62015-04-13 18:39:38 -070046import org.onosproject.net.flowobjective.DefaultForwardingObjective;
47import org.onosproject.net.flowobjective.DefaultNextObjective;
alshabib910aff12015-04-09 16:55:57 -070048import org.onosproject.net.flowobjective.FilteringObjective;
49import org.onosproject.net.flowobjective.FlowObjectiveService;
alshabib2a441c62015-04-13 18:39:38 -070050import org.onosproject.net.flowobjective.ForwardingObjective;
51import org.onosproject.net.flowobjective.NextObjective;
Saurav Dasbd7f7422015-04-23 16:31:47 -070052import org.onosproject.net.flowobjective.Objective;
53import org.onosproject.net.flowobjective.ObjectiveContext;
54import org.onosproject.net.flowobjective.ObjectiveError;
Jonathan Hartf5829202015-02-12 09:37:02 -080055import org.onosproject.net.packet.PacketService;
Jonathan Hart7baba072015-02-23 14:27:59 -080056import org.onosproject.routing.FibEntry;
Jonathan Hart2da1e602015-02-18 19:09:24 -080057import org.onosproject.routing.FibListener;
58import org.onosproject.routing.FibUpdate;
59import org.onosproject.routing.RoutingService;
Jonathan Hart4cb39882015-08-12 23:50:55 -040060import org.onosproject.routing.config.BgpConfig;
Jonathan Hartf5829202015-02-12 09:37:02 -080061import org.slf4j.Logger;
62import org.slf4j.LoggerFactory;
63
alshabib910aff12015-04-09 16:55:57 -070064import java.util.Collection;
alshabib910aff12015-04-09 16:55:57 -070065import java.util.HashMap;
alshabib910aff12015-04-09 16:55:57 -070066import java.util.Map;
Jonathan Hart4cb39882015-08-12 23:50:55 -040067import java.util.Optional;
alshabib910aff12015-04-09 16:55:57 -070068import 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)
Jonathan Hart4cb39882015-08-12 23:50:55 -040098 protected InterfaceService interfaceService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected NetworkConfigService networkConfigService;
Jonathan Hartf5829202015-02-12 09:37:02 -0800102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected PacketService packetService;
105
Saurav Dasbd7f7422015-04-23 16:31:47 -0700106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected FlowObjectiveService flowObjectiveService;
108
109 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
110 protected DeviceService deviceService;
111
Jonathan Hartf5829202015-02-12 09:37:02 -0800112 private ApplicationId appId;
113
Jonathan Hart7baba072015-02-23 14:27:59 -0800114 // Reference count for how many times a next hop is used by a route
115 private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
116
117 // Mapping from prefix to its current next hop
118 private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
119
120 // Mapping from next hop IP to next hop object containing group info
alshabib2a441c62015-04-13 18:39:38 -0700121 private final Map<IpAddress, Integer> nextHops = Maps.newHashMap();
Jonathan Hart7baba072015-02-23 14:27:59 -0800122
123 // Stores FIB updates that are waiting for groups to be set up
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700124 private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
Jonathan Hartf5829202015-02-12 09:37:02 -0800125
Saurav Dasfbe25c52015-03-04 11:12:00 -0800126 // Device id of data-plane switch - should be learned from config
127 private DeviceId deviceId;
128
129 // Device id of control-plane switch (OVS) connected to BGP Speaker - should be
130 // learned from config
131 private DeviceId ctrlDeviceId;
Jonathan Hartf5829202015-02-12 09:37:02 -0800132
Saurav Dasbd7f7422015-04-23 16:31:47 -0700133 // Responsible for handling BGP traffic (encapsulated within OF messages)
134 // between the data-plane switch and the Quagga VM using a control plane OVS.
Jonathan Hartf5829202015-02-12 09:37:02 -0800135 private TunnellingConnectivityManager connectivityManager;
136
Saurav Dasbd7f7422015-04-23 16:31:47 -0700137 private DeviceListener deviceListener;
sangho5eaf0332015-03-09 15:08:12 -0700138 private IcmpHandler icmpHandler;
139
Jonathan Hartf5829202015-02-12 09:37:02 -0800140 @Activate
141 protected void activate() {
Jonathan Hartf5829202015-02-12 09:37:02 -0800142 appId = coreService.registerApplication(BGP_ROUTER_APP);
Jonathan Hart4cb39882015-08-12 23:50:55 -0400143
144 ApplicationId routerAppId = coreService.getAppId(RoutingService.ROUTER_APP_ID);
145 BgpConfig bgpConfig =
146 networkConfigService.getConfig(routerAppId, RoutingService.CONFIG_CLASS);
147
148 if (bgpConfig == null) {
149 log.error("No BgpConfig found");
150 return;
151 }
152
153 getDeviceConfiguration(bgpConfig);
Jonathan Hartf5829202015-02-12 09:37:02 -0800154
155 connectivityManager = new TunnellingConnectivityManager(appId,
Jonathan Hart4cb39882015-08-12 23:50:55 -0400156 bgpConfig,
157 interfaceService,
Jonathan Hart936a7292015-03-06 18:02:57 -0800158 packetService,
Saurav Das3d038262015-04-23 12:36:58 -0700159 flowObjectiveService);
Jonathan Hartf5829202015-02-12 09:37:02 -0800160
Jonathan Hart4cb39882015-08-12 23:50:55 -0400161 icmpHandler = new IcmpHandler(interfaceService, packetService);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700162 deviceListener = new InnerDeviceListener();
Pingping Line28ae4c2015-03-13 11:37:03 -0700163 routingService.addFibListener(new InternalFibListener());
164 routingService.start();
Saurav Dasbd7f7422015-04-23 16:31:47 -0700165 deviceService.addListener(deviceListener);
Jonathan Hartf5829202015-02-12 09:37:02 -0800166 connectivityManager.start();
sangho5eaf0332015-03-09 15:08:12 -0700167 icmpHandler.start();
168
Jonathan Hart49bcae92015-06-04 15:33:15 -0700169 // Initialize devices now if they are already connected
170 if (deviceService.isAvailable(deviceId)) {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400171 processIntfFilters(true, interfaceService.getInterfaces());
Jonathan Hart49bcae92015-06-04 15:33:15 -0700172 }
173
174 if (deviceService.isAvailable(ctrlDeviceId)) {
175 connectivityManager.notifySwitchAvailable();
176 }
177
Jonathan Hartf5829202015-02-12 09:37:02 -0800178 log.info("BgpRouter started");
179 }
180
181 @Deactivate
182 protected void deactivate() {
183 routingService.stop();
184 connectivityManager.stop();
sangho5eaf0332015-03-09 15:08:12 -0700185 icmpHandler.stop();
Saurav Dasbd7f7422015-04-23 16:31:47 -0700186 deviceService.removeListener(deviceListener);
187 //processIntfFilters(false, configService.getInterfaces()); //TODO necessary?
Jonathan Hartf5829202015-02-12 09:37:02 -0800188 log.info("BgpRouter stopped");
189 }
190
Jonathan Hart4cb39882015-08-12 23:50:55 -0400191 private void getDeviceConfiguration(BgpConfig bgpConfig) {
192 Optional<BgpConfig.BgpSpeakerConfig> bgpSpeaker =
193 bgpConfig.bgpSpeakers().stream().findAny();
194
195 if (!bgpSpeaker.isPresent()) {
196 log.error("BGP speaker configuration not found");
Saurav Dasfbe25c52015-03-04 11:12:00 -0800197 return;
198 }
Jonathan Hart4cb39882015-08-12 23:50:55 -0400199
200 ctrlDeviceId = bgpSpeaker.get().connectPoint().deviceId();
201
202 Optional<IpAddress> peerAddress =
203 bgpSpeaker.get().peers().stream().findAny();
204
205 if (!peerAddress.isPresent()) {
206 log.error("BGP speaker must have peers configured");
207 return;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800208 }
sangho5eaf0332015-03-09 15:08:12 -0700209
Jonathan Hart4cb39882015-08-12 23:50:55 -0400210 Interface intf = interfaceService.getMatchingInterface(peerAddress.get());
211
212 if (intf == null) {
213 log.error("No interface found for peer");
214 return;
215 }
216
217 // Assume all peers are configured on the same device - this is required
218 // by the BGP router
219 deviceId = intf.connectPoint().deviceId();
220
Saurav Dasfbe25c52015-03-04 11:12:00 -0800221 log.info("Router dpid: {}", deviceId);
222 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
223 }
224
Jonathan Hartf5829202015-02-12 09:37:02 -0800225 private void updateFibEntry(Collection<FibUpdate> updates) {
alshabib2a441c62015-04-13 18:39:38 -0700226 Map<FibEntry, Integer> toInstall = new HashMap<>(updates.size());
Jonathan Hart5b141422015-03-06 12:59:09 -0800227
Jonathan Hartf5829202015-02-12 09:37:02 -0800228 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800229 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800230
Jonathan Hart7baba072015-02-23 14:27:59 -0800231 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800232
alshabib2a441c62015-04-13 18:39:38 -0700233 Integer nextId;
Jonathan Hart7baba072015-02-23 14:27:59 -0800234 synchronized (pendingUpdates) {
alshabib2a441c62015-04-13 18:39:38 -0700235 nextId = nextHops.get(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800236 }
237
alshabib2a441c62015-04-13 18:39:38 -0700238 toInstall.put(update.entry(), nextId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800239 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800240
241 installFlows(toInstall);
Jonathan Hartf5829202015-02-12 09:37:02 -0800242 }
243
alshabib2a441c62015-04-13 18:39:38 -0700244 private void installFlows(Map<FibEntry, Integer> entriesToInstall) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800245
alshabib2a441c62015-04-13 18:39:38 -0700246 for (Map.Entry<FibEntry, Integer> entry : entriesToInstall.entrySet()) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800247 FibEntry fibEntry = entry.getKey();
alshabib2a441c62015-04-13 18:39:38 -0700248 Integer nextId = entry.getValue();
Jonathan Hart5b141422015-03-06 12:59:09 -0800249
alshabib2a441c62015-04-13 18:39:38 -0700250 flowObjectiveService.forward(deviceId,
Saurav Dasbd7f7422015-04-23 16:31:47 -0700251 generateRibForwardingObj(fibEntry.prefix(), nextId).add());
Saurav Das3d038262015-04-23 12:36:58 -0700252 log.trace("Sending forwarding objective {} -> nextId:{}", fibEntry, nextId);
Jonathan Hart5b141422015-03-06 12:59:09 -0800253 }
254
Jonathan Hart7baba072015-02-23 14:27:59 -0800255 }
256
257 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800258
Jonathan Hart7baba072015-02-23 14:27:59 -0800259 for (FibUpdate update : withdraws) {
260 FibEntry entry = update.entry();
sanghodde53d12015-04-30 10:34:41 -0700261 //Integer nextId = nextHops.get(entry.nextHopIp());
Jonathan Hart7baba072015-02-23 14:27:59 -0800262
Saurav Dasbd7f7422015-04-23 16:31:47 -0700263 /* Group group = deleteNextHop(entry.prefix());
Jonathan Hart37d659c2015-03-08 19:20:38 -0700264 if (group == null) {
265 log.warn("Group not found when deleting {}", entry);
266 return;
alshabib2a441c62015-04-13 18:39:38 -0700267 }*/
Jonathan Hartf5829202015-02-12 09:37:02 -0800268
alshabib2a441c62015-04-13 18:39:38 -0700269 flowObjectiveService.forward(deviceId,
sanghodde53d12015-04-30 10:34:41 -0700270 generateRibForwardingObj(entry.prefix(), null).remove());
Jonathan Hartf5829202015-02-12 09:37:02 -0800271
Jonathan Hartf5829202015-02-12 09:37:02 -0800272 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800273
Jonathan Hartf5829202015-02-12 09:37:02 -0800274 }
275
Saurav Dasbd7f7422015-04-23 16:31:47 -0700276 private ForwardingObjective.Builder generateRibForwardingObj(IpPrefix prefix,
277 Integer nextId) {
Jonathan Hart37d659c2015-03-08 19:20:38 -0700278 TrafficSelector selector = DefaultTrafficSelector.builder()
279 .matchEthType(Ethernet.TYPE_IPV4)
280 .matchIPDst(prefix)
281 .build();
282
Jonathan Hart12ef2052015-03-10 13:58:13 -0700283 int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
284
alshabib2a441c62015-04-13 18:39:38 -0700285 ForwardingObjective.Builder fwdBuilder = DefaultForwardingObjective.builder()
286 .fromApp(appId)
287 .makePermanent()
alshabib2a441c62015-04-13 18:39:38 -0700288 .withSelector(selector)
289 .withPriority(priority)
290 .withFlag(ForwardingObjective.Flag.SPECIFIC);
291
sanghodde53d12015-04-30 10:34:41 -0700292 if (nextId == null) {
Saurav Das100e3b82015-04-30 11:12:10 -0700293 // Route withdraws are not specified with next hops. Generating
294 // dummy treatment as there is no equivalent nextId info.
sanghodde53d12015-04-30 10:34:41 -0700295 fwdBuilder.withTreatment(DefaultTrafficTreatment.builder().build());
296 } else {
297 fwdBuilder.nextStep(nextId);
298 }
alshabib2a441c62015-04-13 18:39:38 -0700299 return fwdBuilder;
Jonathan Hart37d659c2015-03-08 19:20:38 -0700300 }
301
Jonathan Hart7baba072015-02-23 14:27:59 -0800302 private synchronized void addNextHop(FibEntry entry) {
303 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
304 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800305 // There was no next hop in the multiset
306
Jonathan Hart4cb39882015-08-12 23:50:55 -0400307 Interface egressIntf = interfaceService.getMatchingInterface(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800308 if (egressIntf == null) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800309 log.warn("no egress interface found for {}", entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800310 return;
311 }
312
Jonathan Hart7baba072015-02-23 14:27:59 -0800313 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
314
315 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
Jonathan Hartf5829202015-02-12 09:37:02 -0800316
317 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
318 .setEthSrc(egressIntf.mac())
319 .setEthDst(nextHop.mac())
Jonathan Hart54b406b2015-03-06 16:24:14 -0800320 .pushVlan()
Jonathan Hartf5829202015-02-12 09:37:02 -0800321 .setVlanId(egressIntf.vlan())
alshabibda1644e2015-03-13 14:01:35 -0700322 .setVlanPcp((byte) 0)
Jonathan Hartf5829202015-02-12 09:37:02 -0800323 .setOutput(egressIntf.connectPoint().port())
324 .build();
325
Saurav Das3ea46622015-04-22 14:01:34 -0700326 int nextId = flowObjectiveService.allocateNextId();
327
alshabib2a441c62015-04-13 18:39:38 -0700328 NextObjective nextObjective = DefaultNextObjective.builder()
Saurav Das3ea46622015-04-22 14:01:34 -0700329 .withId(nextId)
alshabib2a441c62015-04-13 18:39:38 -0700330 .addTreatment(treatment)
331 .withType(NextObjective.Type.SIMPLE)
332 .fromApp(appId)
Saurav Dasbd7f7422015-04-23 16:31:47 -0700333 .add(); // TODO add callbacks
alshabib2a441c62015-04-13 18:39:38 -0700334
335 flowObjectiveService.next(deviceId, nextObjective);
336
Saurav Das3ea46622015-04-22 14:01:34 -0700337 nextHops.put(nextHop.ip(), nextId);
Jonathan Hart7baba072015-02-23 14:27:59 -0800338
Jonathan Hartf5829202015-02-12 09:37:02 -0800339 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800340
341 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800342 }
343
alshabib2a441c62015-04-13 18:39:38 -0700344 /*private synchronized Group deleteNextHop(IpPrefix prefix) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800345 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
346 NextHop nextHop = nextHops.get(nextHopIp);
347 if (nextHop == null) {
348 log.warn("No next hop found when removing prefix {}", prefix);
Jonathan Hart37d659c2015-03-08 19:20:38 -0700349 return null;
Jonathan Hart7baba072015-02-23 14:27:59 -0800350 }
351
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700352 Group group = groupService.getGroup(deviceId,
353 new DefaultGroupKey(appKryo.
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700354 serialize(nextHop.group())));
Jonathan Hart37d659c2015-03-08 19:20:38 -0700355
Jonathan Hartf9f2cbb2015-03-12 17:44:03 -0700356 // FIXME disabling group deletes for now until we verify the logic is OK
Saurav Dasbd7f7422015-04-23 16:31:47 -0700357 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800358 // There was one or less next hops, so there are now none
359
Jonathan Hart7baba072015-02-23 14:27:59 -0800360 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800361
Jonathan Hart7baba072015-02-23 14:27:59 -0800362 nextHops.remove(nextHopIp);
363
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700364 groupService.removeGroup(deviceId,
365 new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
366 appId);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700367 }
Jonathan Hart37d659c2015-03-08 19:20:38 -0700368
369 return group;
alshabib2a441c62015-04-13 18:39:38 -0700370 }*/
Jonathan Hartf5829202015-02-12 09:37:02 -0800371
372 private class InternalFibListener implements FibListener {
373
374 @Override
375 public void update(Collection<FibUpdate> updates,
376 Collection<FibUpdate> withdraws) {
377 BgpRouter.this.deleteFibEntry(withdraws);
378 BgpRouter.this.updateFibEntry(updates);
379 }
380 }
alshabib10580802015-02-18 18:30:33 -0800381
Saurav Dascfd63d22015-04-13 16:08:24 -0700382 private void processIntfFilters(boolean install, Set<Interface> intfs) {
383 log.info("Processing {} router interfaces", intfs.size());
384 for (Interface intf : intfs) {
Jonathan Hart49bcae92015-06-04 15:33:15 -0700385 if (!intf.connectPoint().deviceId().equals(deviceId)) {
386 // Ignore interfaces if they are not on the router switch
387 continue;
388 }
389
Saurav Dascfd63d22015-04-13 16:08:24 -0700390 FilteringObjective.Builder fob = DefaultFilteringObjective.builder();
391 fob.withKey(Criteria.matchInPort(intf.connectPoint().port()))
392 .addCondition(Criteria.matchEthDst(intf.mac()))
393 .addCondition(Criteria.matchVlanId(intf.vlan()));
394 intf.ipAddresses().stream()
395 .forEach(ipaddr -> fob.addCondition(
Saurav Dasc39f6032015-05-14 17:12:47 -0700396 Criteria.matchIPDst(
397 IpPrefix.valueOf(ipaddr.ipAddress(), 32))));
Saurav Dascfd63d22015-04-13 16:08:24 -0700398 fob.permit().fromApp(appId);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700399 flowObjectiveService.filter(
400 deviceId,
401 fob.add(new ObjectiveContext() {
402 @Override
403 public void onSuccess(Objective objective) {
404 log.info("Successfully installed interface based "
Saurav Dasc39f6032015-05-14 17:12:47 -0700405 + "filtering objectives for intf {}", intf);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700406 }
407
408 @Override
409 public void onError(Objective objective,
410 ObjectiveError error) {
Saurav Dasf9ba4222015-05-07 17:13:59 -0700411 log.error("Failed to install interface filters for intf {}: {}",
412 intf, error);
Saurav Dasbd7f7422015-04-23 16:31:47 -0700413 // TODO something more than just logging
414 }
415 }));
alshabib10580802015-02-18 18:30:33 -0800416 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800417 }
alshabib10580802015-02-18 18:30:33 -0800418
Saurav Dasbd7f7422015-04-23 16:31:47 -0700419 // Triggers driver setup when a device is (re)detected.
420 private class InnerDeviceListener implements DeviceListener {
Jonathan Hart7baba072015-02-23 14:27:59 -0800421 @Override
Saurav Dasbd7f7422015-04-23 16:31:47 -0700422 public void event(DeviceEvent event) {
423 switch (event.type()) {
424 case DEVICE_ADDED:
425 case DEVICE_AVAILABILITY_CHANGED:
426 if (deviceService.isAvailable(event.subject().id())) {
427 log.info("Device connected {}", event.subject().id());
sanghof22fb402015-04-27 23:55:10 -0700428 if (event.subject().id().equals(deviceId)) {
Jonathan Hart4cb39882015-08-12 23:50:55 -0400429 processIntfFilters(true, interfaceService.getInterfaces());
Jonathan Hart7baba072015-02-23 14:27:59 -0800430
sanghodde53d12015-04-30 10:34:41 -0700431 /* For test only - will be removed before Cardinal release
sanghof22fb402015-04-27 23:55:10 -0700432 delay(1000);
433 FibEntry fibEntry = new FibEntry(Ip4Prefix.valueOf("10.1.0.0/16"),
434 Ip4Address.valueOf("192.168.10.1"),
435 MacAddress.valueOf("DE:AD:BE:EF:FE:ED"));
436 FibUpdate fibUpdate = new FibUpdate(FibUpdate.Type.UPDATE, fibEntry);
437 updateFibEntry(Collections.singletonList(fibUpdate));
sanghodde53d12015-04-30 10:34:41 -0700438 */
sanghof22fb402015-04-27 23:55:10 -0700439 }
440
441 if (event.subject().id().equals(ctrlDeviceId)) {
442 connectivityManager.notifySwitchAvailable();
443 }
Saurav Dasbd7f7422015-04-23 16:31:47 -0700444 }
445 break;
Jonathan Hart5b141422015-03-06 12:59:09 -0800446
Saurav Dasbd7f7422015-04-23 16:31:47 -0700447 // TODO other cases
448 case DEVICE_UPDATED:
449 break;
450 case DEVICE_REMOVED:
451 break;
452 case DEVICE_SUSPENDED:
453 break;
454 case PORT_ADDED:
455 break;
456 case PORT_UPDATED:
457 break;
458 case PORT_REMOVED:
459 break;
460 default:
461 break;
Jonathan Hart7baba072015-02-23 14:27:59 -0800462 }
463 }
Saurav Dasbd7f7422015-04-23 16:31:47 -0700464 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800465}