Improvements for the ofdpa driver.
New driver for ofdpa emulation with cpqd switch. Change-Id: I5221069e07abe57538d4e988cdb7190b50c595f7
Showing
3 changed files
with
184 additions
and
116 deletions
1 | +package org.onosproject.driver.pipeline; | ||
2 | + | ||
3 | +import static org.slf4j.LoggerFactory.getLogger; | ||
4 | + | ||
5 | +import org.onosproject.net.flow.DefaultFlowRule; | ||
6 | +import org.onosproject.net.flow.DefaultTrafficSelector; | ||
7 | +import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
8 | +import org.onosproject.net.flow.FlowRule; | ||
9 | +import org.onosproject.net.flow.FlowRuleOperations; | ||
10 | +import org.onosproject.net.flow.FlowRuleOperationsContext; | ||
11 | +import org.onosproject.net.flow.TrafficSelector; | ||
12 | +import org.onosproject.net.flow.TrafficTreatment; | ||
13 | +import org.slf4j.Logger; | ||
14 | + | ||
15 | + | ||
16 | +/** | ||
17 | + * Driver for software switch emulation of the OFDPA 1.0 pipeline. | ||
18 | + * The software switch is the CPqD OF 1.3 switch. | ||
19 | + */ | ||
20 | +public class CpqdOFDPA1Pipeline extends OFDPA1Pipeline { | ||
21 | + | ||
22 | + private final Logger log = getLogger(getClass()); | ||
23 | + | ||
24 | + @Override | ||
25 | + protected void initializePipeline() { | ||
26 | + processPortTable(); | ||
27 | + //processVlanTable(); | ||
28 | + processTmacTable(); | ||
29 | + processIpTable(); | ||
30 | + //processMcastTable(); | ||
31 | + processBridgingTable(); | ||
32 | + //processAclTable(); | ||
33 | + //processGroupTable(); | ||
34 | + } | ||
35 | + | ||
36 | + @Override | ||
37 | + protected void processPortTable() { | ||
38 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
39 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
40 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
41 | + treatment.transition(VLAN_TABLE); | ||
42 | + FlowRule tmisse = DefaultFlowRule.builder() | ||
43 | + .forDevice(deviceId) | ||
44 | + .withSelector(selector.build()) | ||
45 | + .withTreatment(treatment.build()) | ||
46 | + .withPriority(LOWEST_PRIORITY) | ||
47 | + .fromApp(driverId) | ||
48 | + .makePermanent() | ||
49 | + .forTable(PORT_TABLE).build(); | ||
50 | + ops = ops.add(tmisse); | ||
51 | + | ||
52 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
53 | + @Override | ||
54 | + public void onSuccess(FlowRuleOperations ops) { | ||
55 | + log.info("Initialized port table"); | ||
56 | + } | ||
57 | + | ||
58 | + @Override | ||
59 | + public void onError(FlowRuleOperations ops) { | ||
60 | + log.info("Failed to initialize port table"); | ||
61 | + } | ||
62 | + })); | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + protected void processTmacTable() { | ||
67 | + //table miss entry | ||
68 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
69 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
70 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
71 | + selector = DefaultTrafficSelector.builder(); | ||
72 | + treatment = DefaultTrafficTreatment.builder(); | ||
73 | + treatment.transition(BRIDGING_TABLE); | ||
74 | + FlowRule rule = DefaultFlowRule.builder() | ||
75 | + .forDevice(deviceId) | ||
76 | + .withSelector(selector.build()) | ||
77 | + .withTreatment(treatment.build()) | ||
78 | + .withPriority(LOWEST_PRIORITY) | ||
79 | + .fromApp(driverId) | ||
80 | + .makePermanent() | ||
81 | + .forTable(TMAC_TABLE).build(); | ||
82 | + ops = ops.add(rule); | ||
83 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
84 | + @Override | ||
85 | + public void onSuccess(FlowRuleOperations ops) { | ||
86 | + log.info("Initialized tmac table"); | ||
87 | + } | ||
88 | + | ||
89 | + @Override | ||
90 | + public void onError(FlowRuleOperations ops) { | ||
91 | + log.info("Failed to initialize tmac table"); | ||
92 | + } | ||
93 | + })); | ||
94 | + } | ||
95 | + | ||
96 | + @Override | ||
97 | + protected void processIpTable() { | ||
98 | + //table miss entry | ||
99 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
100 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
101 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
102 | + selector = DefaultTrafficSelector.builder(); | ||
103 | + treatment = DefaultTrafficTreatment.builder(); | ||
104 | + treatment.transition(ACL_TABLE); | ||
105 | + FlowRule rule = DefaultFlowRule.builder() | ||
106 | + .forDevice(deviceId) | ||
107 | + .withSelector(selector.build()) | ||
108 | + .withTreatment(treatment.build()) | ||
109 | + .withPriority(LOWEST_PRIORITY) | ||
110 | + .fromApp(driverId) | ||
111 | + .makePermanent() | ||
112 | + .forTable(UNICAST_ROUTING_TABLE).build(); | ||
113 | + ops = ops.add(rule); | ||
114 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
115 | + @Override | ||
116 | + public void onSuccess(FlowRuleOperations ops) { | ||
117 | + log.info("Initialized IP table"); | ||
118 | + } | ||
119 | + | ||
120 | + @Override | ||
121 | + public void onError(FlowRuleOperations ops) { | ||
122 | + log.info("Failed to initialize unicast IP table"); | ||
123 | + } | ||
124 | + })); | ||
125 | + } | ||
126 | + | ||
127 | + private void processBridgingTable() { | ||
128 | + //table miss entry | ||
129 | + FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
130 | + TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
131 | + TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
132 | + selector = DefaultTrafficSelector.builder(); | ||
133 | + treatment = DefaultTrafficTreatment.builder(); | ||
134 | + treatment.transition(ACL_TABLE); | ||
135 | + FlowRule rule = DefaultFlowRule.builder() | ||
136 | + .forDevice(deviceId) | ||
137 | + .withSelector(selector.build()) | ||
138 | + .withTreatment(treatment.build()) | ||
139 | + .withPriority(LOWEST_PRIORITY) | ||
140 | + .fromApp(driverId) | ||
141 | + .makePermanent() | ||
142 | + .forTable(BRIDGING_TABLE).build(); | ||
143 | + ops = ops.add(rule); | ||
144 | + flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
145 | + @Override | ||
146 | + public void onSuccess(FlowRuleOperations ops) { | ||
147 | + log.info("Initialized Bridging table"); | ||
148 | + } | ||
149 | + | ||
150 | + @Override | ||
151 | + public void onError(FlowRuleOperations ops) { | ||
152 | + log.info("Failed to initialize Bridging table"); | ||
153 | + } | ||
154 | + })); | ||
155 | + | ||
156 | + } | ||
157 | + | ||
158 | +} |
... | @@ -105,7 +105,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -105,7 +105,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
105 | 105 | ||
106 | private static final int HIGHEST_PRIORITY = 0xffff; | 106 | private static final int HIGHEST_PRIORITY = 0xffff; |
107 | private static final int DEFAULT_PRIORITY = 0x8000; | 107 | private static final int DEFAULT_PRIORITY = 0x8000; |
108 | - private static final int LOWEST_PRIORITY = 0x0; | 108 | + protected static final int LOWEST_PRIORITY = 0x0; |
109 | 109 | ||
110 | /* | 110 | /* |
111 | * Group keys are normally generated by using the next Objective id. In the | 111 | * Group keys are normally generated by using the next Objective id. In the |
... | @@ -130,12 +130,12 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -130,12 +130,12 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
130 | 130 | ||
131 | private final Logger log = getLogger(getClass()); | 131 | private final Logger log = getLogger(getClass()); |
132 | private ServiceDirectory serviceDirectory; | 132 | private ServiceDirectory serviceDirectory; |
133 | - private FlowRuleService flowRuleService; | 133 | + protected FlowRuleService flowRuleService; |
134 | private CoreService coreService; | 134 | private CoreService coreService; |
135 | private GroupService groupService; | 135 | private GroupService groupService; |
136 | private FlowObjectiveStore flowObjectiveStore; | 136 | private FlowObjectiveStore flowObjectiveStore; |
137 | - private DeviceId deviceId; | 137 | + protected DeviceId deviceId; |
138 | - private ApplicationId driverId; | 138 | + protected ApplicationId driverId; |
139 | 139 | ||
140 | private KryoNamespace appKryo = new KryoNamespace.Builder() | 140 | private KryoNamespace appKryo = new KryoNamespace.Builder() |
141 | .register(KryoNamespaces.API) | 141 | .register(KryoNamespaces.API) |
... | @@ -610,7 +610,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -610,7 +610,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
610 | } | 610 | } |
611 | 611 | ||
612 | 612 | ||
613 | - private void initializePipeline() { | 613 | + protected void initializePipeline() { |
614 | processPortTable(); | 614 | processPortTable(); |
615 | processVlanTable(); | 615 | processVlanTable(); |
616 | processTmacTable(); | 616 | processTmacTable(); |
... | @@ -621,7 +621,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -621,7 +621,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
621 | //processGroupTable(); | 621 | //processGroupTable(); |
622 | } | 622 | } |
623 | 623 | ||
624 | - private void processPortTable() { | 624 | + protected void processPortTable() { |
625 | //XXX is table miss entry enough or do we need to do the maskable in-port 0? | 625 | //XXX is table miss entry enough or do we need to do the maskable in-port 0? |
626 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 626 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
627 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 627 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
... | @@ -653,56 +653,12 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -653,56 +653,12 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
653 | } | 653 | } |
654 | 654 | ||
655 | private void processVlanTable() { | 655 | private void processVlanTable() { |
656 | - // make these up for now - should really be filtering rules | ||
657 | - /*FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | ||
658 | - TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | ||
659 | - TrafficTreatment.Builder treatment = DefaultTrafficTreatment.builder(); | ||
660 | - selector.matchInPort(PortNumber.portNumber(10)); | ||
661 | - selector.matchVlanId(VlanId.vlanId((short) 100)); | ||
662 | - treatment.transition(TMAC_TABLE); | ||
663 | - FlowRule rule = DefaultFlowRule.builder() | ||
664 | - .forDevice(deviceId) | ||
665 | - .withSelector(selector.build()) | ||
666 | - .withTreatment(treatment.build()) | ||
667 | - .withPriority(DEFAULT_PRIORITY) | ||
668 | - .fromApp(appId) | ||
669 | - .makePermanent() | ||
670 | - .forTable(VLAN_TABLE).build(); | ||
671 | - ops = ops.add(rule); | ||
672 | - flowRuleService.apply(ops.build(new FlowRuleOperationsContext() { | ||
673 | - @Override | ||
674 | - public void onSuccess(FlowRuleOperations ops) { | ||
675 | - log.info("Initialized vlan table"); | ||
676 | - } | ||
677 | - | ||
678 | - @Override | ||
679 | - public void onError(FlowRuleOperations ops) { | ||
680 | - log.info("Failed to initialize vlan table"); | ||
681 | - } | ||
682 | - }));*/ | ||
683 | - | ||
684 | // Table miss entry is not required as ofdpa default is to drop | 656 | // Table miss entry is not required as ofdpa default is to drop |
685 | // In OF terms, the absence of a t.m.e. also implies drop | 657 | // In OF terms, the absence of a t.m.e. also implies drop |
686 | } | 658 | } |
687 | 659 | ||
688 | 660 | ||
689 | - private void processTmacTable() { | 661 | + protected void processTmacTable() { |
690 | - // this is made up as well -- should be a filtering rule | ||
691 | - /*selector.matchInPort(PortNumber.portNumber(10)); | ||
692 | - selector.matchVlanId(VlanId.vlanId((short) 100)); | ||
693 | - selector.matchEthType(Ethernet.TYPE_IPV4); | ||
694 | - selector.matchEthDst(MacAddress.valueOf("00:00:00:ba:ba:00")); | ||
695 | - treatment.transition(UNICAST_ROUTING_TABLE); | ||
696 | - FlowRule rule = DefaultFlowRule.builder() | ||
697 | - .forDevice(deviceId) | ||
698 | - .withSelector(selector.build()) | ||
699 | - .withTreatment(treatment.build()) | ||
700 | - .withPriority(DEFAULT_PRIORITY) | ||
701 | - .fromApp(appId) | ||
702 | - .makePermanent() | ||
703 | - .forTable(TMAC_TABLE).build(); | ||
704 | - ops = ops.add(rule);*/ | ||
705 | - | ||
706 | //table miss entry | 662 | //table miss entry |
707 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 663 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
708 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 664 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
... | @@ -732,7 +688,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -732,7 +688,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
732 | }));*/ | 688 | }));*/ |
733 | } | 689 | } |
734 | 690 | ||
735 | - private void processIpTable() { | 691 | + protected void processIpTable() { |
736 | //table miss entry | 692 | //table miss entry |
737 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); | 693 | FlowRuleOperations.Builder ops = FlowRuleOperations.builder(); |
738 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); | 694 | TrafficSelector.Builder selector = DefaultTrafficSelector.builder(); |
... | @@ -762,72 +718,16 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -762,72 +718,16 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
762 | }));*/ | 718 | }));*/ |
763 | } | 719 | } |
764 | 720 | ||
765 | - @SuppressWarnings("unused") | ||
766 | - private void processGroupTable() { | ||
767 | - // Creating a dummy L2 group as per OFDPA requirements | ||
768 | - /* TrafficTreatment treatment = DefaultTrafficTreatment.builder() | ||
769 | - .setOutput(PortNumber.portNumber(10)) | ||
770 | - .build(); | ||
771 | - NextObjective nextObjective = DefaultNextObjective.builder() | ||
772 | - .addTreatment(treatment) | ||
773 | - .fromApp(appId) | ||
774 | - .withId(678) // dummy next objective id | ||
775 | - .withType(NextObjective.Type.SIMPLE) | ||
776 | - .add(); | ||
777 | - Integer l2groupId = 0x0064000a; | ||
778 | - GroupBucket bucket = | ||
779 | - DefaultGroupBucket.createIndirectGroupBucket(treatment); | ||
780 | - final GroupKey key = new DefaultGroupKey(appKryo.serialize(678)); | ||
781 | - GroupDescription groupDescriptionl2 | ||
782 | - = new DefaultGroupDescription(deviceId, | ||
783 | - GroupDescription.Type.INDIRECT, | ||
784 | - new GroupBuckets(Collections | ||
785 | - .singletonList(bucket)), | ||
786 | - key, | ||
787 | - l2groupId, | ||
788 | - appId); | ||
789 | - groupService.addGroup(groupDescriptionl2);*/ | ||
790 | - //pendingNextObjectives.put(key, nextObjective); | ||
791 | - | ||
792 | - } | ||
793 | - | ||
794 | - @SuppressWarnings("unused") | ||
795 | - private void tryGroupChain() { | ||
796 | - //Create a dummy L3 group as per OFDPA requirements | ||
797 | - /*TrafficTreatment treatment2 = DefaultTrafficTreatment.builder() | ||
798 | - .setEthDst(MacAddress.valueOf("00:00:00:aa:aa:aa")) | ||
799 | - .setEthSrc(MacAddress.valueOf("00:00:00:dd:dd:dd")) | ||
800 | - .setVlanId(VlanId.vlanId((short) 100)) | ||
801 | - .group(new DefaultGroupId(0x0064000a)) | ||
802 | - .build(); | ||
803 | - NextObjective nextObjective2 = DefaultNextObjective.builder() | ||
804 | - .addTreatment(treatment2) | ||
805 | - .fromApp(appId) | ||
806 | - .withId(67800) // another dummy next objective id | ||
807 | - .withType(NextObjective.Type.SIMPLE) | ||
808 | - .add(); | ||
809 | - Integer l3groupId = 0x2000000a; | ||
810 | - GroupBucket bucket2 = DefaultGroupBucket.createIndirectGroupBucket(treatment2); | ||
811 | - final GroupKey key2 = new DefaultGroupKey(appKryo.serialize(67800)); | ||
812 | - GroupDescription groupDescriptionl3 | ||
813 | - = new DefaultGroupDescription(deviceId, | ||
814 | - GroupDescription.Type.INDIRECT, | ||
815 | - new GroupBuckets(Collections | ||
816 | - .singletonList(bucket2)), | ||
817 | - key2, | ||
818 | - l3groupId, | ||
819 | - appId); | ||
820 | - groupService.addGroup(groupDescriptionl3); | ||
821 | - pendingNextObjectives.put(key2, nextObjective2); | ||
822 | - */ | ||
823 | - } | ||
824 | - | ||
825 | private class GroupChecker implements Runnable { | 721 | private class GroupChecker implements Runnable { |
826 | @Override | 722 | @Override |
827 | public void run() { | 723 | public void run() { |
828 | Set<GroupKey> keys = pendingGroups.keySet().stream() | 724 | Set<GroupKey> keys = pendingGroups.keySet().stream() |
829 | .filter(key -> groupService.getGroup(deviceId, key) != null) | 725 | .filter(key -> groupService.getGroup(deviceId, key) != null) |
830 | .collect(Collectors.toSet()); | 726 | .collect(Collectors.toSet()); |
727 | + Set<GroupKey> otherkeys = pendingNextObjectives.asMap().keySet().stream() | ||
728 | + .filter(otherkey -> groupService.getGroup(deviceId, otherkey) != null) | ||
729 | + .collect(Collectors.toSet()); | ||
730 | + keys.addAll(otherkeys); | ||
831 | 731 | ||
832 | keys.stream().forEach(key -> { | 732 | keys.stream().forEach(key -> { |
833 | //first check for group chain | 733 | //first check for group chain |
... | @@ -856,7 +756,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline | ... | @@ -856,7 +756,7 @@ public class OFDPA1Pipeline extends AbstractHandlerBehaviour implements Pipeline |
856 | private class InnerGroupListener implements GroupListener { | 756 | private class InnerGroupListener implements GroupListener { |
857 | @Override | 757 | @Override |
858 | public void event(GroupEvent event) { | 758 | public void event(GroupEvent event) { |
859 | - log.info("received group event of type {}", event.type()); | 759 | + log.debug("received group event of type {}", event.type()); |
860 | if (event.type() == GroupEvent.Type.GROUP_ADDED) { | 760 | if (event.type() == GroupEvent.Type.GROUP_ADDED) { |
861 | GroupKey key = event.subject().appCookie(); | 761 | GroupKey key = event.subject().appCookie(); |
862 | // first check for group chain | 762 | // first check for group chain | ... | ... |
... | @@ -63,9 +63,10 @@ | ... | @@ -63,9 +63,10 @@ |
63 | impl="org.onosproject.driver.pipeline.OFDPA1Pipeline"/> | 63 | impl="org.onosproject.driver.pipeline.OFDPA1Pipeline"/> |
64 | </driver> | 64 | </driver> |
65 | <!-- The SoftRouter driver is meant to be used by any software/NPU based | 65 | <!-- The SoftRouter driver is meant to be used by any software/NPU based |
66 | - ~ switch that wishes to implement a simple 2-table router. ONOS needs to | 66 | + ~ switch that wishes to implement a simple 2-table router. To use this |
67 | - ~ be configured with the dpid of such a device to attach this driver | 67 | + ~ driver, configure ONOS with the dpid of the device, or extend the |
68 | - ~ to the device. | 68 | + ~ driver declaration with the manufacturer/hwVersion/swVersion of the |
69 | + ~ device (see 'noviflow' example). | ||
69 | --> | 70 | --> |
70 | <driver name="softrouter" extends="default" | 71 | <driver name="softrouter" extends="default" |
71 | manufacturer="Various" hwVersion="various" swVersion="0.0.0"> | 72 | manufacturer="Various" hwVersion="various" swVersion="0.0.0"> |
... | @@ -85,5 +86,14 @@ | ... | @@ -85,5 +86,14 @@ |
85 | <driver name="noviflow" extends="softrouter" | 86 | <driver name="noviflow" extends="softrouter" |
86 | manufacturer="NoviFlow Inc" hwVersion="NS1132" swVersion="NW250.4.4"> | 87 | manufacturer="NoviFlow Inc" hwVersion="NS1132" swVersion="NW250.4.4"> |
87 | </driver> | 88 | </driver> |
89 | + <!-- Emulation of the ofdpa pipeline using a CPqD OF 1.3 software switch. | ||
90 | + ~ To use this driver, configure ONOS with the dpid of the device. | ||
91 | + --> | ||
92 | + <driver name="ofdpa-cpqd" extends="default" | ||
93 | + manufacturer="ONF" | ||
94 | + hwVersion="OF1.3 Software Switch from CPqD" swVersion="for Group Chaining"> | ||
95 | + <behaviour api="org.onosproject.net.behaviour.Pipeliner" | ||
96 | + impl="org.onosproject.driver.pipeline.CpqdOFDPA1Pipeline"/> | ||
97 | + </driver> | ||
88 | </drivers> | 98 | </drivers> |
89 | 99 | ... | ... |
-
Please register or login to post a comment