alshabib
Committed by Jonathan Hart

WIP: Started implementing static flows for corsa vanderweken pipeline.

Modified to not use Corsa driver by default.

Change-Id: If8df5769cf084346121d34bf4490f578e6b6f2d0
...@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Deactivate; ...@@ -23,6 +23,7 @@ import org.apache.felix.scr.annotations.Deactivate;
23 import org.apache.felix.scr.annotations.Reference; 23 import org.apache.felix.scr.annotations.Reference;
24 import org.apache.felix.scr.annotations.ReferenceCardinality; 24 import org.apache.felix.scr.annotations.ReferenceCardinality;
25 import org.onlab.packet.Ethernet; 25 import org.onlab.packet.Ethernet;
26 +import org.onlab.packet.MacAddress;
26 import org.onosproject.core.ApplicationId; 27 import org.onosproject.core.ApplicationId;
27 import org.onosproject.core.CoreService; 28 import org.onosproject.core.CoreService;
28 import org.onosproject.net.DeviceId; 29 import org.onosproject.net.DeviceId;
...@@ -30,6 +31,8 @@ import org.onosproject.net.flow.DefaultFlowRule; ...@@ -30,6 +31,8 @@ import org.onosproject.net.flow.DefaultFlowRule;
30 import org.onosproject.net.flow.DefaultTrafficSelector; 31 import org.onosproject.net.flow.DefaultTrafficSelector;
31 import org.onosproject.net.flow.DefaultTrafficTreatment; 32 import org.onosproject.net.flow.DefaultTrafficTreatment;
32 import org.onosproject.net.flow.FlowRule; 33 import org.onosproject.net.flow.FlowRule;
34 +import org.onosproject.net.flow.FlowRuleOperations;
35 +import org.onosproject.net.flow.FlowRuleOperationsContext;
33 import org.onosproject.net.flow.FlowRuleService; 36 import org.onosproject.net.flow.FlowRuleService;
34 import org.onosproject.net.flow.TrafficSelector; 37 import org.onosproject.net.flow.TrafficSelector;
35 import org.onosproject.net.flow.TrafficTreatment; 38 import org.onosproject.net.flow.TrafficTreatment;
...@@ -90,15 +93,19 @@ public class BgpRouter { ...@@ -90,15 +93,19 @@ public class BgpRouter {
90 private final Multiset<NextHop> nextHops = ConcurrentHashMultiset.create(); 93 private final Multiset<NextHop> nextHops = ConcurrentHashMultiset.create();
91 private final Map<NextHop, NextHopGroupKey> groups = new HashMap<>(); 94 private final Map<NextHop, NextHopGroupKey> groups = new HashMap<>();
92 95
93 - private DeviceId deviceId = DeviceId.deviceId("of:00000000000000a1"); // TODO config 96 + private DeviceId deviceId = DeviceId.deviceId("of:0000000000000001"); // TODO config
94 97
95 private TunnellingConnectivityManager connectivityManager; 98 private TunnellingConnectivityManager connectivityManager;
96 99
100 + private InternalTableHandler provisionStaticTables = new InternalTableHandler();
101 +
97 @Activate 102 @Activate
98 protected void activate() { 103 protected void activate() {
99 log.info("Bgp1Router started"); 104 log.info("Bgp1Router started");
100 appId = coreService.registerApplication(BGP_ROUTER_APP); 105 appId = coreService.registerApplication(BGP_ROUTER_APP);
101 106
107 + provisionStaticTables.provision(true);
108 +
102 connectivityManager = new TunnellingConnectivityManager(appId, 109 connectivityManager = new TunnellingConnectivityManager(appId,
103 configService, 110 configService,
104 packetService); 111 packetService);
...@@ -114,6 +121,7 @@ public class BgpRouter { ...@@ -114,6 +121,7 @@ public class BgpRouter {
114 protected void deactivate() { 121 protected void deactivate() {
115 routingService.stop(); 122 routingService.stop();
116 connectivityManager.stop(); 123 connectivityManager.stop();
124 + provisionStaticTables.provision(false);
117 125
118 log.info("BgpRouter stopped"); 126 log.info("BgpRouter stopped");
119 } 127 }
...@@ -224,4 +232,303 @@ public class BgpRouter { ...@@ -224,4 +232,303 @@ public class BgpRouter {
224 BgpRouter.this.updateFibEntry(updates); 232 BgpRouter.this.updateFibEntry(updates);
225 } 233 }
226 } 234 }
235 +
236 + private class InternalTableHandler {
237 +
238 + private static final int CONTROLLER_PRIORITY = 255;
239 + private static final int DROP_PRIORITY = 0;
240 +
241 +
242 + public void provision(boolean install) {
243 +
244 + processTableZero(install);
245 + processTableOne(install);
246 + processTableTwo(install);
247 + processTableThree(install);
248 + processTableFive(install);
249 + processTableSix(install);
250 + processTableNine(install);
251 +
252 + }
253 +
254 + private void processTableZero(boolean install) {
255 + TrafficSelector.Builder selector;
256 + TrafficTreatment.Builder treatment;
257 +
258 + selector = DefaultTrafficSelector.builder();
259 + treatment = DefaultTrafficTreatment.builder();
260 +
261 + selector.matchEthDst(MacAddress.BROADCAST);
262 + treatment.transition(FlowRule.Type.VLAN_MPLS);
263 +
264 + FlowRule rule = new DefaultFlowRule(deviceId, selector.build(),
265 + treatment.build(), CONTROLLER_PRIORITY,
266 + appId, 0, true);
267 +
268 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
269 +
270 + ops = install ? ops.add(rule) : ops.remove(rule);
271 +
272 +
273 + //Drop rule
274 + selector = DefaultTrafficSelector.builder();
275 + treatment = DefaultTrafficTreatment.builder();
276 +
277 + treatment.drop();
278 +
279 + rule = new DefaultFlowRule(deviceId, selector.build(),
280 + treatment.build(), DROP_PRIORITY,
281 + appId, 0, true, FlowRule.Type.VLAN_MPLS);
282 +
283 + ops = install ? ops.add(rule) : ops.remove(rule);
284 +
285 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
286 + @Override
287 + public void onSuccess(FlowRuleOperations ops) {
288 + log.info("Provisioned default table for bgp router");
289 + }
290 +
291 + @Override
292 + public void onError(FlowRuleOperations ops) {
293 + log.info("Failed to provision default table for bgp router");
294 + }
295 + }));
296 +
297 + }
298 +
299 + private void processTableOne(boolean install) {
300 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
301 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
302 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
303 + FlowRule rule;
304 +
305 + selector.matchEthType(Ethernet.TYPE_IPV4);
306 + treatment.transition(FlowRule.Type.VLAN);
307 +
308 + rule = new DefaultFlowRule(deviceId, selector.build(),
309 + treatment.build(), CONTROLLER_PRIORITY,
310 + appId, 0, true, FlowRule.Type.VLAN_MPLS);
311 +
312 + ops = install ? ops.add(rule) : ops.remove(rule);
313 +
314 + selector = DefaultTrafficSelector.builder();
315 + treatment = DefaultTrafficTreatment.builder();
316 +
317 + selector.matchEthType(Ethernet.TYPE_ARP);
318 + treatment.transition(FlowRule.Type.VLAN);
319 +
320 + rule = new DefaultFlowRule(deviceId, selector.build(),
321 + treatment.build(), CONTROLLER_PRIORITY,
322 + appId, 0, true, FlowRule.Type.VLAN_MPLS);
323 +
324 + ops = install ? ops.add(rule) : ops.remove(rule);
325 +
326 + selector = DefaultTrafficSelector.builder();
327 + treatment = DefaultTrafficTreatment.builder();
328 +
329 + selector.matchEthType(Ethernet.TYPE_VLAN);
330 + treatment.transition(FlowRule.Type.VLAN);
331 +
332 + rule = new DefaultFlowRule(deviceId, selector.build(),
333 + treatment.build(), CONTROLLER_PRIORITY,
334 + appId, 0, true, FlowRule.Type.VLAN_MPLS);
335 +
336 + ops = install ? ops.add(rule) : ops.remove(rule);
337 +
338 + //Drop rule
339 + selector = DefaultTrafficSelector.builder();
340 + treatment = DefaultTrafficTreatment.builder();
341 +
342 + treatment.drop();
343 +
344 + rule = new DefaultFlowRule(deviceId, selector.build(),
345 + treatment.build(), DROP_PRIORITY,
346 + appId, 0, true, FlowRule.Type.VLAN_MPLS);
347 +
348 + ops = install ? ops.add(rule) : ops.remove(rule);
349 +
350 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
351 + @Override
352 + public void onSuccess(FlowRuleOperations ops) {
353 + log.info("Provisioned vlan/mpls table for bgp router");
354 + }
355 +
356 + @Override
357 + public void onError(FlowRuleOperations ops) {
358 + log.info("Failed to provision vlan/mpls table for bgp router");
359 + }
360 + }));
361 +
362 + }
363 +
364 + private void processTableTwo(boolean install) {
365 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
366 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
367 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
368 + FlowRule rule;
369 +
370 + //Drop rule
371 +
372 + treatment.drop();
373 +
374 + rule = new DefaultFlowRule(deviceId, selector.build(),
375 + treatment.build(), DROP_PRIORITY,
376 + appId, 0, true, FlowRule.Type.VLAN);
377 +
378 + ops = install ? ops.add(rule) : ops.remove(rule);
379 +
380 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
381 + @Override
382 + public void onSuccess(FlowRuleOperations ops) {
383 + log.info("Provisioned vlan table for bgp router");
384 + }
385 +
386 + @Override
387 + public void onError(FlowRuleOperations ops) {
388 + log.info("Failed to provision vlan table for bgp router");
389 + }
390 + }));
391 + }
392 +
393 +
394 +
395 + private void processTableThree(boolean install) {
396 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
397 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
398 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
399 + FlowRule rule;
400 +
401 + selector.matchEthType(Ethernet.TYPE_ARP);
402 + treatment.punt();
403 +
404 + rule = new DefaultFlowRule(deviceId, selector.build(),
405 + treatment.build(), CONTROLLER_PRIORITY,
406 + appId, 0, true, FlowRule.Type.ETHER);
407 +
408 + ops = install ? ops.add(rule) : ops.remove(rule);
409 +
410 + selector = DefaultTrafficSelector.builder();
411 + treatment = DefaultTrafficTreatment.builder();
412 +
413 + selector.matchEthType(Ethernet.TYPE_IPV4);
414 + treatment.transition(FlowRule.Type.COS);
415 +
416 + rule = new DefaultFlowRule(deviceId, selector.build(),
417 + treatment.build(), CONTROLLER_PRIORITY,
418 + appId, 0, true, FlowRule.Type.ETHER);
419 +
420 + ops = install ? ops.add(rule) : ops.remove(rule);
421 +
422 + //Drop rule
423 + selector = DefaultTrafficSelector.builder();
424 + treatment = DefaultTrafficTreatment.builder();
425 +
426 + treatment.drop();
427 +
428 + rule = new DefaultFlowRule(deviceId, selector.build(),
429 + treatment.build(), DROP_PRIORITY,
430 + appId, 0, true, FlowRule.Type.VLAN_MPLS);
431 +
432 + ops = install ? ops.add(rule) : ops.remove(rule);
433 +
434 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
435 + @Override
436 + public void onSuccess(FlowRuleOperations ops) {
437 + log.info("Provisioned ether table for bgp router");
438 + }
439 +
440 + @Override
441 + public void onError(FlowRuleOperations ops) {
442 + log.info("Failed to provision ether table for bgp router");
443 + }
444 + }));
445 +
446 +
447 + }
448 +
449 + private void processTableFive(boolean install) {
450 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
451 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
452 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
453 + FlowRule rule;
454 +
455 + treatment.transition(FlowRule.Type.IP);
456 +
457 + rule = new DefaultFlowRule(deviceId, selector.build(),
458 + treatment.build(), DROP_PRIORITY,
459 + appId, 0, true, FlowRule.Type.COS);
460 +
461 + ops = install ? ops.add(rule) : ops.remove(rule);
462 +
463 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
464 + @Override
465 + public void onSuccess(FlowRuleOperations ops) {
466 + log.info("Provisioned cos table for bgp router");
467 + }
468 +
469 + @Override
470 + public void onError(FlowRuleOperations ops) {
471 + log.info("Failed to provision cos table for bgp router");
472 + }
473 + }));
474 +
475 + }
476 +
477 + private void processTableSix(boolean install) {
478 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
479 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
480 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
481 + FlowRule rule;
482 +
483 + //Drop rule
484 +
485 + treatment.drop();
486 +
487 + rule = new DefaultFlowRule(deviceId, selector.build(),
488 + treatment.build(), DROP_PRIORITY,
489 + appId, 0, true, FlowRule.Type.IP);
490 +
491 + ops = install ? ops.add(rule) : ops.remove(rule);
492 +
493 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
494 + @Override
495 + public void onSuccess(FlowRuleOperations ops) {
496 + log.info("Provisioned FIB table for bgp router");
497 + }
498 +
499 + @Override
500 + public void onError(FlowRuleOperations ops) {
501 + log.info("Failed to provision FIB table for bgp router");
502 + }
503 + }));
504 + }
505 +
506 + private void processTableNine(boolean install) {
507 + TrafficSelector.Builder selector = DefaultTrafficSelector.builder();
508 + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder();
509 + FlowRuleOperations.Builder ops = FlowRuleOperations.builder();
510 + FlowRule rule;
511 +
512 + treatment.punt();
513 +
514 + rule = new DefaultFlowRule(deviceId, selector.build(),
515 + treatment.build(), CONTROLLER_PRIORITY,
516 + appId, 0, true, FlowRule.Type.ACL);
517 +
518 + ops = install ? ops.add(rule) : ops.remove(rule);
519 +
520 + flowService.apply(ops.build(new FlowRuleOperationsContext() {
521 + @Override
522 + public void onSuccess(FlowRuleOperations ops) {
523 + log.info("Provisioned Local table for bgp router");
524 + }
525 +
526 + @Override
527 + public void onError(FlowRuleOperations ops) {
528 + log.info("Failed to provision Local table for bgp router");
529 + }
530 + }));
531 + }
532 +
533 + }
227 } 534 }
......
...@@ -134,6 +134,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment { ...@@ -134,6 +134,7 @@ public final class DefaultTrafficTreatment implements TrafficTreatment {
134 case DROP: 134 case DROP:
135 drop = true; 135 drop = true;
136 break; 136 break;
137 + case TABLE:
137 case OUTPUT: 138 case OUTPUT:
138 outputs.add(instruction); 139 outputs.add(instruction);
139 break; 140 break;
......
1 +/*
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 + */
16 +package org.onosproject.store.group.impl;
17 +
18 +import static org.apache.commons.lang3.concurrent.ConcurrentUtils.createIfAbsentUnchecked;
19 +import static org.slf4j.LoggerFactory.getLogger;
20 +
21 +import java.util.ArrayList;
22 +import java.util.HashMap;
23 +import java.util.List;
24 +import java.util.concurrent.ConcurrentHashMap;
25 +import java.util.concurrent.ConcurrentMap;
26 +import java.util.concurrent.atomic.AtomicInteger;
27 +
28 +import org.apache.felix.scr.annotations.Activate;
29 +import org.apache.felix.scr.annotations.Component;
30 +import org.apache.felix.scr.annotations.Deactivate;
31 +import org.apache.felix.scr.annotations.Service;
32 +import org.onlab.util.NewConcurrentHashMap;
33 +import org.onosproject.core.DefaultGroupId;
34 +import org.onosproject.core.GroupId;
35 +import org.onosproject.net.DeviceId;
36 +import org.onosproject.net.group.DefaultGroup;
37 +import org.onosproject.net.group.DefaultGroupDescription;
38 +import org.onosproject.net.group.Group;
39 +import org.onosproject.net.group.Group.GroupState;
40 +import org.onosproject.net.group.GroupBucket;
41 +import org.onosproject.net.group.GroupBuckets;
42 +import org.onosproject.net.group.GroupDescription;
43 +import org.onosproject.net.group.GroupEvent;
44 +import org.onosproject.net.group.GroupEvent.Type;
45 +import org.onosproject.net.group.GroupKey;
46 +import org.onosproject.net.group.GroupOperation;
47 +import org.onosproject.net.group.GroupStore;
48 +import org.onosproject.net.group.GroupStoreDelegate;
49 +import org.onosproject.net.group.StoredGroupEntry;
50 +import org.onosproject.store.AbstractStore;
51 +import org.slf4j.Logger;
52 +
53 +import com.google.common.base.Function;
54 +import com.google.common.collect.FluentIterable;
55 +
56 +/**
57 + * Manages inventory of group entries using trivial in-memory implementation.
58 + */
59 +@Component(immediate = true)
60 +@Service
61 +public class DistributedGroupStore
62 + extends AbstractStore<GroupEvent, GroupStoreDelegate>
63 + implements GroupStore {
64 +
65 + private final Logger log = getLogger(getClass());
66 +
67 + private final int dummyId = 0xffffffff;
68 + private final GroupId dummyGroupId = new DefaultGroupId(dummyId);
69 +
70 + // inner Map is per device group table
71 + private final ConcurrentMap<DeviceId, ConcurrentMap<GroupKey, StoredGroupEntry>>
72 + groupEntriesByKey = new ConcurrentHashMap<>();
73 + private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, StoredGroupEntry>>
74 + groupEntriesById = new ConcurrentHashMap<>();
75 + private final ConcurrentMap<DeviceId, ConcurrentMap<GroupKey, StoredGroupEntry>>
76 + pendingGroupEntriesByKey = new ConcurrentHashMap<>();
77 + private final ConcurrentMap<DeviceId, ConcurrentMap<GroupId, Group>>
78 + extraneousGroupEntriesById = new ConcurrentHashMap<>();
79 +
80 + private final HashMap<DeviceId, Boolean> deviceAuditStatus =
81 + new HashMap<DeviceId, Boolean>();
82 +
83 + private final AtomicInteger groupIdGen = new AtomicInteger();
84 +
85 + @Activate
86 + public void activate() {
87 + log.info("Started");
88 + }
89 +
90 + @Deactivate
91 + public void deactivate() {
92 + groupEntriesByKey.clear();
93 + groupEntriesById.clear();
94 + log.info("Stopped");
95 + }
96 +
97 + private static NewConcurrentHashMap<GroupKey, StoredGroupEntry>
98 + lazyEmptyGroupKeyTable() {
99 + return NewConcurrentHashMap.<GroupKey, StoredGroupEntry>ifNeeded();
100 + }
101 +
102 + private static NewConcurrentHashMap<GroupId, StoredGroupEntry>
103 + lazyEmptyGroupIdTable() {
104 + return NewConcurrentHashMap.<GroupId, StoredGroupEntry>ifNeeded();
105 + }
106 +
107 + private static NewConcurrentHashMap<GroupKey, StoredGroupEntry>
108 + lazyEmptyPendingGroupKeyTable() {
109 + return NewConcurrentHashMap.<GroupKey, StoredGroupEntry>ifNeeded();
110 + }
111 +
112 + private static NewConcurrentHashMap<GroupId, Group>
113 + lazyEmptyExtraneousGroupIdTable() {
114 + return NewConcurrentHashMap.<GroupId, Group>ifNeeded();
115 + }
116 +
117 + /**
118 + * Returns the group key table for specified device.
119 + *
120 + * @param deviceId identifier of the device
121 + * @return Map representing group key table of given device.
122 + */
123 + private ConcurrentMap<GroupKey, StoredGroupEntry> getGroupKeyTable(DeviceId deviceId) {
124 + return createIfAbsentUnchecked(groupEntriesByKey,
125 + deviceId, lazyEmptyGroupKeyTable());
126 + }
127 +
128 + /**
129 + * Returns the group id table for specified device.
130 + *
131 + * @param deviceId identifier of the device
132 + * @return Map representing group key table of given device.
133 + */
134 + private ConcurrentMap<GroupId, StoredGroupEntry> getGroupIdTable(DeviceId deviceId) {
135 + return createIfAbsentUnchecked(groupEntriesById,
136 + deviceId, lazyEmptyGroupIdTable());
137 + }
138 +
139 + /**
140 + * Returns the pending group key table for specified device.
141 + *
142 + * @param deviceId identifier of the device
143 + * @return Map representing group key table of given device.
144 + */
145 + private ConcurrentMap<GroupKey, StoredGroupEntry>
146 + getPendingGroupKeyTable(DeviceId deviceId) {
147 + return createIfAbsentUnchecked(pendingGroupEntriesByKey,
148 + deviceId, lazyEmptyPendingGroupKeyTable());
149 + }
150 +
151 + /**
152 + * Returns the extraneous group id table for specified device.
153 + *
154 + * @param deviceId identifier of the device
155 + * @return Map representing group key table of given device.
156 + */
157 + private ConcurrentMap<GroupId, Group>
158 + getExtraneousGroupIdTable(DeviceId deviceId) {
159 + return createIfAbsentUnchecked(extraneousGroupEntriesById,
160 + deviceId,
161 + lazyEmptyExtraneousGroupIdTable());
162 + }
163 +
164 + /**
165 + * Returns the number of groups for the specified device in the store.
166 + *
167 + * @return number of groups for the specified device
168 + */
169 + @Override
170 + public int getGroupCount(DeviceId deviceId) {
171 + return (groupEntriesByKey.get(deviceId) != null) ?
172 + groupEntriesByKey.get(deviceId).size() : 0;
173 + }
174 +
175 + /**
176 + * Returns the groups associated with a device.
177 + *
178 + * @param deviceId the device ID
179 + *
180 + * @return the group entries
181 + */
182 + @Override
183 + public Iterable<Group> getGroups(DeviceId deviceId) {
184 + // flatten and make iterator unmodifiable
185 + return FluentIterable.from(getGroupKeyTable(deviceId).values())
186 + .transform(
187 + new Function<StoredGroupEntry, Group>() {
188 +
189 + @Override
190 + public Group apply(
191 + StoredGroupEntry input) {
192 + return input;
193 + }
194 + });
195 + }
196 +
197 + /**
198 + * Returns the stored group entry.
199 + *
200 + * @param deviceId the device ID
201 + * @param appCookie the group key
202 + *
203 + * @return a group associated with the key
204 + */
205 + @Override
206 + public Group getGroup(DeviceId deviceId, GroupKey appCookie) {
207 + return (groupEntriesByKey.get(deviceId) != null) ?
208 + groupEntriesByKey.get(deviceId).get(appCookie) :
209 + null;
210 + }
211 +
212 + private int getFreeGroupIdValue(DeviceId deviceId) {
213 + int freeId = groupIdGen.incrementAndGet();
214 +
215 + while (true) {
216 + Group existing = (
217 + groupEntriesById.get(deviceId) != null) ?
218 + groupEntriesById.get(deviceId).get(new DefaultGroupId(freeId)) :
219 + null;
220 + if (existing == null) {
221 + existing = (
222 + extraneousGroupEntriesById.get(deviceId) != null) ?
223 + extraneousGroupEntriesById.get(deviceId).
224 + get(new DefaultGroupId(freeId)) :
225 + null;
226 + }
227 + if (existing != null) {
228 + freeId = groupIdGen.incrementAndGet();
229 + } else {
230 + break;
231 + }
232 + }
233 + return freeId;
234 + }
235 +
236 + /**
237 + * Stores a new group entry using the information from group description.
238 + *
239 + * @param groupDesc group description to be used to create group entry
240 + */
241 + @Override
242 + public void storeGroupDescription(GroupDescription groupDesc) {
243 + // Check if a group is existing with the same key
244 + if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) {
245 + return;
246 + }
247 +
248 + if (deviceAuditStatus.get(groupDesc.deviceId()) == null) {
249 + // Device group audit has not completed yet
250 + // Add this group description to pending group key table
251 + // Create a group entry object with Dummy Group ID
252 + StoredGroupEntry group = new DefaultGroup(dummyGroupId, groupDesc);
253 + group.setState(GroupState.WAITING_AUDIT_COMPLETE);
254 + ConcurrentMap<GroupKey, StoredGroupEntry> pendingKeyTable =
255 + getPendingGroupKeyTable(groupDesc.deviceId());
256 + pendingKeyTable.put(groupDesc.appCookie(), group);
257 + return;
258 + }
259 +
260 + storeGroupDescriptionInternal(groupDesc);
261 + }
262 +
263 + private void storeGroupDescriptionInternal(GroupDescription groupDesc) {
264 + // Check if a group is existing with the same key
265 + if (getGroup(groupDesc.deviceId(), groupDesc.appCookie()) != null) {
266 + return;
267 + }
268 +
269 + // Get a new group identifier
270 + GroupId id = new DefaultGroupId(getFreeGroupIdValue(groupDesc.deviceId()));
271 + // Create a group entry object
272 + StoredGroupEntry group = new DefaultGroup(id, groupDesc);
273 + // Insert the newly created group entry into concurrent key and id maps
274 + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
275 + getGroupKeyTable(groupDesc.deviceId());
276 + keyTable.put(groupDesc.appCookie(), group);
277 + ConcurrentMap<GroupId, StoredGroupEntry> idTable =
278 + getGroupIdTable(groupDesc.deviceId());
279 + idTable.put(id, group);
280 + notifyDelegate(new GroupEvent(GroupEvent.Type.GROUP_ADD_REQUESTED,
281 + group));
282 + }
283 +
284 + /**
285 + * Updates the existing group entry with the information
286 + * from group description.
287 + *
288 + * @param deviceId the device ID
289 + * @param oldAppCookie the current group key
290 + * @param type update type
291 + * @param newBuckets group buckets for updates
292 + * @param newAppCookie optional new group key
293 + */
294 + @Override
295 + public void updateGroupDescription(DeviceId deviceId,
296 + GroupKey oldAppCookie,
297 + UpdateType type,
298 + GroupBuckets newBuckets,
299 + GroupKey newAppCookie) {
300 + // Check if a group is existing with the provided key
301 + Group oldGroup = getGroup(deviceId, oldAppCookie);
302 + if (oldGroup == null) {
303 + return;
304 + }
305 +
306 + List<GroupBucket> newBucketList = getUpdatedBucketList(oldGroup,
307 + type,
308 + newBuckets);
309 + if (newBucketList != null) {
310 + // Create a new group object from the old group
311 + GroupBuckets updatedBuckets = new GroupBuckets(newBucketList);
312 + GroupKey newCookie = (newAppCookie != null) ? newAppCookie : oldAppCookie;
313 + GroupDescription updatedGroupDesc = new DefaultGroupDescription(
314 + oldGroup.deviceId(),
315 + oldGroup.type(),
316 + updatedBuckets,
317 + newCookie,
318 + oldGroup.appId());
319 + StoredGroupEntry newGroup = new DefaultGroup(oldGroup.id(),
320 + updatedGroupDesc);
321 + newGroup.setState(GroupState.PENDING_UPDATE);
322 + newGroup.setLife(oldGroup.life());
323 + newGroup.setPackets(oldGroup.packets());
324 + newGroup.setBytes(oldGroup.bytes());
325 + // Remove the old entry from maps and add new entry using new key
326 + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
327 + getGroupKeyTable(oldGroup.deviceId());
328 + ConcurrentMap<GroupId, StoredGroupEntry> idTable =
329 + getGroupIdTable(oldGroup.deviceId());
330 + keyTable.remove(oldGroup.appCookie());
331 + idTable.remove(oldGroup.id());
332 + keyTable.put(newGroup.appCookie(), newGroup);
333 + idTable.put(newGroup.id(), newGroup);
334 + notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_REQUESTED, newGroup));
335 + }
336 + }
337 +
338 + private List<GroupBucket> getUpdatedBucketList(Group oldGroup,
339 + UpdateType type,
340 + GroupBuckets buckets) {
341 + GroupBuckets oldBuckets = oldGroup.buckets();
342 + List<GroupBucket> newBucketList = new ArrayList<GroupBucket>(
343 + oldBuckets.buckets());
344 + boolean groupDescUpdated = false;
345 +
346 + if (type == UpdateType.ADD) {
347 + // Check if the any of the new buckets are part of
348 + // the old bucket list
349 + for (GroupBucket addBucket:buckets.buckets()) {
350 + if (!newBucketList.contains(addBucket)) {
351 + newBucketList.add(addBucket);
352 + groupDescUpdated = true;
353 + }
354 + }
355 + } else if (type == UpdateType.REMOVE) {
356 + // Check if the to be removed buckets are part of the
357 + // old bucket list
358 + for (GroupBucket removeBucket:buckets.buckets()) {
359 + if (newBucketList.contains(removeBucket)) {
360 + newBucketList.remove(removeBucket);
361 + groupDescUpdated = true;
362 + }
363 + }
364 + }
365 +
366 + if (groupDescUpdated) {
367 + return newBucketList;
368 + } else {
369 + return null;
370 + }
371 + }
372 +
373 + /**
374 + * Triggers deleting the existing group entry.
375 + *
376 + * @param deviceId the device ID
377 + * @param appCookie the group key
378 + */
379 + @Override
380 + public void deleteGroupDescription(DeviceId deviceId,
381 + GroupKey appCookie) {
382 + // Check if a group is existing with the provided key
383 + StoredGroupEntry existing = (groupEntriesByKey.get(deviceId) != null) ?
384 + groupEntriesByKey.get(deviceId).get(appCookie) :
385 + null;
386 + if (existing == null) {
387 + return;
388 + }
389 +
390 + synchronized (existing) {
391 + existing.setState(GroupState.PENDING_DELETE);
392 + }
393 + notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, existing));
394 + }
395 +
396 + /**
397 + * Stores a new group entry, or updates an existing entry.
398 + *
399 + * @param group group entry
400 + */
401 + @Override
402 + public void addOrUpdateGroupEntry(Group group) {
403 + // check if this new entry is an update to an existing entry
404 + StoredGroupEntry existing = (groupEntriesById.get(
405 + group.deviceId()) != null) ?
406 + groupEntriesById.get(group.deviceId()).get(group.id()) :
407 + null;
408 + GroupEvent event = null;
409 +
410 + if (existing != null) {
411 + synchronized (existing) {
412 + existing.setLife(group.life());
413 + existing.setPackets(group.packets());
414 + existing.setBytes(group.bytes());
415 + if (existing.state() == GroupState.PENDING_ADD) {
416 + existing.setState(GroupState.ADDED);
417 + event = new GroupEvent(Type.GROUP_ADDED, existing);
418 + } else {
419 + if (existing.state() == GroupState.PENDING_UPDATE) {
420 + existing.setState(GroupState.PENDING_UPDATE);
421 + }
422 + event = new GroupEvent(Type.GROUP_UPDATED, existing);
423 + }
424 + }
425 + }
426 +
427 + if (event != null) {
428 + notifyDelegate(event);
429 + }
430 + }
431 +
432 + /**
433 + * Removes the group entry from store.
434 + *
435 + * @param group group entry
436 + */
437 + @Override
438 + public void removeGroupEntry(Group group) {
439 + StoredGroupEntry existing = (groupEntriesById.get(
440 + group.deviceId()) != null) ?
441 + groupEntriesById.get(group.deviceId()).get(group.id()) :
442 + null;
443 +
444 + if (existing != null) {
445 + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
446 + getGroupKeyTable(existing.deviceId());
447 + ConcurrentMap<GroupId, StoredGroupEntry> idTable =
448 + getGroupIdTable(existing.deviceId());
449 + idTable.remove(existing.id());
450 + keyTable.remove(existing.appCookie());
451 + notifyDelegate(new GroupEvent(Type.GROUP_REMOVED, existing));
452 + }
453 + }
454 +
455 + @Override
456 + public void deviceInitialAuditCompleted(DeviceId deviceId,
457 + boolean completed) {
458 + synchronized (deviceAuditStatus) {
459 + if (completed) {
460 + log.debug("deviceInitialAuditCompleted: AUDIT "
461 + + "completed for device {}", deviceId);
462 + deviceAuditStatus.put(deviceId, true);
463 + // Execute all pending group requests
464 + ConcurrentMap<GroupKey, StoredGroupEntry> pendingGroupRequests =
465 + getPendingGroupKeyTable(deviceId);
466 + for (Group group:pendingGroupRequests.values()) {
467 + GroupDescription tmp = new DefaultGroupDescription(
468 + group.deviceId(),
469 + group.type(),
470 + group.buckets(),
471 + group.appCookie(),
472 + group.appId());
473 + storeGroupDescriptionInternal(tmp);
474 + }
475 + getPendingGroupKeyTable(deviceId).clear();
476 + } else {
477 + if (deviceAuditStatus.get(deviceId)) {
478 + log.debug("deviceInitialAuditCompleted: Clearing AUDIT "
479 + + "status for device {}", deviceId);
480 + deviceAuditStatus.put(deviceId, false);
481 + }
482 + }
483 + }
484 + }
485 +
486 + @Override
487 + public boolean deviceInitialAuditStatus(DeviceId deviceId) {
488 + synchronized (deviceAuditStatus) {
489 + return (deviceAuditStatus.get(deviceId) != null)
490 + ? deviceAuditStatus.get(deviceId) : false;
491 + }
492 + }
493 +
494 + @Override
495 + public void groupOperationFailed(DeviceId deviceId, GroupOperation operation) {
496 +
497 + StoredGroupEntry existing = (groupEntriesById.get(
498 + deviceId) != null) ?
499 + groupEntriesById.get(deviceId).get(operation.groupId()) :
500 + null;
501 +
502 + if (existing == null) {
503 + log.warn("No group entry with ID {} found ", operation.groupId());
504 + return;
505 + }
506 +
507 + switch (operation.opType()) {
508 + case ADD:
509 + notifyDelegate(new GroupEvent(Type.GROUP_ADD_FAILED, existing));
510 + break;
511 + case MODIFY:
512 + notifyDelegate(new GroupEvent(Type.GROUP_UPDATE_FAILED, existing));
513 + break;
514 + case DELETE:
515 + notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_FAILED, existing));
516 + break;
517 + default:
518 + log.warn("Unknown group operation type {}", operation.opType());
519 + }
520 +
521 + ConcurrentMap<GroupKey, StoredGroupEntry> keyTable =
522 + getGroupKeyTable(existing.deviceId());
523 + ConcurrentMap<GroupId, StoredGroupEntry> idTable =
524 + getGroupIdTable(existing.deviceId());
525 + idTable.remove(existing.id());
526 + keyTable.remove(existing.appCookie());
527 + }
528 +
529 + @Override
530 + public void addOrUpdateExtraneousGroupEntry(Group group) {
531 + ConcurrentMap<GroupId, Group> extraneousIdTable =
532 + getExtraneousGroupIdTable(group.deviceId());
533 + extraneousIdTable.put(group.id(), group);
534 + // Check the reference counter
535 + if (group.referenceCount() == 0) {
536 + notifyDelegate(new GroupEvent(Type.GROUP_REMOVE_REQUESTED, group));
537 + }
538 + }
539 +
540 + @Override
541 + public void removeExtraneousGroupEntry(Group group) {
542 + ConcurrentMap<GroupId, Group> extraneousIdTable =
543 + getExtraneousGroupIdTable(group.deviceId());
544 + extraneousIdTable.remove(group.id());
545 + }
546 +
547 + @Override
548 + public Iterable<Group> getExtraneousGroups(DeviceId deviceId) {
549 + // flatten and make iterator unmodifiable
550 + return FluentIterable.from(
551 + getExtraneousGroupIdTable(deviceId).values());
552 + }
553 +
554 +
555 +}
...@@ -17,7 +17,6 @@ package org.onosproject.openflow.drivers; ...@@ -17,7 +17,6 @@ package org.onosproject.openflow.drivers;
17 17
18 import com.google.common.collect.Lists; 18 import com.google.common.collect.Lists;
19 import org.onosproject.openflow.controller.Dpid; 19 import org.onosproject.openflow.controller.Dpid;
20 -import org.onosproject.openflow.controller.RoleState;
21 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch; 20 import org.onosproject.openflow.controller.driver.AbstractOpenFlowSwitch;
22 import org.projectfloodlight.openflow.protocol.OFDescStatsReply; 21 import org.projectfloodlight.openflow.protocol.OFDescStatsReply;
23 import org.projectfloodlight.openflow.protocol.OFFlowMod; 22 import org.projectfloodlight.openflow.protocol.OFFlowMod;
...@@ -43,8 +42,6 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch { ...@@ -43,8 +42,6 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
43 private static final int FIB_TABLE = 6; 42 private static final int FIB_TABLE = 6;
44 private static final int LOCAL_TABLE = 9; 43 private static final int LOCAL_TABLE = 9;
45 44
46 -
47 -
48 OFCorsaSwitchDriver(Dpid dpid, OFDescStatsReply desc) { 45 OFCorsaSwitchDriver(Dpid dpid, OFDescStatsReply desc) {
49 super(dpid); 46 super(dpid);
50 47
...@@ -58,10 +55,7 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch { ...@@ -58,10 +55,7 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
58 55
59 @Override 56 @Override
60 public void write(List<OFMessage> msgs) { 57 public void write(List<OFMessage> msgs) {
61 - if (role == RoleState.MASTER) {
62 channel.write(msgs); 58 channel.write(msgs);
63 - }
64 -
65 } 59 }
66 60
67 @Override 61 @Override
...@@ -152,7 +146,9 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch { ...@@ -152,7 +146,9 @@ public class OFCorsaSwitchDriver extends AbstractOpenFlowSwitch {
152 default: 146 default:
153 log.warn("Unknown table type: {}", type); 147 log.warn("Unknown table type: {}", type);
154 } 148 }
149 + builder.setInstructions(newInstructions);
155 this.write(builder.build()); 150 this.write(builder.build());
151 + log.info("Installed {}", builder.build());
156 } else { 152 } else {
157 this.write(msg); 153 this.write(msg);
158 } 154 }
......
...@@ -55,7 +55,7 @@ import java.util.Optional; ...@@ -55,7 +55,7 @@ import java.util.Optional;
55 */ 55 */
56 public class FlowModBuilderVer10 extends FlowModBuilder { 56 public class FlowModBuilderVer10 extends FlowModBuilder {
57 57
58 - private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class); 58 + private final Logger log = LoggerFactory.getLogger(getClass());
59 private static final int OFPCML_NO_BUFFER = 0xffff; 59 private static final int OFPCML_NO_BUFFER = 0xffff;
60 60
61 private final TrafficTreatment treatment; 61 private final TrafficTreatment treatment;
......
...@@ -74,7 +74,7 @@ import java.util.Optional; ...@@ -74,7 +74,7 @@ import java.util.Optional;
74 */ 74 */
75 public class FlowModBuilderVer13 extends FlowModBuilder { 75 public class FlowModBuilderVer13 extends FlowModBuilder {
76 76
77 - private static final Logger log = LoggerFactory.getLogger(FlowModBuilderVer10.class); 77 + private final Logger log = LoggerFactory.getLogger(getClass());
78 private static final int OFPCML_NO_BUFFER = 0xffff; 78 private static final int OFPCML_NO_BUFFER = 0xffff;
79 79
80 private final TrafficTreatment treatment; 80 private final TrafficTreatment treatment;
...@@ -118,6 +118,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -118,6 +118,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
118 .setMatch(match) 118 .setMatch(match)
119 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 119 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
120 .setPriority(flowRule().priority()) 120 .setPriority(flowRule().priority())
121 + .setTableId(TableId.of(flowRule().type().ordinal()))
121 .build(); 122 .build();
122 123
123 return fm; 124 return fm;
...@@ -144,6 +145,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -144,6 +145,7 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
144 .setMatch(match) 145 .setMatch(match)
145 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM)) 146 .setFlags(Collections.singleton(OFFlowModFlags.SEND_FLOW_REM))
146 .setPriority(flowRule().priority()) 147 .setPriority(flowRule().priority())
148 + .setTableId(TableId.of(flowRule().type().ordinal()))
147 .build(); 149 .build();
148 150
149 return fm; 151 return fm;
...@@ -219,6 +221,9 @@ public class FlowModBuilderVer13 extends FlowModBuilder { ...@@ -219,6 +221,9 @@ public class FlowModBuilderVer13 extends FlowModBuilder {
219 .setGroup(OFGroup.of(group.groupId().id())); 221 .setGroup(OFGroup.of(group.groupId().id()));
220 actions.add(groupBuilder.build()); 222 actions.add(groupBuilder.build());
221 break; 223 break;
224 + case TABLE:
225 + //FIXME: should not occur here.
226 + break;
222 default: 227 default:
223 log.warn("Instruction type {} not yet implemented.", i.type()); 228 log.warn("Instruction type {} not yet implemented.", i.type());
224 } 229 }
......
...@@ -36,6 +36,7 @@ public class Ethernet extends BasePacket { ...@@ -36,6 +36,7 @@ public class Ethernet extends BasePacket {
36 public static final short TYPE_IPV4 = (short) 0x0800; 36 public static final short TYPE_IPV4 = (short) 0x0800;
37 public static final short TYPE_IPV6 = (short) 0x86dd; 37 public static final short TYPE_IPV6 = (short) 0x86dd;
38 public static final short TYPE_LLDP = (short) 0x88cc; 38 public static final short TYPE_LLDP = (short) 0x88cc;
39 + public static final short TYPE_VLAN = (short) 0x8100;
39 public static final short TYPE_BSN = (short) 0x8942; 40 public static final short TYPE_BSN = (short) 0x8942;
40 public static final short VLAN_UNTAGGED = (short) 0xffff; 41 public static final short VLAN_UNTAGGED = (short) 0xffff;
41 public static final short MPLS_UNICAST = (short) 0x8847; 42 public static final short MPLS_UNICAST = (short) 0x8847;
...@@ -284,7 +285,7 @@ public class Ethernet extends BasePacket { ...@@ -284,7 +285,7 @@ public class Ethernet extends BasePacket {
284 bb.put(this.destinationMACAddress.toBytes()); 285 bb.put(this.destinationMACAddress.toBytes());
285 bb.put(this.sourceMACAddress.toBytes()); 286 bb.put(this.sourceMACAddress.toBytes());
286 if (this.vlanID != Ethernet.VLAN_UNTAGGED) { 287 if (this.vlanID != Ethernet.VLAN_UNTAGGED) {
287 - bb.putShort((short) 0x8100); 288 + bb.putShort(TYPE_VLAN);
288 bb.putShort((short) (this.priorityCode << 13 | this.vlanID & 0x0fff)); 289 bb.putShort((short) (this.priorityCode << 13 | this.vlanID & 0x0fff));
289 } 290 }
290 bb.putShort(this.etherType); 291 bb.putShort(this.etherType);
...@@ -319,7 +320,7 @@ public class Ethernet extends BasePacket { ...@@ -319,7 +320,7 @@ public class Ethernet extends BasePacket {
319 this.sourceMACAddress = MacAddress.valueOf(srcAddr); 320 this.sourceMACAddress = MacAddress.valueOf(srcAddr);
320 321
321 short ethType = bb.getShort(); 322 short ethType = bb.getShort();
322 - if (ethType == (short) 0x8100) { 323 + if (ethType == TYPE_VLAN) {
323 final short tci = bb.getShort(); 324 final short tci = bb.getShort();
324 this.priorityCode = (byte) (tci >> 13 & 0x07); 325 this.priorityCode = (byte) (tci >> 13 & 0x07);
325 this.vlanID = (short) (tci & 0x0fff); 326 this.vlanID = (short) (tci & 0x0fff);
......