Committed by
Gerrit Code Review
ONOS-3961 ONOS-4285 Implemented BMv2 drivers and protocol
Provides Thrift-based implementation for FlowRuleProgrammable and PortDiscovery behaviours. Change-Id: Ibbf8720d92301bcd23c5c583d156f464015ff1ef
Showing
24 changed files
with
1838 additions
and
2 deletions
... | @@ -38,7 +38,8 @@ public class ExtensionSelectorType { | ... | @@ -38,7 +38,8 @@ public class ExtensionSelectorType { |
38 | NICIRA_MATCH_NSH_CH2(3), | 38 | NICIRA_MATCH_NSH_CH2(3), |
39 | NICIRA_MATCH_NSH_CH3(4), | 39 | NICIRA_MATCH_NSH_CH3(4), |
40 | NICIRA_MATCH_NSH_CH4(5), | 40 | NICIRA_MATCH_NSH_CH4(5), |
41 | - OFDPA_MATCH_VLAN_VID(16); | 41 | + OFDPA_MATCH_VLAN_VID(16), |
42 | + P4_BMV2_MATCH_KEY(128); | ||
42 | 43 | ||
43 | private ExtensionSelectorType type; | 44 | private ExtensionSelectorType type; |
44 | 45 | ... | ... |
... | @@ -45,7 +45,8 @@ public final class ExtensionTreatmentType { | ... | @@ -45,7 +45,8 @@ public final class ExtensionTreatmentType { |
45 | NICIRA_SET_NSH_CH2(35), | 45 | NICIRA_SET_NSH_CH2(35), |
46 | NICIRA_SET_NSH_CH3(36), | 46 | NICIRA_SET_NSH_CH3(36), |
47 | NICIRA_SET_NSH_CH4(37), | 47 | NICIRA_SET_NSH_CH4(37), |
48 | - OFDPA_SET_VLAN_ID(64); | 48 | + OFDPA_SET_VLAN_ID(64), |
49 | + P4_BMV2_ACTION(128); | ||
49 | 50 | ||
50 | private ExtensionTreatmentType type; | 51 | private ExtensionTreatmentType type; |
51 | 52 | ... | ... |
drivers/bmv2/features.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
2 | + | ||
3 | +<!-- | ||
4 | + ~ Copyright 2014-2016 Open Networking Laboratory | ||
5 | + ~ | ||
6 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + ~ you may not use this file except in compliance with the License. | ||
8 | + ~ You may obtain a copy of the License at | ||
9 | + ~ | ||
10 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + ~ | ||
12 | + ~ Unless required by applicable law or agreed to in writing, software | ||
13 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + ~ See the License for the specific language governing permissions and | ||
16 | + ~ limitations under the License. | ||
17 | + --> | ||
18 | + | ||
19 | +<features xmlns="http://karaf.apache.org/xmlns/features/v1.2.0" name="${project.artifactId}-${project.version}"> | ||
20 | + <feature name="${project.artifactId}" version="${project.version}" | ||
21 | + description="${project.description}"> | ||
22 | + <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> | ||
23 | + <bundle>mvn:${project.groupId}/onos-bmv2-protocol/${project.version}</bundle> | ||
24 | + </feature> | ||
25 | +</features> |
drivers/bmv2/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2014-2016 Open Networking Laboratory | ||
4 | + ~ | ||
5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + ~ you may not use this file except in compliance with the License. | ||
7 | + ~ You may obtain a copy of the License at | ||
8 | + ~ | ||
9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + ~ | ||
11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + ~ See the License for the specific language governing permissions and | ||
15 | + ~ limitations under the License. | ||
16 | + --> | ||
17 | + | ||
18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
19 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
20 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
21 | + <parent> | ||
22 | + <artifactId>onos-drivers-general</artifactId> | ||
23 | + <groupId>org.onosproject</groupId> | ||
24 | + <version>1.6.0-SNAPSHOT</version> | ||
25 | + </parent> | ||
26 | + <modelVersion>4.0.0</modelVersion> | ||
27 | + | ||
28 | + <artifactId>onos-drivers-bmv2</artifactId> | ||
29 | + <version>1.6.0-SNAPSHOT</version> | ||
30 | + | ||
31 | + <packaging>bundle</packaging> | ||
32 | + | ||
33 | + <description>Device drivers for p4.org reference softswitch BMv2</description> | ||
34 | + | ||
35 | + <properties> | ||
36 | + <onos.app.name>org.onosproject.drivers.bmv2</onos.app.name> | ||
37 | + <onos.app.origin>ON.Lab</onos.app.origin> | ||
38 | + <onos.app.category>Drivers</onos.app.category> | ||
39 | + <onos.app.title>BMv2 Device Drivers</onos.app.title> | ||
40 | + <onos.app.url>http://onosproject.org</onos.app.url> | ||
41 | + <onos.app.requires> | ||
42 | + org.onosproject.bmv2 | ||
43 | + </onos.app.requires> | ||
44 | + </properties> | ||
45 | + | ||
46 | + <dependencies> | ||
47 | + <dependency> | ||
48 | + <groupId>org.onosproject</groupId> | ||
49 | + <artifactId>onos-bmv2-protocol</artifactId> | ||
50 | + <version>${project.version}</version> | ||
51 | + </dependency> | ||
52 | + </dependencies> | ||
53 | + | ||
54 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.drivers.bmv2; | ||
18 | + | ||
19 | +import org.apache.felix.scr.annotations.Component; | ||
20 | +import org.onosproject.net.driver.AbstractDriverLoader; | ||
21 | + | ||
22 | +/** | ||
23 | + * Loader for barefoot drivers from specific xml. | ||
24 | + */ | ||
25 | +@Component(immediate = true) | ||
26 | +public class Bmv2DriversLoader extends AbstractDriverLoader { | ||
27 | + | ||
28 | + private static final String DRIVERS_XML = "/bmv2-drivers.xml"; | ||
29 | + | ||
30 | + public Bmv2DriversLoader() { | ||
31 | + super(DRIVERS_XML); | ||
32 | + } | ||
33 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.drivers.bmv2; | ||
18 | + | ||
19 | +import com.google.common.base.Preconditions; | ||
20 | +import com.google.common.collect.Lists; | ||
21 | +import com.google.common.collect.Maps; | ||
22 | +import com.google.common.collect.Sets; | ||
23 | +import org.onosproject.bmv2.api.Bmv2ExtensionSelector; | ||
24 | +import org.onosproject.bmv2.api.Bmv2ExtensionTreatment; | ||
25 | +import org.onosproject.bmv2.api.Bmv2TableEntry; | ||
26 | +import org.onosproject.bmv2.api.Bmv2Exception; | ||
27 | +import org.onosproject.bmv2.ctl.Bmv2ThriftClient; | ||
28 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
29 | +import org.onosproject.net.flow.DefaultFlowEntry; | ||
30 | +import org.onosproject.net.flow.FlowEntry; | ||
31 | +import org.onosproject.net.flow.FlowRule; | ||
32 | +import org.onosproject.net.flow.FlowRuleProgrammable; | ||
33 | +import org.onosproject.net.flow.criteria.Criterion; | ||
34 | +import org.onosproject.net.flow.criteria.ExtensionCriterion; | ||
35 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
36 | +import org.onosproject.net.flow.criteria.ExtensionSelectorType; | ||
37 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
38 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
39 | +import org.onosproject.net.flow.instructions.Instruction; | ||
40 | +import org.onosproject.net.flow.instructions.Instructions; | ||
41 | +import org.slf4j.Logger; | ||
42 | +import org.slf4j.LoggerFactory; | ||
43 | + | ||
44 | +import java.util.Collection; | ||
45 | +import java.util.Collections; | ||
46 | +import java.util.List; | ||
47 | +import java.util.Map; | ||
48 | +import java.util.Set; | ||
49 | + | ||
50 | +public class Bmv2FlowRuleDriver extends AbstractHandlerBehaviour | ||
51 | + implements FlowRuleProgrammable { | ||
52 | + | ||
53 | + private final Logger log = | ||
54 | + LoggerFactory.getLogger(this.getClass()); | ||
55 | + | ||
56 | + // Bmv2 doesn't support proper table dump, use a local store | ||
57 | + // FIXME: synchronize entries with device | ||
58 | + private final Map<FlowRule, FlowEntry> deviceEntriesMap = Maps.newHashMap(); | ||
59 | + private final Map<Integer, Set<FlowRule>> tableRulesMap = Maps.newHashMap(); | ||
60 | + private final Map<FlowRule, Long> tableEntryIdsMap = Maps.newHashMap(); | ||
61 | + | ||
62 | + @Override | ||
63 | + public Collection<FlowEntry> getFlowEntries() { | ||
64 | + return Collections.unmodifiableCollection( | ||
65 | + deviceEntriesMap.values()); | ||
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public Collection<FlowRule> applyFlowRules(Collection<FlowRule> rules) { | ||
70 | + Bmv2ThriftClient deviceClient; | ||
71 | + try { | ||
72 | + deviceClient = getDeviceClient(); | ||
73 | + } catch (Bmv2Exception e) { | ||
74 | + return Collections.emptyList(); | ||
75 | + } | ||
76 | + | ||
77 | + List<FlowRule> appliedFlowRules = Lists.newArrayList(); | ||
78 | + | ||
79 | + for (FlowRule rule : rules) { | ||
80 | + | ||
81 | + Bmv2TableEntry entry; | ||
82 | + | ||
83 | + try { | ||
84 | + entry = parseFlowRule(rule); | ||
85 | + } catch (IllegalStateException e) { | ||
86 | + log.error("Unable to parse flow rule", e); | ||
87 | + continue; | ||
88 | + } | ||
89 | + | ||
90 | + // Instantiate flowrule set for table if it does not exist | ||
91 | + if (!tableRulesMap.containsKey(rule.tableId())) { | ||
92 | + tableRulesMap.put(rule.tableId(), Sets.newHashSet()); | ||
93 | + } | ||
94 | + | ||
95 | + if (tableRulesMap.get(rule.tableId()).contains(rule)) { | ||
96 | + /* Rule is already installed in the table */ | ||
97 | + long entryId = tableEntryIdsMap.get(rule); | ||
98 | + | ||
99 | + try { | ||
100 | + deviceClient.modifyTableEntry( | ||
101 | + entry.tableName(), entryId, entry.action()); | ||
102 | + | ||
103 | + // Replace stored rule as treatment, etc. might have changed | ||
104 | + // Java Set doesn't replace on add, remove first | ||
105 | + tableRulesMap.get(rule.tableId()).remove(rule); | ||
106 | + tableRulesMap.get(rule.tableId()).add(rule); | ||
107 | + tableEntryIdsMap.put(rule, entryId); | ||
108 | + deviceEntriesMap.put(rule, new DefaultFlowEntry( | ||
109 | + rule, FlowEntry.FlowEntryState.ADDED, 0, 0, 0)); | ||
110 | + } catch (Bmv2Exception e) { | ||
111 | + log.error("Unable to update flow rule", e); | ||
112 | + continue; | ||
113 | + } | ||
114 | + | ||
115 | + } else { | ||
116 | + /* Rule is new */ | ||
117 | + try { | ||
118 | + long entryId = deviceClient.addTableEntry(entry); | ||
119 | + | ||
120 | + tableRulesMap.get(rule.tableId()).add(rule); | ||
121 | + tableEntryIdsMap.put(rule, entryId); | ||
122 | + deviceEntriesMap.put(rule, new DefaultFlowEntry( | ||
123 | + rule, FlowEntry.FlowEntryState.ADDED, 0, 0, 0)); | ||
124 | + } catch (Bmv2Exception e) { | ||
125 | + log.error("Unable to add flow rule", e); | ||
126 | + continue; | ||
127 | + } | ||
128 | + } | ||
129 | + | ||
130 | + appliedFlowRules.add(rule); | ||
131 | + } | ||
132 | + | ||
133 | + return Collections.unmodifiableCollection(appliedFlowRules); | ||
134 | + } | ||
135 | + | ||
136 | + @Override | ||
137 | + public Collection<FlowRule> removeFlowRules(Collection<FlowRule> rules) { | ||
138 | + Bmv2ThriftClient deviceClient; | ||
139 | + try { | ||
140 | + deviceClient = getDeviceClient(); | ||
141 | + } catch (Bmv2Exception e) { | ||
142 | + return Collections.emptyList(); | ||
143 | + } | ||
144 | + | ||
145 | + List<FlowRule> removedFlowRules = Lists.newArrayList(); | ||
146 | + | ||
147 | + for (FlowRule rule : rules) { | ||
148 | + | ||
149 | + if (tableEntryIdsMap.containsKey(rule)) { | ||
150 | + long entryId = tableEntryIdsMap.get(rule); | ||
151 | + String tableName = parseTableName(rule.tableId()); | ||
152 | + | ||
153 | + try { | ||
154 | + deviceClient.deleteTableEntry(tableName, entryId); | ||
155 | + } catch (Bmv2Exception e) { | ||
156 | + log.error("Unable to delete flow rule", e); | ||
157 | + continue; | ||
158 | + } | ||
159 | + | ||
160 | + /* remove from local store */ | ||
161 | + tableEntryIdsMap.remove(rule); | ||
162 | + tableRulesMap.get(rule.tableId()).remove(rule); | ||
163 | + deviceEntriesMap.remove(rule); | ||
164 | + | ||
165 | + removedFlowRules.add(rule); | ||
166 | + } | ||
167 | + } | ||
168 | + | ||
169 | + return Collections.unmodifiableCollection(removedFlowRules); | ||
170 | + } | ||
171 | + | ||
172 | + private Bmv2TableEntry parseFlowRule(FlowRule flowRule) { | ||
173 | + | ||
174 | + // TODO make it pipeline dependant, i.e. implement mapping | ||
175 | + | ||
176 | + Bmv2TableEntry.Builder entryBuilder = Bmv2TableEntry.builder(); | ||
177 | + | ||
178 | + // Check selector | ||
179 | + ExtensionCriterion ec = | ||
180 | + (ExtensionCriterion) flowRule | ||
181 | + .selector().getCriterion(Criterion.Type.EXTENSION); | ||
182 | + Preconditions.checkState( | ||
183 | + flowRule.selector().criteria().size() == 1 | ||
184 | + && ec != null, | ||
185 | + "Selector must have only 1 criterion of type EXTENSION"); | ||
186 | + ExtensionSelector es = ec.extensionSelector(); | ||
187 | + Preconditions.checkState( | ||
188 | + es.type() == ExtensionSelectorType.ExtensionSelectorTypes.P4_BMV2_MATCH_KEY.type(), | ||
189 | + "ExtensionSelectorType must be P4_BMV2_MATCH_KEY"); | ||
190 | + | ||
191 | + // Selector OK, get Bmv2MatchKey | ||
192 | + entryBuilder.withMatchKey(((Bmv2ExtensionSelector) es).matchKey()); | ||
193 | + | ||
194 | + // Check treatment | ||
195 | + Instruction inst = flowRule.treatment().allInstructions().get(0); | ||
196 | + Preconditions.checkState( | ||
197 | + flowRule.treatment().allInstructions().size() == 1 | ||
198 | + && inst.type() == Instruction.Type.EXTENSION, | ||
199 | + "Treatment must have only 1 instruction of type EXTENSION"); | ||
200 | + ExtensionTreatment et = | ||
201 | + ((Instructions.ExtensionInstructionWrapper) inst) | ||
202 | + .extensionInstruction(); | ||
203 | + | ||
204 | + Preconditions.checkState( | ||
205 | + et.type() == ExtensionTreatmentType.ExtensionTreatmentTypes.P4_BMV2_ACTION.type(), | ||
206 | + "ExtensionTreatmentType must be P4_BMV2_ACTION"); | ||
207 | + | ||
208 | + // Treatment OK, get Bmv2Action | ||
209 | + entryBuilder.withAction(((Bmv2ExtensionTreatment) et).getAction()); | ||
210 | + | ||
211 | + // Table name | ||
212 | + entryBuilder.withTableName(parseTableName(flowRule.tableId())); | ||
213 | + | ||
214 | + if (!flowRule.isPermanent()) { | ||
215 | + entryBuilder.withTimeout(flowRule.timeout()); | ||
216 | + } | ||
217 | + | ||
218 | + entryBuilder.withPriority(flowRule.priority()); | ||
219 | + | ||
220 | + return entryBuilder.build(); | ||
221 | + } | ||
222 | + | ||
223 | + private String parseTableName(int tableId) { | ||
224 | + // TODO: map tableId with tableName according to P4 JSON | ||
225 | + return "table" + String.valueOf(tableId); | ||
226 | + } | ||
227 | + | ||
228 | + private Bmv2ThriftClient getDeviceClient() throws Bmv2Exception { | ||
229 | + try { | ||
230 | + return Bmv2ThriftClient.of(handler().data().deviceId()); | ||
231 | + } catch (Bmv2Exception e) { | ||
232 | + log.error("Failed to connect to Bmv2 device", e); | ||
233 | + throw e; | ||
234 | + } | ||
235 | + } | ||
236 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.drivers.bmv2; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableList; | ||
20 | +import com.google.common.collect.Lists; | ||
21 | +import org.onosproject.bmv2.api.Bmv2Exception; | ||
22 | +import org.onosproject.bmv2.ctl.Bmv2ThriftClient; | ||
23 | +import org.onosproject.net.DefaultAnnotations; | ||
24 | +import org.onosproject.net.PortNumber; | ||
25 | +import org.onosproject.net.SparseAnnotations; | ||
26 | +import org.onosproject.net.behaviour.PortDiscovery; | ||
27 | +import org.onosproject.net.device.DefaultPortDescription; | ||
28 | +import org.onosproject.net.device.PortDescription; | ||
29 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
30 | +import org.slf4j.Logger; | ||
31 | +import org.slf4j.LoggerFactory; | ||
32 | + | ||
33 | +import java.util.Collections; | ||
34 | +import java.util.List; | ||
35 | + | ||
36 | +public class Bmv2PortGetterDriver extends AbstractHandlerBehaviour | ||
37 | + implements PortDiscovery { | ||
38 | + | ||
39 | + private final Logger log = | ||
40 | + LoggerFactory.getLogger(this.getClass()); | ||
41 | + | ||
42 | + @Override | ||
43 | + public List<PortDescription> getPorts() { | ||
44 | + Bmv2ThriftClient deviceClient; | ||
45 | + try { | ||
46 | + deviceClient = Bmv2ThriftClient.of(handler().data().deviceId()); | ||
47 | + } catch (Bmv2Exception e) { | ||
48 | + log.error("Failed to connect to Bmv2 device", e); | ||
49 | + return Collections.emptyList(); | ||
50 | + } | ||
51 | + | ||
52 | + List<PortDescription> portDescriptions = Lists.newArrayList(); | ||
53 | + | ||
54 | + try { | ||
55 | + | ||
56 | + deviceClient.getPortsInfo().forEach( | ||
57 | + p -> { | ||
58 | + DefaultAnnotations.Builder builder = | ||
59 | + DefaultAnnotations.builder(); | ||
60 | + p.getExtraProperties().forEach(builder::set); | ||
61 | + SparseAnnotations annotations = builder.build(); | ||
62 | + | ||
63 | + portDescriptions.add(new DefaultPortDescription( | ||
64 | + PortNumber.portNumber( | ||
65 | + (long) p.portNumber(), | ||
66 | + p.ifaceName()), | ||
67 | + p.isUp(), | ||
68 | + annotations | ||
69 | + )); | ||
70 | + }); | ||
71 | + } catch (Bmv2Exception e) { | ||
72 | + log.error("Unable to get port description from Bmv2 device", e); | ||
73 | + } | ||
74 | + | ||
75 | + return ImmutableList.copyOf(portDescriptions); | ||
76 | + } | ||
77 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +/** | ||
18 | + * BMv2 driver implementation. | ||
19 | + */ | ||
20 | +package org.onosproject.drivers.bmv2; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | + | ||
3 | +<!-- | ||
4 | + ~ Copyright 2014-2016 Open Networking Laboratory | ||
5 | + ~ | ||
6 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
7 | + ~ you may not use this file except in compliance with the License. | ||
8 | + ~ You may obtain a copy of the License at | ||
9 | + ~ | ||
10 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
11 | + ~ | ||
12 | + ~ Unless required by applicable law or agreed to in writing, software | ||
13 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
14 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
15 | + ~ See the License for the specific language governing permissions and | ||
16 | + ~ limitations under the License. | ||
17 | + --> | ||
18 | +<drivers> | ||
19 | + <driver name="bmv2-thrift" manufacturer="p4.org" hwVersion="bmv2" swVersion="unknown"> | ||
20 | + <behaviour api="org.onosproject.net.behaviour.PortDiscovery" | ||
21 | + impl="org.onosproject.drivers.bmv2.Bmv2PortGetterDriver"/> | ||
22 | + <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable" | ||
23 | + impl="org.onosproject.drivers.bmv2.Bmv2FlowRuleDriver"/> | ||
24 | + </driver> | ||
25 | +</drivers> |
... | @@ -41,6 +41,7 @@ | ... | @@ -41,6 +41,7 @@ |
41 | <module>utilities</module> | 41 | <module>utilities</module> |
42 | <module>lumentum</module> | 42 | <module>lumentum</module> |
43 | <module>bti</module> | 43 | <module>bti</module> |
44 | + <module>bmv2</module> | ||
44 | </modules> | 45 | </modules> |
45 | 46 | ||
46 | <!--<properties> | 47 | <!--<properties> | ... | ... |
protocols/bmv2/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2014-2016 Open Networking Laboratory | ||
4 | + ~ | ||
5 | + ~ Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + ~ you may not use this file except in compliance with the License. | ||
7 | + ~ You may obtain a copy of the License at | ||
8 | + ~ | ||
9 | + ~ http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + ~ | ||
11 | + ~ Unless required by applicable law or agreed to in writing, software | ||
12 | + ~ distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + ~ See the License for the specific language governing permissions and | ||
15 | + ~ limitations under the License. | ||
16 | + --> | ||
17 | + | ||
18 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
19 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
20 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
21 | + <parent> | ||
22 | + <artifactId>onos-protocols</artifactId> | ||
23 | + <groupId>org.onosproject</groupId> | ||
24 | + <version>1.6.0-SNAPSHOT</version> | ||
25 | + </parent> | ||
26 | + <modelVersion>4.0.0</modelVersion> | ||
27 | + | ||
28 | + <artifactId>onos-bmv2-protocol</artifactId> | ||
29 | + <version>1.6.0-SNAPSHOT</version> | ||
30 | + | ||
31 | + <packaging>bundle</packaging> | ||
32 | + | ||
33 | + <description>BMv2 protocol subsystem</description> | ||
34 | + | ||
35 | + <properties> | ||
36 | + <!-- BMv2 Commit ID and Thrift version --> | ||
37 | + <bmv2.commit>a012ee4124c1892a91a359660824d311d5d7fe88</bmv2.commit> | ||
38 | + <bmv2.thrift.version>0.9.3</bmv2.thrift.version> | ||
39 | + <!-- Do not change below --> | ||
40 | + <bmv2.baseurl> | ||
41 | + https://raw.githubusercontent.com/p4lang/behavioral-model/${bmv2.commit} | ||
42 | + </bmv2.baseurl> | ||
43 | + <bmv2.thrift.srcdir>${project.basedir}/src/main/thrift</bmv2.thrift.srcdir> | ||
44 | + <thrift.path>${project.build.directory}/thrift-compiler/</thrift.path> | ||
45 | + <thrift.filename>thrift-${os.detected.classifier}.exe</thrift.filename> | ||
46 | + </properties> | ||
47 | + | ||
48 | + <dependencies> | ||
49 | + <dependency> | ||
50 | + <groupId>org.apache.thrift</groupId> | ||
51 | + <artifactId>libthrift</artifactId> | ||
52 | + <version>${bmv2.thrift.version}</version> | ||
53 | + </dependency> | ||
54 | + <dependency> | ||
55 | + <groupId>org.onosproject</groupId> | ||
56 | + <artifactId>onos-api</artifactId> | ||
57 | + <version>${project.version}</version> | ||
58 | + </dependency> | ||
59 | + </dependencies> | ||
60 | + | ||
61 | + <repositories> | ||
62 | + <!-- Needed for thrift-compiler, which is hosted on GitHub --> | ||
63 | + <repository> | ||
64 | + <id>jitpack.io</id> | ||
65 | + <url>https://jitpack.io</url> | ||
66 | + </repository> | ||
67 | + </repositories> | ||
68 | + | ||
69 | + <build> | ||
70 | + <extensions> | ||
71 | + <extension> | ||
72 | + <groupId>kr.motd.maven</groupId> | ||
73 | + <artifactId>os-maven-plugin</artifactId> | ||
74 | + <version>1.4.0.Final</version> | ||
75 | + </extension> | ||
76 | + </extensions> | ||
77 | + | ||
78 | + <plugins> | ||
79 | + <!-- Download Thrift source files from BMv2 Github repo --> | ||
80 | + <plugin> | ||
81 | + <groupId>org.codehaus.mojo</groupId> | ||
82 | + <artifactId>wagon-maven-plugin</artifactId> | ||
83 | + <version>1.0</version> | ||
84 | + <executions> | ||
85 | + <execution> | ||
86 | + <id>download-bmv2-thrift-standard</id> | ||
87 | + <phase>validate</phase> | ||
88 | + <goals> | ||
89 | + <goal>download-single</goal> | ||
90 | + </goals> | ||
91 | + <configuration> | ||
92 | + <url>${bmv2.baseurl}</url> | ||
93 | + <fromFile>thrift_src/standard.thrift</fromFile> | ||
94 | + <toDir>${bmv2.thrift.srcdir}</toDir> | ||
95 | + </configuration> | ||
96 | + </execution> | ||
97 | + <execution> | ||
98 | + <id>download-bmv2-thrift-simple_pre</id> | ||
99 | + <phase>initialize</phase> | ||
100 | + <goals> | ||
101 | + <goal>download-single</goal> | ||
102 | + </goals> | ||
103 | + <configuration> | ||
104 | + <url>${bmv2.baseurl}</url> | ||
105 | + <fromFile>thrift_src/simple_pre.thrift</fromFile> | ||
106 | + <toDir>${bmv2.thrift.srcdir}</toDir> | ||
107 | + </configuration> | ||
108 | + </execution> | ||
109 | + <execution> | ||
110 | + <id>download-bmv2-thrift-simple_pre_lag</id> | ||
111 | + <phase>initialize</phase> | ||
112 | + <goals> | ||
113 | + <goal>download-single</goal> | ||
114 | + </goals> | ||
115 | + <configuration> | ||
116 | + <url>${bmv2.baseurl}</url> | ||
117 | + <fromFile>thrift_src/simple_pre_lag.thrift | ||
118 | + </fromFile> | ||
119 | + <toDir>${bmv2.thrift.srcdir}</toDir> | ||
120 | + </configuration> | ||
121 | + </execution> | ||
122 | + <execution> | ||
123 | + <id>download-bmv2-thrift-simple_switch</id> | ||
124 | + <phase>initialize</phase> | ||
125 | + <goals> | ||
126 | + <goal>download-single</goal> | ||
127 | + </goals> | ||
128 | + <configuration> | ||
129 | + <url>${bmv2.baseurl}</url> | ||
130 | + <fromFile> | ||
131 | + targets/simple_switch/thrift/simple_switch.thrift | ||
132 | + </fromFile> | ||
133 | + <toDir>${bmv2.thrift.srcdir}</toDir> | ||
134 | + </configuration> | ||
135 | + </execution> | ||
136 | + </executions> | ||
137 | + </plugin> | ||
138 | + <!-- Extract Thrift compiler --> | ||
139 | + <plugin> | ||
140 | + <groupId>org.apache.maven.plugins</groupId> | ||
141 | + <artifactId>maven-dependency-plugin</artifactId> | ||
142 | + <executions> | ||
143 | + <execution> | ||
144 | + <id>unpack</id> | ||
145 | + <phase>initialize</phase> | ||
146 | + <goals> | ||
147 | + <goal>unpack</goal> | ||
148 | + </goals> | ||
149 | + <configuration> | ||
150 | + <artifactItems> | ||
151 | + <artifactItem> | ||
152 | + <groupId>com.github.ccascone</groupId> | ||
153 | + <artifactId>mvn-thrift-compiler</artifactId> | ||
154 | + <version>1.1_${bmv2.thrift.version}</version> | ||
155 | + <type>jar</type> | ||
156 | + <includes>${thrift.filename}</includes> | ||
157 | + <outputDirectory>${project.build.directory}/thrift-compiler</outputDirectory> | ||
158 | + </artifactItem> | ||
159 | + </artifactItems> | ||
160 | + </configuration> | ||
161 | + </execution> | ||
162 | + </executions> | ||
163 | + </plugin> | ||
164 | + <!-- Add missing java namespace to Thrift files --> | ||
165 | + <plugin> | ||
166 | + <groupId>org.codehaus.mojo</groupId> | ||
167 | + <artifactId>exec-maven-plugin</artifactId> | ||
168 | + <version>1.4.0</version> | ||
169 | + <executions> | ||
170 | + <execution> | ||
171 | + <id>add-bmv2-thrift-java-namespace</id> | ||
172 | + <phase>initialize</phase> | ||
173 | + <goals> | ||
174 | + <goal>exec</goal> | ||
175 | + </goals> | ||
176 | + <configuration> | ||
177 | + <executable>${bmv2.thrift.srcdir}/patch.sh | ||
178 | + </executable> | ||
179 | + </configuration> | ||
180 | + </execution> | ||
181 | + <execution> | ||
182 | + <id>set-thrift-compiler-permissions</id> | ||
183 | + <phase>initialize</phase> | ||
184 | + <goals> | ||
185 | + <goal>exec</goal> | ||
186 | + </goals> | ||
187 | + <configuration> | ||
188 | + <executable>chmod</executable> | ||
189 | + <arguments> | ||
190 | + <argument>+x</argument> | ||
191 | + <argument>${thrift.path}/${thrift.filename}</argument> | ||
192 | + </arguments> | ||
193 | + </configuration> | ||
194 | + </execution> | ||
195 | + </executions> | ||
196 | + </plugin> | ||
197 | + <!-- Compile Thrift files --> | ||
198 | + <plugin> | ||
199 | + <groupId>org.apache.thrift.tools</groupId> | ||
200 | + <artifactId>maven-thrift-plugin</artifactId> | ||
201 | + <version>0.1.11</version> | ||
202 | + <configuration> | ||
203 | + <thriftExecutable>${thrift.path}/${thrift.filename}</thriftExecutable> | ||
204 | + </configuration> | ||
205 | + <executions> | ||
206 | + <execution> | ||
207 | + <id>thrift-sources</id> | ||
208 | + <phase>generate-sources</phase> | ||
209 | + <goals> | ||
210 | + <goal>compile</goal> | ||
211 | + </goals> | ||
212 | + </execution> | ||
213 | + </executions> | ||
214 | + </plugin> | ||
215 | + <!-- Make generated sources visible --> | ||
216 | + <plugin> | ||
217 | + <groupId>org.codehaus.mojo</groupId> | ||
218 | + <artifactId>build-helper-maven-plugin</artifactId> | ||
219 | + <version>1.4</version> | ||
220 | + <executions> | ||
221 | + <execution> | ||
222 | + <id>add-thrift-sources-to-path</id> | ||
223 | + <phase>generate-sources</phase> | ||
224 | + <goals> | ||
225 | + <goal>add-source</goal> | ||
226 | + </goals> | ||
227 | + <configuration> | ||
228 | + <sources> | ||
229 | + <source> | ||
230 | + ${project.build.directory}/target/generated-sources/thrift | ||
231 | + </source> | ||
232 | + </sources> | ||
233 | + </configuration> | ||
234 | + </execution> | ||
235 | + </executions> | ||
236 | + </plugin> | ||
237 | + </plugins> | ||
238 | + </build> | ||
239 | + | ||
240 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +import com.google.common.base.MoreObjects; | ||
20 | +import com.google.common.collect.Lists; | ||
21 | + | ||
22 | +import java.nio.ByteBuffer; | ||
23 | +import java.util.Collections; | ||
24 | +import java.util.List; | ||
25 | +import java.util.Objects; | ||
26 | + | ||
27 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
28 | + | ||
29 | +/** | ||
30 | + * Bmv2 Action representation. | ||
31 | + */ | ||
32 | +public final class Bmv2Action { | ||
33 | + | ||
34 | + private final String name; | ||
35 | + private final List<ByteBuffer> parameters; | ||
36 | + | ||
37 | + private Bmv2Action(String name, List<ByteBuffer> parameters) { | ||
38 | + // hide constructor | ||
39 | + this.name = name; | ||
40 | + this.parameters = parameters; | ||
41 | + } | ||
42 | + | ||
43 | + /** | ||
44 | + * Returns a new action builder. | ||
45 | + */ | ||
46 | + public static Builder builder() { | ||
47 | + return new Builder(); | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * Get action name. | ||
52 | + * | ||
53 | + * @return action name | ||
54 | + */ | ||
55 | + public final String name() { | ||
56 | + return name; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Get list of action parameters ordered as per P4 action definition. | ||
61 | + * | ||
62 | + * @return List of action parameters | ||
63 | + */ | ||
64 | + public final List<ByteBuffer> parameters() { | ||
65 | + return Collections.unmodifiableList(parameters); | ||
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public final int hashCode() { | ||
70 | + return Objects.hash(name, parameters); | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
74 | + public final boolean equals(Object obj) { | ||
75 | + if (this == obj) { | ||
76 | + return true; | ||
77 | + } | ||
78 | + if (obj == null || getClass() != obj.getClass()) { | ||
79 | + return false; | ||
80 | + } | ||
81 | + final Bmv2Action other = (Bmv2Action) obj; | ||
82 | + return Objects.equals(this.name, other.name) | ||
83 | + && Objects.equals(this.parameters, other.parameters); | ||
84 | + } | ||
85 | + | ||
86 | + @Override | ||
87 | + public final String toString() { | ||
88 | + return MoreObjects.toStringHelper(this) | ||
89 | + .add("name", name) | ||
90 | + .add("parameters", parameters) | ||
91 | + .toString(); | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * A Bmv2 action builder. | ||
96 | + */ | ||
97 | + public static final class Builder { | ||
98 | + | ||
99 | + private String name; | ||
100 | + private List<ByteBuffer> parameters; | ||
101 | + | ||
102 | + private Builder() { | ||
103 | + this.parameters = Lists.newArrayList(); | ||
104 | + } | ||
105 | + | ||
106 | + /** | ||
107 | + * Set the action name. | ||
108 | + * | ||
109 | + * @param actionName a string value | ||
110 | + * @return this | ||
111 | + */ | ||
112 | + public Builder withName(String actionName) { | ||
113 | + this.name = actionName; | ||
114 | + return this; | ||
115 | + } | ||
116 | + | ||
117 | + /** | ||
118 | + * Add a parameter at the end of the parameters list. | ||
119 | + * | ||
120 | + * @param parameter a ByteBuffer value | ||
121 | + * @return this | ||
122 | + */ | ||
123 | + public Builder addParameter(ByteBuffer parameter) { | ||
124 | + parameters.add(parameter); | ||
125 | + return this; | ||
126 | + } | ||
127 | + | ||
128 | + /** | ||
129 | + * Builds a Bmv2 action object. | ||
130 | + * | ||
131 | + * @return a Bmv2 action | ||
132 | + */ | ||
133 | + public Bmv2Action build() { | ||
134 | + checkNotNull(name, "Action name not set"); | ||
135 | + return new Bmv2Action(name, parameters); | ||
136 | + } | ||
137 | + } | ||
138 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +/** | ||
20 | + * General Bmv2 exception. | ||
21 | + */ | ||
22 | +public class Bmv2Exception extends Exception { | ||
23 | + | ||
24 | + public Bmv2Exception(String message, Throwable cause) { | ||
25 | + super(message, cause); | ||
26 | + } | ||
27 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +import org.onlab.util.KryoNamespace; | ||
20 | +import org.onosproject.net.flow.AbstractExtension; | ||
21 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
22 | +import org.onosproject.net.flow.criteria.ExtensionSelectorType; | ||
23 | + | ||
24 | +public class Bmv2ExtensionSelector extends AbstractExtension implements ExtensionSelector { | ||
25 | + | ||
26 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
27 | + private Bmv2MatchKey matchKey; | ||
28 | + | ||
29 | + public Bmv2ExtensionSelector(Bmv2MatchKey matchKey) { | ||
30 | + this.matchKey = matchKey; | ||
31 | + } | ||
32 | + | ||
33 | + public Bmv2MatchKey matchKey() { | ||
34 | + return matchKey; | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public ExtensionSelectorType type() { | ||
39 | + return ExtensionSelectorType.ExtensionSelectorTypes.P4_BMV2_MATCH_KEY.type(); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public byte[] serialize() { | ||
44 | + return appKryo.serialize(matchKey); | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public void deserialize(byte[] data) { | ||
49 | + matchKey = appKryo.deserialize(data); | ||
50 | + } | ||
51 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +import org.onlab.util.KryoNamespace; | ||
20 | +import org.onosproject.net.flow.AbstractExtension; | ||
21 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
22 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
23 | + | ||
24 | +public class Bmv2ExtensionTreatment extends AbstractExtension implements ExtensionTreatment { | ||
25 | + | ||
26 | + private final KryoNamespace appKryo = new KryoNamespace.Builder().build(); | ||
27 | + private Bmv2Action action; | ||
28 | + | ||
29 | + public Bmv2ExtensionTreatment(Bmv2Action action) { | ||
30 | + this.action = action; | ||
31 | + } | ||
32 | + | ||
33 | + public Bmv2Action getAction() { | ||
34 | + return action; | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public ExtensionTreatmentType type() { | ||
39 | + return ExtensionTreatmentType.ExtensionTreatmentTypes.P4_BMV2_ACTION.type(); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public byte[] serialize() { | ||
44 | + return appKryo.serialize(action); | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public void deserialize(byte[] data) { | ||
49 | + action = appKryo.deserialize(data); | ||
50 | + } | ||
51 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +import com.google.common.base.MoreObjects; | ||
20 | +import com.google.common.collect.Lists; | ||
21 | +import org.p4.bmv2.thrift.BmMatchParam; | ||
22 | +import org.p4.bmv2.thrift.BmMatchParamExact; | ||
23 | +import org.p4.bmv2.thrift.BmMatchParamLPM; | ||
24 | +import org.p4.bmv2.thrift.BmMatchParamTernary; | ||
25 | +import org.p4.bmv2.thrift.BmMatchParamType; | ||
26 | +import org.p4.bmv2.thrift.BmMatchParamValid; | ||
27 | + | ||
28 | +import java.nio.ByteBuffer; | ||
29 | +import java.util.Arrays; | ||
30 | +import java.util.Collections; | ||
31 | +import java.util.List; | ||
32 | +import java.util.Objects; | ||
33 | + | ||
34 | +/** | ||
35 | + * Bmv2 match key representation. | ||
36 | + */ | ||
37 | +public final class Bmv2MatchKey { | ||
38 | + | ||
39 | + private final List<BmMatchParam> matchParams; | ||
40 | + | ||
41 | + /** | ||
42 | + * Creates a new match key. | ||
43 | + * | ||
44 | + * @param matchParams The ordered list of match parameters | ||
45 | + */ | ||
46 | + private Bmv2MatchKey(List<BmMatchParam> matchParams) { | ||
47 | + this.matchParams = matchParams; | ||
48 | + } | ||
49 | + | ||
50 | + public static Builder builder() { | ||
51 | + return new Builder(); | ||
52 | + } | ||
53 | + | ||
54 | + /** | ||
55 | + * Returns the match parameters defined for this match key (read-only). | ||
56 | + * | ||
57 | + * @return match parameters | ||
58 | + */ | ||
59 | + public final List<BmMatchParam> bmMatchParams() { | ||
60 | + return Collections.unmodifiableList(matchParams); | ||
61 | + } | ||
62 | + | ||
63 | + @Override | ||
64 | + public final int hashCode() { | ||
65 | + return Objects.hashCode(matchParams); | ||
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public final boolean equals(Object obj) { | ||
70 | + if (this == obj) { | ||
71 | + return true; | ||
72 | + } | ||
73 | + if (obj == null || getClass() != obj.getClass()) { | ||
74 | + return false; | ||
75 | + } | ||
76 | + final Bmv2MatchKey other = (Bmv2MatchKey) obj; | ||
77 | + | ||
78 | + return Objects.equals(this.matchParams, other.matchParams); | ||
79 | + } | ||
80 | + | ||
81 | + @Override | ||
82 | + public final String toString() { | ||
83 | + return MoreObjects.toStringHelper(this) | ||
84 | + .addValue(matchParams) | ||
85 | + .toString(); | ||
86 | + } | ||
87 | + | ||
88 | + /** | ||
89 | + * Builder of a Bmv2 match key. | ||
90 | + */ | ||
91 | + public static final class Builder { | ||
92 | + | ||
93 | + private List<BmMatchParam> matchParams; | ||
94 | + | ||
95 | + private Builder() { | ||
96 | + this.matchParams = Lists.newArrayList(); | ||
97 | + } | ||
98 | + | ||
99 | + /** | ||
100 | + * Adds an exact match parameter. | ||
101 | + * | ||
102 | + * @param key a ByteBuffer value | ||
103 | + * @return this | ||
104 | + */ | ||
105 | + public Builder withExact(ByteBuffer key) { | ||
106 | + this.matchParams.add( | ||
107 | + new BmMatchParam(BmMatchParamType.EXACT) | ||
108 | + .setExact(new BmMatchParamExact(key))); | ||
109 | + return this; | ||
110 | + } | ||
111 | + | ||
112 | + | ||
113 | + /** | ||
114 | + * Adds a longest prefix match parameter. | ||
115 | + * | ||
116 | + * @param key a ByteBuffer value | ||
117 | + * @param prefixLength an integer value | ||
118 | + * @return this | ||
119 | + */ | ||
120 | + public Builder withLpm(ByteBuffer key, int prefixLength) { | ||
121 | + this.matchParams.add( | ||
122 | + new BmMatchParam(BmMatchParamType.LPM) | ||
123 | + .setLpm(new BmMatchParamLPM(key, prefixLength))); | ||
124 | + return this; | ||
125 | + } | ||
126 | + | ||
127 | + /** | ||
128 | + * Adds a ternary match parameter. | ||
129 | + * | ||
130 | + * @param key a ByteBuffer value | ||
131 | + * @param mask an ByteBuffer value | ||
132 | + * @return this | ||
133 | + */ | ||
134 | + public Builder withTernary(ByteBuffer key, ByteBuffer mask) { | ||
135 | + this.matchParams.add( | ||
136 | + new BmMatchParam(BmMatchParamType.TERNARY). | ||
137 | + setTernary(new BmMatchParamTernary(key, mask))); | ||
138 | + return this; | ||
139 | + } | ||
140 | + | ||
141 | + /** | ||
142 | + * Adds a ternary match parameter where all bits are don't-care. | ||
143 | + * | ||
144 | + * @param byteLength an integer value representing the length in byte of the parameter | ||
145 | + * @return this | ||
146 | + */ | ||
147 | + public Builder withWildcard(int byteLength) { | ||
148 | + byte[] zeros = new byte[byteLength]; | ||
149 | + Arrays.fill(zeros, (byte) 0); | ||
150 | + return this.withTernary(ByteBuffer.wrap(zeros), ByteBuffer.wrap(zeros)); | ||
151 | + } | ||
152 | + | ||
153 | + /** | ||
154 | + * Adds a valid match parameter. | ||
155 | + * | ||
156 | + * @param key a boolean value | ||
157 | + * @return this | ||
158 | + */ | ||
159 | + public Builder withValid(boolean key) { | ||
160 | + this.matchParams.add( | ||
161 | + new BmMatchParam(BmMatchParamType.VALID) | ||
162 | + .setValid(new BmMatchParamValid(key))); | ||
163 | + return this; | ||
164 | + } | ||
165 | + | ||
166 | + /** | ||
167 | + * Builds a new match key object. | ||
168 | + * | ||
169 | + * @return match key | ||
170 | + */ | ||
171 | + public Bmv2MatchKey build() { | ||
172 | + return new Bmv2MatchKey(this.matchParams); | ||
173 | + } | ||
174 | + } | ||
175 | +} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +import com.google.common.base.MoreObjects; | ||
20 | +import org.p4.bmv2.thrift.DevMgrPortInfo; | ||
21 | + | ||
22 | +import java.util.Collections; | ||
23 | +import java.util.Map; | ||
24 | + | ||
25 | +/** | ||
26 | + * Bmv2 representation of a switch port information. | ||
27 | + */ | ||
28 | +public final class Bmv2PortInfo { | ||
29 | + | ||
30 | + private final DevMgrPortInfo portInfo; | ||
31 | + | ||
32 | + public Bmv2PortInfo(DevMgrPortInfo portInfo) { | ||
33 | + this.portInfo = portInfo; | ||
34 | + } | ||
35 | + | ||
36 | + public final String ifaceName() { | ||
37 | + return portInfo.getIface_name(); | ||
38 | + } | ||
39 | + | ||
40 | + public final int portNumber() { | ||
41 | + return portInfo.getPort_num(); | ||
42 | + } | ||
43 | + | ||
44 | + public final boolean isUp() { | ||
45 | + return portInfo.isIs_up(); | ||
46 | + } | ||
47 | + | ||
48 | + public final Map<String, String> getExtraProperties() { | ||
49 | + return Collections.unmodifiableMap(portInfo.getExtra()); | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public final String toString() { | ||
54 | + return MoreObjects.toStringHelper(this) | ||
55 | + .addValue(portInfo) | ||
56 | + .toString(); | ||
57 | + } | ||
58 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.api; | ||
18 | + | ||
19 | +import com.google.common.base.Preconditions; | ||
20 | + | ||
21 | +import java.util.Objects; | ||
22 | + | ||
23 | +/** | ||
24 | + * Bmv2 representation of a table entry. | ||
25 | + */ | ||
26 | +public final class Bmv2TableEntry { | ||
27 | + | ||
28 | + private static final int NO_PRIORITY_VALUE = -1; | ||
29 | + private static final int NO_TIMEOUT_VALUE = -1; | ||
30 | + | ||
31 | + private final String tableName; | ||
32 | + private final Bmv2MatchKey matchKey; | ||
33 | + private final Bmv2Action action; | ||
34 | + private final int priority; | ||
35 | + private final double timeout; | ||
36 | + | ||
37 | + private Bmv2TableEntry(String tableName, Bmv2MatchKey matchKey, | ||
38 | + Bmv2Action action, int priority, double timeout) { | ||
39 | + this.tableName = tableName; | ||
40 | + this.matchKey = matchKey; | ||
41 | + this.action = action; | ||
42 | + this.priority = priority; | ||
43 | + this.timeout = timeout; | ||
44 | + } | ||
45 | + | ||
46 | + public static Builder builder() { | ||
47 | + return new Builder(); | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * Returns the name of the table where this entry is installed. | ||
52 | + * | ||
53 | + * @return table name | ||
54 | + */ | ||
55 | + public final String tableName() { | ||
56 | + return this.tableName; | ||
57 | + } | ||
58 | + | ||
59 | + /** | ||
60 | + * Returns the match key. | ||
61 | + * | ||
62 | + * @return match key | ||
63 | + */ | ||
64 | + public final Bmv2MatchKey matchKey() { | ||
65 | + return matchKey; | ||
66 | + } | ||
67 | + | ||
68 | + /** | ||
69 | + * Returns the action. | ||
70 | + * | ||
71 | + * @return action | ||
72 | + */ | ||
73 | + public final Bmv2Action action() { | ||
74 | + return action; | ||
75 | + } | ||
76 | + | ||
77 | + /** | ||
78 | + * Returns true is the entry has a valid priority value set. | ||
79 | + * | ||
80 | + * @return true if priority is set, false elsewhere | ||
81 | + */ | ||
82 | + public final boolean hasPriority() { | ||
83 | + return this.priority != NO_PRIORITY_VALUE; | ||
84 | + } | ||
85 | + | ||
86 | + /** | ||
87 | + * Return the entry priority. | ||
88 | + * | ||
89 | + * @return priority | ||
90 | + */ | ||
91 | + public final int priority() { | ||
92 | + return priority; | ||
93 | + } | ||
94 | + | ||
95 | + /** | ||
96 | + * Returns true is the entry has a valid timeout value set. | ||
97 | + * | ||
98 | + * @return true if timeout is set, false elsewhere | ||
99 | + */ | ||
100 | + public final boolean hasTimeout() { | ||
101 | + return this.timeout != NO_PRIORITY_VALUE; | ||
102 | + } | ||
103 | + | ||
104 | + /** | ||
105 | + * Returns the entry timeout in fractional seconds. | ||
106 | + * | ||
107 | + * @return timeout | ||
108 | + */ | ||
109 | + public final double timeout() { | ||
110 | + return timeout; | ||
111 | + } | ||
112 | + | ||
113 | + @Override | ||
114 | + public final int hashCode() { | ||
115 | + return Objects.hash(matchKey, action, priority, timeout); | ||
116 | + } | ||
117 | + | ||
118 | + @Override | ||
119 | + public final boolean equals(Object obj) { | ||
120 | + if (this == obj) { | ||
121 | + return true; | ||
122 | + } | ||
123 | + if (obj == null || getClass() != obj.getClass()) { | ||
124 | + return false; | ||
125 | + } | ||
126 | + final Bmv2TableEntry other = (Bmv2TableEntry) obj; | ||
127 | + return Objects.equals(this.matchKey, other.matchKey) | ||
128 | + && Objects.equals(this.action, other.action) | ||
129 | + && Objects.equals(this.priority, other.priority) | ||
130 | + && Objects.equals(this.timeout, other.timeout); | ||
131 | + } | ||
132 | + | ||
133 | + @Override | ||
134 | + public final String toString() { | ||
135 | + return com.google.common.base.MoreObjects.toStringHelper(this) | ||
136 | + .addValue(matchKey) | ||
137 | + .addValue(action) | ||
138 | + .add("priority", priority) | ||
139 | + .add("timeout", timeout) | ||
140 | + .toString(); | ||
141 | + } | ||
142 | + | ||
143 | + public static final class Builder { | ||
144 | + | ||
145 | + private String tableName; | ||
146 | + private Bmv2MatchKey matchKey; | ||
147 | + private Bmv2Action action; | ||
148 | + private int priority = NO_PRIORITY_VALUE; | ||
149 | + private double timeout = NO_TIMEOUT_VALUE; | ||
150 | + | ||
151 | + private Builder() { | ||
152 | + // hide constructor | ||
153 | + } | ||
154 | + | ||
155 | + /** | ||
156 | + * Sets the table name. | ||
157 | + * | ||
158 | + * @param tableName a string value | ||
159 | + * @return this | ||
160 | + */ | ||
161 | + public Builder withTableName(String tableName) { | ||
162 | + this.tableName = tableName; | ||
163 | + return this; | ||
164 | + } | ||
165 | + | ||
166 | + /** | ||
167 | + * Sets the match key. | ||
168 | + * | ||
169 | + * @param matchKey a match key value | ||
170 | + * @return this | ||
171 | + */ | ||
172 | + public Builder withMatchKey(Bmv2MatchKey matchKey) { | ||
173 | + this.matchKey = matchKey; | ||
174 | + return this; | ||
175 | + } | ||
176 | + | ||
177 | + /** | ||
178 | + * Sets the action. | ||
179 | + * | ||
180 | + * @param action an action value | ||
181 | + * @return this | ||
182 | + */ | ||
183 | + public Builder withAction(Bmv2Action action) { | ||
184 | + this.action = action; | ||
185 | + return this; | ||
186 | + } | ||
187 | + | ||
188 | + public Builder withPriority(int priority) { | ||
189 | + this.priority = priority; | ||
190 | + return this; | ||
191 | + } | ||
192 | + | ||
193 | + /** | ||
194 | + * Sets the timeout. | ||
195 | + * | ||
196 | + * @param timeout a timeout value in fractional seconds | ||
197 | + * @return this | ||
198 | + */ | ||
199 | + public Builder withTimeout(double timeout) { | ||
200 | + this.timeout = timeout; | ||
201 | + return this; | ||
202 | + } | ||
203 | + | ||
204 | + /** | ||
205 | + * Build the table entry. | ||
206 | + * | ||
207 | + * @return a new table entry object | ||
208 | + */ | ||
209 | + public Bmv2TableEntry build() { | ||
210 | + Preconditions.checkNotNull(tableName); | ||
211 | + Preconditions.checkNotNull(matchKey); | ||
212 | + Preconditions.checkNotNull(action); | ||
213 | + | ||
214 | + return new Bmv2TableEntry(tableName, matchKey, action, priority, | ||
215 | + timeout); | ||
216 | + | ||
217 | + } | ||
218 | + } | ||
219 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +/** | ||
18 | + * Bmv2 API abstractions. | ||
19 | + */ | ||
20 | +package org.onosproject.bmv2.api; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +package org.onosproject.bmv2.ctl; | ||
18 | + | ||
19 | +import com.google.common.cache.CacheBuilder; | ||
20 | +import com.google.common.cache.CacheLoader; | ||
21 | +import com.google.common.cache.LoadingCache; | ||
22 | +import com.google.common.cache.RemovalListener; | ||
23 | +import com.google.common.cache.RemovalNotification; | ||
24 | +import com.google.common.collect.Lists; | ||
25 | +import org.apache.commons.lang3.tuple.ImmutablePair; | ||
26 | +import org.apache.commons.lang3.tuple.Pair; | ||
27 | +import org.apache.thrift.TException; | ||
28 | +import org.apache.thrift.protocol.TBinaryProtocol; | ||
29 | +import org.apache.thrift.protocol.TMultiplexedProtocol; | ||
30 | +import org.apache.thrift.protocol.TProtocol; | ||
31 | +import org.apache.thrift.transport.TSocket; | ||
32 | +import org.apache.thrift.transport.TTransport; | ||
33 | +import org.apache.thrift.transport.TTransportException; | ||
34 | +import org.onosproject.bmv2.api.Bmv2Action; | ||
35 | +import org.onosproject.bmv2.api.Bmv2Exception; | ||
36 | +import org.onosproject.bmv2.api.Bmv2PortInfo; | ||
37 | +import org.onosproject.bmv2.api.Bmv2TableEntry; | ||
38 | +import org.onosproject.net.DeviceId; | ||
39 | +import org.p4.bmv2.thrift.BmAddEntryOptions; | ||
40 | +import org.p4.bmv2.thrift.DevMgrPortInfo; | ||
41 | +import org.p4.bmv2.thrift.Standard; | ||
42 | + | ||
43 | +import java.util.Collection; | ||
44 | +import java.util.List; | ||
45 | +import java.util.concurrent.ExecutionException; | ||
46 | +import java.util.concurrent.TimeUnit; | ||
47 | +import java.util.stream.Collectors; | ||
48 | + | ||
49 | +import static com.google.common.base.Preconditions.checkNotNull; | ||
50 | + | ||
51 | +/** | ||
52 | + * Implementation of a Thrift client to control the Bmv2 switch. | ||
53 | + */ | ||
54 | +public final class Bmv2ThriftClient { | ||
55 | + /* | ||
56 | + FIXME: derive context_id from device id | ||
57 | + Using different context id values should serve to control different | ||
58 | + switches responding to the same IP address and port | ||
59 | + */ | ||
60 | + private static final int CONTEXT_ID = 0; | ||
61 | + /* | ||
62 | + Static transport/client cache: | ||
63 | + - avoids opening a new transport session when there's one already open | ||
64 | + - close the connection after a predefined timeout of 5 seconds | ||
65 | + */ | ||
66 | + private static LoadingCache<DeviceId, Pair<TTransport, Standard.Iface>> | ||
67 | + clientCache = CacheBuilder.newBuilder() | ||
68 | + .expireAfterAccess(5, TimeUnit.SECONDS) | ||
69 | + .removalListener(new ClientRemovalListener()) | ||
70 | + .build(new ClientLoader()); | ||
71 | + private final Standard.Iface stdClient; | ||
72 | + | ||
73 | + // ban constructor | ||
74 | + private Bmv2ThriftClient(Standard.Iface stdClient) { | ||
75 | + this.stdClient = stdClient; | ||
76 | + } | ||
77 | + | ||
78 | + /** | ||
79 | + * Returns a client object to control the passed device. | ||
80 | + * | ||
81 | + * @param deviceId device id | ||
82 | + * @return bmv2 client object | ||
83 | + * @throws Bmv2Exception if a connection to the device cannot be established | ||
84 | + */ | ||
85 | + public static Bmv2ThriftClient of(DeviceId deviceId) throws Bmv2Exception { | ||
86 | + try { | ||
87 | + checkNotNull(deviceId, "deviceId cannot be null"); | ||
88 | + return new Bmv2ThriftClient(clientCache.get(deviceId).getValue()); | ||
89 | + } catch (ExecutionException e) { | ||
90 | + throw new Bmv2Exception(e.getMessage(), e.getCause()); | ||
91 | + } | ||
92 | + } | ||
93 | + | ||
94 | + /** | ||
95 | + * Pings the device. Returns true if the device is reachable, | ||
96 | + * false otherwise. | ||
97 | + * | ||
98 | + * @param deviceId device id | ||
99 | + * @return true if reachable, false otherwise | ||
100 | + */ | ||
101 | + public static boolean ping(DeviceId deviceId) { | ||
102 | + // poll ports status as workaround to assess device reachability | ||
103 | + try { | ||
104 | + of(deviceId).stdClient.bm_dev_mgr_show_ports(); | ||
105 | + return true; | ||
106 | + } catch (TException | Bmv2Exception e) { | ||
107 | + return false; | ||
108 | + } | ||
109 | + } | ||
110 | + | ||
111 | + /** | ||
112 | + * Parse device ID into host and port. | ||
113 | + * | ||
114 | + * @param did device ID | ||
115 | + * @return a pair of host and port | ||
116 | + */ | ||
117 | + private static Pair<String, Integer> parseDeviceId(DeviceId did) { | ||
118 | + String[] info = did.toString().split(":"); | ||
119 | + if (info.length == 3) { | ||
120 | + String host = info[1]; | ||
121 | + int port = Integer.parseInt(info[2]); | ||
122 | + return ImmutablePair.of(host, port); | ||
123 | + } else { | ||
124 | + throw new IllegalArgumentException( | ||
125 | + "Unable to parse BMv2 device ID " | ||
126 | + + did.toString() | ||
127 | + + ", expected format is scheme:host:port"); | ||
128 | + } | ||
129 | + } | ||
130 | + | ||
131 | + /** | ||
132 | + * Adds a new table entry. | ||
133 | + * | ||
134 | + * @param entry a table entry value | ||
135 | + * @return table-specific entry ID | ||
136 | + * @throws Bmv2Exception if any error occurs | ||
137 | + */ | ||
138 | + public final long addTableEntry(Bmv2TableEntry entry) throws Bmv2Exception { | ||
139 | + | ||
140 | + long entryId = -1; | ||
141 | + | ||
142 | + try { | ||
143 | + BmAddEntryOptions options = new BmAddEntryOptions(); | ||
144 | + | ||
145 | + if (entry.hasPriority()) { | ||
146 | + options.setPriority(entry.priority()); | ||
147 | + } | ||
148 | + | ||
149 | + entryId = stdClient.bm_mt_add_entry( | ||
150 | + CONTEXT_ID, | ||
151 | + entry.tableName(), | ||
152 | + entry.matchKey().bmMatchParams(), | ||
153 | + entry.action().name(), | ||
154 | + entry.action().parameters(), | ||
155 | + options); | ||
156 | + | ||
157 | + if (entry.hasTimeout()) { | ||
158 | + /* bmv2 accepts timeouts in milliseconds */ | ||
159 | + int msTimeout = (int) Math.round(entry.timeout() * 1_000); | ||
160 | + stdClient.bm_mt_set_entry_ttl( | ||
161 | + CONTEXT_ID, entry.tableName(), entryId, msTimeout); | ||
162 | + } | ||
163 | + | ||
164 | + return entryId; | ||
165 | + | ||
166 | + } catch (TException e) { | ||
167 | + if (entryId != -1) { | ||
168 | + try { | ||
169 | + stdClient.bm_mt_delete_entry( | ||
170 | + CONTEXT_ID, entry.tableName(), entryId); | ||
171 | + } catch (TException e1) { | ||
172 | + // this should never happen as we know the entry is there | ||
173 | + throw new Bmv2Exception(e1.getMessage(), e1); | ||
174 | + } | ||
175 | + } | ||
176 | + throw new Bmv2Exception(e.getMessage(), e); | ||
177 | + } | ||
178 | + } | ||
179 | + | ||
180 | + /** | ||
181 | + * Modifies a currently installed entry by updating its action. | ||
182 | + * | ||
183 | + * @param tableName string value of table name | ||
184 | + * @param entryId long value of entry ID | ||
185 | + * @param action an action value | ||
186 | + * @throws Bmv2Exception if any error occurs | ||
187 | + */ | ||
188 | + public final void modifyTableEntry(String tableName, | ||
189 | + long entryId, Bmv2Action action) | ||
190 | + throws Bmv2Exception { | ||
191 | + | ||
192 | + try { | ||
193 | + stdClient.bm_mt_modify_entry( | ||
194 | + CONTEXT_ID, | ||
195 | + tableName, | ||
196 | + entryId, | ||
197 | + action.name(), | ||
198 | + action.parameters() | ||
199 | + ); | ||
200 | + } catch (TException e) { | ||
201 | + throw new Bmv2Exception(e.getMessage(), e); | ||
202 | + } | ||
203 | + } | ||
204 | + | ||
205 | + /** | ||
206 | + * Deletes currently installed entry. | ||
207 | + * | ||
208 | + * @param tableName string value of table name | ||
209 | + * @param entryId long value of entry ID | ||
210 | + * @throws Bmv2Exception if any error occurs | ||
211 | + */ | ||
212 | + public final void deleteTableEntry(String tableName, | ||
213 | + long entryId) throws Bmv2Exception { | ||
214 | + | ||
215 | + try { | ||
216 | + stdClient.bm_mt_delete_entry(CONTEXT_ID, tableName, entryId); | ||
217 | + } catch (TException e) { | ||
218 | + throw new Bmv2Exception(e.getMessage(), e); | ||
219 | + } | ||
220 | + } | ||
221 | + | ||
222 | + /** | ||
223 | + * Sets table default action. | ||
224 | + * | ||
225 | + * @param tableName string value of table name | ||
226 | + * @param action an action value | ||
227 | + * @throws Bmv2Exception if any error occurs | ||
228 | + */ | ||
229 | + public final void setTableDefaultAction(String tableName, Bmv2Action action) | ||
230 | + throws Bmv2Exception { | ||
231 | + | ||
232 | + try { | ||
233 | + stdClient.bm_mt_set_default_action( | ||
234 | + CONTEXT_ID, | ||
235 | + tableName, | ||
236 | + action.name(), | ||
237 | + action.parameters()); | ||
238 | + } catch (TException e) { | ||
239 | + throw new Bmv2Exception(e.getMessage(), e); | ||
240 | + } | ||
241 | + } | ||
242 | + | ||
243 | + /** | ||
244 | + * Returns information of the ports currently configured in the switch. | ||
245 | + * | ||
246 | + * @return collection of port information | ||
247 | + * @throws Bmv2Exception if any error occurs | ||
248 | + */ | ||
249 | + public Collection<Bmv2PortInfo> getPortsInfo() throws Bmv2Exception { | ||
250 | + | ||
251 | + try { | ||
252 | + List<DevMgrPortInfo> portInfos = stdClient.bm_dev_mgr_show_ports(); | ||
253 | + | ||
254 | + Collection<Bmv2PortInfo> bmv2PortInfos = Lists.newArrayList(); | ||
255 | + | ||
256 | + bmv2PortInfos.addAll( | ||
257 | + portInfos.stream() | ||
258 | + .map(Bmv2PortInfo::new) | ||
259 | + .collect(Collectors.toList())); | ||
260 | + | ||
261 | + return bmv2PortInfos; | ||
262 | + | ||
263 | + } catch (TException e) { | ||
264 | + throw new Bmv2Exception(e.getMessage(), e); | ||
265 | + } | ||
266 | + } | ||
267 | + | ||
268 | + /** | ||
269 | + * Return a string representation of a table content. | ||
270 | + * | ||
271 | + * @param tableName string value of table name | ||
272 | + * @return table string dump | ||
273 | + * @throws Bmv2Exception if any error occurs | ||
274 | + */ | ||
275 | + public String dumpTable(String tableName) throws Bmv2Exception { | ||
276 | + | ||
277 | + try { | ||
278 | + return stdClient.bm_dump_table(CONTEXT_ID, tableName); | ||
279 | + } catch (TException e) { | ||
280 | + throw new Bmv2Exception(e.getMessage(), e); | ||
281 | + } | ||
282 | + } | ||
283 | + | ||
284 | + /** | ||
285 | + * Reset the state of the switch (e.g. delete all entries, etc.). | ||
286 | + * | ||
287 | + * @throws Bmv2Exception if any error occurs | ||
288 | + */ | ||
289 | + public void resetState() throws Bmv2Exception { | ||
290 | + | ||
291 | + try { | ||
292 | + stdClient.bm_reset_state(); | ||
293 | + } catch (TException e) { | ||
294 | + throw new Bmv2Exception(e.getMessage(), e); | ||
295 | + } | ||
296 | + } | ||
297 | + | ||
298 | + /** | ||
299 | + * Transport/client cache loader. | ||
300 | + */ | ||
301 | + private static class ClientLoader | ||
302 | + extends CacheLoader<DeviceId, Pair<TTransport, Standard.Iface>> { | ||
303 | + | ||
304 | + @Override | ||
305 | + public Pair<TTransport, Standard.Iface> load(DeviceId deviceId) | ||
306 | + throws TTransportException { | ||
307 | + Pair<String, Integer> info = parseDeviceId(deviceId); | ||
308 | + //make the expensive call | ||
309 | + TTransport transport = new TSocket( | ||
310 | + info.getLeft(), info.getRight()); | ||
311 | + TProtocol protocol = new TBinaryProtocol(transport); | ||
312 | + Standard.Iface stdClient = new Standard.Client( | ||
313 | + new TMultiplexedProtocol(protocol, "standard")); | ||
314 | + | ||
315 | + transport.open(); | ||
316 | + | ||
317 | + return ImmutablePair.of(transport, stdClient); | ||
318 | + } | ||
319 | + } | ||
320 | + | ||
321 | + /** | ||
322 | + * Client cache removal listener. Close the connection on cache removal. | ||
323 | + */ | ||
324 | + private static class ClientRemovalListener implements | ||
325 | + RemovalListener<DeviceId, Pair<TTransport, Standard.Iface>> { | ||
326 | + | ||
327 | + @Override | ||
328 | + public void onRemoval( | ||
329 | + RemovalNotification<DeviceId, Pair<TTransport, Standard.Iface>> | ||
330 | + notification) { | ||
331 | + // close the transport connection | ||
332 | + notification.getValue().getKey().close(); | ||
333 | + } | ||
334 | + } | ||
335 | +} |
1 | +/* | ||
2 | + * Copyright 2014-2016 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 | + | ||
17 | +/** | ||
18 | + * BMv2 Thrift client implementation. | ||
19 | + */ | ||
20 | +package org.onosproject.bmv2.ctl; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
protocols/bmv2/src/main/thrift/.gitignore
0 → 100644
1 | +*.thrift | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
protocols/bmv2/src/main/thrift/patch.sh
0 → 100755
1 | +#! /bin/bash | ||
2 | +# | ||
3 | +# Copyright 2014-2016 Open Networking Laboratory | ||
4 | +# | ||
5 | +# Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | +# you may not use this file except in compliance with the License. | ||
7 | +# You may obtain a copy of the License at | ||
8 | +# | ||
9 | +# http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | +# | ||
11 | +# Unless required by applicable law or agreed to in writing, software | ||
12 | +# distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | +# See the License for the specific language governing permissions and | ||
15 | +# limitations under the License. | ||
16 | + | ||
17 | +# exit on errors | ||
18 | +set -e | ||
19 | + | ||
20 | +basedir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" | ||
21 | +ns="org.p4.bmv2.thrift" | ||
22 | + | ||
23 | +# add java namespace at beginning of file | ||
24 | +for f in ${basedir}/*.thrift | ||
25 | +do | ||
26 | + echo "namespace java ${ns}" | cat - ${f} > temp && mv temp ${f} | ||
27 | +done | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
-
Please register or login to post a comment