Committed by
Jonathan Hart
WIP: Started implementing static flows for corsa vanderweken pipeline.
Modified to not use Corsa driver by default. Change-Id: If8df5769cf084346121d34bf4490f578e6b6f2d0
Showing
7 changed files
with
876 additions
and
11 deletions
... | @@ -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; | ... | ... |
core/store/dist/src/main/java/org/onosproject/store/group/impl/DistributedGroupStore.java
0 → 100644
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 | } | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer10.java
... | @@ -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; | ... | ... |
providers/openflow/flow/src/main/java/org/onosproject/provider/of/flow/impl/FlowModBuilderVer13.java
... | @@ -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); | ... | ... |
-
Please register or login to post a comment