blob: aed558b7e78c2fbeb02f59e6043ce2680c062be8 [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;
Saurav Dasfbe25c52015-03-04 11:12:00 -080023
Jonathan Hartf5829202015-02-12 09:37:02 -080024import org.apache.felix.scr.annotations.Activate;
25import org.apache.felix.scr.annotations.Component;
26import org.apache.felix.scr.annotations.Deactivate;
27import org.apache.felix.scr.annotations.Reference;
28import org.apache.felix.scr.annotations.ReferenceCardinality;
29import org.onlab.packet.Ethernet;
alshabib10580802015-02-18 18:30:33 -080030import org.onlab.packet.MacAddress;
Jonathan Hart7baba072015-02-23 14:27:59 -080031import org.onlab.packet.IpAddress;
32import org.onlab.packet.IpPrefix;
Saurav Dasfbe25c52015-03-04 11:12:00 -080033import org.onlab.packet.VlanId;
Jonathan Hartf5829202015-02-12 09:37:02 -080034import org.onosproject.core.ApplicationId;
35import org.onosproject.core.CoreService;
36import org.onosproject.net.DeviceId;
37import org.onosproject.net.flow.DefaultFlowRule;
38import org.onosproject.net.flow.DefaultTrafficSelector;
39import org.onosproject.net.flow.DefaultTrafficTreatment;
40import org.onosproject.net.flow.FlowRule;
alshabib10580802015-02-18 18:30:33 -080041import org.onosproject.net.flow.FlowRuleOperations;
42import org.onosproject.net.flow.FlowRuleOperationsContext;
Jonathan Hartf5829202015-02-12 09:37:02 -080043import org.onosproject.net.flow.FlowRuleService;
44import org.onosproject.net.flow.TrafficSelector;
45import org.onosproject.net.flow.TrafficTreatment;
Saurav Dasfbe25c52015-03-04 11:12:00 -080046import org.onosproject.net.flow.FlowRule.Type;
Jonathan Hartf5829202015-02-12 09:37:02 -080047import org.onosproject.net.group.DefaultGroupBucket;
48import org.onosproject.net.group.DefaultGroupDescription;
49import org.onosproject.net.group.Group;
50import org.onosproject.net.group.GroupBucket;
51import org.onosproject.net.group.GroupBuckets;
52import org.onosproject.net.group.GroupDescription;
Jonathan Hart7baba072015-02-23 14:27:59 -080053import org.onosproject.net.group.GroupEvent;
Jonathan Hartf5829202015-02-12 09:37:02 -080054import org.onosproject.net.group.GroupKey;
Jonathan Hart7baba072015-02-23 14:27:59 -080055import org.onosproject.net.group.GroupListener;
Jonathan Hartf5829202015-02-12 09:37:02 -080056import org.onosproject.net.group.GroupService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080057import org.onosproject.net.host.InterfaceIpAddress;
Jonathan Hartf5829202015-02-12 09:37:02 -080058import org.onosproject.net.packet.PacketService;
Jonathan Hart7baba072015-02-23 14:27:59 -080059import org.onosproject.routing.FibEntry;
Jonathan Hart2da1e602015-02-18 19:09:24 -080060import org.onosproject.routing.FibListener;
61import org.onosproject.routing.FibUpdate;
62import org.onosproject.routing.RoutingService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080063import org.onosproject.routing.config.BgpSpeaker;
Jonathan Hart2da1e602015-02-18 19:09:24 -080064import org.onosproject.routing.config.Interface;
65import org.onosproject.routing.config.RoutingConfigurationService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080066import org.onosproject.config.NetworkConfigService;
Jonathan Hartf5829202015-02-12 09:37:02 -080067import org.slf4j.Logger;
68import org.slf4j.LoggerFactory;
69
70import java.util.Collection;
71import java.util.Collections;
Saurav Dasfbe25c52015-03-04 11:12:00 -080072import java.util.HashSet;
Jonathan Hartf5829202015-02-12 09:37:02 -080073import java.util.Map;
Saurav Dasfbe25c52015-03-04 11:12:00 -080074import java.util.Set;
Jonathan Hartf5829202015-02-12 09:37:02 -080075
76/**
77 * BgpRouter component.
78 */
79@Component(immediate = true)
80public class BgpRouter {
81
82 private static final Logger log = LoggerFactory.getLogger(BgpRouter.class);
83
84 private static final String BGP_ROUTER_APP = "org.onosproject.bgprouter";
85
86 private static final int PRIORITY = 1;
87
88 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
89 protected CoreService coreService;
90
91 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
92 protected FlowRuleService flowService;
93
94 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
95 protected GroupService groupService;
96
97 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
98 protected RoutingService routingService;
99
100 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
101 protected RoutingConfigurationService configService;
102
103 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
104 protected PacketService packetService;
105
Saurav Dasfbe25c52015-03-04 11:12:00 -0800106 //
107 // NOTE: Unused reference - needed to guarantee that the
108 // NetworkConfigReader component is activated and the network configuration
109 // is read.
110 //
111 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
112 protected NetworkConfigService networkConfigService;
113
Jonathan Hartf5829202015-02-12 09:37:02 -0800114 private ApplicationId appId;
115
Jonathan Hart7baba072015-02-23 14:27:59 -0800116 // Reference count for how many times a next hop is used by a route
117 private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
118
119 // Mapping from prefix to its current next hop
120 private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
121
122 // Mapping from next hop IP to next hop object containing group info
123 private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap();
124
125 // Stores FIB updates that are waiting for groups to be set up
126 private final Multimap<GroupKey, FibEntry> pendingUpdates = HashMultimap.create();
Jonathan Hartf5829202015-02-12 09:37:02 -0800127
Saurav Dasfbe25c52015-03-04 11:12:00 -0800128 // Device id of data-plane switch - should be learned from config
129 private DeviceId deviceId;
130
131 // Device id of control-plane switch (OVS) connected to BGP Speaker - should be
132 // learned from config
133 private DeviceId ctrlDeviceId;
Jonathan Hartf5829202015-02-12 09:37:02 -0800134
Jonathan Hart7baba072015-02-23 14:27:59 -0800135 private final GroupListener groupListener = new InternalGroupListener();
136
Jonathan Hartf5829202015-02-12 09:37:02 -0800137 private TunnellingConnectivityManager connectivityManager;
138
alshabib10580802015-02-18 18:30:33 -0800139 private InternalTableHandler provisionStaticTables = new InternalTableHandler();
140
Jonathan Hartf5829202015-02-12 09:37:02 -0800141 @Activate
142 protected void activate() {
Jonathan Hartf5829202015-02-12 09:37:02 -0800143 appId = coreService.registerApplication(BGP_ROUTER_APP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800144 getDeviceConfiguration(configService.getBgpSpeakers());
Jonathan Hartf5829202015-02-12 09:37:02 -0800145
Jonathan Hart7baba072015-02-23 14:27:59 -0800146 groupService.addListener(groupListener);
147
Saurav Dasfbe25c52015-03-04 11:12:00 -0800148 provisionStaticTables.provision(true, configService.getInterfaces());
alshabib10580802015-02-18 18:30:33 -0800149
Jonathan Hartf5829202015-02-12 09:37:02 -0800150 connectivityManager = new TunnellingConnectivityManager(appId,
151 configService,
152 packetService);
153
154 routingService.start(new InternalFibListener());
155
156 connectivityManager.start();
157
158 log.info("BgpRouter started");
159 }
160
161 @Deactivate
162 protected void deactivate() {
163 routingService.stop();
164 connectivityManager.stop();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800165 provisionStaticTables.provision(false, configService.getInterfaces());
Jonathan Hartf5829202015-02-12 09:37:02 -0800166
Jonathan Hart7baba072015-02-23 14:27:59 -0800167 groupService.removeListener(groupListener);
168
Jonathan Hartf5829202015-02-12 09:37:02 -0800169 log.info("BgpRouter stopped");
170 }
171
Saurav Dasfbe25c52015-03-04 11:12:00 -0800172 private void getDeviceConfiguration(Map<String, BgpSpeaker> bgps) {
173 if (bgps == null || bgps.values().isEmpty()) {
174 log.error("BGP speakers configuration is missing");
175 return;
176 }
177 for (BgpSpeaker s : bgps.values()) {
178 ctrlDeviceId = s.connectPoint().deviceId();
179 if (s.interfaceAddresses() == null || s.interfaceAddresses().isEmpty()) {
180 log.error("BGP Router must have interfaces configured");
181 return;
182 }
183 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
184 break;
185 }
186 log.info("Router dpid: {}", deviceId);
187 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
188 }
189
Jonathan Hartf5829202015-02-12 09:37:02 -0800190 private void updateFibEntry(Collection<FibUpdate> updates) {
191 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800192 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800193
Jonathan Hart7baba072015-02-23 14:27:59 -0800194 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800195
Jonathan Hart7baba072015-02-23 14:27:59 -0800196 Group group;
197 synchronized (pendingUpdates) {
198 NextHop nextHop = nextHops.get(entry.nextHopIp());
199 group = groupService.getGroup(deviceId, nextHop.group());
Jonathan Hartf5829202015-02-12 09:37:02 -0800200
Jonathan Hart7baba072015-02-23 14:27:59 -0800201 if (group == null) {
202 log.debug("Adding pending flow {}", update.entry());
203 pendingUpdates.put(nextHop.group(), update.entry());
204 continue;
205 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800206 }
207
Jonathan Hart7baba072015-02-23 14:27:59 -0800208 installFlow(update.entry(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800209 }
210 }
211
Jonathan Hart7baba072015-02-23 14:27:59 -0800212 private void installFlow(FibEntry entry, Group group) {
213 TrafficSelector selector = DefaultTrafficSelector.builder()
214 .matchEthType(Ethernet.TYPE_IPV4)
215 .matchIPDst(entry.prefix())
216 .build();
Jonathan Hartf5829202015-02-12 09:37:02 -0800217
Jonathan Hart7baba072015-02-23 14:27:59 -0800218 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
219 .group(group.id())
220 .build();
221
222 FlowRule flowRule = new DefaultFlowRule(deviceId, selector, treatment,
223 PRIORITY, appId, 0, true,
224 FlowRule.Type.IP);
225
226 flowService.applyFlowRules(flowRule);
227 }
228
229 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
230 for (FibUpdate update : withdraws) {
231 FibEntry entry = update.entry();
232
233 deleteNextHop(entry.prefix());
Jonathan Hartf5829202015-02-12 09:37:02 -0800234
235 TrafficSelector selector = DefaultTrafficSelector.builder()
Jonathan Hart7baba072015-02-23 14:27:59 -0800236 .matchEthType(Ethernet.TYPE_IPV4)
Jonathan Hartf5829202015-02-12 09:37:02 -0800237 .matchIPDst(update.entry().prefix())
238 .build();
239
240 FlowRule flowRule = new DefaultFlowRule(deviceId, selector, null,
241 PRIORITY, appId, 0, true,
242 FlowRule.Type.IP);
243
244 flowService.removeFlowRules(flowRule);
245 }
246 }
247
Jonathan Hart7baba072015-02-23 14:27:59 -0800248 private synchronized void addNextHop(FibEntry entry) {
249 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
250 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800251 // There was no next hop in the multiset
252
Jonathan Hart7baba072015-02-23 14:27:59 -0800253 Interface egressIntf = configService.getMatchingInterface(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800254 if (egressIntf == null) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800255 log.warn("no egress interface found for {}", entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800256 return;
257 }
258
Jonathan Hart7baba072015-02-23 14:27:59 -0800259 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
260
261 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
Jonathan Hartf5829202015-02-12 09:37:02 -0800262
263 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
264 .setEthSrc(egressIntf.mac())
265 .setEthDst(nextHop.mac())
266 .setVlanId(egressIntf.vlan())
267 .setOutput(egressIntf.connectPoint().port())
268 .build();
269
270 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
271
272 GroupDescription groupDescription
273 = new DefaultGroupDescription(deviceId,
274 GroupDescription.Type.INDIRECT,
275 new GroupBuckets(Collections
276 .singletonList(bucket)),
277 groupKey,
278 appId);
279
280 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800281
282 nextHops.put(nextHop.ip(), nextHop);
283
Jonathan Hartf5829202015-02-12 09:37:02 -0800284 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800285
286 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800287 }
288
Jonathan Hart7baba072015-02-23 14:27:59 -0800289 private synchronized void deleteNextHop(IpPrefix prefix) {
290 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
291 NextHop nextHop = nextHops.get(nextHopIp);
292 if (nextHop == null) {
293 log.warn("No next hop found when removing prefix {}", prefix);
294 return;
295 }
296
297 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800298 // There was one or less next hops, so there are now none
299
Jonathan Hart7baba072015-02-23 14:27:59 -0800300 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800301
Jonathan Hart7baba072015-02-23 14:27:59 -0800302 nextHops.remove(nextHopIp);
303
304 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800305 }
306 }
307
308 private class InternalFibListener implements FibListener {
309
310 @Override
311 public void update(Collection<FibUpdate> updates,
312 Collection<FibUpdate> withdraws) {
313 BgpRouter.this.deleteFibEntry(withdraws);
314 BgpRouter.this.updateFibEntry(updates);
315 }
316 }
alshabib10580802015-02-18 18:30:33 -0800317
318 private class InternalTableHandler {
319
320 private static final int CONTROLLER_PRIORITY = 255;
321 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800322 private static final int HIGHEST_PRIORITY = 0xffff;
323 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
324 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
325 private Set<VlanId> intfVlans = new HashSet<VlanId>();
alshabib10580802015-02-18 18:30:33 -0800326
Saurav Dasfbe25c52015-03-04 11:12:00 -0800327 public void provision(boolean install, Set<Interface> intfs) {
328 getIntefaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800329 processTableZero(install);
330 processTableOne(install);
331 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800332 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800333 processTableFive(install);
334 processTableSix(install);
335 processTableNine(install);
336
337 }
338
Saurav Dasfbe25c52015-03-04 11:12:00 -0800339 private void getIntefaceConfig(Set<Interface> intfs) {
340 log.info("Processing {} router interfaces", intfs.size());
341 for (Interface intf : intfs) {
342 intfIps.addAll(intf.ipAddresses());
343 intfMacs.add(intf.mac());
344 intfVlans.add(intf.vlan());
345 }
346 }
347
alshabib10580802015-02-18 18:30:33 -0800348 private void processTableZero(boolean install) {
349 TrafficSelector.Builder selector;
350 TrafficTreatment.Builder treatment;
351
Saurav Dasfbe25c52015-03-04 11:12:00 -0800352 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800353 selector = DefaultTrafficSelector.builder();
354 treatment = DefaultTrafficTreatment.builder();
355
356 selector.matchEthDst(MacAddress.BROADCAST);
357 treatment.transition(FlowRule.Type.VLAN_MPLS);
358
359 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800360 treatment.build(),
361 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800362 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800363
364 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
365
366 ops = install ? ops.add(rule) : ops.remove(rule);
367
Saurav Dasfbe25c52015-03-04 11:12:00 -0800368 // Interface MACs
369 for (MacAddress mac : intfMacs) {
370 log.debug("adding rule for MAC: {}", mac);
371 selector = DefaultTrafficSelector.builder();
372 treatment = DefaultTrafficTreatment.builder();
373
374 selector.matchEthDst(mac);
375 treatment.transition(FlowRule.Type.VLAN_MPLS);
376
377 rule = new DefaultFlowRule(deviceId, selector.build(),
378 treatment.build(),
379 CONTROLLER_PRIORITY, appId, 0,
380 true, FlowRule.Type.FIRST);
381
382 ops = install ? ops.add(rule) : ops.remove(rule);
383 }
384
alshabib10580802015-02-18 18:30:33 -0800385 //Drop rule
386 selector = DefaultTrafficSelector.builder();
387 treatment = DefaultTrafficTreatment.builder();
388
389 treatment.drop();
390
391 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800392 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800393 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800394
395 ops = install ? ops.add(rule) : ops.remove(rule);
396
397 flowService.apply(ops.build(new FlowRuleOperationsContext() {
398 @Override
399 public void onSuccess(FlowRuleOperations ops) {
400 log.info("Provisioned default table for bgp router");
401 }
402
403 @Override
404 public void onError(FlowRuleOperations ops) {
405 log.info("Failed to provision default table for bgp router");
406 }
407 }));
408
409 }
410
411 private void processTableOne(boolean install) {
412 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800413 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
414 .builder();
alshabib10580802015-02-18 18:30:33 -0800415 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
416 FlowRule rule;
417
418 selector.matchEthType(Ethernet.TYPE_IPV4);
419 treatment.transition(FlowRule.Type.VLAN);
420
Jonathan Hart7baba072015-02-23 14:27:59 -0800421 rule = new DefaultFlowRule(deviceId, selector.build(), treatment.build(), CONTROLLER_PRIORITY,
422 appId, 0, true, FlowRule.Type.VLAN_MPLS);
alshabib10580802015-02-18 18:30:33 -0800423
424 ops = install ? ops.add(rule) : ops.remove(rule);
425
426 selector = DefaultTrafficSelector.builder();
427 treatment = DefaultTrafficTreatment.builder();
428
429 selector.matchEthType(Ethernet.TYPE_ARP);
430 treatment.transition(FlowRule.Type.VLAN);
431
432 rule = new DefaultFlowRule(deviceId, selector.build(),
433 treatment.build(), CONTROLLER_PRIORITY,
434 appId, 0, true, FlowRule.Type.VLAN_MPLS);
435
436 ops = install ? ops.add(rule) : ops.remove(rule);
437
438 selector = DefaultTrafficSelector.builder();
439 treatment = DefaultTrafficTreatment.builder();
440
441 selector.matchEthType(Ethernet.TYPE_VLAN);
442 treatment.transition(FlowRule.Type.VLAN);
443
444 rule = new DefaultFlowRule(deviceId, selector.build(),
445 treatment.build(), CONTROLLER_PRIORITY,
446 appId, 0, true, FlowRule.Type.VLAN_MPLS);
447
448 ops = install ? ops.add(rule) : ops.remove(rule);
449
450 //Drop rule
451 selector = DefaultTrafficSelector.builder();
452 treatment = DefaultTrafficTreatment.builder();
453
454 treatment.drop();
455
456 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800457 treatment.build(), DROP_PRIORITY, appId,
458 0, true, FlowRule.Type.VLAN_MPLS);
alshabib10580802015-02-18 18:30:33 -0800459
460 ops = install ? ops.add(rule) : ops.remove(rule);
461
462 flowService.apply(ops.build(new FlowRuleOperationsContext() {
463 @Override
464 public void onSuccess(FlowRuleOperations ops) {
465 log.info("Provisioned vlan/mpls table for bgp router");
466 }
467
468 @Override
469 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800470 log.info(
471 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800472 }
473 }));
474
475 }
476
477 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800478 TrafficSelector.Builder selector;
479 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800480 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
481 FlowRule rule;
482
Saurav Dasfbe25c52015-03-04 11:12:00 -0800483 //Interface Vlans
484 for (VlanId vid : intfVlans) {
485 log.debug("adding rule for VLAN: {}", vid);
486 selector = DefaultTrafficSelector.builder();
487 treatment = DefaultTrafficTreatment.builder();
488
489 selector.matchVlanId(vid);
490 treatment.popVlan();
491 treatment.transition(Type.ETHER);
492
493 rule = new DefaultFlowRule(deviceId, selector.build(),
494 treatment.build(), CONTROLLER_PRIORITY, appId,
495 0, true, FlowRule.Type.VLAN);
496
497 ops = install ? ops.add(rule) : ops.remove(rule);
498 }
499
alshabib10580802015-02-18 18:30:33 -0800500 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800501 selector = DefaultTrafficSelector.builder();
502 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800503
504 treatment.drop();
505
506 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800507 treatment.build(), DROP_PRIORITY, appId,
508 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800509
510 ops = install ? ops.add(rule) : ops.remove(rule);
511
512 flowService.apply(ops.build(new FlowRuleOperationsContext() {
513 @Override
514 public void onSuccess(FlowRuleOperations ops) {
515 log.info("Provisioned vlan table for bgp router");
516 }
517
518 @Override
519 public void onError(FlowRuleOperations ops) {
520 log.info("Failed to provision vlan table for bgp router");
521 }
522 }));
523 }
524
Saurav Dascbe6de32015-03-01 18:30:46 -0800525 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800526 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800527 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
528 .builder();
alshabib10580802015-02-18 18:30:33 -0800529 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
530 FlowRule rule;
531
532 selector.matchEthType(Ethernet.TYPE_ARP);
533 treatment.punt();
534
535 rule = new DefaultFlowRule(deviceId, selector.build(),
536 treatment.build(), CONTROLLER_PRIORITY,
537 appId, 0, true, FlowRule.Type.ETHER);
538
539 ops = install ? ops.add(rule) : ops.remove(rule);
540
541 selector = DefaultTrafficSelector.builder();
542 treatment = DefaultTrafficTreatment.builder();
543
544 selector.matchEthType(Ethernet.TYPE_IPV4);
545 treatment.transition(FlowRule.Type.COS);
546
547 rule = new DefaultFlowRule(deviceId, selector.build(),
548 treatment.build(), CONTROLLER_PRIORITY,
549 appId, 0, true, FlowRule.Type.ETHER);
550
551 ops = install ? ops.add(rule) : ops.remove(rule);
552
553 //Drop rule
554 selector = DefaultTrafficSelector.builder();
555 treatment = DefaultTrafficTreatment.builder();
556
557 treatment.drop();
558
559 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800560 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800561 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800562
563 ops = install ? ops.add(rule) : ops.remove(rule);
564
565 flowService.apply(ops.build(new FlowRuleOperationsContext() {
566 @Override
567 public void onSuccess(FlowRuleOperations ops) {
568 log.info("Provisioned ether table for bgp router");
569 }
570
571 @Override
572 public void onError(FlowRuleOperations ops) {
573 log.info("Failed to provision ether table for bgp router");
574 }
575 }));
576
alshabib10580802015-02-18 18:30:33 -0800577 }
578
579 private void processTableFive(boolean install) {
580 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800581 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
582 .builder();
alshabib10580802015-02-18 18:30:33 -0800583 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
584 FlowRule rule;
585
586 treatment.transition(FlowRule.Type.IP);
587
588 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800589 treatment.build(), DROP_PRIORITY, appId,
590 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800591
592 ops = install ? ops.add(rule) : ops.remove(rule);
593
594 flowService.apply(ops.build(new FlowRuleOperationsContext() {
595 @Override
596 public void onSuccess(FlowRuleOperations ops) {
597 log.info("Provisioned cos table for bgp router");
598 }
599
600 @Override
601 public void onError(FlowRuleOperations ops) {
602 log.info("Failed to provision cos table for bgp router");
603 }
604 }));
605
606 }
607
608 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800609 TrafficSelector.Builder selector;
610 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800611 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
612 FlowRule rule;
613
Saurav Dasfbe25c52015-03-04 11:12:00 -0800614
615 //Interface IPs
616 for (InterfaceIpAddress ipAddr : intfIps) {
617 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
618 selector = DefaultTrafficSelector.builder();
619 treatment = DefaultTrafficTreatment.builder();
620
621 selector.matchEthType(Ethernet.TYPE_IPV4);
622 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
623 treatment.transition(Type.ACL);
624
625 rule = new DefaultFlowRule(deviceId, selector.build(),
626 treatment.build(), HIGHEST_PRIORITY, appId,
627 0, true, FlowRule.Type.IP);
628
629 ops = install ? ops.add(rule) : ops.remove(rule);
630 }
631
632
alshabib10580802015-02-18 18:30:33 -0800633 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800634 selector = DefaultTrafficSelector.builder();
635 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800636
637 treatment.drop();
638
639 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800640 treatment.build(), DROP_PRIORITY, appId,
641 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800642
643 ops = install ? ops.add(rule) : ops.remove(rule);
644
645 flowService.apply(ops.build(new FlowRuleOperationsContext() {
646 @Override
647 public void onSuccess(FlowRuleOperations ops) {
648 log.info("Provisioned FIB table for bgp router");
649 }
650
651 @Override
652 public void onError(FlowRuleOperations ops) {
653 log.info("Failed to provision FIB table for bgp router");
654 }
655 }));
656 }
657
658 private void processTableNine(boolean install) {
659 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800660 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
661 .builder();
alshabib10580802015-02-18 18:30:33 -0800662 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
663 FlowRule rule;
664
665 treatment.punt();
666
667 rule = new DefaultFlowRule(deviceId, selector.build(),
668 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800669 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800670
671 ops = install ? ops.add(rule) : ops.remove(rule);
672
673 flowService.apply(ops.build(new FlowRuleOperationsContext() {
674 @Override
675 public void onSuccess(FlowRuleOperations ops) {
676 log.info("Provisioned Local table for bgp router");
677 }
678
679 @Override
680 public void onError(FlowRuleOperations ops) {
681 log.info("Failed to provision Local table for bgp router");
682 }
683 }));
684 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800685 }
alshabib10580802015-02-18 18:30:33 -0800686
Jonathan Hart7baba072015-02-23 14:27:59 -0800687 private class InternalGroupListener implements GroupListener {
688
689 @Override
690 public void event(GroupEvent event) {
691 Group group = event.subject();
692
693 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
694 event.type() == GroupEvent.Type.GROUP_UPDATED) {
695 synchronized (pendingUpdates) {
696 pendingUpdates.removeAll(group.appCookie())
697 .forEach((entry) -> installFlow(entry, group));
698 }
699 }
700 }
alshabib10580802015-02-18 18:30:33 -0800701 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800702}