blob: 66e4b256d9348a4db3560d7628869a535ba5f7b3 [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;
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,
Jonathan Hart936a7292015-03-06 18:02:57 -0800152 packetService,
153 flowService);
Jonathan Hartf5829202015-02-12 09:37:02 -0800154
155 routingService.start(new InternalFibListener());
156
157 connectivityManager.start();
158
159 log.info("BgpRouter started");
160 }
161
162 @Deactivate
163 protected void deactivate() {
164 routingService.stop();
165 connectivityManager.stop();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800166 provisionStaticTables.provision(false, configService.getInterfaces());
Jonathan Hartf5829202015-02-12 09:37:02 -0800167
Jonathan Hart7baba072015-02-23 14:27:59 -0800168 groupService.removeListener(groupListener);
169
Jonathan Hartf5829202015-02-12 09:37:02 -0800170 log.info("BgpRouter stopped");
171 }
172
Saurav Dasfbe25c52015-03-04 11:12:00 -0800173 private void getDeviceConfiguration(Map<String, BgpSpeaker> bgps) {
174 if (bgps == null || bgps.values().isEmpty()) {
175 log.error("BGP speakers configuration is missing");
176 return;
177 }
178 for (BgpSpeaker s : bgps.values()) {
179 ctrlDeviceId = s.connectPoint().deviceId();
180 if (s.interfaceAddresses() == null || s.interfaceAddresses().isEmpty()) {
181 log.error("BGP Router must have interfaces configured");
182 return;
183 }
184 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
185 break;
186 }
187 log.info("Router dpid: {}", deviceId);
188 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
189 }
190
Jonathan Hartf5829202015-02-12 09:37:02 -0800191 private void updateFibEntry(Collection<FibUpdate> updates) {
192 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800193 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800194
Jonathan Hart7baba072015-02-23 14:27:59 -0800195 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800196
Jonathan Hart7baba072015-02-23 14:27:59 -0800197 Group group;
198 synchronized (pendingUpdates) {
199 NextHop nextHop = nextHops.get(entry.nextHopIp());
200 group = groupService.getGroup(deviceId, nextHop.group());
Jonathan Hartf5829202015-02-12 09:37:02 -0800201
Jonathan Hart7baba072015-02-23 14:27:59 -0800202 if (group == null) {
203 log.debug("Adding pending flow {}", update.entry());
204 pendingUpdates.put(nextHop.group(), update.entry());
205 continue;
206 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800207 }
208
Jonathan Hart7baba072015-02-23 14:27:59 -0800209 installFlow(update.entry(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800210 }
211 }
212
Jonathan Hart7baba072015-02-23 14:27:59 -0800213 private void installFlow(FibEntry entry, Group group) {
214 TrafficSelector selector = DefaultTrafficSelector.builder()
215 .matchEthType(Ethernet.TYPE_IPV4)
216 .matchIPDst(entry.prefix())
217 .build();
Jonathan Hartf5829202015-02-12 09:37:02 -0800218
Jonathan Hart7baba072015-02-23 14:27:59 -0800219 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
220 .group(group.id())
221 .build();
222
223 FlowRule flowRule = new DefaultFlowRule(deviceId, selector, treatment,
224 PRIORITY, appId, 0, true,
225 FlowRule.Type.IP);
226
227 flowService.applyFlowRules(flowRule);
228 }
229
230 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
231 for (FibUpdate update : withdraws) {
232 FibEntry entry = update.entry();
233
234 deleteNextHop(entry.prefix());
Jonathan Hartf5829202015-02-12 09:37:02 -0800235
236 TrafficSelector selector = DefaultTrafficSelector.builder()
Jonathan Hart7baba072015-02-23 14:27:59 -0800237 .matchEthType(Ethernet.TYPE_IPV4)
Jonathan Hartf5829202015-02-12 09:37:02 -0800238 .matchIPDst(update.entry().prefix())
239 .build();
240
241 FlowRule flowRule = new DefaultFlowRule(deviceId, selector, null,
242 PRIORITY, appId, 0, true,
243 FlowRule.Type.IP);
244
245 flowService.removeFlowRules(flowRule);
246 }
247 }
248
Jonathan Hart7baba072015-02-23 14:27:59 -0800249 private synchronized void addNextHop(FibEntry entry) {
250 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
251 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800252 // There was no next hop in the multiset
253
Jonathan Hart7baba072015-02-23 14:27:59 -0800254 Interface egressIntf = configService.getMatchingInterface(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800255 if (egressIntf == null) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800256 log.warn("no egress interface found for {}", entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800257 return;
258 }
259
Jonathan Hart7baba072015-02-23 14:27:59 -0800260 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
261
262 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
Jonathan Hartf5829202015-02-12 09:37:02 -0800263
264 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
265 .setEthSrc(egressIntf.mac())
266 .setEthDst(nextHop.mac())
Jonathan Hart54b406b2015-03-06 16:24:14 -0800267 .pushVlan()
Jonathan Hartf5829202015-02-12 09:37:02 -0800268 .setVlanId(egressIntf.vlan())
269 .setOutput(egressIntf.connectPoint().port())
270 .build();
271
272 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
273
274 GroupDescription groupDescription
275 = new DefaultGroupDescription(deviceId,
276 GroupDescription.Type.INDIRECT,
277 new GroupBuckets(Collections
278 .singletonList(bucket)),
279 groupKey,
280 appId);
281
282 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800283
284 nextHops.put(nextHop.ip(), nextHop);
285
Jonathan Hartf5829202015-02-12 09:37:02 -0800286 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800287
288 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800289 }
290
Jonathan Hart7baba072015-02-23 14:27:59 -0800291 private synchronized void deleteNextHop(IpPrefix prefix) {
292 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
293 NextHop nextHop = nextHops.get(nextHopIp);
294 if (nextHop == null) {
295 log.warn("No next hop found when removing prefix {}", prefix);
296 return;
297 }
298
299 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800300 // There was one or less next hops, so there are now none
301
Jonathan Hart7baba072015-02-23 14:27:59 -0800302 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800303
Jonathan Hart7baba072015-02-23 14:27:59 -0800304 nextHops.remove(nextHopIp);
305
306 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800307 }
308 }
309
310 private class InternalFibListener implements FibListener {
311
312 @Override
313 public void update(Collection<FibUpdate> updates,
314 Collection<FibUpdate> withdraws) {
315 BgpRouter.this.deleteFibEntry(withdraws);
316 BgpRouter.this.updateFibEntry(updates);
317 }
318 }
alshabib10580802015-02-18 18:30:33 -0800319
320 private class InternalTableHandler {
321
322 private static final int CONTROLLER_PRIORITY = 255;
323 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800324 private static final int HIGHEST_PRIORITY = 0xffff;
325 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
326 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800327 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800328
Saurav Dasfbe25c52015-03-04 11:12:00 -0800329 public void provision(boolean install, Set<Interface> intfs) {
330 getIntefaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800331 processTableZero(install);
332 processTableOne(install);
333 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800334 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800335 processTableFive(install);
336 processTableSix(install);
337 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800338 }
339
Saurav Dasfbe25c52015-03-04 11:12:00 -0800340 private void getIntefaceConfig(Set<Interface> intfs) {
341 log.info("Processing {} router interfaces", intfs.size());
342 for (Interface intf : intfs) {
343 intfIps.addAll(intf.ipAddresses());
344 intfMacs.add(intf.mac());
alshabib346b5b32015-03-06 00:42:16 -0800345 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800346 }
347 }
348
alshabib10580802015-02-18 18:30:33 -0800349 private void processTableZero(boolean install) {
350 TrafficSelector.Builder selector;
351 TrafficTreatment.Builder treatment;
352
Saurav Dasfbe25c52015-03-04 11:12:00 -0800353 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800354 selector = DefaultTrafficSelector.builder();
355 treatment = DefaultTrafficTreatment.builder();
356
357 selector.matchEthDst(MacAddress.BROADCAST);
358 treatment.transition(FlowRule.Type.VLAN_MPLS);
359
360 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800361 treatment.build(),
362 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800363 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800364
365 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
366
367 ops = install ? ops.add(rule) : ops.remove(rule);
368
Saurav Dasfbe25c52015-03-04 11:12:00 -0800369 // Interface MACs
370 for (MacAddress mac : intfMacs) {
371 log.debug("adding rule for MAC: {}", mac);
372 selector = DefaultTrafficSelector.builder();
373 treatment = DefaultTrafficTreatment.builder();
374
375 selector.matchEthDst(mac);
376 treatment.transition(FlowRule.Type.VLAN_MPLS);
377
378 rule = new DefaultFlowRule(deviceId, selector.build(),
379 treatment.build(),
380 CONTROLLER_PRIORITY, appId, 0,
381 true, FlowRule.Type.FIRST);
382
383 ops = install ? ops.add(rule) : ops.remove(rule);
384 }
385
alshabib10580802015-02-18 18:30:33 -0800386 //Drop rule
387 selector = DefaultTrafficSelector.builder();
388 treatment = DefaultTrafficTreatment.builder();
389
390 treatment.drop();
391
392 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800393 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800394 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800395
396 ops = install ? ops.add(rule) : ops.remove(rule);
397
398 flowService.apply(ops.build(new FlowRuleOperationsContext() {
399 @Override
400 public void onSuccess(FlowRuleOperations ops) {
401 log.info("Provisioned default table for bgp router");
402 }
403
404 @Override
405 public void onError(FlowRuleOperations ops) {
406 log.info("Failed to provision default table for bgp router");
407 }
408 }));
409
410 }
411
412 private void processTableOne(boolean install) {
413 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800414 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
415 .builder();
alshabib10580802015-02-18 18:30:33 -0800416 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
417 FlowRule rule;
418
alshabib10580802015-02-18 18:30:33 -0800419 selector.matchEthType(Ethernet.TYPE_VLAN);
420 treatment.transition(FlowRule.Type.VLAN);
421
422 rule = new DefaultFlowRule(deviceId, selector.build(),
423 treatment.build(), CONTROLLER_PRIORITY,
424 appId, 0, true, FlowRule.Type.VLAN_MPLS);
425
426 ops = install ? ops.add(rule) : ops.remove(rule);
427
alshabib10580802015-02-18 18:30:33 -0800428 flowService.apply(ops.build(new FlowRuleOperationsContext() {
429 @Override
430 public void onSuccess(FlowRuleOperations ops) {
431 log.info("Provisioned vlan/mpls table for bgp router");
432 }
433
434 @Override
435 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800436 log.info(
437 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800438 }
439 }));
440
441 }
442
443 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800444 TrafficSelector.Builder selector;
445 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800446 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
447 FlowRule rule;
448
Saurav Dasfbe25c52015-03-04 11:12:00 -0800449 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800450 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
451 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800452 selector = DefaultTrafficSelector.builder();
453 treatment = DefaultTrafficTreatment.builder();
454
alshabib346b5b32015-03-06 00:42:16 -0800455 selector.matchVlanId(portVlan.getValue());
456 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800457 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800458 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800459
460 rule = new DefaultFlowRule(deviceId, selector.build(),
461 treatment.build(), CONTROLLER_PRIORITY, appId,
462 0, true, FlowRule.Type.VLAN);
463
464 ops = install ? ops.add(rule) : ops.remove(rule);
465 }
466
alshabib10580802015-02-18 18:30:33 -0800467 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800468 selector = DefaultTrafficSelector.builder();
469 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800470
471 treatment.drop();
472
473 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800474 treatment.build(), DROP_PRIORITY, appId,
475 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800476
477 ops = install ? ops.add(rule) : ops.remove(rule);
478
479 flowService.apply(ops.build(new FlowRuleOperationsContext() {
480 @Override
481 public void onSuccess(FlowRuleOperations ops) {
482 log.info("Provisioned vlan table for bgp router");
483 }
484
485 @Override
486 public void onError(FlowRuleOperations ops) {
487 log.info("Failed to provision vlan table for bgp router");
488 }
489 }));
490 }
491
Saurav Dascbe6de32015-03-01 18:30:46 -0800492 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800493 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800494 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
495 .builder();
alshabib10580802015-02-18 18:30:33 -0800496 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
497 FlowRule rule;
498
499 selector.matchEthType(Ethernet.TYPE_ARP);
500 treatment.punt();
501
502 rule = new DefaultFlowRule(deviceId, selector.build(),
503 treatment.build(), CONTROLLER_PRIORITY,
504 appId, 0, true, FlowRule.Type.ETHER);
505
506 ops = install ? ops.add(rule) : ops.remove(rule);
507
508 selector = DefaultTrafficSelector.builder();
509 treatment = DefaultTrafficTreatment.builder();
510
511 selector.matchEthType(Ethernet.TYPE_IPV4);
512 treatment.transition(FlowRule.Type.COS);
513
514 rule = new DefaultFlowRule(deviceId, selector.build(),
515 treatment.build(), CONTROLLER_PRIORITY,
516 appId, 0, true, FlowRule.Type.ETHER);
517
518 ops = install ? ops.add(rule) : ops.remove(rule);
519
520 //Drop rule
521 selector = DefaultTrafficSelector.builder();
522 treatment = DefaultTrafficTreatment.builder();
523
524 treatment.drop();
525
526 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800527 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800528 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800529
530 ops = install ? ops.add(rule) : ops.remove(rule);
531
532 flowService.apply(ops.build(new FlowRuleOperationsContext() {
533 @Override
534 public void onSuccess(FlowRuleOperations ops) {
535 log.info("Provisioned ether table for bgp router");
536 }
537
538 @Override
539 public void onError(FlowRuleOperations ops) {
540 log.info("Failed to provision ether table for bgp router");
541 }
542 }));
543
alshabib10580802015-02-18 18:30:33 -0800544 }
545
546 private void processTableFive(boolean install) {
547 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800548 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
549 .builder();
alshabib10580802015-02-18 18:30:33 -0800550 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
551 FlowRule rule;
552
553 treatment.transition(FlowRule.Type.IP);
554
555 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800556 treatment.build(), DROP_PRIORITY, appId,
557 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800558
559 ops = install ? ops.add(rule) : ops.remove(rule);
560
561 flowService.apply(ops.build(new FlowRuleOperationsContext() {
562 @Override
563 public void onSuccess(FlowRuleOperations ops) {
564 log.info("Provisioned cos table for bgp router");
565 }
566
567 @Override
568 public void onError(FlowRuleOperations ops) {
569 log.info("Failed to provision cos table for bgp router");
570 }
571 }));
572
573 }
574
575 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800576 TrafficSelector.Builder selector;
577 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800578 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
579 FlowRule rule;
580
Saurav Dasfbe25c52015-03-04 11:12:00 -0800581
582 //Interface IPs
583 for (InterfaceIpAddress ipAddr : intfIps) {
584 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
585 selector = DefaultTrafficSelector.builder();
586 treatment = DefaultTrafficTreatment.builder();
587
588 selector.matchEthType(Ethernet.TYPE_IPV4);
589 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
590 treatment.transition(Type.ACL);
591
592 rule = new DefaultFlowRule(deviceId, selector.build(),
593 treatment.build(), HIGHEST_PRIORITY, appId,
594 0, true, FlowRule.Type.IP);
595
596 ops = install ? ops.add(rule) : ops.remove(rule);
597 }
598
599
alshabib10580802015-02-18 18:30:33 -0800600 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800601 selector = DefaultTrafficSelector.builder();
602 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800603
604 treatment.drop();
605
606 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800607 treatment.build(), DROP_PRIORITY, appId,
608 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800609
610 ops = install ? ops.add(rule) : ops.remove(rule);
611
612 flowService.apply(ops.build(new FlowRuleOperationsContext() {
613 @Override
614 public void onSuccess(FlowRuleOperations ops) {
615 log.info("Provisioned FIB table for bgp router");
616 }
617
618 @Override
619 public void onError(FlowRuleOperations ops) {
620 log.info("Failed to provision FIB table for bgp router");
621 }
622 }));
623 }
624
625 private void processTableNine(boolean install) {
626 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800627 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
628 .builder();
alshabib10580802015-02-18 18:30:33 -0800629 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
630 FlowRule rule;
631
632 treatment.punt();
633
634 rule = new DefaultFlowRule(deviceId, selector.build(),
635 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800636 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800637
638 ops = install ? ops.add(rule) : ops.remove(rule);
639
640 flowService.apply(ops.build(new FlowRuleOperationsContext() {
641 @Override
642 public void onSuccess(FlowRuleOperations ops) {
643 log.info("Provisioned Local table for bgp router");
644 }
645
646 @Override
647 public void onError(FlowRuleOperations ops) {
648 log.info("Failed to provision Local table for bgp router");
649 }
650 }));
651 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800652 }
alshabib10580802015-02-18 18:30:33 -0800653
Jonathan Hart7baba072015-02-23 14:27:59 -0800654 private class InternalGroupListener implements GroupListener {
655
656 @Override
657 public void event(GroupEvent event) {
658 Group group = event.subject();
659
660 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
661 event.type() == GroupEvent.Type.GROUP_UPDATED) {
662 synchronized (pendingUpdates) {
663 pendingUpdates.removeAll(group.appCookie())
664 .forEach((entry) -> installFlow(entry, group));
665 }
666 }
667 }
alshabib10580802015-02-18 18:30:33 -0800668 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800669}