blob: b6c921eb9b9541537174a5e7f7ac8e0632642dcd [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
88 private static final int PRIORITY = 1;
89
90 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
91 protected CoreService coreService;
92
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected FlowRuleService flowService;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected GroupService groupService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected RoutingService routingService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected RoutingConfigurationService configService;
104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 protected PacketService packetService;
107
Saurav Dasfbe25c52015-03-04 11:12:00 -0800108 //
109 // NOTE: Unused reference - needed to guarantee that the
110 // NetworkConfigReader component is activated and the network configuration
111 // is read.
112 //
113 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
114 protected NetworkConfigService networkConfigService;
115
Jonathan Hartf5829202015-02-12 09:37:02 -0800116 private ApplicationId appId;
117
Jonathan Hart7baba072015-02-23 14:27:59 -0800118 // Reference count for how many times a next hop is used by a route
119 private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
120
121 // Mapping from prefix to its current next hop
122 private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
123
124 // Mapping from next hop IP to next hop object containing group info
125 private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap();
126
127 // Stores FIB updates that are waiting for groups to be set up
128 private final Multimap<GroupKey, FibEntry> pendingUpdates = HashMultimap.create();
Jonathan Hartf5829202015-02-12 09:37:02 -0800129
Saurav Dasfbe25c52015-03-04 11:12:00 -0800130 // Device id of data-plane switch - should be learned from config
131 private DeviceId deviceId;
132
133 // Device id of control-plane switch (OVS) connected to BGP Speaker - should be
134 // learned from config
135 private DeviceId ctrlDeviceId;
Jonathan Hartf5829202015-02-12 09:37:02 -0800136
Jonathan Hart7baba072015-02-23 14:27:59 -0800137 private final GroupListener groupListener = new InternalGroupListener();
138
Jonathan Hartf5829202015-02-12 09:37:02 -0800139 private TunnellingConnectivityManager connectivityManager;
140
sangho5eaf0332015-03-09 15:08:12 -0700141 private IcmpHandler icmpHandler;
142
alshabib10580802015-02-18 18:30:33 -0800143 private InternalTableHandler provisionStaticTables = new InternalTableHandler();
144
Jonathan Hartf5829202015-02-12 09:37:02 -0800145 @Activate
146 protected void activate() {
Jonathan Hartf5829202015-02-12 09:37:02 -0800147 appId = coreService.registerApplication(BGP_ROUTER_APP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800148 getDeviceConfiguration(configService.getBgpSpeakers());
Jonathan Hartf5829202015-02-12 09:37:02 -0800149
Jonathan Hart7baba072015-02-23 14:27:59 -0800150 groupService.addListener(groupListener);
151
Saurav Dasfbe25c52015-03-04 11:12:00 -0800152 provisionStaticTables.provision(true, configService.getInterfaces());
alshabib10580802015-02-18 18:30:33 -0800153
Jonathan Hartf5829202015-02-12 09:37:02 -0800154 connectivityManager = new TunnellingConnectivityManager(appId,
155 configService,
Jonathan Hart936a7292015-03-06 18:02:57 -0800156 packetService,
157 flowService);
Jonathan Hartf5829202015-02-12 09:37:02 -0800158
sangho5eaf0332015-03-09 15:08:12 -0700159 icmpHandler = new IcmpHandler(configService, packetService);
160
Jonathan Hartf5829202015-02-12 09:37:02 -0800161 routingService.start(new InternalFibListener());
162
163 connectivityManager.start();
164
sangho5eaf0332015-03-09 15:08:12 -0700165 icmpHandler.start();
166
Jonathan Hartf5829202015-02-12 09:37:02 -0800167 log.info("BgpRouter started");
168 }
169
170 @Deactivate
171 protected void deactivate() {
172 routingService.stop();
173 connectivityManager.stop();
sangho5eaf0332015-03-09 15:08:12 -0700174 icmpHandler.stop();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800175 provisionStaticTables.provision(false, configService.getInterfaces());
Jonathan Hartf5829202015-02-12 09:37:02 -0800176
Jonathan Hart7baba072015-02-23 14:27:59 -0800177 groupService.removeListener(groupListener);
178
Jonathan Hartf5829202015-02-12 09:37:02 -0800179 log.info("BgpRouter stopped");
180 }
181
Saurav Dasfbe25c52015-03-04 11:12:00 -0800182 private void getDeviceConfiguration(Map<String, BgpSpeaker> bgps) {
183 if (bgps == null || bgps.values().isEmpty()) {
184 log.error("BGP speakers configuration is missing");
185 return;
186 }
187 for (BgpSpeaker s : bgps.values()) {
188 ctrlDeviceId = s.connectPoint().deviceId();
189 if (s.interfaceAddresses() == null || s.interfaceAddresses().isEmpty()) {
190 log.error("BGP Router must have interfaces configured");
191 return;
192 }
193 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
194 break;
195 }
sangho5eaf0332015-03-09 15:08:12 -0700196
Saurav Dasfbe25c52015-03-04 11:12:00 -0800197 log.info("Router dpid: {}", deviceId);
198 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
199 }
200
Jonathan Hartf5829202015-02-12 09:37:02 -0800201 private void updateFibEntry(Collection<FibUpdate> updates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800202 Map<FibEntry, Group> toInstall = new HashMap<>(updates.size());
203
Jonathan Hartf5829202015-02-12 09:37:02 -0800204 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800205 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800206
Jonathan Hart7baba072015-02-23 14:27:59 -0800207 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800208
Jonathan Hart7baba072015-02-23 14:27:59 -0800209 Group group;
210 synchronized (pendingUpdates) {
211 NextHop nextHop = nextHops.get(entry.nextHopIp());
212 group = groupService.getGroup(deviceId, nextHop.group());
Jonathan Hartf5829202015-02-12 09:37:02 -0800213
Jonathan Hart7baba072015-02-23 14:27:59 -0800214 if (group == null) {
215 log.debug("Adding pending flow {}", update.entry());
216 pendingUpdates.put(nextHop.group(), update.entry());
217 continue;
218 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800219 }
220
Jonathan Hart5b141422015-03-06 12:59:09 -0800221 toInstall.put(update.entry(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800222 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800223
224 installFlows(toInstall);
Jonathan Hartf5829202015-02-12 09:37:02 -0800225 }
226
Jonathan Hart5b141422015-03-06 12:59:09 -0800227 private void installFlows(Map<FibEntry, Group> entriesToInstall) {
228 FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800229
Jonathan Hart5b141422015-03-06 12:59:09 -0800230 for (Map.Entry<FibEntry, Group> entry : entriesToInstall.entrySet()) {
231 FibEntry fibEntry = entry.getKey();
232 Group group = entry.getValue();
233
234 FlowRule flowRule = generateRibFlowRule(fibEntry.prefix(), group);
235
236 builder.add(flowRule);
237 }
238
239 flowService.apply(builder.build());
Jonathan Hart7baba072015-02-23 14:27:59 -0800240 }
241
242 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800243 FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
244
Jonathan Hart7baba072015-02-23 14:27:59 -0800245 for (FibUpdate update : withdraws) {
246 FibEntry entry = update.entry();
247
Jonathan Hart37d659c2015-03-08 19:20:38 -0700248 Group group = deleteNextHop(entry.prefix());
249 if (group == null) {
250 log.warn("Group not found when deleting {}", entry);
251 return;
252 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800253
Jonathan Hart37d659c2015-03-08 19:20:38 -0700254 FlowRule flowRule = generateRibFlowRule(entry.prefix(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800255
Jonathan Hart5b141422015-03-06 12:59:09 -0800256 builder.remove(flowRule);
Jonathan Hartf5829202015-02-12 09:37:02 -0800257 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800258
259 flowService.apply(builder.build());
Jonathan Hartf5829202015-02-12 09:37:02 -0800260 }
261
Jonathan Hart37d659c2015-03-08 19:20:38 -0700262 private FlowRule generateRibFlowRule(IpPrefix prefix, Group group) {
263 TrafficSelector selector = DefaultTrafficSelector.builder()
264 .matchEthType(Ethernet.TYPE_IPV4)
265 .matchIPDst(prefix)
266 .build();
267
268 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
269 .group(group.id())
270 .build();
271
272 return new DefaultFlowRule(deviceId, selector, treatment,
273 PRIORITY, appId, 0, true,
274 FlowRule.Type.IP);
275 }
276
Jonathan Hart7baba072015-02-23 14:27:59 -0800277 private synchronized void addNextHop(FibEntry entry) {
278 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
279 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800280 // There was no next hop in the multiset
281
Jonathan Hart7baba072015-02-23 14:27:59 -0800282 Interface egressIntf = configService.getMatchingInterface(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800283 if (egressIntf == null) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800284 log.warn("no egress interface found for {}", entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800285 return;
286 }
287
Jonathan Hart7baba072015-02-23 14:27:59 -0800288 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
289
290 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
Jonathan Hartf5829202015-02-12 09:37:02 -0800291
292 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
293 .setEthSrc(egressIntf.mac())
294 .setEthDst(nextHop.mac())
Jonathan Hart54b406b2015-03-06 16:24:14 -0800295 .pushVlan()
Jonathan Hartf5829202015-02-12 09:37:02 -0800296 .setVlanId(egressIntf.vlan())
297 .setOutput(egressIntf.connectPoint().port())
298 .build();
299
300 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
301
302 GroupDescription groupDescription
303 = new DefaultGroupDescription(deviceId,
304 GroupDescription.Type.INDIRECT,
305 new GroupBuckets(Collections
306 .singletonList(bucket)),
307 groupKey,
308 appId);
309
310 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800311
312 nextHops.put(nextHop.ip(), nextHop);
313
Jonathan Hartf5829202015-02-12 09:37:02 -0800314 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800315
316 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800317 }
318
Jonathan Hart37d659c2015-03-08 19:20:38 -0700319 private synchronized Group deleteNextHop(IpPrefix prefix) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800320 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
321 NextHop nextHop = nextHops.get(nextHopIp);
322 if (nextHop == null) {
323 log.warn("No next hop found when removing prefix {}", prefix);
Jonathan Hart37d659c2015-03-08 19:20:38 -0700324 return null;
Jonathan Hart7baba072015-02-23 14:27:59 -0800325 }
326
Jonathan Hart37d659c2015-03-08 19:20:38 -0700327 Group group = groupService.getGroup(deviceId, nextHop.group());
328
Jonathan Hart7baba072015-02-23 14:27:59 -0800329 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800330 // There was one or less next hops, so there are now none
331
Jonathan Hart7baba072015-02-23 14:27:59 -0800332 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800333
Jonathan Hart7baba072015-02-23 14:27:59 -0800334 nextHops.remove(nextHopIp);
335
336 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800337 }
Jonathan Hart37d659c2015-03-08 19:20:38 -0700338
339 return group;
Jonathan Hartf5829202015-02-12 09:37:02 -0800340 }
341
342 private class InternalFibListener implements FibListener {
343
344 @Override
345 public void update(Collection<FibUpdate> updates,
346 Collection<FibUpdate> withdraws) {
347 BgpRouter.this.deleteFibEntry(withdraws);
348 BgpRouter.this.updateFibEntry(updates);
349 }
350 }
alshabib10580802015-02-18 18:30:33 -0800351
352 private class InternalTableHandler {
353
354 private static final int CONTROLLER_PRIORITY = 255;
355 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800356 private static final int HIGHEST_PRIORITY = 0xffff;
357 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
358 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800359 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800360
Saurav Dasfbe25c52015-03-04 11:12:00 -0800361 public void provision(boolean install, Set<Interface> intfs) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800362 getInterfaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800363 processTableZero(install);
364 processTableOne(install);
365 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800366 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800367 processTableFive(install);
368 processTableSix(install);
369 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800370 }
371
Jonathan Hart5b141422015-03-06 12:59:09 -0800372 private void getInterfaceConfig(Set<Interface> intfs) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800373 log.info("Processing {} router interfaces", intfs.size());
374 for (Interface intf : intfs) {
375 intfIps.addAll(intf.ipAddresses());
376 intfMacs.add(intf.mac());
alshabib346b5b32015-03-06 00:42:16 -0800377 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800378 }
379 }
380
alshabib10580802015-02-18 18:30:33 -0800381 private void processTableZero(boolean install) {
382 TrafficSelector.Builder selector;
383 TrafficTreatment.Builder treatment;
384
Saurav Dasfbe25c52015-03-04 11:12:00 -0800385 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800386 selector = DefaultTrafficSelector.builder();
387 treatment = DefaultTrafficTreatment.builder();
388
389 selector.matchEthDst(MacAddress.BROADCAST);
390 treatment.transition(FlowRule.Type.VLAN_MPLS);
391
392 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800393 treatment.build(),
394 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800395 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800396
397 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
398
399 ops = install ? ops.add(rule) : ops.remove(rule);
400
Saurav Dasfbe25c52015-03-04 11:12:00 -0800401 // Interface MACs
402 for (MacAddress mac : intfMacs) {
403 log.debug("adding rule for MAC: {}", mac);
404 selector = DefaultTrafficSelector.builder();
405 treatment = DefaultTrafficTreatment.builder();
406
407 selector.matchEthDst(mac);
408 treatment.transition(FlowRule.Type.VLAN_MPLS);
409
410 rule = new DefaultFlowRule(deviceId, selector.build(),
411 treatment.build(),
412 CONTROLLER_PRIORITY, appId, 0,
413 true, FlowRule.Type.FIRST);
414
415 ops = install ? ops.add(rule) : ops.remove(rule);
416 }
417
alshabib10580802015-02-18 18:30:33 -0800418 //Drop rule
419 selector = DefaultTrafficSelector.builder();
420 treatment = DefaultTrafficTreatment.builder();
421
422 treatment.drop();
423
424 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800425 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800426 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800427
428 ops = install ? ops.add(rule) : ops.remove(rule);
429
430 flowService.apply(ops.build(new FlowRuleOperationsContext() {
431 @Override
432 public void onSuccess(FlowRuleOperations ops) {
433 log.info("Provisioned default table for bgp router");
434 }
435
436 @Override
437 public void onError(FlowRuleOperations ops) {
438 log.info("Failed to provision default table for bgp router");
439 }
440 }));
441
442 }
443
444 private void processTableOne(boolean install) {
445 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800446 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
447 .builder();
alshabib10580802015-02-18 18:30:33 -0800448 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
449 FlowRule rule;
450
alshabib10580802015-02-18 18:30:33 -0800451 selector.matchEthType(Ethernet.TYPE_VLAN);
452 treatment.transition(FlowRule.Type.VLAN);
453
454 rule = new DefaultFlowRule(deviceId, selector.build(),
455 treatment.build(), CONTROLLER_PRIORITY,
456 appId, 0, true, FlowRule.Type.VLAN_MPLS);
457
458 ops = install ? ops.add(rule) : ops.remove(rule);
459
alshabib10580802015-02-18 18:30:33 -0800460 flowService.apply(ops.build(new FlowRuleOperationsContext() {
461 @Override
462 public void onSuccess(FlowRuleOperations ops) {
463 log.info("Provisioned vlan/mpls table for bgp router");
464 }
465
466 @Override
467 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800468 log.info(
469 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800470 }
471 }));
472
473 }
474
475 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800476 TrafficSelector.Builder selector;
477 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800478 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
479 FlowRule rule;
480
Saurav Dasfbe25c52015-03-04 11:12:00 -0800481 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800482 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
483 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800484 selector = DefaultTrafficSelector.builder();
485 treatment = DefaultTrafficTreatment.builder();
486
alshabib346b5b32015-03-06 00:42:16 -0800487 selector.matchVlanId(portVlan.getValue());
488 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800489 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800490 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800491
492 rule = new DefaultFlowRule(deviceId, selector.build(),
493 treatment.build(), CONTROLLER_PRIORITY, appId,
494 0, true, FlowRule.Type.VLAN);
495
496 ops = install ? ops.add(rule) : ops.remove(rule);
497 }
498
alshabib10580802015-02-18 18:30:33 -0800499 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800500 selector = DefaultTrafficSelector.builder();
501 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800502
503 treatment.drop();
504
505 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800506 treatment.build(), DROP_PRIORITY, appId,
507 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800508
509 ops = install ? ops.add(rule) : ops.remove(rule);
510
511 flowService.apply(ops.build(new FlowRuleOperationsContext() {
512 @Override
513 public void onSuccess(FlowRuleOperations ops) {
514 log.info("Provisioned vlan table for bgp router");
515 }
516
517 @Override
518 public void onError(FlowRuleOperations ops) {
519 log.info("Failed to provision vlan table for bgp router");
520 }
521 }));
522 }
523
Saurav Dascbe6de32015-03-01 18:30:46 -0800524 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800525 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800526 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
527 .builder();
alshabib10580802015-02-18 18:30:33 -0800528 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
529 FlowRule rule;
530
531 selector.matchEthType(Ethernet.TYPE_ARP);
532 treatment.punt();
533
534 rule = new DefaultFlowRule(deviceId, selector.build(),
535 treatment.build(), CONTROLLER_PRIORITY,
536 appId, 0, true, FlowRule.Type.ETHER);
537
538 ops = install ? ops.add(rule) : ops.remove(rule);
539
540 selector = DefaultTrafficSelector.builder();
541 treatment = DefaultTrafficTreatment.builder();
542
543 selector.matchEthType(Ethernet.TYPE_IPV4);
544 treatment.transition(FlowRule.Type.COS);
545
546 rule = new DefaultFlowRule(deviceId, selector.build(),
547 treatment.build(), CONTROLLER_PRIORITY,
548 appId, 0, true, FlowRule.Type.ETHER);
549
550 ops = install ? ops.add(rule) : ops.remove(rule);
551
552 //Drop rule
553 selector = DefaultTrafficSelector.builder();
554 treatment = DefaultTrafficTreatment.builder();
555
556 treatment.drop();
557
558 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800559 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800560 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800561
562 ops = install ? ops.add(rule) : ops.remove(rule);
563
564 flowService.apply(ops.build(new FlowRuleOperationsContext() {
565 @Override
566 public void onSuccess(FlowRuleOperations ops) {
567 log.info("Provisioned ether table for bgp router");
568 }
569
570 @Override
571 public void onError(FlowRuleOperations ops) {
572 log.info("Failed to provision ether table for bgp router");
573 }
574 }));
575
alshabib10580802015-02-18 18:30:33 -0800576 }
577
578 private void processTableFive(boolean install) {
579 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800580 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
581 .builder();
alshabib10580802015-02-18 18:30:33 -0800582 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
583 FlowRule rule;
584
585 treatment.transition(FlowRule.Type.IP);
586
587 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800588 treatment.build(), DROP_PRIORITY, appId,
589 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800590
591 ops = install ? ops.add(rule) : ops.remove(rule);
592
593 flowService.apply(ops.build(new FlowRuleOperationsContext() {
594 @Override
595 public void onSuccess(FlowRuleOperations ops) {
596 log.info("Provisioned cos table for bgp router");
597 }
598
599 @Override
600 public void onError(FlowRuleOperations ops) {
601 log.info("Failed to provision cos table for bgp router");
602 }
603 }));
604
605 }
606
607 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800608 TrafficSelector.Builder selector;
609 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800610 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
611 FlowRule rule;
612
Saurav Dasfbe25c52015-03-04 11:12:00 -0800613
614 //Interface IPs
615 for (InterfaceIpAddress ipAddr : intfIps) {
616 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
617 selector = DefaultTrafficSelector.builder();
618 treatment = DefaultTrafficTreatment.builder();
619
620 selector.matchEthType(Ethernet.TYPE_IPV4);
621 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
622 treatment.transition(Type.ACL);
623
624 rule = new DefaultFlowRule(deviceId, selector.build(),
625 treatment.build(), HIGHEST_PRIORITY, appId,
626 0, true, FlowRule.Type.IP);
627
628 ops = install ? ops.add(rule) : ops.remove(rule);
629 }
630
631
alshabib10580802015-02-18 18:30:33 -0800632 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800633 selector = DefaultTrafficSelector.builder();
634 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800635
636 treatment.drop();
637
638 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800639 treatment.build(), DROP_PRIORITY, appId,
640 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800641
642 ops = install ? ops.add(rule) : ops.remove(rule);
643
644 flowService.apply(ops.build(new FlowRuleOperationsContext() {
645 @Override
646 public void onSuccess(FlowRuleOperations ops) {
647 log.info("Provisioned FIB table for bgp router");
648 }
649
650 @Override
651 public void onError(FlowRuleOperations ops) {
652 log.info("Failed to provision FIB table for bgp router");
653 }
654 }));
655 }
656
657 private void processTableNine(boolean install) {
658 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800659 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
660 .builder();
alshabib10580802015-02-18 18:30:33 -0800661 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
662 FlowRule rule;
663
664 treatment.punt();
665
666 rule = new DefaultFlowRule(deviceId, selector.build(),
667 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800668 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800669
670 ops = install ? ops.add(rule) : ops.remove(rule);
671
672 flowService.apply(ops.build(new FlowRuleOperationsContext() {
673 @Override
674 public void onSuccess(FlowRuleOperations ops) {
675 log.info("Provisioned Local table for bgp router");
676 }
677
678 @Override
679 public void onError(FlowRuleOperations ops) {
680 log.info("Failed to provision Local table for bgp router");
681 }
682 }));
683 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800684 }
alshabib10580802015-02-18 18:30:33 -0800685
Jonathan Hart7baba072015-02-23 14:27:59 -0800686 private class InternalGroupListener implements GroupListener {
687
688 @Override
689 public void event(GroupEvent event) {
690 Group group = event.subject();
691
692 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
693 event.type() == GroupEvent.Type.GROUP_UPDATED) {
694 synchronized (pendingUpdates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800695
696 Map<FibEntry, Group> entriesToInstall =
697 pendingUpdates.removeAll(group.appCookie())
698 .stream()
699 .collect(Collectors
700 .toMap(e -> e, e -> group));
701
702 installFlows(entriesToInstall);
Jonathan Hart7baba072015-02-23 14:27:59 -0800703 }
704 }
705 }
alshabib10580802015-02-18 18:30:33 -0800706 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800707}