blob: 1035cd6edcff428250dba41d69504738b781aa7a [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 Hart7baba072015-02-23 14:27:59 -0800334 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800335 // There was one or less next hops, so there are now none
336
Jonathan Hart7baba072015-02-23 14:27:59 -0800337 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800338
Jonathan Hart7baba072015-02-23 14:27:59 -0800339 nextHops.remove(nextHopIp);
340
341 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800342 }
Jonathan Hart37d659c2015-03-08 19:20:38 -0700343
344 return group;
Jonathan Hartf5829202015-02-12 09:37:02 -0800345 }
346
347 private class InternalFibListener implements FibListener {
348
349 @Override
350 public void update(Collection<FibUpdate> updates,
351 Collection<FibUpdate> withdraws) {
352 BgpRouter.this.deleteFibEntry(withdraws);
353 BgpRouter.this.updateFibEntry(updates);
354 }
355 }
alshabib10580802015-02-18 18:30:33 -0800356
357 private class InternalTableHandler {
358
359 private static final int CONTROLLER_PRIORITY = 255;
360 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800361 private static final int HIGHEST_PRIORITY = 0xffff;
362 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
363 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800364 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800365
Saurav Dasfbe25c52015-03-04 11:12:00 -0800366 public void provision(boolean install, Set<Interface> intfs) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800367 getInterfaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800368 processTableZero(install);
369 processTableOne(install);
370 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800371 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800372 processTableFive(install);
373 processTableSix(install);
374 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800375 }
376
Jonathan Hart5b141422015-03-06 12:59:09 -0800377 private void getInterfaceConfig(Set<Interface> intfs) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800378 log.info("Processing {} router interfaces", intfs.size());
379 for (Interface intf : intfs) {
380 intfIps.addAll(intf.ipAddresses());
381 intfMacs.add(intf.mac());
alshabib346b5b32015-03-06 00:42:16 -0800382 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800383 }
384 }
385
alshabib10580802015-02-18 18:30:33 -0800386 private void processTableZero(boolean install) {
387 TrafficSelector.Builder selector;
388 TrafficTreatment.Builder treatment;
389
Saurav Dasfbe25c52015-03-04 11:12:00 -0800390 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800391 selector = DefaultTrafficSelector.builder();
392 treatment = DefaultTrafficTreatment.builder();
393
394 selector.matchEthDst(MacAddress.BROADCAST);
395 treatment.transition(FlowRule.Type.VLAN_MPLS);
396
397 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800398 treatment.build(),
399 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800400 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800401
402 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
403
404 ops = install ? ops.add(rule) : ops.remove(rule);
405
Saurav Dasfbe25c52015-03-04 11:12:00 -0800406 // Interface MACs
407 for (MacAddress mac : intfMacs) {
408 log.debug("adding rule for MAC: {}", mac);
409 selector = DefaultTrafficSelector.builder();
410 treatment = DefaultTrafficTreatment.builder();
411
412 selector.matchEthDst(mac);
413 treatment.transition(FlowRule.Type.VLAN_MPLS);
414
415 rule = new DefaultFlowRule(deviceId, selector.build(),
416 treatment.build(),
417 CONTROLLER_PRIORITY, appId, 0,
418 true, FlowRule.Type.FIRST);
419
420 ops = install ? ops.add(rule) : ops.remove(rule);
421 }
422
alshabib10580802015-02-18 18:30:33 -0800423 //Drop rule
424 selector = DefaultTrafficSelector.builder();
425 treatment = DefaultTrafficTreatment.builder();
426
427 treatment.drop();
428
429 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800430 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800431 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800432
433 ops = install ? ops.add(rule) : ops.remove(rule);
434
435 flowService.apply(ops.build(new FlowRuleOperationsContext() {
436 @Override
437 public void onSuccess(FlowRuleOperations ops) {
438 log.info("Provisioned default table for bgp router");
439 }
440
441 @Override
442 public void onError(FlowRuleOperations ops) {
443 log.info("Failed to provision default table for bgp router");
444 }
445 }));
446
447 }
448
449 private void processTableOne(boolean install) {
450 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800451 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
452 .builder();
alshabib10580802015-02-18 18:30:33 -0800453 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
454 FlowRule rule;
455
alshabib10580802015-02-18 18:30:33 -0800456 selector.matchEthType(Ethernet.TYPE_VLAN);
457 treatment.transition(FlowRule.Type.VLAN);
458
459 rule = new DefaultFlowRule(deviceId, selector.build(),
460 treatment.build(), CONTROLLER_PRIORITY,
461 appId, 0, true, FlowRule.Type.VLAN_MPLS);
462
463 ops = install ? ops.add(rule) : ops.remove(rule);
464
alshabib10580802015-02-18 18:30:33 -0800465 flowService.apply(ops.build(new FlowRuleOperationsContext() {
466 @Override
467 public void onSuccess(FlowRuleOperations ops) {
468 log.info("Provisioned vlan/mpls table for bgp router");
469 }
470
471 @Override
472 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800473 log.info(
474 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800475 }
476 }));
477
478 }
479
480 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800481 TrafficSelector.Builder selector;
482 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800483 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
484 FlowRule rule;
485
Saurav Dasfbe25c52015-03-04 11:12:00 -0800486 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800487 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
488 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800489 selector = DefaultTrafficSelector.builder();
490 treatment = DefaultTrafficTreatment.builder();
491
alshabib346b5b32015-03-06 00:42:16 -0800492 selector.matchVlanId(portVlan.getValue());
493 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800494 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800495 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800496
497 rule = new DefaultFlowRule(deviceId, selector.build(),
498 treatment.build(), CONTROLLER_PRIORITY, appId,
499 0, true, FlowRule.Type.VLAN);
500
501 ops = install ? ops.add(rule) : ops.remove(rule);
502 }
503
alshabib10580802015-02-18 18:30:33 -0800504 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800505 selector = DefaultTrafficSelector.builder();
506 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800507
508 treatment.drop();
509
510 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800511 treatment.build(), DROP_PRIORITY, appId,
512 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800513
514 ops = install ? ops.add(rule) : ops.remove(rule);
515
516 flowService.apply(ops.build(new FlowRuleOperationsContext() {
517 @Override
518 public void onSuccess(FlowRuleOperations ops) {
519 log.info("Provisioned vlan table for bgp router");
520 }
521
522 @Override
523 public void onError(FlowRuleOperations ops) {
524 log.info("Failed to provision vlan table for bgp router");
525 }
526 }));
527 }
528
Saurav Dascbe6de32015-03-01 18:30:46 -0800529 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800530 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800531 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
532 .builder();
alshabib10580802015-02-18 18:30:33 -0800533 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
534 FlowRule rule;
535
536 selector.matchEthType(Ethernet.TYPE_ARP);
537 treatment.punt();
538
539 rule = new DefaultFlowRule(deviceId, selector.build(),
540 treatment.build(), CONTROLLER_PRIORITY,
541 appId, 0, true, FlowRule.Type.ETHER);
542
543 ops = install ? ops.add(rule) : ops.remove(rule);
544
545 selector = DefaultTrafficSelector.builder();
546 treatment = DefaultTrafficTreatment.builder();
547
548 selector.matchEthType(Ethernet.TYPE_IPV4);
549 treatment.transition(FlowRule.Type.COS);
550
551 rule = new DefaultFlowRule(deviceId, selector.build(),
552 treatment.build(), CONTROLLER_PRIORITY,
553 appId, 0, true, FlowRule.Type.ETHER);
554
555 ops = install ? ops.add(rule) : ops.remove(rule);
556
557 //Drop rule
558 selector = DefaultTrafficSelector.builder();
559 treatment = DefaultTrafficTreatment.builder();
560
561 treatment.drop();
562
563 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800564 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800565 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800566
567 ops = install ? ops.add(rule) : ops.remove(rule);
568
569 flowService.apply(ops.build(new FlowRuleOperationsContext() {
570 @Override
571 public void onSuccess(FlowRuleOperations ops) {
572 log.info("Provisioned ether table for bgp router");
573 }
574
575 @Override
576 public void onError(FlowRuleOperations ops) {
577 log.info("Failed to provision ether table for bgp router");
578 }
579 }));
580
alshabib10580802015-02-18 18:30:33 -0800581 }
582
583 private void processTableFive(boolean install) {
584 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800585 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
586 .builder();
alshabib10580802015-02-18 18:30:33 -0800587 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
588 FlowRule rule;
589
590 treatment.transition(FlowRule.Type.IP);
591
592 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800593 treatment.build(), DROP_PRIORITY, appId,
594 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800595
596 ops = install ? ops.add(rule) : ops.remove(rule);
597
598 flowService.apply(ops.build(new FlowRuleOperationsContext() {
599 @Override
600 public void onSuccess(FlowRuleOperations ops) {
601 log.info("Provisioned cos table for bgp router");
602 }
603
604 @Override
605 public void onError(FlowRuleOperations ops) {
606 log.info("Failed to provision cos table for bgp router");
607 }
608 }));
609
610 }
611
612 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800613 TrafficSelector.Builder selector;
614 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800615 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
616 FlowRule rule;
617
Saurav Dasfbe25c52015-03-04 11:12:00 -0800618
619 //Interface IPs
620 for (InterfaceIpAddress ipAddr : intfIps) {
621 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
622 selector = DefaultTrafficSelector.builder();
623 treatment = DefaultTrafficTreatment.builder();
624
625 selector.matchEthType(Ethernet.TYPE_IPV4);
626 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
627 treatment.transition(Type.ACL);
628
629 rule = new DefaultFlowRule(deviceId, selector.build(),
630 treatment.build(), HIGHEST_PRIORITY, appId,
631 0, true, FlowRule.Type.IP);
632
633 ops = install ? ops.add(rule) : ops.remove(rule);
634 }
635
636
alshabib10580802015-02-18 18:30:33 -0800637 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800638 selector = DefaultTrafficSelector.builder();
639 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800640
641 treatment.drop();
642
643 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800644 treatment.build(), DROP_PRIORITY, appId,
645 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800646
647 ops = install ? ops.add(rule) : ops.remove(rule);
648
649 flowService.apply(ops.build(new FlowRuleOperationsContext() {
650 @Override
651 public void onSuccess(FlowRuleOperations ops) {
652 log.info("Provisioned FIB table for bgp router");
653 }
654
655 @Override
656 public void onError(FlowRuleOperations ops) {
657 log.info("Failed to provision FIB table for bgp router");
658 }
659 }));
660 }
661
662 private void processTableNine(boolean install) {
663 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800664 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
665 .builder();
alshabib10580802015-02-18 18:30:33 -0800666 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
667 FlowRule rule;
668
669 treatment.punt();
670
671 rule = new DefaultFlowRule(deviceId, selector.build(),
672 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800673 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800674
675 ops = install ? ops.add(rule) : ops.remove(rule);
676
677 flowService.apply(ops.build(new FlowRuleOperationsContext() {
678 @Override
679 public void onSuccess(FlowRuleOperations ops) {
680 log.info("Provisioned Local table for bgp router");
681 }
682
683 @Override
684 public void onError(FlowRuleOperations ops) {
685 log.info("Failed to provision Local table for bgp router");
686 }
687 }));
688 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800689 }
alshabib10580802015-02-18 18:30:33 -0800690
Jonathan Hart7baba072015-02-23 14:27:59 -0800691 private class InternalGroupListener implements GroupListener {
692
693 @Override
694 public void event(GroupEvent event) {
695 Group group = event.subject();
696
697 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
698 event.type() == GroupEvent.Type.GROUP_UPDATED) {
699 synchronized (pendingUpdates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800700
701 Map<FibEntry, Group> entriesToInstall =
702 pendingUpdates.removeAll(group.appCookie())
703 .stream()
704 .collect(Collectors
705 .toMap(e -> e, e -> group));
706
707 installFlows(entriesToInstall);
Jonathan Hart7baba072015-02-23 14:27:59 -0800708 }
709 }
710 }
alshabib10580802015-02-18 18:30:33 -0800711 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800712}