blob: 413401a9090229869f971c3098c94e6eaa252583 [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())
301 .setOutput(egressIntf.connectPoint().port())
302 .build();
303
304 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
305
306 GroupDescription groupDescription
307 = new DefaultGroupDescription(deviceId,
308 GroupDescription.Type.INDIRECT,
309 new GroupBuckets(Collections
310 .singletonList(bucket)),
311 groupKey,
312 appId);
313
314 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800315
316 nextHops.put(nextHop.ip(), nextHop);
317
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
Jonathan Hart37d659c2015-03-08 19:20: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
Jonathan Hart37d659c2015-03-08 19:20:38 -0700331 Group group = groupService.getGroup(deviceId, nextHop.group());
332
Jonathan Hart7baba072015-02-23 14:27:59 -0800333 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800334 // There was one or less next hops, so there are now none
335
Jonathan Hart7baba072015-02-23 14:27:59 -0800336 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800337
Jonathan Hart7baba072015-02-23 14:27:59 -0800338 nextHops.remove(nextHopIp);
339
340 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800341 }
Jonathan Hart37d659c2015-03-08 19:20:38 -0700342
343 return group;
Jonathan Hartf5829202015-02-12 09:37:02 -0800344 }
345
346 private class InternalFibListener implements FibListener {
347
348 @Override
349 public void update(Collection<FibUpdate> updates,
350 Collection<FibUpdate> withdraws) {
351 BgpRouter.this.deleteFibEntry(withdraws);
352 BgpRouter.this.updateFibEntry(updates);
353 }
354 }
alshabib10580802015-02-18 18:30:33 -0800355
356 private class InternalTableHandler {
357
358 private static final int CONTROLLER_PRIORITY = 255;
359 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800360 private static final int HIGHEST_PRIORITY = 0xffff;
361 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
362 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800363 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800364
Saurav Dasfbe25c52015-03-04 11:12:00 -0800365 public void provision(boolean install, Set<Interface> intfs) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800366 getInterfaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800367 processTableZero(install);
368 processTableOne(install);
369 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800370 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800371 processTableFive(install);
372 processTableSix(install);
373 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800374 }
375
Jonathan Hart5b141422015-03-06 12:59:09 -0800376 private void getInterfaceConfig(Set<Interface> intfs) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800377 log.info("Processing {} router interfaces", intfs.size());
378 for (Interface intf : intfs) {
379 intfIps.addAll(intf.ipAddresses());
380 intfMacs.add(intf.mac());
alshabib346b5b32015-03-06 00:42:16 -0800381 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800382 }
383 }
384
alshabib10580802015-02-18 18:30:33 -0800385 private void processTableZero(boolean install) {
386 TrafficSelector.Builder selector;
387 TrafficTreatment.Builder treatment;
388
Saurav Dasfbe25c52015-03-04 11:12:00 -0800389 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800390 selector = DefaultTrafficSelector.builder();
391 treatment = DefaultTrafficTreatment.builder();
392
393 selector.matchEthDst(MacAddress.BROADCAST);
394 treatment.transition(FlowRule.Type.VLAN_MPLS);
395
396 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800397 treatment.build(),
398 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800399 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800400
401 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
402
403 ops = install ? ops.add(rule) : ops.remove(rule);
404
Saurav Dasfbe25c52015-03-04 11:12:00 -0800405 // Interface MACs
406 for (MacAddress mac : intfMacs) {
407 log.debug("adding rule for MAC: {}", mac);
408 selector = DefaultTrafficSelector.builder();
409 treatment = DefaultTrafficTreatment.builder();
410
411 selector.matchEthDst(mac);
412 treatment.transition(FlowRule.Type.VLAN_MPLS);
413
414 rule = new DefaultFlowRule(deviceId, selector.build(),
415 treatment.build(),
416 CONTROLLER_PRIORITY, appId, 0,
417 true, FlowRule.Type.FIRST);
418
419 ops = install ? ops.add(rule) : ops.remove(rule);
420 }
421
alshabib10580802015-02-18 18:30:33 -0800422 //Drop rule
423 selector = DefaultTrafficSelector.builder();
424 treatment = DefaultTrafficTreatment.builder();
425
426 treatment.drop();
427
428 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800429 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800430 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800431
432 ops = install ? ops.add(rule) : ops.remove(rule);
433
434 flowService.apply(ops.build(new FlowRuleOperationsContext() {
435 @Override
436 public void onSuccess(FlowRuleOperations ops) {
437 log.info("Provisioned default table for bgp router");
438 }
439
440 @Override
441 public void onError(FlowRuleOperations ops) {
442 log.info("Failed to provision default table for bgp router");
443 }
444 }));
445
446 }
447
448 private void processTableOne(boolean install) {
449 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800450 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
451 .builder();
alshabib10580802015-02-18 18:30:33 -0800452 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
453 FlowRule rule;
454
alshabib10580802015-02-18 18:30:33 -0800455 selector.matchEthType(Ethernet.TYPE_VLAN);
456 treatment.transition(FlowRule.Type.VLAN);
457
458 rule = new DefaultFlowRule(deviceId, selector.build(),
459 treatment.build(), CONTROLLER_PRIORITY,
460 appId, 0, true, FlowRule.Type.VLAN_MPLS);
461
462 ops = install ? ops.add(rule) : ops.remove(rule);
463
alshabib10580802015-02-18 18:30:33 -0800464 flowService.apply(ops.build(new FlowRuleOperationsContext() {
465 @Override
466 public void onSuccess(FlowRuleOperations ops) {
467 log.info("Provisioned vlan/mpls table for bgp router");
468 }
469
470 @Override
471 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800472 log.info(
473 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800474 }
475 }));
476
477 }
478
479 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800480 TrafficSelector.Builder selector;
481 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800482 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
483 FlowRule rule;
484
Saurav Dasfbe25c52015-03-04 11:12:00 -0800485 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800486 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
487 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800488 selector = DefaultTrafficSelector.builder();
489 treatment = DefaultTrafficTreatment.builder();
490
alshabib346b5b32015-03-06 00:42:16 -0800491 selector.matchVlanId(portVlan.getValue());
492 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800493 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800494 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800495
496 rule = new DefaultFlowRule(deviceId, selector.build(),
497 treatment.build(), CONTROLLER_PRIORITY, appId,
498 0, true, FlowRule.Type.VLAN);
499
500 ops = install ? ops.add(rule) : ops.remove(rule);
501 }
502
alshabib10580802015-02-18 18:30:33 -0800503 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800504 selector = DefaultTrafficSelector.builder();
505 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800506
507 treatment.drop();
508
509 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800510 treatment.build(), DROP_PRIORITY, appId,
511 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800512
513 ops = install ? ops.add(rule) : ops.remove(rule);
514
515 flowService.apply(ops.build(new FlowRuleOperationsContext() {
516 @Override
517 public void onSuccess(FlowRuleOperations ops) {
518 log.info("Provisioned vlan table for bgp router");
519 }
520
521 @Override
522 public void onError(FlowRuleOperations ops) {
523 log.info("Failed to provision vlan table for bgp router");
524 }
525 }));
526 }
527
Saurav Dascbe6de32015-03-01 18:30:46 -0800528 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800529 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800530 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
531 .builder();
alshabib10580802015-02-18 18:30:33 -0800532 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
533 FlowRule rule;
534
535 selector.matchEthType(Ethernet.TYPE_ARP);
536 treatment.punt();
537
538 rule = new DefaultFlowRule(deviceId, selector.build(),
539 treatment.build(), CONTROLLER_PRIORITY,
540 appId, 0, true, FlowRule.Type.ETHER);
541
542 ops = install ? ops.add(rule) : ops.remove(rule);
543
544 selector = DefaultTrafficSelector.builder();
545 treatment = DefaultTrafficTreatment.builder();
546
547 selector.matchEthType(Ethernet.TYPE_IPV4);
548 treatment.transition(FlowRule.Type.COS);
549
550 rule = new DefaultFlowRule(deviceId, selector.build(),
551 treatment.build(), CONTROLLER_PRIORITY,
552 appId, 0, true, FlowRule.Type.ETHER);
553
554 ops = install ? ops.add(rule) : ops.remove(rule);
555
556 //Drop rule
557 selector = DefaultTrafficSelector.builder();
558 treatment = DefaultTrafficTreatment.builder();
559
560 treatment.drop();
561
562 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800563 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800564 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800565
566 ops = install ? ops.add(rule) : ops.remove(rule);
567
568 flowService.apply(ops.build(new FlowRuleOperationsContext() {
569 @Override
570 public void onSuccess(FlowRuleOperations ops) {
571 log.info("Provisioned ether table for bgp router");
572 }
573
574 @Override
575 public void onError(FlowRuleOperations ops) {
576 log.info("Failed to provision ether table for bgp router");
577 }
578 }));
579
alshabib10580802015-02-18 18:30:33 -0800580 }
581
582 private void processTableFive(boolean install) {
583 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800584 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
585 .builder();
alshabib10580802015-02-18 18:30:33 -0800586 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
587 FlowRule rule;
588
589 treatment.transition(FlowRule.Type.IP);
590
591 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800592 treatment.build(), DROP_PRIORITY, appId,
593 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800594
595 ops = install ? ops.add(rule) : ops.remove(rule);
596
597 flowService.apply(ops.build(new FlowRuleOperationsContext() {
598 @Override
599 public void onSuccess(FlowRuleOperations ops) {
600 log.info("Provisioned cos table for bgp router");
601 }
602
603 @Override
604 public void onError(FlowRuleOperations ops) {
605 log.info("Failed to provision cos table for bgp router");
606 }
607 }));
608
609 }
610
611 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800612 TrafficSelector.Builder selector;
613 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800614 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
615 FlowRule rule;
616
Saurav Dasfbe25c52015-03-04 11:12:00 -0800617
618 //Interface IPs
619 for (InterfaceIpAddress ipAddr : intfIps) {
620 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
621 selector = DefaultTrafficSelector.builder();
622 treatment = DefaultTrafficTreatment.builder();
623
624 selector.matchEthType(Ethernet.TYPE_IPV4);
625 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
626 treatment.transition(Type.ACL);
627
628 rule = new DefaultFlowRule(deviceId, selector.build(),
629 treatment.build(), HIGHEST_PRIORITY, appId,
630 0, true, FlowRule.Type.IP);
631
632 ops = install ? ops.add(rule) : ops.remove(rule);
633 }
634
635
alshabib10580802015-02-18 18:30:33 -0800636 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800637 selector = DefaultTrafficSelector.builder();
638 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800639
640 treatment.drop();
641
642 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800643 treatment.build(), DROP_PRIORITY, appId,
644 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800645
646 ops = install ? ops.add(rule) : ops.remove(rule);
647
648 flowService.apply(ops.build(new FlowRuleOperationsContext() {
649 @Override
650 public void onSuccess(FlowRuleOperations ops) {
651 log.info("Provisioned FIB table for bgp router");
652 }
653
654 @Override
655 public void onError(FlowRuleOperations ops) {
656 log.info("Failed to provision FIB table for bgp router");
657 }
658 }));
659 }
660
661 private void processTableNine(boolean install) {
662 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800663 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
664 .builder();
alshabib10580802015-02-18 18:30:33 -0800665 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
666 FlowRule rule;
667
668 treatment.punt();
669
670 rule = new DefaultFlowRule(deviceId, selector.build(),
671 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800672 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800673
674 ops = install ? ops.add(rule) : ops.remove(rule);
675
676 flowService.apply(ops.build(new FlowRuleOperationsContext() {
677 @Override
678 public void onSuccess(FlowRuleOperations ops) {
679 log.info("Provisioned Local table for bgp router");
680 }
681
682 @Override
683 public void onError(FlowRuleOperations ops) {
684 log.info("Failed to provision Local table for bgp router");
685 }
686 }));
687 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800688 }
alshabib10580802015-02-18 18:30:33 -0800689
Jonathan Hart7baba072015-02-23 14:27:59 -0800690 private class InternalGroupListener implements GroupListener {
691
692 @Override
693 public void event(GroupEvent event) {
694 Group group = event.subject();
695
696 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
697 event.type() == GroupEvent.Type.GROUP_UPDATED) {
698 synchronized (pendingUpdates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800699
700 Map<FibEntry, Group> entriesToInstall =
701 pendingUpdates.removeAll(group.appCookie())
702 .stream()
703 .collect(Collectors
704 .toMap(e -> e, e -> group));
705
706 installFlows(entriesToInstall);
Jonathan Hart7baba072015-02-23 14:27:59 -0800707 }
708 }
709 }
alshabib10580802015-02-18 18:30:33 -0800710 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800711}