blob: cc508194455837fbf0b0810002284a83553e4420 [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,
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())
Jonathan Hart54b406b2015-03-06 16:24:14 -0800266 .pushVlan()
Jonathan Hartf5829202015-02-12 09:37:02 -0800267 .setVlanId(egressIntf.vlan())
268 .setOutput(egressIntf.connectPoint().port())
269 .build();
270
271 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
272
273 GroupDescription groupDescription
274 = new DefaultGroupDescription(deviceId,
275 GroupDescription.Type.INDIRECT,
276 new GroupBuckets(Collections
277 .singletonList(bucket)),
278 groupKey,
279 appId);
280
281 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800282
283 nextHops.put(nextHop.ip(), nextHop);
284
Jonathan Hartf5829202015-02-12 09:37:02 -0800285 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800286
287 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800288 }
289
Jonathan Hart7baba072015-02-23 14:27:59 -0800290 private synchronized void deleteNextHop(IpPrefix prefix) {
291 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
292 NextHop nextHop = nextHops.get(nextHopIp);
293 if (nextHop == null) {
294 log.warn("No next hop found when removing prefix {}", prefix);
295 return;
296 }
297
298 if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800299 // There was one or less next hops, so there are now none
300
Jonathan Hart7baba072015-02-23 14:27:59 -0800301 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800302
Jonathan Hart7baba072015-02-23 14:27:59 -0800303 nextHops.remove(nextHopIp);
304
305 groupService.removeGroup(deviceId, nextHop.group(), appId);
Jonathan Hartf5829202015-02-12 09:37:02 -0800306 }
307 }
308
309 private class InternalFibListener implements FibListener {
310
311 @Override
312 public void update(Collection<FibUpdate> updates,
313 Collection<FibUpdate> withdraws) {
314 BgpRouter.this.deleteFibEntry(withdraws);
315 BgpRouter.this.updateFibEntry(updates);
316 }
317 }
alshabib10580802015-02-18 18:30:33 -0800318
319 private class InternalTableHandler {
320
321 private static final int CONTROLLER_PRIORITY = 255;
322 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800323 private static final int HIGHEST_PRIORITY = 0xffff;
324 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
325 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800326 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800327
Saurav Dasfbe25c52015-03-04 11:12:00 -0800328 public void provision(boolean install, Set<Interface> intfs) {
329 getIntefaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800330 processTableZero(install);
331 processTableOne(install);
332 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800333 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800334 processTableFive(install);
335 processTableSix(install);
336 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800337 }
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());
alshabib346b5b32015-03-06 00:42:16 -0800344 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800345 }
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
alshabib10580802015-02-18 18:30:33 -0800418 selector.matchEthType(Ethernet.TYPE_VLAN);
419 treatment.transition(FlowRule.Type.VLAN);
420
421 rule = new DefaultFlowRule(deviceId, selector.build(),
422 treatment.build(), CONTROLLER_PRIORITY,
423 appId, 0, true, FlowRule.Type.VLAN_MPLS);
424
425 ops = install ? ops.add(rule) : ops.remove(rule);
426
alshabib10580802015-02-18 18:30:33 -0800427 flowService.apply(ops.build(new FlowRuleOperationsContext() {
428 @Override
429 public void onSuccess(FlowRuleOperations ops) {
430 log.info("Provisioned vlan/mpls table for bgp router");
431 }
432
433 @Override
434 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800435 log.info(
436 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800437 }
438 }));
439
440 }
441
442 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800443 TrafficSelector.Builder selector;
444 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800445 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
446 FlowRule rule;
447
Saurav Dasfbe25c52015-03-04 11:12:00 -0800448 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800449 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
450 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800451 selector = DefaultTrafficSelector.builder();
452 treatment = DefaultTrafficTreatment.builder();
453
alshabib346b5b32015-03-06 00:42:16 -0800454 selector.matchVlanId(portVlan.getValue());
455 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800456 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800457 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800458
459 rule = new DefaultFlowRule(deviceId, selector.build(),
460 treatment.build(), CONTROLLER_PRIORITY, appId,
461 0, true, FlowRule.Type.VLAN);
462
463 ops = install ? ops.add(rule) : ops.remove(rule);
464 }
465
alshabib10580802015-02-18 18:30:33 -0800466 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800467 selector = DefaultTrafficSelector.builder();
468 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800469
470 treatment.drop();
471
472 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800473 treatment.build(), DROP_PRIORITY, appId,
474 0, true, FlowRule.Type.VLAN);
alshabib10580802015-02-18 18:30:33 -0800475
476 ops = install ? ops.add(rule) : ops.remove(rule);
477
478 flowService.apply(ops.build(new FlowRuleOperationsContext() {
479 @Override
480 public void onSuccess(FlowRuleOperations ops) {
481 log.info("Provisioned vlan table for bgp router");
482 }
483
484 @Override
485 public void onError(FlowRuleOperations ops) {
486 log.info("Failed to provision vlan table for bgp router");
487 }
488 }));
489 }
490
Saurav Dascbe6de32015-03-01 18:30:46 -0800491 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800492 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800493 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
494 .builder();
alshabib10580802015-02-18 18:30:33 -0800495 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
496 FlowRule rule;
497
498 selector.matchEthType(Ethernet.TYPE_ARP);
499 treatment.punt();
500
501 rule = new DefaultFlowRule(deviceId, selector.build(),
502 treatment.build(), CONTROLLER_PRIORITY,
503 appId, 0, true, FlowRule.Type.ETHER);
504
505 ops = install ? ops.add(rule) : ops.remove(rule);
506
507 selector = DefaultTrafficSelector.builder();
508 treatment = DefaultTrafficTreatment.builder();
509
510 selector.matchEthType(Ethernet.TYPE_IPV4);
511 treatment.transition(FlowRule.Type.COS);
512
513 rule = new DefaultFlowRule(deviceId, selector.build(),
514 treatment.build(), CONTROLLER_PRIORITY,
515 appId, 0, true, FlowRule.Type.ETHER);
516
517 ops = install ? ops.add(rule) : ops.remove(rule);
518
519 //Drop rule
520 selector = DefaultTrafficSelector.builder();
521 treatment = DefaultTrafficTreatment.builder();
522
523 treatment.drop();
524
525 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800526 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800527 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800528
529 ops = install ? ops.add(rule) : ops.remove(rule);
530
531 flowService.apply(ops.build(new FlowRuleOperationsContext() {
532 @Override
533 public void onSuccess(FlowRuleOperations ops) {
534 log.info("Provisioned ether table for bgp router");
535 }
536
537 @Override
538 public void onError(FlowRuleOperations ops) {
539 log.info("Failed to provision ether table for bgp router");
540 }
541 }));
542
alshabib10580802015-02-18 18:30:33 -0800543 }
544
545 private void processTableFive(boolean install) {
546 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800547 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
548 .builder();
alshabib10580802015-02-18 18:30:33 -0800549 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
550 FlowRule rule;
551
552 treatment.transition(FlowRule.Type.IP);
553
554 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800555 treatment.build(), DROP_PRIORITY, appId,
556 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800557
558 ops = install ? ops.add(rule) : ops.remove(rule);
559
560 flowService.apply(ops.build(new FlowRuleOperationsContext() {
561 @Override
562 public void onSuccess(FlowRuleOperations ops) {
563 log.info("Provisioned cos table for bgp router");
564 }
565
566 @Override
567 public void onError(FlowRuleOperations ops) {
568 log.info("Failed to provision cos table for bgp router");
569 }
570 }));
571
572 }
573
574 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800575 TrafficSelector.Builder selector;
576 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800577 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
578 FlowRule rule;
579
Saurav Dasfbe25c52015-03-04 11:12:00 -0800580
581 //Interface IPs
582 for (InterfaceIpAddress ipAddr : intfIps) {
583 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
584 selector = DefaultTrafficSelector.builder();
585 treatment = DefaultTrafficTreatment.builder();
586
587 selector.matchEthType(Ethernet.TYPE_IPV4);
588 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
589 treatment.transition(Type.ACL);
590
591 rule = new DefaultFlowRule(deviceId, selector.build(),
592 treatment.build(), HIGHEST_PRIORITY, appId,
593 0, true, FlowRule.Type.IP);
594
595 ops = install ? ops.add(rule) : ops.remove(rule);
596 }
597
598
alshabib10580802015-02-18 18:30:33 -0800599 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800600 selector = DefaultTrafficSelector.builder();
601 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800602
603 treatment.drop();
604
605 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800606 treatment.build(), DROP_PRIORITY, appId,
607 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800608
609 ops = install ? ops.add(rule) : ops.remove(rule);
610
611 flowService.apply(ops.build(new FlowRuleOperationsContext() {
612 @Override
613 public void onSuccess(FlowRuleOperations ops) {
614 log.info("Provisioned FIB table for bgp router");
615 }
616
617 @Override
618 public void onError(FlowRuleOperations ops) {
619 log.info("Failed to provision FIB table for bgp router");
620 }
621 }));
622 }
623
624 private void processTableNine(boolean install) {
625 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800626 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
627 .builder();
alshabib10580802015-02-18 18:30:33 -0800628 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
629 FlowRule rule;
630
631 treatment.punt();
632
633 rule = new DefaultFlowRule(deviceId, selector.build(),
634 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800635 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800636
637 ops = install ? ops.add(rule) : ops.remove(rule);
638
639 flowService.apply(ops.build(new FlowRuleOperationsContext() {
640 @Override
641 public void onSuccess(FlowRuleOperations ops) {
642 log.info("Provisioned Local table for bgp router");
643 }
644
645 @Override
646 public void onError(FlowRuleOperations ops) {
647 log.info("Failed to provision Local table for bgp router");
648 }
649 }));
650 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800651 }
alshabib10580802015-02-18 18:30:33 -0800652
Jonathan Hart7baba072015-02-23 14:27:59 -0800653 private class InternalGroupListener implements GroupListener {
654
655 @Override
656 public void event(GroupEvent event) {
657 Group group = event.subject();
658
659 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
660 event.type() == GroupEvent.Type.GROUP_UPDATED) {
661 synchronized (pendingUpdates) {
662 pendingUpdates.removeAll(group.appCookie())
663 .forEach((entry) -> installFlow(entry, group));
664 }
665 }
666 }
alshabib10580802015-02-18 18:30:33 -0800667 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800668}