Committed by
Thomas Vachuska
Added BMv2 demo apps (onos1.6 cherry-pick)
Change-Id: I19484a826acce724c1fcd5b6e9910d724bda686f
Showing
21 changed files
with
971 additions
and
0 deletions
apps/bmv2-demo/common/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2016-present 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 | + <modelVersion>4.0.0</modelVersion> | ||
22 | + | ||
23 | + <parent> | ||
24 | + <artifactId>onos-app-bmv2-demo</artifactId> | ||
25 | + <groupId>org.onosproject</groupId> | ||
26 | + <version>1.7.0-SNAPSHOT</version> | ||
27 | + <relativePath>../pom.xml</relativePath> | ||
28 | + </parent> | ||
29 | + | ||
30 | + <artifactId>onos-app-bmv2-demo-common</artifactId> | ||
31 | + | ||
32 | + <packaging>bundle</packaging> | ||
33 | + | ||
34 | + <dependencies> | ||
35 | + <dependency> | ||
36 | + <groupId>org.onosproject</groupId> | ||
37 | + <artifactId>onos-bmv2-protocol-api</artifactId> | ||
38 | + <version>${project.version}</version> | ||
39 | + </dependency> | ||
40 | + </dependencies> | ||
41 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
apps/bmv2-demo/common/src/main/java/org/onosproject/bmv2/demo/app/common/package-info.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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 demo app common classes. | ||
19 | + */ | ||
20 | +package org.onosproject.bmv2.demo.app.common; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/bmv2-demo/ecmp/features.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
2 | + | ||
3 | +<!-- | ||
4 | + ~ Copyright 2016-present 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-app-bmv2-demo-common/${project.version}</bundle> | ||
24 | + </feature> | ||
25 | +</features> |
apps/bmv2-demo/ecmp/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2016-present 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 | + <modelVersion>4.0.0</modelVersion> | ||
22 | + | ||
23 | + <parent> | ||
24 | + <artifactId>onos-app-bmv2-demo</artifactId> | ||
25 | + <groupId>org.onosproject</groupId> | ||
26 | + <version>1.7.0-SNAPSHOT</version> | ||
27 | + <relativePath>../pom.xml</relativePath> | ||
28 | + </parent> | ||
29 | + | ||
30 | + <artifactId>onos-app-bmv2-demo-ecmp</artifactId> | ||
31 | + | ||
32 | + <packaging>bundle</packaging> | ||
33 | + | ||
34 | + <properties> | ||
35 | + <onos.app.name>org.onosproject.bmv2-ecmp-fabric</onos.app.name> | ||
36 | + <onos.app.title>P4/BMv2 Demo Fabric App v1 (ECMP)</onos.app.title> | ||
37 | + <onos.app.category>Traffic Steering</onos.app.category> | ||
38 | + <onos.app.url>http://onosproject.org</onos.app.url> | ||
39 | + <onos.app.readme>P4/BMv2 demo application with ECMP support for a 2-stage clos fabric topology</onos.app.readme> | ||
40 | + </properties> | ||
41 | + | ||
42 | + <dependencies> | ||
43 | + <dependency> | ||
44 | + <groupId>org.onosproject</groupId> | ||
45 | + <artifactId>onos-app-bmv2-demo-common</artifactId> | ||
46 | + <version>${project.version}</version> | ||
47 | + </dependency> | ||
48 | + </dependencies> | ||
49 | + | ||
50 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
1 | +/* | ||
2 | + * Copyright 2016-present 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.demo.app.ecmp; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableMap; | ||
20 | +import org.onlab.util.ImmutableByteSequence; | ||
21 | +import org.onosproject.bmv2.api.context.Bmv2HeaderTypeModel; | ||
22 | +import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam; | ||
23 | +import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; | ||
24 | +import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; | ||
25 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
26 | + | ||
27 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; | ||
28 | +import static org.onosproject.bmv2.demo.app.ecmp.EcmpFabricApp.ECMP_CONTEXT; | ||
29 | +import static org.onosproject.bmv2.demo.app.ecmp.EcmpInterpreter.*; | ||
30 | + | ||
31 | +/** | ||
32 | + * Builder of ECMP group table extension selector. | ||
33 | + */ | ||
34 | +public class EcmpGroupTableSelectorBuilder { | ||
35 | + | ||
36 | + private int groupId; | ||
37 | + private int selector; | ||
38 | + | ||
39 | + /** | ||
40 | + * Sets the ECMP group ID. | ||
41 | + * | ||
42 | + * @param groupId an integer value | ||
43 | + * @return this | ||
44 | + */ | ||
45 | + public EcmpGroupTableSelectorBuilder withGroupId(int groupId) { | ||
46 | + this.groupId = groupId; | ||
47 | + return this; | ||
48 | + } | ||
49 | + | ||
50 | + /** | ||
51 | + * Sets the ECMP selector. | ||
52 | + * | ||
53 | + * @param selector an integer value | ||
54 | + * @return this | ||
55 | + */ | ||
56 | + public EcmpGroupTableSelectorBuilder withSelector(int selector) { | ||
57 | + this.selector = selector; | ||
58 | + return this; | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * Returns a new extension selector. | ||
63 | + * | ||
64 | + * @return an extension selector | ||
65 | + */ | ||
66 | + public ExtensionSelector build() { | ||
67 | + Bmv2HeaderTypeModel headerTypeModel = ECMP_CONTEXT.configuration().headerType(ECMP_METADATA_T); | ||
68 | + int groupIdBitWidth = headerTypeModel.field(GROUP_ID).bitWidth(); | ||
69 | + int selectorBitWidth = headerTypeModel.field(SELECTOR).bitWidth(); | ||
70 | + | ||
71 | + try { | ||
72 | + ImmutableByteSequence groupIdBs = fitByteSequence(ImmutableByteSequence.copyFrom(groupId), | ||
73 | + groupIdBitWidth); | ||
74 | + ImmutableByteSequence selectorBs = fitByteSequence(ImmutableByteSequence.copyFrom(selector), | ||
75 | + selectorBitWidth); | ||
76 | + | ||
77 | + Bmv2ExactMatchParam groupIdMatch = new Bmv2ExactMatchParam(groupIdBs); | ||
78 | + Bmv2ExactMatchParam hashMatch = new Bmv2ExactMatchParam(selectorBs); | ||
79 | + | ||
80 | + return new Bmv2ExtensionSelector(ImmutableMap.of( | ||
81 | + ECMP_METADATA + "." + GROUP_ID, groupIdMatch, | ||
82 | + ECMP_METADATA + "." + SELECTOR, hashMatch)); | ||
83 | + | ||
84 | + } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { | ||
85 | + throw new RuntimeException(e); | ||
86 | + } | ||
87 | + } | ||
88 | +} |
apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpGroupTreatmentBuilder.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.demo.app.ecmp; | ||
18 | + | ||
19 | +import com.google.common.collect.Maps; | ||
20 | +import org.onlab.util.ImmutableByteSequence; | ||
21 | +import org.onosproject.bmv2.api.context.Bmv2ActionModel; | ||
22 | +import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
23 | +import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; | ||
24 | +import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; | ||
25 | +import org.onosproject.net.DeviceId; | ||
26 | +import org.onosproject.net.PortNumber; | ||
27 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
28 | + | ||
29 | +import java.util.Map; | ||
30 | +import java.util.Set; | ||
31 | + | ||
32 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; | ||
33 | +import static org.onosproject.bmv2.demo.app.ecmp.EcmpFabricApp.ECMP_CONTEXT; | ||
34 | +import static org.onosproject.bmv2.demo.app.ecmp.EcmpInterpreter.*; | ||
35 | + | ||
36 | +/** | ||
37 | + * Builder of ECMP extension treatments. | ||
38 | + */ | ||
39 | +public class EcmpGroupTreatmentBuilder { | ||
40 | + | ||
41 | + private static final Map<DeviceId, Map<Set<PortNumber>, Short>> DEVICE_GROUP_ID_MAP = Maps.newHashMap(); | ||
42 | + private int groupId; | ||
43 | + private int groupSize; | ||
44 | + | ||
45 | + /** | ||
46 | + * Sets the group ID. | ||
47 | + * | ||
48 | + * @param groupId an integer value | ||
49 | + * @return this | ||
50 | + */ | ||
51 | + public EcmpGroupTreatmentBuilder withGroupId(int groupId) { | ||
52 | + this.groupId = groupId; | ||
53 | + return this; | ||
54 | + } | ||
55 | + | ||
56 | + /** | ||
57 | + * Sets the group size. | ||
58 | + * | ||
59 | + * @param groupSize an integer value | ||
60 | + * @return this | ||
61 | + */ | ||
62 | + public EcmpGroupTreatmentBuilder withGroupSize(int groupSize) { | ||
63 | + this.groupSize = groupSize; | ||
64 | + return this; | ||
65 | + } | ||
66 | + | ||
67 | + /** | ||
68 | + * Returns a new extension treatment. | ||
69 | + * | ||
70 | + * @return an extension treatment | ||
71 | + */ | ||
72 | + public ExtensionTreatment build() { | ||
73 | + Bmv2ActionModel actionModel = ECMP_CONTEXT.configuration().action(ECMP_GROUP); | ||
74 | + int groupIdBitWidth = actionModel.runtimeData(GROUP_ID).bitWidth(); | ||
75 | + int groupSizeBitWidth = actionModel.runtimeData(GROUP_SIZE).bitWidth(); | ||
76 | + | ||
77 | + try { | ||
78 | + ImmutableByteSequence groupIdBs = fitByteSequence(ImmutableByteSequence.copyFrom(groupId), groupIdBitWidth); | ||
79 | + ImmutableByteSequence groupSizeBs = fitByteSequence(ImmutableByteSequence.copyFrom(groupSize), | ||
80 | + groupSizeBitWidth); | ||
81 | + | ||
82 | + return new Bmv2ExtensionTreatment(Bmv2Action.builder() | ||
83 | + .withName(ECMP_GROUP) | ||
84 | + .addParameter(groupIdBs) | ||
85 | + .addParameter(groupSizeBs) | ||
86 | + .build()); | ||
87 | + | ||
88 | + } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { | ||
89 | + throw new RuntimeException(e); | ||
90 | + } | ||
91 | + } | ||
92 | + | ||
93 | + /** | ||
94 | + * Returns a group ID for the given device and set of ports. | ||
95 | + * | ||
96 | + * @param deviceId a device ID | ||
97 | + * @param ports a set of ports | ||
98 | + * @return an integer value | ||
99 | + */ | ||
100 | + public static int groupIdOf(DeviceId deviceId, Set<PortNumber> ports) { | ||
101 | + DEVICE_GROUP_ID_MAP.putIfAbsent(deviceId, Maps.newHashMap()); | ||
102 | + // Counts the number of unique portNumber sets for each deviceId. | ||
103 | + // Each distinct set of portNumbers will have a unique ID. | ||
104 | + return DEVICE_GROUP_ID_MAP.get(deviceId).computeIfAbsent(ports, (pp) -> | ||
105 | + (short) (DEVICE_GROUP_ID_MAP.get(deviceId).size() + 1)); | ||
106 | + } | ||
107 | +} |
apps/bmv2-demo/ecmp/src/main/java/org/onosproject/bmv2/demo/app/ecmp/EcmpInterpreter.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.demo.app.ecmp; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableBiMap; | ||
20 | +import org.onlab.util.ImmutableByteSequence; | ||
21 | +import org.onosproject.bmv2.api.context.Bmv2Configuration; | ||
22 | +import org.onosproject.bmv2.api.context.Bmv2Interpreter; | ||
23 | +import org.onosproject.bmv2.api.context.Bmv2InterpreterException; | ||
24 | +import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
25 | +import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; | ||
26 | +import org.onosproject.net.PortNumber; | ||
27 | +import org.onosproject.net.flow.TrafficTreatment; | ||
28 | +import org.onosproject.net.flow.criteria.Criterion; | ||
29 | +import org.onosproject.net.flow.instructions.Instruction; | ||
30 | + | ||
31 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; | ||
32 | +import static org.onosproject.net.PortNumber.CONTROLLER; | ||
33 | +import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
34 | + | ||
35 | +/** | ||
36 | + * Implementation of a BMv2 interpreter for the ecmp.json configuration. | ||
37 | + */ | ||
38 | +public class EcmpInterpreter implements Bmv2Interpreter { | ||
39 | + | ||
40 | + protected static final String ECMP_METADATA_T = "ecmp_metadata_t"; | ||
41 | + protected static final String ECMP_METADATA = "ecmp_metadata"; | ||
42 | + protected static final String SELECTOR = "selector"; | ||
43 | + protected static final String GROUP_ID = "groupId"; | ||
44 | + protected static final String GROUP_SIZE = "groupSize"; | ||
45 | + protected static final String ECMP_GROUP = "ecmp_group"; | ||
46 | + protected static final String ECMP_GROUP_TABLE = "ecmp_group_table"; | ||
47 | + protected static final String TABLE0 = "table0"; | ||
48 | + protected static final String SEND_TO_CPU = "send_to_cpu"; | ||
49 | + protected static final String DROP = "_drop"; | ||
50 | + protected static final String SET_EGRESS_PORT = "set_egress_port"; | ||
51 | + protected static final String PORT = "port"; | ||
52 | + | ||
53 | + private static final ImmutableBiMap<Criterion.Type, String> CRITERION_TYPE_MAP = ImmutableBiMap.of( | ||
54 | + Criterion.Type.IN_PORT, "standard_metadata.ingress_port", | ||
55 | + Criterion.Type.ETH_DST, "ethernet.dstAddr", | ||
56 | + Criterion.Type.ETH_SRC, "ethernet.srcAddr", | ||
57 | + Criterion.Type.ETH_TYPE, "ethernet.etherType"); | ||
58 | + | ||
59 | + private static final ImmutableBiMap<Integer, String> TABLE_ID_MAP = ImmutableBiMap.of( | ||
60 | + 0, TABLE0, | ||
61 | + 1, ECMP_GROUP_TABLE); | ||
62 | + | ||
63 | + @Override | ||
64 | + public ImmutableBiMap<Integer, String> tableIdMap() { | ||
65 | + return TABLE_ID_MAP; | ||
66 | + } | ||
67 | + | ||
68 | + @Override | ||
69 | + public ImmutableBiMap<Criterion.Type, String> criterionTypeMap() { | ||
70 | + return CRITERION_TYPE_MAP; | ||
71 | + } | ||
72 | + | ||
73 | + @Override | ||
74 | + public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration) | ||
75 | + throws Bmv2InterpreterException { | ||
76 | + | ||
77 | + if (treatment.allInstructions().size() == 0) { | ||
78 | + // No instructions means drop for us. | ||
79 | + return actionWithName(DROP); | ||
80 | + } else if (treatment.allInstructions().size() > 1) { | ||
81 | + // Otherwise, we understand treatments with only 1 instruction. | ||
82 | + throw new Bmv2InterpreterException("Treatment has multiple instructions"); | ||
83 | + } | ||
84 | + | ||
85 | + Instruction instruction = treatment.allInstructions().get(0); | ||
86 | + | ||
87 | + switch (instruction.type()) { | ||
88 | + case OUTPUT: | ||
89 | + OutputInstruction outInstruction = (OutputInstruction) instruction; | ||
90 | + PortNumber port = outInstruction.port(); | ||
91 | + if (!port.isLogical()) { | ||
92 | + return buildEgressAction(port, configuration); | ||
93 | + } else if (port.equals(CONTROLLER)) { | ||
94 | + return actionWithName(SEND_TO_CPU); | ||
95 | + } else { | ||
96 | + throw new Bmv2InterpreterException("Egress on logical port not supported: " + port); | ||
97 | + } | ||
98 | + case NOACTION: | ||
99 | + return actionWithName(DROP); | ||
100 | + default: | ||
101 | + throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name()); | ||
102 | + } | ||
103 | + } | ||
104 | + | ||
105 | + private static Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration) | ||
106 | + throws Bmv2InterpreterException { | ||
107 | + | ||
108 | + int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth(); | ||
109 | + | ||
110 | + try { | ||
111 | + ImmutableByteSequence portBs = fitByteSequence(ImmutableByteSequence.copyFrom(port.toLong()), portBitWidth); | ||
112 | + return Bmv2Action.builder() | ||
113 | + .withName(SET_EGRESS_PORT) | ||
114 | + .addParameter(portBs) | ||
115 | + .build(); | ||
116 | + } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { | ||
117 | + throw new Bmv2InterpreterException(e.getMessage()); | ||
118 | + } | ||
119 | + } | ||
120 | + | ||
121 | + private static Bmv2Action actionWithName(String name) { | ||
122 | + return Bmv2Action.builder().withName(name).build(); | ||
123 | + } | ||
124 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 demo app for the ECMP configuration. | ||
19 | + */ | ||
20 | +package org.onosproject.bmv2.demo.app.ecmp; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/Users/carmelo/workspace/onos-p4-dev/p4src/build/ecmp.json | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
apps/bmv2-demo/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2014-present 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 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
18 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
19 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> | ||
20 | + <modelVersion>4.0.0</modelVersion> | ||
21 | + | ||
22 | + <parent> | ||
23 | + <groupId>org.onosproject</groupId> | ||
24 | + <artifactId>onos-apps</artifactId> | ||
25 | + <version>1.7.0-SNAPSHOT</version> | ||
26 | + <relativePath>../pom.xml</relativePath> | ||
27 | + </parent> | ||
28 | + | ||
29 | + <artifactId>onos-app-bmv2-demo</artifactId> | ||
30 | + | ||
31 | + <packaging>pom</packaging> | ||
32 | + | ||
33 | + <modules> | ||
34 | + <module>common</module> | ||
35 | + <module>ecmp</module> | ||
36 | + <module>wcmp</module> | ||
37 | + </modules> | ||
38 | + | ||
39 | +</project> |
apps/bmv2-demo/wcmp/features.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8" standalone="yes"?> | ||
2 | + | ||
3 | +<!-- | ||
4 | + ~ Copyright 2016-present 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-app-bmv2-demo-common/${project.version}</bundle> | ||
24 | + </feature> | ||
25 | +</features> |
apps/bmv2-demo/wcmp/pom.xml
0 → 100644
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<!-- | ||
3 | + ~ Copyright 2016-present 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 | + <modelVersion>4.0.0</modelVersion> | ||
22 | + | ||
23 | + <parent> | ||
24 | + <artifactId>onos-app-bmv2-demo</artifactId> | ||
25 | + <groupId>org.onosproject</groupId> | ||
26 | + <version>1.7.0-SNAPSHOT</version> | ||
27 | + <relativePath>../pom.xml</relativePath> | ||
28 | + </parent> | ||
29 | + | ||
30 | + <artifactId>onos-app-bmv2-demo-wcmp</artifactId> | ||
31 | + | ||
32 | + <packaging>bundle</packaging> | ||
33 | + | ||
34 | + <properties> | ||
35 | + <onos.app.name>org.onosproject.bmv2-wcmp-fabric</onos.app.name> | ||
36 | + <onos.app.title>P4/BMv2 Demo Fabric App v2 (WCMP)</onos.app.title> | ||
37 | + <onos.app.category>Traffic Steering</onos.app.category> | ||
38 | + <onos.app.url>http://onosproject.org</onos.app.url> | ||
39 | + <onos.app.readme>P4/BMv2 demo application with WCMP support for a 2-stage clos fabric topology</onos.app.readme> | ||
40 | + </properties> | ||
41 | + | ||
42 | + <dependencies> | ||
43 | + <dependency> | ||
44 | + <groupId>org.onosproject</groupId> | ||
45 | + <artifactId>onos-app-bmv2-demo-common</artifactId> | ||
46 | + <version>${project.version}</version> | ||
47 | + </dependency> | ||
48 | + </dependencies> | ||
49 | + | ||
50 | +</project> | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
1 | +/* | ||
2 | + * Copyright 2016-present 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.demo.app.wcmp; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableMap; | ||
20 | +import org.onlab.util.ImmutableByteSequence; | ||
21 | +import org.onosproject.bmv2.api.runtime.Bmv2ExactMatchParam; | ||
22 | +import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; | ||
23 | +import org.onosproject.bmv2.api.runtime.Bmv2LpmMatchParam; | ||
24 | +import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; | ||
25 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
26 | + | ||
27 | +import static com.google.common.base.Preconditions.checkArgument; | ||
28 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; | ||
29 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.roundToBytes; | ||
30 | +import static org.onosproject.bmv2.demo.app.wcmp.WcmpFabricApp.WCMP_CONTEXT; | ||
31 | +import static org.onosproject.bmv2.demo.app.wcmp.WcmpInterpreter.*; | ||
32 | + | ||
33 | +/** | ||
34 | + * Builder of WCMP group table extension selector. | ||
35 | + */ | ||
36 | +public final class WcmpGroupTableSelectorBuilder { | ||
37 | + | ||
38 | + private int groupId; | ||
39 | + private int prefixLength; | ||
40 | + | ||
41 | + /** | ||
42 | + * Sets the WCMP group ID. | ||
43 | + * | ||
44 | + * @param groupId an integer value | ||
45 | + * @return this | ||
46 | + */ | ||
47 | + public WcmpGroupTableSelectorBuilder withGroupId(int groupId) { | ||
48 | + this.groupId = groupId; | ||
49 | + return this; | ||
50 | + } | ||
51 | + | ||
52 | + /** | ||
53 | + * Sets the WCMP selector's prefix length. | ||
54 | + * | ||
55 | + * @param prefixLength an integer value | ||
56 | + * @return this | ||
57 | + */ | ||
58 | + public WcmpGroupTableSelectorBuilder withPrefixLength(int prefixLength) { | ||
59 | + this.prefixLength = prefixLength; | ||
60 | + return this; | ||
61 | + } | ||
62 | + | ||
63 | + /** | ||
64 | + * Returns a new extension selector. | ||
65 | + * | ||
66 | + * @return an extension selector | ||
67 | + */ | ||
68 | + public ExtensionSelector build() { | ||
69 | + | ||
70 | + final int selectorBitWidth = WCMP_CONTEXT.configuration().headerType(WCMP_META_T).field(SELECTOR).bitWidth(); | ||
71 | + final int groupIdBitWidth = WCMP_CONTEXT.configuration().headerType(WCMP_META_T).field(GROUP_ID).bitWidth(); | ||
72 | + final ImmutableByteSequence ones = ImmutableByteSequence.ofOnes(roundToBytes(selectorBitWidth)); | ||
73 | + | ||
74 | + checkArgument(prefixLength >= 1 && prefixLength <= selectorBitWidth, | ||
75 | + "prefix length must be between 1 and " + selectorBitWidth); | ||
76 | + try { | ||
77 | + ImmutableByteSequence groupIdBs = fitByteSequence(ImmutableByteSequence.copyFrom(groupId), groupIdBitWidth); | ||
78 | + Bmv2ExactMatchParam groupIdMatch = new Bmv2ExactMatchParam(groupIdBs); | ||
79 | + Bmv2LpmMatchParam selectorMatch = new Bmv2LpmMatchParam(ones, prefixLength); | ||
80 | + | ||
81 | + return new Bmv2ExtensionSelector(ImmutableMap.of( | ||
82 | + WCMP_META + "." + GROUP_ID, groupIdMatch, | ||
83 | + WCMP_META + "." + SELECTOR, selectorMatch)); | ||
84 | + | ||
85 | + } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { | ||
86 | + throw new RuntimeException(e); | ||
87 | + } | ||
88 | + } | ||
89 | +} |
apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpGroupTreatmentBuilder.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.demo.app.wcmp; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableList; | ||
20 | +import com.google.common.collect.Lists; | ||
21 | +import com.google.common.collect.Maps; | ||
22 | +import org.onlab.util.ImmutableByteSequence; | ||
23 | +import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
24 | +import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; | ||
25 | +import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; | ||
26 | +import org.onosproject.net.DeviceId; | ||
27 | +import org.onosproject.net.PortNumber; | ||
28 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
29 | + | ||
30 | +import java.util.Collections; | ||
31 | +import java.util.List; | ||
32 | +import java.util.Map; | ||
33 | + | ||
34 | +import static com.google.common.base.Preconditions.checkArgument; | ||
35 | +import static java.util.stream.Collectors.toList; | ||
36 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; | ||
37 | +import static org.onosproject.bmv2.demo.app.wcmp.WcmpFabricApp.WCMP_CONTEXT; | ||
38 | +import static org.onosproject.bmv2.demo.app.wcmp.WcmpInterpreter.*; | ||
39 | + | ||
40 | +/** | ||
41 | + * Builder of WCMP extension treatment. | ||
42 | + */ | ||
43 | +public final class WcmpGroupTreatmentBuilder { | ||
44 | + | ||
45 | + private static final double MAX_ERROR = 0.0001; | ||
46 | + | ||
47 | + private static final Map<DeviceId, Map<Map<PortNumber, Double>, Integer>> DEVICE_GROUP_ID_MAP = Maps.newHashMap(); | ||
48 | + | ||
49 | + private int groupId; | ||
50 | + | ||
51 | + /** | ||
52 | + * Sets the WCMP group ID. | ||
53 | + * | ||
54 | + * @param groupId an integer value | ||
55 | + * @return this | ||
56 | + */ | ||
57 | + public WcmpGroupTreatmentBuilder withGroupId(int groupId) { | ||
58 | + this.groupId = groupId; | ||
59 | + return this; | ||
60 | + } | ||
61 | + | ||
62 | + /** | ||
63 | + * Returns a new extension treatment. | ||
64 | + * | ||
65 | + * @return an extension treatment | ||
66 | + */ | ||
67 | + public ExtensionTreatment build() { | ||
68 | + checkArgument(groupId >= 0, "group id must be a non-zero positive integer"); | ||
69 | + ImmutableByteSequence groupIdBs = ImmutableByteSequence.copyFrom(groupId); | ||
70 | + final int groupIdBitWidth = WCMP_CONTEXT.configuration().headerType(WCMP_META_T).field(GROUP_ID).bitWidth(); | ||
71 | + try { | ||
72 | + groupIdBs = fitByteSequence(groupIdBs, groupIdBitWidth); | ||
73 | + return new Bmv2ExtensionTreatment( | ||
74 | + Bmv2Action.builder() | ||
75 | + .withName(WCMP_GROUP) | ||
76 | + .addParameter(groupIdBs) | ||
77 | + .build()); | ||
78 | + } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { | ||
79 | + throw new RuntimeException(e); | ||
80 | + } | ||
81 | + } | ||
82 | + | ||
83 | + public static int groupIdOf(DeviceId did, Map<PortNumber, Double> weightedPorts) { | ||
84 | + DEVICE_GROUP_ID_MAP.putIfAbsent(did, Maps.newHashMap()); | ||
85 | + // Counts the number of unique portNumber sets for each device ID. | ||
86 | + // Each distinct set of portNumbers will have a unique ID. | ||
87 | + return DEVICE_GROUP_ID_MAP.get(did).computeIfAbsent(weightedPorts, | ||
88 | + (pp) -> DEVICE_GROUP_ID_MAP.get(did).size() + 1); | ||
89 | + } | ||
90 | + | ||
91 | + public static List<Integer> toPrefixLengths(List<Double> weigths) throws WcmpGroupException { | ||
92 | + | ||
93 | + double weightSum = weigths.stream() | ||
94 | + .mapToDouble(Double::doubleValue) | ||
95 | + .map(WcmpGroupTreatmentBuilder::roundDouble) | ||
96 | + .sum(); | ||
97 | + | ||
98 | + if (Math.abs(weightSum - 1) > MAX_ERROR) { | ||
99 | + throw new WcmpGroupException("weights sum is expected to be 1, found was " + weightSum); | ||
100 | + } | ||
101 | + | ||
102 | + final int selectorBitWidth = WCMP_CONTEXT.configuration().headerType(WCMP_META_T).field(SELECTOR).bitWidth(); | ||
103 | + final int availableBits = selectorBitWidth - 1; | ||
104 | + | ||
105 | + List<Long> prefixDiffs = weigths.stream().map(w -> Math.round(w * availableBits)).collect(toList()); | ||
106 | + | ||
107 | + final long bitSum = prefixDiffs.stream().mapToLong(Long::longValue).sum(); | ||
108 | + final long error = availableBits - bitSum; | ||
109 | + | ||
110 | + if (error != 0) { | ||
111 | + // Lazy intuition here is that the error can be absorbed by the longest prefixDiff with the minor impact. | ||
112 | + Long maxDiff = Collections.max(prefixDiffs); | ||
113 | + int idx = prefixDiffs.indexOf(maxDiff); | ||
114 | + prefixDiffs.remove(idx); | ||
115 | + prefixDiffs.add(idx, maxDiff + error); | ||
116 | + } | ||
117 | + List<Integer> prefixLengths = Lists.newArrayList(); | ||
118 | + | ||
119 | + int prefix = 1; | ||
120 | + for (Long p : prefixDiffs) { | ||
121 | + prefixLengths.add(prefix); | ||
122 | + prefix += p; | ||
123 | + } | ||
124 | + return ImmutableList.copyOf(prefixLengths); | ||
125 | + } | ||
126 | + | ||
127 | + private static double roundDouble(double n) { | ||
128 | + // 5 digits precision. | ||
129 | + return (double) Math.round(n * 100000d) / 100000d; | ||
130 | + } | ||
131 | + | ||
132 | + public static class WcmpGroupException extends Exception { | ||
133 | + public WcmpGroupException(String s) { | ||
134 | + } | ||
135 | + } | ||
136 | +} |
apps/bmv2-demo/wcmp/src/main/java/org/onosproject/bmv2/demo/app/wcmp/WcmpInterpreter.java
0 → 100644
1 | +/* | ||
2 | + * Copyright 2016-present 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.demo.app.wcmp; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableBiMap; | ||
20 | +import org.onlab.util.ImmutableByteSequence; | ||
21 | +import org.onosproject.bmv2.api.context.Bmv2Configuration; | ||
22 | +import org.onosproject.bmv2.api.context.Bmv2Interpreter; | ||
23 | +import org.onosproject.bmv2.api.context.Bmv2InterpreterException; | ||
24 | +import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
25 | +import org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils; | ||
26 | +import org.onosproject.net.PortNumber; | ||
27 | +import org.onosproject.net.flow.TrafficTreatment; | ||
28 | +import org.onosproject.net.flow.criteria.Criterion; | ||
29 | +import org.onosproject.net.flow.instructions.Instruction; | ||
30 | +import org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
31 | + | ||
32 | +import java.util.Map; | ||
33 | + | ||
34 | +import static org.onosproject.bmv2.api.utils.Bmv2TranslatorUtils.fitByteSequence; | ||
35 | +import static org.onosproject.net.PortNumber.CONTROLLER; | ||
36 | + | ||
37 | +/** | ||
38 | + * Implementation of a BMv2 interpreter for the wcmp.json configuration. | ||
39 | + */ | ||
40 | +public final class WcmpInterpreter implements Bmv2Interpreter { | ||
41 | + | ||
42 | + protected static final String WCMP_META_T = "wcmp_meta_t"; | ||
43 | + protected static final String WCMP_META = "wcmp_meta"; | ||
44 | + protected static final String SELECTOR = "selector"; | ||
45 | + protected static final String GROUP_ID = "groupId"; | ||
46 | + protected static final String WCMP_GROUP = "wcmp_group"; | ||
47 | + protected static final String WCMP_SET_SELECTOR = "wcmp_set_selector"; | ||
48 | + protected static final String WCMP_SET_SELECTOR_TABLE = "wcmp_set_selector_table"; | ||
49 | + protected static final String WCMP_GROUP_TABLE = "wcmp_group_table"; | ||
50 | + protected static final String TABLE0 = "table0"; | ||
51 | + protected static final String SEND_TO_CPU = "send_to_cpu"; | ||
52 | + protected static final String DROP = "_drop"; | ||
53 | + protected static final String SET_EGRESS_PORT = "set_egress_port"; | ||
54 | + protected static final String PORT = "port"; | ||
55 | + | ||
56 | + private static final ImmutableBiMap<Criterion.Type, String> CRITERION_TYPE_MAP = ImmutableBiMap.of( | ||
57 | + Criterion.Type.IN_PORT, "standard_metadata.ingress_port", | ||
58 | + Criterion.Type.ETH_DST, "ethernet.dstAddr", | ||
59 | + Criterion.Type.ETH_SRC, "ethernet.srcAddr", | ||
60 | + Criterion.Type.ETH_TYPE, "ethernet.etherType"); | ||
61 | + | ||
62 | + private static final ImmutableBiMap<Integer, String> TABLE_ID_MAP = ImmutableBiMap.of( | ||
63 | + 0, TABLE0, | ||
64 | + 1, WCMP_GROUP_TABLE); | ||
65 | + | ||
66 | + private static final Map<String, Bmv2Action> DEFAULT_ACTIONS_MAP = ImmutableBiMap.of( | ||
67 | + WCMP_SET_SELECTOR_TABLE, actionWithName(WCMP_SET_SELECTOR)); | ||
68 | + | ||
69 | + @Override | ||
70 | + public ImmutableBiMap<Integer, String> tableIdMap() { | ||
71 | + return TABLE_ID_MAP; | ||
72 | + } | ||
73 | + | ||
74 | + @Override | ||
75 | + public ImmutableBiMap<Criterion.Type, String> criterionTypeMap() { | ||
76 | + return CRITERION_TYPE_MAP; | ||
77 | + } | ||
78 | + | ||
79 | + public Map<String, Bmv2Action> defaultActionsMap() { | ||
80 | + return DEFAULT_ACTIONS_MAP; | ||
81 | + } | ||
82 | + | ||
83 | + @Override | ||
84 | + public Bmv2Action mapTreatment(TrafficTreatment treatment, Bmv2Configuration configuration) | ||
85 | + throws Bmv2InterpreterException { | ||
86 | + | ||
87 | + if (treatment.allInstructions().size() == 0) { | ||
88 | + // No instructions means drop for us. | ||
89 | + return actionWithName(DROP); | ||
90 | + } else if (treatment.allInstructions().size() > 1) { | ||
91 | + // Otherwise, we understand treatments with only 1 instruction. | ||
92 | + throw new Bmv2InterpreterException("Treatment has multiple instructions"); | ||
93 | + } | ||
94 | + | ||
95 | + Instruction instruction = treatment.allInstructions().get(0); | ||
96 | + | ||
97 | + switch (instruction.type()) { | ||
98 | + case OUTPUT: | ||
99 | + OutputInstruction outInstruction = (OutputInstruction) instruction; | ||
100 | + PortNumber port = outInstruction.port(); | ||
101 | + if (!port.isLogical()) { | ||
102 | + return buildEgressAction(port, configuration); | ||
103 | + } else if (port.equals(CONTROLLER)) { | ||
104 | + return actionWithName(SEND_TO_CPU); | ||
105 | + } else { | ||
106 | + throw new Bmv2InterpreterException("Egress on logical port not supported: " + port); | ||
107 | + } | ||
108 | + case NOACTION: | ||
109 | + return actionWithName(DROP); | ||
110 | + default: | ||
111 | + throw new Bmv2InterpreterException("Instruction type not supported: " + instruction.type().name()); | ||
112 | + } | ||
113 | + } | ||
114 | + | ||
115 | + private static Bmv2Action buildEgressAction(PortNumber port, Bmv2Configuration configuration) | ||
116 | + throws Bmv2InterpreterException { | ||
117 | + | ||
118 | + int portBitWidth = configuration.action(SET_EGRESS_PORT).runtimeData(PORT).bitWidth(); | ||
119 | + | ||
120 | + try { | ||
121 | + ImmutableByteSequence portBs = fitByteSequence(ImmutableByteSequence.copyFrom(port.toLong()), portBitWidth); | ||
122 | + return Bmv2Action.builder() | ||
123 | + .withName(SET_EGRESS_PORT) | ||
124 | + .addParameter(portBs) | ||
125 | + .build(); | ||
126 | + } catch (Bmv2TranslatorUtils.ByteSequenceFitException e) { | ||
127 | + throw new Bmv2InterpreterException(e.getMessage()); | ||
128 | + } | ||
129 | + } | ||
130 | + | ||
131 | + private static Bmv2Action actionWithName(String name) { | ||
132 | + return Bmv2Action.builder().withName(name).build(); | ||
133 | + } | ||
134 | +} |
1 | +/* | ||
2 | + * Copyright 2016-present 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 demo app for the WCMP configuration. | ||
19 | + */ | ||
20 | +package org.onosproject.bmv2.demo.app.wcmp; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
1 | +/Users/carmelo/workspace/onos-p4-dev/p4src/build/wcmp.json | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
... | @@ -71,6 +71,7 @@ | ... | @@ -71,6 +71,7 @@ |
71 | <module>graphitemetrics</module> | 71 | <module>graphitemetrics</module> |
72 | <module>xosclient</module> | 72 | <module>xosclient</module> |
73 | <module>scalablegateway</module> | 73 | <module>scalablegateway</module> |
74 | + <module>bmv2-demo</module> | ||
74 | </modules> | 75 | </modules> |
75 | 76 | ||
76 | 77 | ... | ... |
-
Please register or login to post a comment