blob: a17046f2b7dbed2352d844f0ab0db566003f2056 [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
18import com.google.common.collect.ConcurrentHashMultiset;
Jonathan Hart7baba072015-02-23 14:27:59 -080019import com.google.common.collect.HashMultimap;
20import com.google.common.collect.Maps;
21import com.google.common.collect.Multimap;
Jonathan Hartf5829202015-02-12 09:37:02 -080022import com.google.common.collect.Multiset;
23import 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 Hart54b406b2015-03-06 16:24:14 -080031import org.onlab.packet.MacAddress;
Saurav Dasfbe25c52015-03-04 11:12:00 -080032import org.onlab.packet.VlanId;
Jonathan Hart54b406b2015-03-06 16:24:14 -080033import org.onosproject.config.NetworkConfigService;
Jonathan Hartf5829202015-02-12 09:37:02 -080034import org.onosproject.core.ApplicationId;
35import org.onosproject.core.CoreService;
36import org.onosproject.net.DeviceId;
alshabib346b5b32015-03-06 00:42:16 -080037import org.onosproject.net.PortNumber;
Jonathan Hartf5829202015-02-12 09:37:02 -080038import org.onosproject.net.flow.DefaultFlowRule;
39import org.onosproject.net.flow.DefaultTrafficSelector;
40import org.onosproject.net.flow.DefaultTrafficTreatment;
41import org.onosproject.net.flow.FlowRule;
Jonathan Hart54b406b2015-03-06 16:24:14 -080042import org.onosproject.net.flow.FlowRule.Type;
alshabib10580802015-02-18 18:30:33 -080043import org.onosproject.net.flow.FlowRuleOperations;
44import org.onosproject.net.flow.FlowRuleOperationsContext;
Jonathan Hartf5829202015-02-12 09:37:02 -080045import org.onosproject.net.flow.FlowRuleService;
46import org.onosproject.net.flow.TrafficSelector;
47import org.onosproject.net.flow.TrafficTreatment;
48import org.onosproject.net.group.DefaultGroupBucket;
49import org.onosproject.net.group.DefaultGroupDescription;
50import org.onosproject.net.group.Group;
51import org.onosproject.net.group.GroupBucket;
52import org.onosproject.net.group.GroupBuckets;
53import org.onosproject.net.group.GroupDescription;
Jonathan Hart7baba072015-02-23 14:27:59 -080054import org.onosproject.net.group.GroupEvent;
Jonathan Hartf5829202015-02-12 09:37:02 -080055import org.onosproject.net.group.GroupKey;
Jonathan Hart7baba072015-02-23 14:27:59 -080056import org.onosproject.net.group.GroupListener;
Jonathan Hartf5829202015-02-12 09:37:02 -080057import org.onosproject.net.group.GroupService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080058import org.onosproject.net.host.InterfaceIpAddress;
Jonathan Hartf5829202015-02-12 09:37:02 -080059import org.onosproject.net.packet.PacketService;
Jonathan Hart7baba072015-02-23 14:27:59 -080060import org.onosproject.routing.FibEntry;
Jonathan Hart2da1e602015-02-18 19:09:24 -080061import org.onosproject.routing.FibListener;
62import org.onosproject.routing.FibUpdate;
63import org.onosproject.routing.RoutingService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080064import org.onosproject.routing.config.BgpSpeaker;
Jonathan Hart2da1e602015-02-18 19:09:24 -080065import org.onosproject.routing.config.Interface;
66import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hartf5829202015-02-12 09:37:02 -080067import org.slf4j.Logger;
68import org.slf4j.LoggerFactory;
69
70import java.util.Collection;
71import java.util.Collections;
Jonathan Hart5b141422015-03-06 12:59:09 -080072import java.util.HashMap;
Saurav Dasfbe25c52015-03-04 11:12:00 -080073import java.util.HashSet;
Jonathan Hartf5829202015-02-12 09:37:02 -080074import java.util.Map;
Saurav Dasfbe25c52015-03-04 11:12:00 -080075import java.util.Set;
Jonathan Hart5b141422015-03-06 12:59:09 -080076import java.util.stream.Collectors;
Jonathan Hartf5829202015-02-12 09:37:02 -080077
78/**
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)
95 protected FlowRuleService flowService;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected GroupService groupService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected RoutingService routingService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected RoutingConfigurationService configService;
105
106 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
107 protected PacketService packetService;
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
126 private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap();
127
128 // Stores FIB updates that are waiting for groups to be set up
129 private final Multimap<GroupKey, 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
Jonathan Hart7baba072015-02-23 14:27:59 -0800138 private final GroupListener groupListener = new InternalGroupListener();
139
Jonathan Hartf5829202015-02-12 09:37:02 -0800140 private TunnellingConnectivityManager connectivityManager;
141
sangho5eaf0332015-03-09 15:08:12 -0700142 private IcmpHandler icmpHandler;
143
alshabib10580802015-02-18 18:30:33 -0800144 private InternalTableHandler provisionStaticTables = new InternalTableHandler();
145
Jonathan Hartf5829202015-02-12 09:37:02 -0800146 @Activate
147 protected void activate() {
Jonathan Hartf5829202015-02-12 09:37:02 -0800148 appId = coreService.registerApplication(BGP_ROUTER_APP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800149 getDeviceConfiguration(configService.getBgpSpeakers());
Jonathan Hartf5829202015-02-12 09:37:02 -0800150
Jonathan Hart7baba072015-02-23 14:27:59 -0800151 groupService.addListener(groupListener);
152
Saurav Dasfbe25c52015-03-04 11:12:00 -0800153 provisionStaticTables.provision(true, configService.getInterfaces());
alshabib10580802015-02-18 18:30:33 -0800154
Jonathan Hartf5829202015-02-12 09:37:02 -0800155 connectivityManager = new TunnellingConnectivityManager(appId,
156 configService,
Jonathan Hart936a7292015-03-06 18:02:57 -0800157 packetService,
158 flowService);
Jonathan Hartf5829202015-02-12 09:37:02 -0800159
sangho5eaf0332015-03-09 15:08:12 -0700160 icmpHandler = new IcmpHandler(configService, packetService);
161
Jonathan Hartf5829202015-02-12 09:37:02 -0800162 routingService.start(new InternalFibListener());
163
164 connectivityManager.start();
165
sangho5eaf0332015-03-09 15:08:12 -0700166 icmpHandler.start();
167
Jonathan Hartf5829202015-02-12 09:37:02 -0800168 log.info("BgpRouter started");
169 }
170
171 @Deactivate
172 protected void deactivate() {
173 routingService.stop();
174 connectivityManager.stop();
sangho5eaf0332015-03-09 15:08:12 -0700175 icmpHandler.stop();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800176 provisionStaticTables.provision(false, configService.getInterfaces());
Jonathan Hartf5829202015-02-12 09:37:02 -0800177
Jonathan Hart7baba072015-02-23 14:27:59 -0800178 groupService.removeListener(groupListener);
179
Jonathan Hartf5829202015-02-12 09:37:02 -0800180 log.info("BgpRouter stopped");
181 }
182
Saurav Dasfbe25c52015-03-04 11:12:00 -0800183 private void getDeviceConfiguration(Map<String, BgpSpeaker> bgps) {
184 if (bgps == null || bgps.values().isEmpty()) {
185 log.error("BGP speakers configuration is missing");
186 return;
187 }
188 for (BgpSpeaker s : bgps.values()) {
189 ctrlDeviceId = s.connectPoint().deviceId();
190 if (s.interfaceAddresses() == null || s.interfaceAddresses().isEmpty()) {
191 log.error("BGP Router must have interfaces configured");
192 return;
193 }
194 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
195 break;
196 }
sangho5eaf0332015-03-09 15:08:12 -0700197
Saurav Dasfbe25c52015-03-04 11:12:00 -0800198 log.info("Router dpid: {}", deviceId);
199 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
200 }
201
Jonathan Hartf5829202015-02-12 09:37:02 -0800202 private void updateFibEntry(Collection<FibUpdate> updates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800203 Map<FibEntry, Group> toInstall = new HashMap<>(updates.size());
204
Jonathan Hartf5829202015-02-12 09:37:02 -0800205 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800206 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800207
Jonathan Hart7baba072015-02-23 14:27:59 -0800208 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800209
Jonathan Hart7baba072015-02-23 14:27:59 -0800210 Group group;
211 synchronized (pendingUpdates) {
212 NextHop nextHop = nextHops.get(entry.nextHopIp());
213 group = groupService.getGroup(deviceId, nextHop.group());
Jonathan Hartf5829202015-02-12 09:37:02 -0800214
Jonathan Hart7baba072015-02-23 14:27:59 -0800215 if (group == null) {
216 log.debug("Adding pending flow {}", update.entry());
217 pendingUpdates.put(nextHop.group(), update.entry());
218 continue;
219 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800220 }
221
Jonathan Hart5b141422015-03-06 12:59:09 -0800222 toInstall.put(update.entry(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800223 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800224
225 installFlows(toInstall);
Jonathan Hartf5829202015-02-12 09:37:02 -0800226 }
227
Jonathan Hart5b141422015-03-06 12:59:09 -0800228 private void installFlows(Map<FibEntry, Group> entriesToInstall) {
229 FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800230
Jonathan Hart5b141422015-03-06 12:59:09 -0800231 for (Map.Entry<FibEntry, Group> entry : entriesToInstall.entrySet()) {
232 FibEntry fibEntry = entry.getKey();
233 Group group = entry.getValue();
234
235 FlowRule flowRule = generateRibFlowRule(fibEntry.prefix(), group);
236
237 builder.add(flowRule);
238 }
239
240 flowService.apply(builder.build());
Jonathan Hart7baba072015-02-23 14:27:59 -0800241 }
242
243 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800244 FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
245
Jonathan Hart7baba072015-02-23 14:27:59 -0800246 for (FibUpdate update : withdraws) {
247 FibEntry entry = update.entry();
248
Jonathan Hart37d659c2015-03-08 19:20:38 -0700249 Group group = deleteNextHop(entry.prefix());
250 if (group == null) {
251 log.warn("Group not found when deleting {}", entry);
252 return;
253 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800254
Jonathan Hart37d659c2015-03-08 19:20:38 -0700255 FlowRule flowRule = generateRibFlowRule(entry.prefix(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800256
Jonathan Hart5b141422015-03-06 12:59:09 -0800257 builder.remove(flowRule);
Jonathan Hartf5829202015-02-12 09:37:02 -0800258 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800259
260 flowService.apply(builder.build());
Jonathan Hartf5829202015-02-12 09:37:02 -0800261 }
262
Jonathan Hart37d659c2015-03-08 19:20:38 -0700263 private FlowRule generateRibFlowRule(IpPrefix prefix, Group group) {
264 TrafficSelector selector = DefaultTrafficSelector.builder()
265 .matchEthType(Ethernet.TYPE_IPV4)
266 .matchIPDst(prefix)
267 .build();
268
269 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
270 .group(group.id())
271 .build();
272
Jonathan Hart12ef2052015-03-10 13:58:13 -0700273
274 int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
275
Jonathan Hart37d659c2015-03-08 19:20:38 -0700276 return new DefaultFlowRule(deviceId, selector, treatment,
Jonathan Hart12ef2052015-03-10 13:58:13 -0700277 priority, appId, 0, true,
Jonathan Hart37d659c2015-03-08 19:20:38 -0700278 FlowRule.Type.IP);
279 }
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
305 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
306
307 GroupDescription groupDescription
308 = new DefaultGroupDescription(deviceId,
309 GroupDescription.Type.INDIRECT,
310 new GroupBuckets(Collections
311 .singletonList(bucket)),
312 groupKey,
313 appId);
314
315 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800316
317 nextHops.put(nextHop.ip(), nextHop);
318
Jonathan Hartf5829202015-02-12 09:37:02 -0800319 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800320
321 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800322 }
323
Jonathan Hart37d659c2015-03-08 19:20:38 -0700324 private synchronized Group deleteNextHop(IpPrefix prefix) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800325 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
326 NextHop nextHop = nextHops.get(nextHopIp);
327 if (nextHop == null) {
328 log.warn("No next hop found when removing prefix {}", prefix);
Jonathan Hart37d659c2015-03-08 19:20:38 -0700329 return null;
Jonathan Hart7baba072015-02-23 14:27:59 -0800330 }
331
Jonathan Hart37d659c2015-03-08 19:20:38 -0700332 Group group = groupService.getGroup(deviceId, nextHop.group());
333
Jonathan Hartf9f2cbb2015-03-12 17:44:03 -0700334 // FIXME disabling group deletes for now until we verify the logic is OK
335 /*if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800336 // There was one or less next hops, so there are now none
337
Jonathan Hart7baba072015-02-23 14:27:59 -0800338 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800339
Jonathan Hart7baba072015-02-23 14:27:59 -0800340 nextHops.remove(nextHopIp);
341
342 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf9f2cbb2015-03-12 17:44:03 -0700343 }*/
Jonathan Hart37d659c2015-03-08 19:20:38 -0700344
345 return group;
Jonathan Hartf5829202015-02-12 09:37:02 -0800346 }
347
348 private class InternalFibListener implements FibListener {
349
350 @Override
351 public void update(Collection<FibUpdate> updates,
352 Collection<FibUpdate> withdraws) {
353 BgpRouter.this.deleteFibEntry(withdraws);
354 BgpRouter.this.updateFibEntry(updates);
355 }
356 }
alshabib10580802015-02-18 18:30:33 -0800357
358 private class InternalTableHandler {
359
360 private static final int CONTROLLER_PRIORITY = 255;
361 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800362 private static final int HIGHEST_PRIORITY = 0xffff;
363 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
364 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800365 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800366
Saurav Dasfbe25c52015-03-04 11:12:00 -0800367 public void provision(boolean install, Set<Interface> intfs) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800368 getInterfaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800369 processTableZero(install);
370 processTableOne(install);
371 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800372 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800373 processTableFive(install);
374 processTableSix(install);
375 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800376 }
377
Jonathan Hart5b141422015-03-06 12:59:09 -0800378 private void getInterfaceConfig(Set<Interface> intfs) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800379 log.info("Processing {} router interfaces", intfs.size());
380 for (Interface intf : intfs) {
381 intfIps.addAll(intf.ipAddresses());
382 intfMacs.add(intf.mac());
alshabib346b5b32015-03-06 00:42:16 -0800383 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800384 }
385 }
386
alshabib10580802015-02-18 18:30:33 -0800387 private void processTableZero(boolean install) {
388 TrafficSelector.Builder selector;
389 TrafficTreatment.Builder treatment;
390
Saurav Dasfbe25c52015-03-04 11:12:00 -0800391 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800392 selector = DefaultTrafficSelector.builder();
393 treatment = DefaultTrafficTreatment.builder();
394
395 selector.matchEthDst(MacAddress.BROADCAST);
396 treatment.transition(FlowRule.Type.VLAN_MPLS);
397
398 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800399 treatment.build(),
400 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800401 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800402
403 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
404
405 ops = install ? ops.add(rule) : ops.remove(rule);
406
Saurav Dasfbe25c52015-03-04 11:12:00 -0800407 // Interface MACs
408 for (MacAddress mac : intfMacs) {
409 log.debug("adding rule for MAC: {}", mac);
410 selector = DefaultTrafficSelector.builder();
411 treatment = DefaultTrafficTreatment.builder();
412
413 selector.matchEthDst(mac);
414 treatment.transition(FlowRule.Type.VLAN_MPLS);
415
416 rule = new DefaultFlowRule(deviceId, selector.build(),
417 treatment.build(),
418 CONTROLLER_PRIORITY, appId, 0,
419 true, FlowRule.Type.FIRST);
420
421 ops = install ? ops.add(rule) : ops.remove(rule);
422 }
423
alshabib10580802015-02-18 18:30:33 -0800424 //Drop rule
425 selector = DefaultTrafficSelector.builder();
426 treatment = DefaultTrafficTreatment.builder();
427
428 treatment.drop();
429
430 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800431 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800432 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800433
434 ops = install ? ops.add(rule) : ops.remove(rule);
435
436 flowService.apply(ops.build(new FlowRuleOperationsContext() {
437 @Override
438 public void onSuccess(FlowRuleOperations ops) {
439 log.info("Provisioned default table for bgp router");
440 }
441
442 @Override
443 public void onError(FlowRuleOperations ops) {
444 log.info("Failed to provision default table for bgp router");
445 }
446 }));
447
448 }
449
450 private void processTableOne(boolean install) {
451 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800452 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
453 .builder();
alshabib10580802015-02-18 18:30:33 -0800454 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
455 FlowRule rule;
456
sanghoc0b3c342015-03-12 17:12:10 -0700457 selector.matchVlanId(VlanId.ANY);
alshabib10580802015-02-18 18:30:33 -0800458 treatment.transition(FlowRule.Type.VLAN);
459
460 rule = new DefaultFlowRule(deviceId, selector.build(),
461 treatment.build(), CONTROLLER_PRIORITY,
462 appId, 0, true, FlowRule.Type.VLAN_MPLS);
463
464 ops = install ? ops.add(rule) : ops.remove(rule);
465
alshabib10580802015-02-18 18:30:33 -0800466 flowService.apply(ops.build(new FlowRuleOperationsContext() {
467 @Override
468 public void onSuccess(FlowRuleOperations ops) {
469 log.info("Provisioned vlan/mpls table for bgp router");
470 }
471
472 @Override
473 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800474 log.info(
475 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800476 }
477 }));
478
479 }
480
481 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800482 TrafficSelector.Builder selector;
483 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800484 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
485 FlowRule rule;
486
Saurav Dasfbe25c52015-03-04 11:12:00 -0800487 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800488 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
489 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800490 selector = DefaultTrafficSelector.builder();
491 treatment = DefaultTrafficTreatment.builder();
492
alshabib346b5b32015-03-06 00:42:16 -0800493 selector.matchVlanId(portVlan.getValue());
494 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800495 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800496 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800497
498 rule = new DefaultFlowRule(deviceId, selector.build(),
499 treatment.build(), CONTROLLER_PRIORITY, appId,
500 0, true, FlowRule.Type.VLAN);
501
502 ops = install ? ops.add(rule) : ops.remove(rule);
503 }
504
alshabib10580802015-02-18 18:30:33 -0800505 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800506 selector = DefaultTrafficSelector.builder();
507 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800508
509 treatment.drop();
510
511 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800512 treatment.build(), DROP_PRIORITY, appId,
513 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800514
515 ops = install ? ops.add(rule) : ops.remove(rule);
516
517 flowService.apply(ops.build(new FlowRuleOperationsContext() {
518 @Override
519 public void onSuccess(FlowRuleOperations ops) {
520 log.info("Provisioned vlan table for bgp router");
521 }
522
523 @Override
524 public void onError(FlowRuleOperations ops) {
525 log.info("Failed to provision vlan table for bgp router");
526 }
527 }));
528 }
529
Saurav Dascbe6de32015-03-01 18:30:46 -0800530 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800531 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800532 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
533 .builder();
alshabib10580802015-02-18 18:30:33 -0800534 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
535 FlowRule rule;
536
537 selector.matchEthType(Ethernet.TYPE_ARP);
538 treatment.punt();
539
540 rule = new DefaultFlowRule(deviceId, selector.build(),
541 treatment.build(), CONTROLLER_PRIORITY,
542 appId, 0, true, FlowRule.Type.ETHER);
543
544 ops = install ? ops.add(rule) : ops.remove(rule);
545
546 selector = DefaultTrafficSelector.builder();
547 treatment = DefaultTrafficTreatment.builder();
548
549 selector.matchEthType(Ethernet.TYPE_IPV4);
550 treatment.transition(FlowRule.Type.COS);
551
552 rule = new DefaultFlowRule(deviceId, selector.build(),
553 treatment.build(), CONTROLLER_PRIORITY,
554 appId, 0, true, FlowRule.Type.ETHER);
555
556 ops = install ? ops.add(rule) : ops.remove(rule);
557
558 //Drop rule
559 selector = DefaultTrafficSelector.builder();
560 treatment = DefaultTrafficTreatment.builder();
561
562 treatment.drop();
563
564 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800565 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800566 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800567
568 ops = install ? ops.add(rule) : ops.remove(rule);
569
570 flowService.apply(ops.build(new FlowRuleOperationsContext() {
571 @Override
572 public void onSuccess(FlowRuleOperations ops) {
573 log.info("Provisioned ether table for bgp router");
574 }
575
576 @Override
577 public void onError(FlowRuleOperations ops) {
578 log.info("Failed to provision ether table for bgp router");
579 }
580 }));
581
alshabib10580802015-02-18 18:30:33 -0800582 }
583
584 private void processTableFive(boolean install) {
585 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800586 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
587 .builder();
alshabib10580802015-02-18 18:30:33 -0800588 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
589 FlowRule rule;
590
591 treatment.transition(FlowRule.Type.IP);
592
593 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800594 treatment.build(), DROP_PRIORITY, appId,
595 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800596
597 ops = install ? ops.add(rule) : ops.remove(rule);
598
599 flowService.apply(ops.build(new FlowRuleOperationsContext() {
600 @Override
601 public void onSuccess(FlowRuleOperations ops) {
602 log.info("Provisioned cos table for bgp router");
603 }
604
605 @Override
606 public void onError(FlowRuleOperations ops) {
607 log.info("Failed to provision cos table for bgp router");
608 }
609 }));
610
611 }
612
613 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800614 TrafficSelector.Builder selector;
615 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800616 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
617 FlowRule rule;
618
Saurav Dasfbe25c52015-03-04 11:12:00 -0800619
620 //Interface IPs
621 for (InterfaceIpAddress ipAddr : intfIps) {
622 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
623 selector = DefaultTrafficSelector.builder();
624 treatment = DefaultTrafficTreatment.builder();
625
626 selector.matchEthType(Ethernet.TYPE_IPV4);
627 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
628 treatment.transition(Type.ACL);
629
630 rule = new DefaultFlowRule(deviceId, selector.build(),
631 treatment.build(), HIGHEST_PRIORITY, appId,
632 0, true, FlowRule.Type.IP);
633
634 ops = install ? ops.add(rule) : ops.remove(rule);
635 }
636
637
alshabib10580802015-02-18 18:30:33 -0800638 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800639 selector = DefaultTrafficSelector.builder();
640 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800641
642 treatment.drop();
643
644 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800645 treatment.build(), DROP_PRIORITY, appId,
646 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800647
648 ops = install ? ops.add(rule) : ops.remove(rule);
649
650 flowService.apply(ops.build(new FlowRuleOperationsContext() {
651 @Override
652 public void onSuccess(FlowRuleOperations ops) {
653 log.info("Provisioned FIB table for bgp router");
654 }
655
656 @Override
657 public void onError(FlowRuleOperations ops) {
658 log.info("Failed to provision FIB table for bgp router");
659 }
660 }));
661 }
662
663 private void processTableNine(boolean install) {
664 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800665 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
666 .builder();
alshabib10580802015-02-18 18:30:33 -0800667 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
668 FlowRule rule;
669
670 treatment.punt();
671
672 rule = new DefaultFlowRule(deviceId, selector.build(),
673 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800674 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800675
676 ops = install ? ops.add(rule) : ops.remove(rule);
677
678 flowService.apply(ops.build(new FlowRuleOperationsContext() {
679 @Override
680 public void onSuccess(FlowRuleOperations ops) {
681 log.info("Provisioned Local table for bgp router");
682 }
683
684 @Override
685 public void onError(FlowRuleOperations ops) {
686 log.info("Failed to provision Local table for bgp router");
687 }
688 }));
689 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800690 }
alshabib10580802015-02-18 18:30:33 -0800691
Jonathan Hart7baba072015-02-23 14:27:59 -0800692 private class InternalGroupListener implements GroupListener {
693
694 @Override
695 public void event(GroupEvent event) {
696 Group group = event.subject();
697
698 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
699 event.type() == GroupEvent.Type.GROUP_UPDATED) {
700 synchronized (pendingUpdates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800701
702 Map<FibEntry, Group> entriesToInstall =
703 pendingUpdates.removeAll(group.appCookie())
704 .stream()
705 .collect(Collectors
706 .toMap(e -> e, e -> group));
707
708 installFlows(entriesToInstall);
Jonathan Hart7baba072015-02-23 14:27:59 -0800709 }
710 }
711 }
alshabib10580802015-02-18 18:30:33 -0800712 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800713}