blob: b50681ec70023e218f16cd1921b5485c79a68752 [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
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070018import java.util.Collection;
19import java.util.Collections;
20import java.util.HashMap;
21import java.util.HashSet;
22import java.util.Map;
23import java.util.Set;
24import java.util.stream.Collectors;
25
Jonathan Hartf5829202015-02-12 09:37:02 -080026import org.apache.felix.scr.annotations.Activate;
27import org.apache.felix.scr.annotations.Component;
28import org.apache.felix.scr.annotations.Deactivate;
29import org.apache.felix.scr.annotations.Reference;
30import org.apache.felix.scr.annotations.ReferenceCardinality;
31import org.onlab.packet.Ethernet;
Jonathan Hart7baba072015-02-23 14:27:59 -080032import org.onlab.packet.IpAddress;
33import org.onlab.packet.IpPrefix;
Jonathan Hart54b406b2015-03-06 16:24:14 -080034import org.onlab.packet.MacAddress;
Saurav Dasfbe25c52015-03-04 11:12:00 -080035import org.onlab.packet.VlanId;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070036import org.onlab.util.KryoNamespace;
Jonathan Hart54b406b2015-03-06 16:24:14 -080037import org.onosproject.config.NetworkConfigService;
Jonathan Hartf5829202015-02-12 09:37:02 -080038import org.onosproject.core.ApplicationId;
39import org.onosproject.core.CoreService;
40import org.onosproject.net.DeviceId;
alshabib346b5b32015-03-06 00:42:16 -080041import org.onosproject.net.PortNumber;
Jonathan Hartf5829202015-02-12 09:37:02 -080042import org.onosproject.net.flow.DefaultFlowRule;
43import org.onosproject.net.flow.DefaultTrafficSelector;
44import org.onosproject.net.flow.DefaultTrafficTreatment;
45import org.onosproject.net.flow.FlowRule;
Jonathan Hart54b406b2015-03-06 16:24:14 -080046import org.onosproject.net.flow.FlowRule.Type;
alshabib10580802015-02-18 18:30:33 -080047import org.onosproject.net.flow.FlowRuleOperations;
48import org.onosproject.net.flow.FlowRuleOperationsContext;
Jonathan Hartf5829202015-02-12 09:37:02 -080049import org.onosproject.net.flow.FlowRuleService;
50import org.onosproject.net.flow.TrafficSelector;
51import org.onosproject.net.flow.TrafficTreatment;
52import org.onosproject.net.group.DefaultGroupBucket;
53import org.onosproject.net.group.DefaultGroupDescription;
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070054import org.onosproject.net.group.DefaultGroupKey;
Jonathan Hartf5829202015-02-12 09:37:02 -080055import org.onosproject.net.group.Group;
56import org.onosproject.net.group.GroupBucket;
57import org.onosproject.net.group.GroupBuckets;
58import org.onosproject.net.group.GroupDescription;
Jonathan Hart7baba072015-02-23 14:27:59 -080059import org.onosproject.net.group.GroupEvent;
Jonathan Hart7baba072015-02-23 14:27:59 -080060import org.onosproject.net.group.GroupListener;
Jonathan Hartf5829202015-02-12 09:37:02 -080061import org.onosproject.net.group.GroupService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080062import org.onosproject.net.host.InterfaceIpAddress;
Jonathan Hartf5829202015-02-12 09:37:02 -080063import org.onosproject.net.packet.PacketService;
Jonathan Hart7baba072015-02-23 14:27:59 -080064import org.onosproject.routing.FibEntry;
Jonathan Hart2da1e602015-02-18 19:09:24 -080065import org.onosproject.routing.FibListener;
66import org.onosproject.routing.FibUpdate;
67import org.onosproject.routing.RoutingService;
Saurav Dasfbe25c52015-03-04 11:12:00 -080068import org.onosproject.routing.config.BgpSpeaker;
Jonathan Hart2da1e602015-02-18 19:09:24 -080069import org.onosproject.routing.config.Interface;
70import org.onosproject.routing.config.RoutingConfigurationService;
Jonathan Hartf5829202015-02-12 09:37:02 -080071import org.slf4j.Logger;
72import org.slf4j.LoggerFactory;
73
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -070074import com.google.common.collect.ConcurrentHashMultiset;
75import com.google.common.collect.HashMultimap;
76import com.google.common.collect.Maps;
77import com.google.common.collect.Multimap;
78import com.google.common.collect.Multiset;
Jonathan Hartf5829202015-02-12 09:37:02 -080079
80/**
81 * BgpRouter component.
82 */
83@Component(immediate = true)
84public class BgpRouter {
85
86 private static final Logger log = LoggerFactory.getLogger(BgpRouter.class);
87
88 private static final String BGP_ROUTER_APP = "org.onosproject.bgprouter";
89
Jonathan Hart12ef2052015-03-10 13:58:13 -070090 private static final int PRIORITY_OFFSET = 100;
91 private static final int PRIORITY_MULTIPLIER = 5;
Jonathan Hartf5829202015-02-12 09:37:02 -080092
93 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
94 protected CoreService coreService;
95
96 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
97 protected FlowRuleService flowService;
98
99 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
100 protected GroupService groupService;
101
102 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
103 protected RoutingService routingService;
104
105 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
106 protected RoutingConfigurationService configService;
107
108 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
109 protected PacketService packetService;
110
Saurav Dasfbe25c52015-03-04 11:12:00 -0800111 //
112 // NOTE: Unused reference - needed to guarantee that the
113 // NetworkConfigReader component is activated and the network configuration
114 // is read.
115 //
116 @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
117 protected NetworkConfigService networkConfigService;
118
Jonathan Hartf5829202015-02-12 09:37:02 -0800119 private ApplicationId appId;
120
Jonathan Hart7baba072015-02-23 14:27:59 -0800121 // Reference count for how many times a next hop is used by a route
122 private final Multiset<IpAddress> nextHopsCount = ConcurrentHashMultiset.create();
123
124 // Mapping from prefix to its current next hop
125 private final Map<IpPrefix, IpAddress> prefixToNextHop = Maps.newHashMap();
126
127 // Mapping from next hop IP to next hop object containing group info
128 private final Map<IpAddress, NextHop> nextHops = Maps.newHashMap();
129
130 // Stores FIB updates that are waiting for groups to be set up
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700131 private final Multimap<NextHopGroupKey, FibEntry> pendingUpdates = HashMultimap.create();
Jonathan Hartf5829202015-02-12 09:37:02 -0800132
Saurav Dasfbe25c52015-03-04 11:12:00 -0800133 // Device id of data-plane switch - should be learned from config
134 private DeviceId deviceId;
135
136 // Device id of control-plane switch (OVS) connected to BGP Speaker - should be
137 // learned from config
138 private DeviceId ctrlDeviceId;
Jonathan Hartf5829202015-02-12 09:37:02 -0800139
Jonathan Hart7baba072015-02-23 14:27:59 -0800140 private final GroupListener groupListener = new InternalGroupListener();
141
Jonathan Hartf5829202015-02-12 09:37:02 -0800142 private TunnellingConnectivityManager connectivityManager;
143
sangho5eaf0332015-03-09 15:08:12 -0700144 private IcmpHandler icmpHandler;
145
alshabib10580802015-02-18 18:30:33 -0800146 private InternalTableHandler provisionStaticTables = new InternalTableHandler();
147
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700148 private KryoNamespace.Builder appKryo = new KryoNamespace.Builder()
149 .register(IpAddress.Version.class)
150 .register(IpAddress.class)
151 .register(NextHopGroupKey.class);
152
Jonathan Hartf5829202015-02-12 09:37:02 -0800153 @Activate
154 protected void activate() {
Jonathan Hartf5829202015-02-12 09:37:02 -0800155 appId = coreService.registerApplication(BGP_ROUTER_APP);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800156 getDeviceConfiguration(configService.getBgpSpeakers());
Jonathan Hartf5829202015-02-12 09:37:02 -0800157
Jonathan Hart7baba072015-02-23 14:27:59 -0800158 groupService.addListener(groupListener);
159
Saurav Dasfbe25c52015-03-04 11:12:00 -0800160 provisionStaticTables.provision(true, configService.getInterfaces());
alshabib10580802015-02-18 18:30:33 -0800161
Jonathan Hartf5829202015-02-12 09:37:02 -0800162 connectivityManager = new TunnellingConnectivityManager(appId,
163 configService,
Jonathan Hart936a7292015-03-06 18:02:57 -0800164 packetService,
165 flowService);
Jonathan Hartf5829202015-02-12 09:37:02 -0800166
sangho5eaf0332015-03-09 15:08:12 -0700167 icmpHandler = new IcmpHandler(configService, packetService);
168
Jonathan Hartf5829202015-02-12 09:37:02 -0800169 routingService.start(new InternalFibListener());
170
171 connectivityManager.start();
172
sangho5eaf0332015-03-09 15:08:12 -0700173 icmpHandler.start();
174
Jonathan Hartf5829202015-02-12 09:37:02 -0800175 log.info("BgpRouter started");
176 }
177
178 @Deactivate
179 protected void deactivate() {
180 routingService.stop();
181 connectivityManager.stop();
sangho5eaf0332015-03-09 15:08:12 -0700182 icmpHandler.stop();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800183 provisionStaticTables.provision(false, configService.getInterfaces());
Jonathan Hartf5829202015-02-12 09:37:02 -0800184
Jonathan Hart7baba072015-02-23 14:27:59 -0800185 groupService.removeListener(groupListener);
186
Jonathan Hartf5829202015-02-12 09:37:02 -0800187 log.info("BgpRouter stopped");
188 }
189
Saurav Dasfbe25c52015-03-04 11:12:00 -0800190 private void getDeviceConfiguration(Map<String, BgpSpeaker> bgps) {
191 if (bgps == null || bgps.values().isEmpty()) {
192 log.error("BGP speakers configuration is missing");
193 return;
194 }
195 for (BgpSpeaker s : bgps.values()) {
196 ctrlDeviceId = s.connectPoint().deviceId();
197 if (s.interfaceAddresses() == null || s.interfaceAddresses().isEmpty()) {
198 log.error("BGP Router must have interfaces configured");
199 return;
200 }
201 deviceId = s.interfaceAddresses().get(0).connectPoint().deviceId();
202 break;
203 }
sangho5eaf0332015-03-09 15:08:12 -0700204
Saurav Dasfbe25c52015-03-04 11:12:00 -0800205 log.info("Router dpid: {}", deviceId);
206 log.info("Control Plane OVS dpid: {}", ctrlDeviceId);
207 }
208
Jonathan Hartf5829202015-02-12 09:37:02 -0800209 private void updateFibEntry(Collection<FibUpdate> updates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800210 Map<FibEntry, Group> toInstall = new HashMap<>(updates.size());
211
Jonathan Hartf5829202015-02-12 09:37:02 -0800212 for (FibUpdate update : updates) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800213 FibEntry entry = update.entry();
Jonathan Hartf5829202015-02-12 09:37:02 -0800214
Jonathan Hart7baba072015-02-23 14:27:59 -0800215 addNextHop(entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800216
Jonathan Hart7baba072015-02-23 14:27:59 -0800217 Group group;
218 synchronized (pendingUpdates) {
219 NextHop nextHop = nextHops.get(entry.nextHopIp());
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700220 group = groupService.getGroup(deviceId,
221 new DefaultGroupKey(
222 appKryo.build().serialize(nextHop.group())));
Jonathan Hartf5829202015-02-12 09:37:02 -0800223
Jonathan Hart7baba072015-02-23 14:27:59 -0800224 if (group == null) {
225 log.debug("Adding pending flow {}", update.entry());
226 pendingUpdates.put(nextHop.group(), update.entry());
227 continue;
228 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800229 }
230
Jonathan Hart5b141422015-03-06 12:59:09 -0800231 toInstall.put(update.entry(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800232 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800233
234 installFlows(toInstall);
Jonathan Hartf5829202015-02-12 09:37:02 -0800235 }
236
Jonathan Hart5b141422015-03-06 12:59:09 -0800237 private void installFlows(Map<FibEntry, Group> entriesToInstall) {
238 FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800239
Jonathan Hart5b141422015-03-06 12:59:09 -0800240 for (Map.Entry<FibEntry, Group> entry : entriesToInstall.entrySet()) {
241 FibEntry fibEntry = entry.getKey();
242 Group group = entry.getValue();
243
244 FlowRule flowRule = generateRibFlowRule(fibEntry.prefix(), group);
245
246 builder.add(flowRule);
247 }
248
249 flowService.apply(builder.build());
Jonathan Hart7baba072015-02-23 14:27:59 -0800250 }
251
252 private synchronized void deleteFibEntry(Collection<FibUpdate> withdraws) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800253 FlowRuleOperations.Builder builder = FlowRuleOperations.builder();
254
Jonathan Hart7baba072015-02-23 14:27:59 -0800255 for (FibUpdate update : withdraws) {
256 FibEntry entry = update.entry();
257
Jonathan Hart37d659c2015-03-08 19:20:38 -0700258 Group group = deleteNextHop(entry.prefix());
259 if (group == null) {
260 log.warn("Group not found when deleting {}", entry);
261 return;
262 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800263
Jonathan Hart37d659c2015-03-08 19:20:38 -0700264 FlowRule flowRule = generateRibFlowRule(entry.prefix(), group);
Jonathan Hartf5829202015-02-12 09:37:02 -0800265
Jonathan Hart5b141422015-03-06 12:59:09 -0800266 builder.remove(flowRule);
Jonathan Hartf5829202015-02-12 09:37:02 -0800267 }
Jonathan Hart5b141422015-03-06 12:59:09 -0800268
269 flowService.apply(builder.build());
Jonathan Hartf5829202015-02-12 09:37:02 -0800270 }
271
Jonathan Hart37d659c2015-03-08 19:20:38 -0700272 private FlowRule generateRibFlowRule(IpPrefix prefix, Group group) {
273 TrafficSelector selector = DefaultTrafficSelector.builder()
274 .matchEthType(Ethernet.TYPE_IPV4)
275 .matchIPDst(prefix)
276 .build();
277
278 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
279 .group(group.id())
280 .build();
281
Jonathan Hart12ef2052015-03-10 13:58:13 -0700282
283 int priority = prefix.prefixLength() * PRIORITY_MULTIPLIER + PRIORITY_OFFSET;
284
Jonathan Hart37d659c2015-03-08 19:20:38 -0700285 return new DefaultFlowRule(deviceId, selector, treatment,
Jonathan Hart12ef2052015-03-10 13:58:13 -0700286 priority, appId, 0, true,
Jonathan Hart37d659c2015-03-08 19:20:38 -0700287 FlowRule.Type.IP);
288 }
289
Jonathan Hart7baba072015-02-23 14:27:59 -0800290 private synchronized void addNextHop(FibEntry entry) {
291 prefixToNextHop.put(entry.prefix(), entry.nextHopIp());
292 if (nextHopsCount.count(entry.nextHopIp()) == 0) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800293 // There was no next hop in the multiset
294
Jonathan Hart7baba072015-02-23 14:27:59 -0800295 Interface egressIntf = configService.getMatchingInterface(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800296 if (egressIntf == null) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800297 log.warn("no egress interface found for {}", entry);
Jonathan Hartf5829202015-02-12 09:37:02 -0800298 return;
299 }
300
Jonathan Hart7baba072015-02-23 14:27:59 -0800301 NextHopGroupKey groupKey = new NextHopGroupKey(entry.nextHopIp());
302
303 NextHop nextHop = new NextHop(entry.nextHopIp(), entry.nextHopMac(), groupKey);
Jonathan Hartf5829202015-02-12 09:37:02 -0800304
305 TrafficTreatment treatment = DefaultTrafficTreatment.builder()
306 .setEthSrc(egressIntf.mac())
307 .setEthDst(nextHop.mac())
Jonathan Hart54b406b2015-03-06 16:24:14 -0800308 .pushVlan()
Jonathan Hartf5829202015-02-12 09:37:02 -0800309 .setVlanId(egressIntf.vlan())
alshabibda1644e2015-03-13 14:01:35 -0700310 .setVlanPcp((byte) 0)
Jonathan Hartf5829202015-02-12 09:37:02 -0800311 .setOutput(egressIntf.connectPoint().port())
312 .build();
313
314 GroupBucket bucket = DefaultGroupBucket.createIndirectGroupBucket(treatment);
315
316 GroupDescription groupDescription
317 = new DefaultGroupDescription(deviceId,
318 GroupDescription.Type.INDIRECT,
319 new GroupBuckets(Collections
320 .singletonList(bucket)),
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700321 new DefaultGroupKey(appKryo.build().serialize(groupKey)),
Jonathan Hartf5829202015-02-12 09:37:02 -0800322 appId);
323
324 groupService.addGroup(groupDescription);
Jonathan Hart7baba072015-02-23 14:27:59 -0800325
326 nextHops.put(nextHop.ip(), nextHop);
327
Jonathan Hartf5829202015-02-12 09:37:02 -0800328 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800329
330 nextHopsCount.add(entry.nextHopIp());
Jonathan Hartf5829202015-02-12 09:37:02 -0800331 }
332
Jonathan Hart37d659c2015-03-08 19:20:38 -0700333 private synchronized Group deleteNextHop(IpPrefix prefix) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800334 IpAddress nextHopIp = prefixToNextHop.remove(prefix);
335 NextHop nextHop = nextHops.get(nextHopIp);
336 if (nextHop == null) {
337 log.warn("No next hop found when removing prefix {}", prefix);
Jonathan Hart37d659c2015-03-08 19:20:38 -0700338 return null;
Jonathan Hart7baba072015-02-23 14:27:59 -0800339 }
340
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700341 Group group = groupService.getGroup(deviceId,
342 new DefaultGroupKey(appKryo.
343 build().
344 serialize(nextHop.group())));
Jonathan Hart37d659c2015-03-08 19:20:38 -0700345
Jonathan Hartf9f2cbb2015-03-12 17:44:03 -0700346 // FIXME disabling group deletes for now until we verify the logic is OK
347 /*if (nextHopsCount.remove(nextHopIp, 1) <= 1) {
Jonathan Hartf5829202015-02-12 09:37:02 -0800348 // There was one or less next hops, so there are now none
349
Jonathan Hart7baba072015-02-23 14:27:59 -0800350 log.debug("removing group for next hop {}", nextHop);
Jonathan Hartf5829202015-02-12 09:37:02 -0800351
Jonathan Hart7baba072015-02-23 14:27:59 -0800352 nextHops.remove(nextHopIp);
353
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700354 groupService.removeGroup(deviceId,
355 new DefaultGroupKey(appKryo.build().serialize(nextHop.group())),
356 appId);
Jonathan Hartf9f2cbb2015-03-12 17:44:03 -0700357 }*/
Jonathan Hart37d659c2015-03-08 19:20:38 -0700358
359 return group;
Jonathan Hartf5829202015-02-12 09:37:02 -0800360 }
361
362 private class InternalFibListener implements FibListener {
363
364 @Override
365 public void update(Collection<FibUpdate> updates,
366 Collection<FibUpdate> withdraws) {
367 BgpRouter.this.deleteFibEntry(withdraws);
368 BgpRouter.this.updateFibEntry(updates);
369 }
370 }
alshabib10580802015-02-18 18:30:33 -0800371
372 private class InternalTableHandler {
373
374 private static final int CONTROLLER_PRIORITY = 255;
375 private static final int DROP_PRIORITY = 0;
Saurav Dasfbe25c52015-03-04 11:12:00 -0800376 private static final int HIGHEST_PRIORITY = 0xffff;
377 private Set<InterfaceIpAddress> intfIps = new HashSet<InterfaceIpAddress>();
378 private Set<MacAddress> intfMacs = new HashSet<MacAddress>();
alshabib346b5b32015-03-06 00:42:16 -0800379 private Map<PortNumber, VlanId> portVlanPair = Maps.newHashMap();
alshabib10580802015-02-18 18:30:33 -0800380
Saurav Dasfbe25c52015-03-04 11:12:00 -0800381 public void provision(boolean install, Set<Interface> intfs) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800382 getInterfaceConfig(intfs);
alshabib10580802015-02-18 18:30:33 -0800383 processTableZero(install);
384 processTableOne(install);
385 processTableTwo(install);
Saurav Dascbe6de32015-03-01 18:30:46 -0800386 processTableFour(install);
alshabib10580802015-02-18 18:30:33 -0800387 processTableFive(install);
388 processTableSix(install);
389 processTableNine(install);
alshabib10580802015-02-18 18:30:33 -0800390 }
391
Jonathan Hart5b141422015-03-06 12:59:09 -0800392 private void getInterfaceConfig(Set<Interface> intfs) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800393 log.info("Processing {} router interfaces", intfs.size());
394 for (Interface intf : intfs) {
395 intfIps.addAll(intf.ipAddresses());
396 intfMacs.add(intf.mac());
alshabib346b5b32015-03-06 00:42:16 -0800397 portVlanPair.put(intf.connectPoint().port(), intf.vlan());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800398 }
399 }
400
alshabib10580802015-02-18 18:30:33 -0800401 private void processTableZero(boolean install) {
402 TrafficSelector.Builder selector;
403 TrafficTreatment.Builder treatment;
404
Saurav Dasfbe25c52015-03-04 11:12:00 -0800405 // Bcast rule
alshabib10580802015-02-18 18:30:33 -0800406 selector = DefaultTrafficSelector.builder();
407 treatment = DefaultTrafficTreatment.builder();
408
409 selector.matchEthDst(MacAddress.BROADCAST);
410 treatment.transition(FlowRule.Type.VLAN_MPLS);
411
412 FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800413 treatment.build(),
414 CONTROLLER_PRIORITY, appId, 0,
Saurav Dascbe6de32015-03-01 18:30:46 -0800415 true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800416
417 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
418
419 ops = install ? ops.add(rule) : ops.remove(rule);
420
Saurav Dasfbe25c52015-03-04 11:12:00 -0800421 // Interface MACs
422 for (MacAddress mac : intfMacs) {
423 log.debug("adding rule for MAC: {}", mac);
424 selector = DefaultTrafficSelector.builder();
425 treatment = DefaultTrafficTreatment.builder();
426
427 selector.matchEthDst(mac);
428 treatment.transition(FlowRule.Type.VLAN_MPLS);
429
430 rule = new DefaultFlowRule(deviceId, selector.build(),
431 treatment.build(),
432 CONTROLLER_PRIORITY, appId, 0,
433 true, FlowRule.Type.FIRST);
434
435 ops = install ? ops.add(rule) : ops.remove(rule);
436 }
437
alshabib10580802015-02-18 18:30:33 -0800438 //Drop rule
439 selector = DefaultTrafficSelector.builder();
440 treatment = DefaultTrafficTreatment.builder();
441
442 treatment.drop();
443
444 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800445 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800446 0, true, FlowRule.Type.FIRST);
alshabib10580802015-02-18 18:30:33 -0800447
448 ops = install ? ops.add(rule) : ops.remove(rule);
449
450 flowService.apply(ops.build(new FlowRuleOperationsContext() {
451 @Override
452 public void onSuccess(FlowRuleOperations ops) {
453 log.info("Provisioned default table for bgp router");
454 }
455
456 @Override
457 public void onError(FlowRuleOperations ops) {
458 log.info("Failed to provision default table for bgp router");
459 }
460 }));
461
462 }
463
464 private void processTableOne(boolean install) {
465 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800466 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
467 .builder();
alshabib10580802015-02-18 18:30:33 -0800468 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
469 FlowRule rule;
470
sanghoc0b3c342015-03-12 17:12:10 -0700471 selector.matchVlanId(VlanId.ANY);
alshabib10580802015-02-18 18:30:33 -0800472 treatment.transition(FlowRule.Type.VLAN);
473
474 rule = new DefaultFlowRule(deviceId, selector.build(),
475 treatment.build(), CONTROLLER_PRIORITY,
476 appId, 0, true, FlowRule.Type.VLAN_MPLS);
477
478 ops = install ? ops.add(rule) : ops.remove(rule);
479
alshabib10580802015-02-18 18:30:33 -0800480 flowService.apply(ops.build(new FlowRuleOperationsContext() {
481 @Override
482 public void onSuccess(FlowRuleOperations ops) {
483 log.info("Provisioned vlan/mpls table for bgp router");
484 }
485
486 @Override
487 public void onError(FlowRuleOperations ops) {
Jonathan Hart7baba072015-02-23 14:27:59 -0800488 log.info(
489 "Failed to provision vlan/mpls table for bgp router");
alshabib10580802015-02-18 18:30:33 -0800490 }
491 }));
492
493 }
494
495 private void processTableTwo(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800496 TrafficSelector.Builder selector;
497 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800498 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
499 FlowRule rule;
500
Saurav Dasfbe25c52015-03-04 11:12:00 -0800501 //Interface Vlans
alshabib346b5b32015-03-06 00:42:16 -0800502 for (Map.Entry<PortNumber, VlanId> portVlan : portVlanPair.entrySet()) {
503 log.debug("adding rule for VLAN: {}", portVlan);
Saurav Dasfbe25c52015-03-04 11:12:00 -0800504 selector = DefaultTrafficSelector.builder();
505 treatment = DefaultTrafficTreatment.builder();
506
alshabib346b5b32015-03-06 00:42:16 -0800507 selector.matchVlanId(portVlan.getValue());
508 selector.matchInPort(portVlan.getKey());
Saurav Dasfbe25c52015-03-04 11:12:00 -0800509 treatment.transition(Type.ETHER);
alshabib346b5b32015-03-06 00:42:16 -0800510 treatment.deferred().popVlan();
Saurav Dasfbe25c52015-03-04 11:12:00 -0800511
512 rule = new DefaultFlowRule(deviceId, selector.build(),
513 treatment.build(), CONTROLLER_PRIORITY, appId,
514 0, true, FlowRule.Type.VLAN);
515
516 ops = install ? ops.add(rule) : ops.remove(rule);
517 }
518
alshabib10580802015-02-18 18:30:33 -0800519 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800520 selector = DefaultTrafficSelector.builder();
521 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800522
523 treatment.drop();
524
525 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800526 treatment.build(), DROP_PRIORITY, appId,
527 0, true, FlowRule.Type.VLAN);
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 vlan table for bgp router");
535 }
536
537 @Override
538 public void onError(FlowRuleOperations ops) {
539 log.info("Failed to provision vlan table for bgp router");
540 }
541 }));
542 }
543
Saurav Dascbe6de32015-03-01 18:30:46 -0800544 private void processTableFour(boolean install) {
alshabib10580802015-02-18 18:30:33 -0800545 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800546 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
547 .builder();
alshabib10580802015-02-18 18:30:33 -0800548 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
549 FlowRule rule;
550
551 selector.matchEthType(Ethernet.TYPE_ARP);
552 treatment.punt();
553
554 rule = new DefaultFlowRule(deviceId, selector.build(),
555 treatment.build(), CONTROLLER_PRIORITY,
556 appId, 0, true, FlowRule.Type.ETHER);
557
558 ops = install ? ops.add(rule) : ops.remove(rule);
559
560 selector = DefaultTrafficSelector.builder();
561 treatment = DefaultTrafficTreatment.builder();
562
563 selector.matchEthType(Ethernet.TYPE_IPV4);
564 treatment.transition(FlowRule.Type.COS);
565
566 rule = new DefaultFlowRule(deviceId, selector.build(),
567 treatment.build(), CONTROLLER_PRIORITY,
568 appId, 0, true, FlowRule.Type.ETHER);
569
570 ops = install ? ops.add(rule) : ops.remove(rule);
571
572 //Drop rule
573 selector = DefaultTrafficSelector.builder();
574 treatment = DefaultTrafficTreatment.builder();
575
576 treatment.drop();
577
578 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800579 treatment.build(), DROP_PRIORITY, appId,
Saurav Dascbe6de32015-03-01 18:30:46 -0800580 0, true, FlowRule.Type.ETHER);
alshabib10580802015-02-18 18:30:33 -0800581
582 ops = install ? ops.add(rule) : ops.remove(rule);
583
584 flowService.apply(ops.build(new FlowRuleOperationsContext() {
585 @Override
586 public void onSuccess(FlowRuleOperations ops) {
587 log.info("Provisioned ether table for bgp router");
588 }
589
590 @Override
591 public void onError(FlowRuleOperations ops) {
592 log.info("Failed to provision ether table for bgp router");
593 }
594 }));
595
alshabib10580802015-02-18 18:30:33 -0800596 }
597
598 private void processTableFive(boolean install) {
599 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800600 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
601 .builder();
alshabib10580802015-02-18 18:30:33 -0800602 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
603 FlowRule rule;
604
605 treatment.transition(FlowRule.Type.IP);
606
607 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800608 treatment.build(), DROP_PRIORITY, appId,
609 0, true, FlowRule.Type.COS);
alshabib10580802015-02-18 18:30:33 -0800610
611 ops = install ? ops.add(rule) : ops.remove(rule);
612
613 flowService.apply(ops.build(new FlowRuleOperationsContext() {
614 @Override
615 public void onSuccess(FlowRuleOperations ops) {
616 log.info("Provisioned cos table for bgp router");
617 }
618
619 @Override
620 public void onError(FlowRuleOperations ops) {
621 log.info("Failed to provision cos table for bgp router");
622 }
623 }));
624
625 }
626
627 private void processTableSix(boolean install) {
Saurav Dasfbe25c52015-03-04 11:12:00 -0800628 TrafficSelector.Builder selector;
629 TrafficTreatment.Builder treatment;
alshabib10580802015-02-18 18:30:33 -0800630 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
631 FlowRule rule;
632
Saurav Dasfbe25c52015-03-04 11:12:00 -0800633
634 //Interface IPs
635 for (InterfaceIpAddress ipAddr : intfIps) {
636 log.debug("adding rule for IPs: {}", ipAddr.ipAddress());
637 selector = DefaultTrafficSelector.builder();
638 treatment = DefaultTrafficTreatment.builder();
639
640 selector.matchEthType(Ethernet.TYPE_IPV4);
641 selector.matchIPDst(IpPrefix.valueOf(ipAddr.ipAddress(), 32));
642 treatment.transition(Type.ACL);
643
644 rule = new DefaultFlowRule(deviceId, selector.build(),
645 treatment.build(), HIGHEST_PRIORITY, appId,
646 0, true, FlowRule.Type.IP);
647
648 ops = install ? ops.add(rule) : ops.remove(rule);
649 }
650
651
alshabib10580802015-02-18 18:30:33 -0800652 //Drop rule
Saurav Dasfbe25c52015-03-04 11:12:00 -0800653 selector = DefaultTrafficSelector.builder();
654 treatment = DefaultTrafficTreatment.builder();
alshabib10580802015-02-18 18:30:33 -0800655
656 treatment.drop();
657
658 rule = new DefaultFlowRule(deviceId, selector.build(),
Jonathan Hart7baba072015-02-23 14:27:59 -0800659 treatment.build(), DROP_PRIORITY, appId,
660 0, true, FlowRule.Type.IP);
alshabib10580802015-02-18 18:30:33 -0800661
662 ops = install ? ops.add(rule) : ops.remove(rule);
663
664 flowService.apply(ops.build(new FlowRuleOperationsContext() {
665 @Override
666 public void onSuccess(FlowRuleOperations ops) {
667 log.info("Provisioned FIB table for bgp router");
668 }
669
670 @Override
671 public void onError(FlowRuleOperations ops) {
672 log.info("Failed to provision FIB table for bgp router");
673 }
674 }));
675 }
676
677 private void processTableNine(boolean install) {
678 TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
Jonathan Hart7baba072015-02-23 14:27:59 -0800679 TrafficTreatment.Builder treatment = DefaultTrafficTreatment
680 .builder();
alshabib10580802015-02-18 18:30:33 -0800681 FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
682 FlowRule rule;
683
684 treatment.punt();
685
686 rule = new DefaultFlowRule(deviceId, selector.build(),
687 treatment.build(), CONTROLLER_PRIORITY,
Saurav Dasfa2fa932015-03-03 11:29:48 -0800688 appId, 0, true, FlowRule.Type.DEFAULT);
alshabib10580802015-02-18 18:30:33 -0800689
690 ops = install ? ops.add(rule) : ops.remove(rule);
691
692 flowService.apply(ops.build(new FlowRuleOperationsContext() {
693 @Override
694 public void onSuccess(FlowRuleOperations ops) {
695 log.info("Provisioned Local table for bgp router");
696 }
697
698 @Override
699 public void onError(FlowRuleOperations ops) {
700 log.info("Failed to provision Local table for bgp router");
701 }
702 }));
703 }
Jonathan Hart7baba072015-02-23 14:27:59 -0800704 }
alshabib10580802015-02-18 18:30:33 -0800705
Jonathan Hart7baba072015-02-23 14:27:59 -0800706 private class InternalGroupListener implements GroupListener {
707
708 @Override
709 public void event(GroupEvent event) {
710 Group group = event.subject();
711
712 if (event.type() == GroupEvent.Type.GROUP_ADDED ||
713 event.type() == GroupEvent.Type.GROUP_UPDATED) {
714 synchronized (pendingUpdates) {
Jonathan Hart5b141422015-03-06 12:59:09 -0800715
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700716 NextHopGroupKey nhGroupKey =
717 appKryo.build().deserialize(group.appCookie().key());
Jonathan Hart5b141422015-03-06 12:59:09 -0800718 Map<FibEntry, Group> entriesToInstall =
Srikanth Vavilapalli717361f2015-03-16 12:06:04 -0700719 pendingUpdates.removeAll(nhGroupKey)
Jonathan Hart5b141422015-03-06 12:59:09 -0800720 .stream()
721 .collect(Collectors
722 .toMap(e -> e, e -> group));
723
724 installFlows(entriesToInstall);
Jonathan Hart7baba072015-02-23 14:27:59 -0800725 }
726 }
727 }
alshabib10580802015-02-18 18:30:33 -0800728 }
Jonathan Hartf5829202015-02-12 09:37:02 -0800729}