Committed by
Brian O'Connor
Various changes in BMv2 driver and provider modules
Driver notable changes: - Implemented new behaviors, removed deprecated ones - Removed flow rule translator classes (now under protocol module) - Improved FlowRuleProgrammable: now it uses BMv2TableEntryService to lookup/bind flow rules with BMv2 table entries, retrieves flow statistics, better exception handling when adding/replacing/removing table entries. - Improved PacketProgrammable: better exception handling and logging Provider notable changes: - Bmv2DeviceProvider: detects and notifies device configuration changes and reboots to Bmv2DeviceContextService, added support for periodic polling of port statistics - Bmv2PacketProvider: implemented workaround for OutboundPackets with flood treatment Change-Id: I79b756b533d4afb6b70025a137b2e811fd42a4e8
Showing
31 changed files
with
411 additions
and
588 deletions
... | @@ -20,6 +20,6 @@ | ... | @@ -20,6 +20,6 @@ |
20 | <feature name="${project.artifactId}" version="${project.version}" | 20 | <feature name="${project.artifactId}" version="${project.version}" |
21 | description="${project.description}"> | 21 | description="${project.description}"> |
22 | <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> | 22 | <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> |
23 | - <bundle>mvn:${project.groupId}/onos-bmv2-protocol/${project.version}</bundle> | 23 | + <bundle>mvn:${project.groupId}/onos-bmv2-protocol-api/${project.version}</bundle> |
24 | </feature> | 24 | </feature> |
25 | </features> | 25 | </features> | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-drivers-general</artifactId> | 22 | <artifactId>onos-drivers-general</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | <modelVersion>4.0.0</modelVersion> | 27 | <modelVersion>4.0.0</modelVersion> |
27 | 28 | ||
... | @@ -36,7 +37,7 @@ | ... | @@ -36,7 +37,7 @@ |
36 | <onos.app.name>org.onosproject.drivers.bmv2</onos.app.name> | 37 | <onos.app.name>org.onosproject.drivers.bmv2</onos.app.name> |
37 | <onos.app.origin>ON.Lab</onos.app.origin> | 38 | <onos.app.origin>ON.Lab</onos.app.origin> |
38 | <onos.app.category>Drivers</onos.app.category> | 39 | <onos.app.category>Drivers</onos.app.category> |
39 | - <onos.app.title>BMv2 Device Drivers</onos.app.title> | 40 | + <onos.app.title>BMv2 Drivers</onos.app.title> |
40 | <onos.app.url>http://onosproject.org</onos.app.url> | 41 | <onos.app.url>http://onosproject.org</onos.app.url> |
41 | <onos.app.requires> | 42 | <onos.app.requires> |
42 | org.onosproject.bmv2 | 43 | org.onosproject.bmv2 |
... | @@ -46,7 +47,7 @@ | ... | @@ -46,7 +47,7 @@ |
46 | <dependencies> | 47 | <dependencies> |
47 | <dependency> | 48 | <dependency> |
48 | <groupId>org.onosproject</groupId> | 49 | <groupId>org.onosproject</groupId> |
49 | - <artifactId>onos-bmv2-protocol</artifactId> | 50 | + <artifactId>onos-bmv2-protocol-api</artifactId> |
50 | <version>${project.version}</version> | 51 | <version>${project.version}</version> |
51 | </dependency> | 52 | </dependency> |
52 | <dependency> | 53 | <dependency> | ... | ... |
drivers/bmv2/src/main/java/org/onosproject/drivers/bmv2/Bmv2DeviceDescriptionDiscovery.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.drivers.bmv2; | ||
18 | + | ||
19 | +import com.google.common.collect.ImmutableList; | ||
20 | +import com.google.common.collect.Lists; | ||
21 | +import org.onlab.packet.ChassisId; | ||
22 | +import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; | ||
23 | +import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; | ||
24 | +import org.onosproject.bmv2.api.service.Bmv2Controller; | ||
25 | +import org.onosproject.net.AnnotationKeys; | ||
26 | +import org.onosproject.net.DefaultAnnotations; | ||
27 | +import org.onosproject.net.DeviceId; | ||
28 | +import org.onosproject.net.PortNumber; | ||
29 | +import org.onosproject.net.device.DefaultDeviceDescription; | ||
30 | +import org.onosproject.net.device.DefaultPortDescription; | ||
31 | +import org.onosproject.net.device.DeviceDescription; | ||
32 | +import org.onosproject.net.device.DeviceDescriptionDiscovery; | ||
33 | +import org.onosproject.net.device.PortDescription; | ||
34 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
35 | +import org.slf4j.Logger; | ||
36 | +import org.slf4j.LoggerFactory; | ||
37 | + | ||
38 | +import java.math.BigInteger; | ||
39 | +import java.util.List; | ||
40 | + | ||
41 | +import static org.onosproject.bmv2.api.runtime.Bmv2Device.*; | ||
42 | +import static org.onosproject.net.Device.Type.SWITCH; | ||
43 | + | ||
44 | +/** | ||
45 | + * Implementation of the device description discovery behaviour for BMv2. | ||
46 | + */ | ||
47 | +public class Bmv2DeviceDescriptionDiscovery extends AbstractHandlerBehaviour implements DeviceDescriptionDiscovery { | ||
48 | + | ||
49 | + private static final String JSON_CONFIG_MD5 = "bmv2JsonConfigMd5"; | ||
50 | + private static final String PROCESS_INSTANCE_ID = "bmv2ProcessInstanceId"; | ||
51 | + | ||
52 | + private final Logger log = LoggerFactory.getLogger(this.getClass()); | ||
53 | + | ||
54 | + private Bmv2Controller controller; | ||
55 | + | ||
56 | + private boolean init() { | ||
57 | + controller = handler().get(Bmv2Controller.class); | ||
58 | + if (controller == null) { | ||
59 | + log.warn("Failed to get a BMv2 controller"); | ||
60 | + return false; | ||
61 | + } | ||
62 | + return true; | ||
63 | + } | ||
64 | + | ||
65 | + @Override | ||
66 | + public DeviceDescription discoverDeviceDetails() { | ||
67 | + | ||
68 | + if (!init()) { | ||
69 | + return null; | ||
70 | + } | ||
71 | + | ||
72 | + DeviceId deviceId = handler().data().deviceId(); | ||
73 | + | ||
74 | + Bmv2DeviceAgent deviceAgent; | ||
75 | + try { | ||
76 | + deviceAgent = controller.getAgent(deviceId); | ||
77 | + } catch (Bmv2RuntimeException e) { | ||
78 | + log.error("Failed to connect to Bmv2 device", e); | ||
79 | + return null; | ||
80 | + } | ||
81 | + | ||
82 | + DefaultAnnotations.Builder annotationsBuilder = DefaultAnnotations.builder(); | ||
83 | + | ||
84 | + try { | ||
85 | + String md5 = deviceAgent.getJsonConfigMd5(); | ||
86 | + BigInteger i = new BigInteger(1, md5.getBytes()); | ||
87 | + annotationsBuilder.set(JSON_CONFIG_MD5, String.format("%1$032X", i).toLowerCase()); | ||
88 | + } catch (Bmv2RuntimeException e) { | ||
89 | + log.warn("Unable to dump JSON configuration from {}: {}", deviceId, e.explain()); | ||
90 | + } | ||
91 | + try { | ||
92 | + int instanceId = deviceAgent.getProcessInstanceId(); | ||
93 | + annotationsBuilder.set(PROCESS_INSTANCE_ID, String.valueOf(instanceId)); | ||
94 | + } catch (Bmv2RuntimeException e) { | ||
95 | + log.warn("Unable to get process instance ID from {}: {}", deviceId, e.explain()); | ||
96 | + } | ||
97 | + | ||
98 | + annotationsBuilder.set(AnnotationKeys.PROTOCOL, PROTOCOL); | ||
99 | + | ||
100 | + return new DefaultDeviceDescription(deviceId.uri(), | ||
101 | + SWITCH, | ||
102 | + MANUFACTURER, | ||
103 | + HW_VERSION, | ||
104 | + SW_VERSION, | ||
105 | + SERIAL_NUMBER, | ||
106 | + new ChassisId(), | ||
107 | + annotationsBuilder.build()); | ||
108 | + } | ||
109 | + | ||
110 | + @Override | ||
111 | + public List<PortDescription> discoverPortDetails() { | ||
112 | + | ||
113 | + if (!init()) { | ||
114 | + return null; | ||
115 | + } | ||
116 | + | ||
117 | + DeviceId deviceId = handler().data().deviceId(); | ||
118 | + | ||
119 | + Bmv2DeviceAgent deviceAgent; | ||
120 | + try { | ||
121 | + deviceAgent = controller.getAgent(deviceId); | ||
122 | + } catch (Bmv2RuntimeException e) { | ||
123 | + log.error("Failed to connect to Bmv2 device", e); | ||
124 | + return null; | ||
125 | + } | ||
126 | + | ||
127 | + List<PortDescription> portDescriptions = Lists.newArrayList(); | ||
128 | + | ||
129 | + try { | ||
130 | + deviceAgent.getPortsInfo().forEach(p -> { | ||
131 | + PortNumber portNumber = PortNumber.portNumber((long) p.number(), p.ifaceName()); | ||
132 | + portDescriptions.add(new DefaultPortDescription(portNumber, p.isUp(), DefaultAnnotations.EMPTY)); | ||
133 | + }); | ||
134 | + } catch (Bmv2RuntimeException e) { | ||
135 | + log.error("Unable to get port descriptions of {}: {}", deviceId, e); | ||
136 | + } | ||
137 | + | ||
138 | + return ImmutableList.copyOf(portDescriptions); | ||
139 | + } | ||
140 | +} |
... | @@ -20,7 +20,7 @@ import org.apache.felix.scr.annotations.Component; | ... | @@ -20,7 +20,7 @@ import org.apache.felix.scr.annotations.Component; |
20 | import org.onosproject.net.driver.AbstractDriverLoader; | 20 | import org.onosproject.net.driver.AbstractDriverLoader; |
21 | 21 | ||
22 | /** | 22 | /** |
23 | - * Loader for barefoot drivers from specific xml. | 23 | + * Loader for BMv2 drivers from xml file. |
24 | */ | 24 | */ |
25 | @Component(immediate = true) | 25 | @Component(immediate = true) |
26 | public class Bmv2DriversLoader extends AbstractDriverLoader { | 26 | public class Bmv2DriversLoader extends AbstractDriverLoader { | ... | ... |
... | @@ -14,7 +14,29 @@ | ... | @@ -14,7 +14,29 @@ |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | +package org.onosproject.drivers.bmv2; | ||
18 | + | ||
19 | +import org.onosproject.bmv2.api.runtime.Bmv2ExtensionSelector; | ||
20 | +import org.onosproject.net.behaviour.ExtensionSelectorResolver; | ||
21 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
22 | +import org.onosproject.net.flow.criteria.ExtensionSelector; | ||
23 | +import org.onosproject.net.flow.criteria.ExtensionSelectorType; | ||
24 | + | ||
25 | +import java.util.Collections; | ||
26 | + | ||
27 | +import static org.onosproject.net.flow.criteria.ExtensionSelectorType.ExtensionSelectorTypes.BMV2_MATCH_PARAMS; | ||
28 | + | ||
17 | /** | 29 | /** |
18 | - * Translators of ONOS abstractions to BMv2 model-dependent abstractions. | 30 | + * Implementation of the extension selector resolver behaviour for BMv2. |
19 | */ | 31 | */ |
20 | -package org.onosproject.drivers.bmv2.translators; | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
32 | +public class Bmv2ExtensionSelectorResolver extends AbstractHandlerBehaviour implements ExtensionSelectorResolver { | ||
33 | + | ||
34 | + @Override | ||
35 | + public ExtensionSelector getExtensionSelector(ExtensionSelectorType type) { | ||
36 | + if (type.equals(BMV2_MATCH_PARAMS.type())) { | ||
37 | + return new Bmv2ExtensionSelector(Collections.emptyMap()); | ||
38 | + } | ||
39 | + | ||
40 | + return null; | ||
41 | + } | ||
42 | +} | ... | ... |
... | @@ -14,14 +14,26 @@ | ... | @@ -14,14 +14,26 @@ |
14 | * limitations under the License. | 14 | * limitations under the License. |
15 | */ | 15 | */ |
16 | 16 | ||
17 | -package org.onosproject.drivers.bmv2.translators; | 17 | +package org.onosproject.drivers.bmv2; |
18 | + | ||
19 | +import org.onosproject.bmv2.api.runtime.Bmv2ExtensionTreatment; | ||
20 | +import org.onosproject.net.behaviour.ExtensionTreatmentResolver; | ||
21 | +import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
22 | +import org.onosproject.net.flow.instructions.ExtensionTreatment; | ||
23 | +import org.onosproject.net.flow.instructions.ExtensionTreatmentType; | ||
24 | + | ||
25 | +import static org.onosproject.net.flow.instructions.ExtensionTreatmentType.ExtensionTreatmentTypes.BMV2_ACTION; | ||
18 | 26 | ||
19 | /** | 27 | /** |
20 | - * BMv2 flow rule translator exception. | 28 | + * Implementation of the extension treatment resolver behavior for BMv2. |
21 | */ | 29 | */ |
22 | -public class Bmv2FlowRuleTranslatorException extends Exception { | 30 | +public class Bmv2ExtensionTreatmentResolver extends AbstractHandlerBehaviour implements ExtensionTreatmentResolver { |
23 | 31 | ||
24 | - Bmv2FlowRuleTranslatorException(String msg) { | 32 | + @Override |
25 | - super(msg); | 33 | + public ExtensionTreatment getExtensionInstruction(ExtensionTreatmentType type) { |
34 | + if (type.equals(BMV2_ACTION.type())) { | ||
35 | + return new Bmv2ExtensionTreatment(null); | ||
36 | + } | ||
37 | + return null; | ||
26 | } | 38 | } |
27 | } | 39 | } | ... | ... |
This diff is collapsed. Click to expand it.
... | @@ -17,57 +17,60 @@ | ... | @@ -17,57 +17,60 @@ |
17 | package org.onosproject.drivers.bmv2; | 17 | package org.onosproject.drivers.bmv2; |
18 | 18 | ||
19 | import org.onlab.util.ImmutableByteSequence; | 19 | import org.onlab.util.ImmutableByteSequence; |
20 | -import org.onosproject.bmv2.api.runtime.Bmv2Client; | 20 | +import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; |
21 | import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; | 21 | import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; |
22 | -import org.onosproject.bmv2.ctl.Bmv2ThriftClient; | 22 | +import org.onosproject.bmv2.api.service.Bmv2Controller; |
23 | import org.onosproject.net.DeviceId; | 23 | import org.onosproject.net.DeviceId; |
24 | import org.onosproject.net.driver.AbstractHandlerBehaviour; | 24 | import org.onosproject.net.driver.AbstractHandlerBehaviour; |
25 | import org.onosproject.net.flow.TrafficTreatment; | 25 | import org.onosproject.net.flow.TrafficTreatment; |
26 | -import org.onosproject.net.flow.instructions.Instructions; | ||
27 | import org.onosproject.net.packet.OutboundPacket; | 26 | import org.onosproject.net.packet.OutboundPacket; |
28 | import org.onosproject.net.packet.PacketProgrammable; | 27 | import org.onosproject.net.packet.PacketProgrammable; |
29 | import org.slf4j.Logger; | 28 | import org.slf4j.Logger; |
30 | import org.slf4j.LoggerFactory; | 29 | import org.slf4j.LoggerFactory; |
31 | 30 | ||
31 | +import java.util.List; | ||
32 | + | ||
32 | import static java.lang.Math.toIntExact; | 33 | import static java.lang.Math.toIntExact; |
33 | -import static org.onosproject.net.PortNumber.FLOOD; | 34 | +import static java.util.stream.Collectors.toList; |
34 | import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT; | 35 | import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT; |
36 | +import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
35 | 37 | ||
36 | /** | 38 | /** |
37 | - * Packet programmable device behaviour implementation for BMv2. | 39 | + * Implementation of the packet programmable behaviour for BMv2. |
38 | */ | 40 | */ |
39 | public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements PacketProgrammable { | 41 | public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements PacketProgrammable { |
40 | 42 | ||
41 | - private static final Logger LOG = | 43 | + private final Logger log = LoggerFactory.getLogger(this.getClass()); |
42 | - LoggerFactory.getLogger(Bmv2PacketProgrammable.class); | ||
43 | 44 | ||
44 | @Override | 45 | @Override |
45 | public void emit(OutboundPacket packet) { | 46 | public void emit(OutboundPacket packet) { |
46 | 47 | ||
47 | TrafficTreatment treatment = packet.treatment(); | 48 | TrafficTreatment treatment = packet.treatment(); |
48 | 49 | ||
49 | - treatment.allInstructions().forEach(inst -> { | 50 | + // BMv2 supports only OUTPUT instructions. |
50 | - if (inst.type().equals(OUTPUT)) { | 51 | + List<OutputInstruction> outInstructions = treatment.allInstructions() |
51 | - Instructions.OutputInstruction outInst = (Instructions.OutputInstruction) inst; | 52 | + .stream() |
52 | - if (outInst.port().isLogical()) { | 53 | + .filter(i -> i.type().equals(OUTPUT)) |
53 | - if (outInst.port() == FLOOD) { | 54 | + .map(i -> (OutputInstruction) i) |
54 | - // TODO: implement flood | 55 | + .collect(toList()); |
55 | - LOG.info("Flood not implemented", outInst); | 56 | + |
57 | + if (treatment.allInstructions().size() != outInstructions.size()) { | ||
58 | + // There are other instructions that are not of type OUTPUT | ||
59 | + log.warn("Dropping emit request, treatment nor supported: {}", treatment); | ||
60 | + return; | ||
56 | } | 61 | } |
57 | - LOG.info("Output on logical port not supported: {}", outInst); | 62 | + |
63 | + outInstructions.forEach(outInst -> { | ||
64 | + if (outInst.port().isLogical()) { | ||
65 | + log.warn("Dropping emit request, logical port not supported: {}", outInst.port()); | ||
58 | } else { | 66 | } else { |
59 | try { | 67 | try { |
60 | - long longPort = outInst.port().toLong(); | 68 | + int portNumber = toIntExact(outInst.port().toLong()); |
61 | - int portNumber = toIntExact(longPort); | ||
62 | send(portNumber, packet); | 69 | send(portNumber, packet); |
63 | } catch (ArithmeticException e) { | 70 | } catch (ArithmeticException e) { |
64 | - LOG.error("Port number overflow! Cannot send packet on port {} (long), as the bmv2" + | 71 | + log.error("Dropping emit request, port number too big: {}", outInst.port().toLong()); |
65 | - " device only accepts int port values."); | ||
66 | } | 72 | } |
67 | } | 73 | } |
68 | - } else { | ||
69 | - LOG.info("Instruction type not supported: {}", inst.type().name()); | ||
70 | - } | ||
71 | }); | 74 | }); |
72 | } | 75 | } |
73 | 76 | ||
... | @@ -75,19 +78,25 @@ public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements | ... | @@ -75,19 +78,25 @@ public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements |
75 | 78 | ||
76 | DeviceId deviceId = handler().data().deviceId(); | 79 | DeviceId deviceId = handler().data().deviceId(); |
77 | 80 | ||
78 | - Bmv2Client deviceClient; | 81 | + Bmv2Controller controller = handler().get(Bmv2Controller.class); |
82 | + if (controller == null) { | ||
83 | + log.error("Failed to get BMv2 controller"); | ||
84 | + return; | ||
85 | + } | ||
86 | + | ||
87 | + Bmv2DeviceAgent deviceAgent; | ||
79 | try { | 88 | try { |
80 | - deviceClient = Bmv2ThriftClient.of(deviceId); | 89 | + deviceAgent = controller.getAgent(deviceId); |
81 | } catch (Bmv2RuntimeException e) { | 90 | } catch (Bmv2RuntimeException e) { |
82 | - LOG.error("Failed to connect to Bmv2 device", e); | 91 | + log.error("Failed to get Bmv2 device agent for {}: {}", deviceId, e.explain()); |
83 | return; | 92 | return; |
84 | } | 93 | } |
85 | 94 | ||
86 | ImmutableByteSequence bs = ImmutableByteSequence.copyFrom(packet.data()); | 95 | ImmutableByteSequence bs = ImmutableByteSequence.copyFrom(packet.data()); |
87 | try { | 96 | try { |
88 | - deviceClient.transmitPacket(port, bs); | 97 | + deviceAgent.transmitPacket(port, bs); |
89 | } catch (Bmv2RuntimeException e) { | 98 | } catch (Bmv2RuntimeException e) { |
90 | - LOG.info("Unable to push packet to device: deviceId={}, packet={}", deviceId, bs); | 99 | + log.warn("Unable to emit packet trough {}: {}", deviceId, e.explain()); |
91 | } | 100 | } |
92 | } | 101 | } |
93 | } | 102 | } | ... | ... |
... | @@ -37,8 +37,8 @@ public class Bmv2Pipeliner extends AbstractHandlerBehaviour implements Pipeliner | ... | @@ -37,8 +37,8 @@ public class Bmv2Pipeliner extends AbstractHandlerBehaviour implements Pipeliner |
37 | 37 | ||
38 | @Override | 38 | @Override |
39 | public void init(DeviceId deviceId, PipelinerContext context) { | 39 | public void init(DeviceId deviceId, PipelinerContext context) { |
40 | - // TODO: get multi-table pipeliner dynamically based on BMv2 device running model | 40 | + // TODO: get multi-table pipeliner dynamically based on BMv2 device running model (hard). |
41 | - // Right now we only support single table pipelines | 41 | + // Right now we are able to map flow objectives only in the first table of the pipeline. |
42 | pipeliner = new DefaultSingleTablePipeline(); | 42 | pipeliner = new DefaultSingleTablePipeline(); |
43 | pipeliner.init(deviceId, context); | 43 | pipeliner.init(deviceId, context); |
44 | } | 44 | } | ... | ... |
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.runtime.Bmv2Client; | ||
22 | -import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; | ||
23 | -import org.onosproject.bmv2.ctl.Bmv2ThriftClient; | ||
24 | -import org.onosproject.net.DefaultAnnotations; | ||
25 | -import org.onosproject.net.PortNumber; | ||
26 | -import org.onosproject.net.SparseAnnotations; | ||
27 | -import org.onosproject.net.behaviour.PortDiscovery; | ||
28 | -import org.onosproject.net.device.DefaultPortDescription; | ||
29 | -import org.onosproject.net.device.PortDescription; | ||
30 | -import org.onosproject.net.driver.AbstractHandlerBehaviour; | ||
31 | -import org.slf4j.Logger; | ||
32 | -import org.slf4j.LoggerFactory; | ||
33 | - | ||
34 | -import java.util.Collections; | ||
35 | -import java.util.List; | ||
36 | - | ||
37 | -public class Bmv2PortDiscovery extends AbstractHandlerBehaviour | ||
38 | - implements PortDiscovery { | ||
39 | - | ||
40 | - private final Logger log = | ||
41 | - LoggerFactory.getLogger(this.getClass()); | ||
42 | - | ||
43 | - @Override | ||
44 | - public List<PortDescription> getPorts() { | ||
45 | - Bmv2Client deviceClient; | ||
46 | - try { | ||
47 | - deviceClient = Bmv2ThriftClient.of(handler().data().deviceId()); | ||
48 | - } catch (Bmv2RuntimeException e) { | ||
49 | - log.error("Failed to connect to Bmv2 device", e); | ||
50 | - return Collections.emptyList(); | ||
51 | - } | ||
52 | - | ||
53 | - List<PortDescription> portDescriptions = Lists.newArrayList(); | ||
54 | - | ||
55 | - try { | ||
56 | - | ||
57 | - deviceClient.getPortsInfo().forEach( | ||
58 | - p -> { | ||
59 | - DefaultAnnotations.Builder builder = | ||
60 | - DefaultAnnotations.builder(); | ||
61 | - p.getExtraProperties().forEach(builder::set); | ||
62 | - SparseAnnotations annotations = builder.build(); | ||
63 | - | ||
64 | - portDescriptions.add(new DefaultPortDescription( | ||
65 | - PortNumber.portNumber( | ||
66 | - (long) p.portNumber(), | ||
67 | - p.ifaceName()), | ||
68 | - p.isUp(), | ||
69 | - annotations | ||
70 | - )); | ||
71 | - }); | ||
72 | - } catch (Bmv2RuntimeException e) { | ||
73 | - log.error("Unable to get port description from Bmv2 device", e); | ||
74 | - } | ||
75 | - | ||
76 | - return ImmutableList.copyOf(portDescriptions); | ||
77 | - } | ||
78 | -} |
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.drivers.bmv2.translators; | ||
18 | - | ||
19 | -import com.google.common.annotations.Beta; | ||
20 | -import org.onosproject.bmv2.api.model.Bmv2Model; | ||
21 | -import org.onosproject.net.flow.criteria.Criterion; | ||
22 | - | ||
23 | -import java.util.Map; | ||
24 | - | ||
25 | -import static org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator.TranslatorConfig; | ||
26 | - | ||
27 | -/** | ||
28 | - * Default implementation of a BMv2 flow rule translator configuration. | ||
29 | - */ | ||
30 | -@Beta | ||
31 | -public abstract class Bmv2DefaultTranslatorConfig implements TranslatorConfig { | ||
32 | - | ||
33 | - private final Bmv2Model model; | ||
34 | - private final Map<String, Criterion.Type> fieldMap; | ||
35 | - | ||
36 | - /** | ||
37 | - * Creates a new translator configuration. | ||
38 | - * | ||
39 | - * @param model a BMv2 packet processing model | ||
40 | - * @param fieldMap a field-to-criterion type map | ||
41 | - */ | ||
42 | - protected Bmv2DefaultTranslatorConfig(Bmv2Model model, Map<String, Criterion.Type> fieldMap) { | ||
43 | - this.model = model; | ||
44 | - this.fieldMap = fieldMap; | ||
45 | - } | ||
46 | - | ||
47 | - @Override | ||
48 | - public Bmv2Model model() { | ||
49 | - return this.model; | ||
50 | - } | ||
51 | - | ||
52 | - @Override | ||
53 | - public Map<String, Criterion.Type> fieldToCriterionTypeMap() { | ||
54 | - return this.fieldMap; | ||
55 | - } | ||
56 | -} |
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.drivers.bmv2.translators; | ||
18 | - | ||
19 | -import com.google.common.annotations.Beta; | ||
20 | -import org.onosproject.bmv2.api.model.Bmv2Model; | ||
21 | -import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
22 | -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; | ||
23 | -import org.onosproject.net.flow.FlowRule; | ||
24 | -import org.onosproject.net.flow.TrafficTreatment; | ||
25 | -import org.onosproject.net.flow.criteria.Criterion; | ||
26 | - | ||
27 | -import java.util.Map; | ||
28 | - | ||
29 | -/** | ||
30 | - * Translator of ONOS flow rules to BMv2 table entries. Translation depends on a | ||
31 | - * {@link TranslatorConfig translator configuration}. | ||
32 | - */ | ||
33 | -@Beta | ||
34 | -public interface Bmv2FlowRuleTranslator { | ||
35 | - | ||
36 | - /** | ||
37 | - * Returns a new BMv2 table entry equivalent to the given flow rule. | ||
38 | - * | ||
39 | - * @param rule a flow rule | ||
40 | - * @return a BMv2 table entry | ||
41 | - * @throws Bmv2FlowRuleTranslatorException if the flow rule cannot be | ||
42 | - * translated | ||
43 | - */ | ||
44 | - Bmv2TableEntry translate(FlowRule rule) throws Bmv2FlowRuleTranslatorException; | ||
45 | - | ||
46 | - /** | ||
47 | - * Returns the configuration of this translator. | ||
48 | - * | ||
49 | - * @return a translator configuration | ||
50 | - */ | ||
51 | - TranslatorConfig config(); | ||
52 | - | ||
53 | - /** | ||
54 | - * BMv2 flow rules translator configuration. Such a configuration is used to | ||
55 | - * generate table entries that are compatible with a given {@link Bmv2Model}. | ||
56 | - */ | ||
57 | - @Beta | ||
58 | - interface TranslatorConfig { | ||
59 | - /** | ||
60 | - * Return the {@link Bmv2Model} associated with this configuration. | ||
61 | - * | ||
62 | - * @return a BMv2 model | ||
63 | - */ | ||
64 | - Bmv2Model model(); | ||
65 | - | ||
66 | - /** | ||
67 | - * Returns a map describing a one-to-one relationship between BMv2 | ||
68 | - * header field names and ONOS criterion types. Header field names are | ||
69 | - * formatted using the notation {@code header_name.field_name} | ||
70 | - * representing a specific header field instance extracted by the BMv2 | ||
71 | - * parser (e.g. {@code ethernet.dstAddr}). | ||
72 | - * | ||
73 | - * @return a map where the keys represent BMv2 header field names and | ||
74 | - * values are criterion types | ||
75 | - */ | ||
76 | - Map<String, Criterion.Type> fieldToCriterionTypeMap(); | ||
77 | - | ||
78 | - /** | ||
79 | - * Return a BMv2 action that is equivalent to the given ONOS traffic | ||
80 | - * treatment. | ||
81 | - * | ||
82 | - * @param treatment a traffic treatment | ||
83 | - * @return a BMv2 action object | ||
84 | - * @throws Bmv2FlowRuleTranslatorException if the treatment cannot be | ||
85 | - * translated to a BMv2 action | ||
86 | - */ | ||
87 | - Bmv2Action buildAction(TrafficTreatment treatment) | ||
88 | - throws Bmv2FlowRuleTranslatorException; | ||
89 | - } | ||
90 | -} |
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.drivers.bmv2.translators; | ||
18 | - | ||
19 | -import com.google.common.annotations.Beta; | ||
20 | -import com.google.common.collect.ImmutableMap; | ||
21 | -import org.onlab.util.ImmutableByteSequence; | ||
22 | -import org.onosproject.bmv2.api.model.Bmv2Model; | ||
23 | -import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
24 | -import org.onosproject.net.PortNumber; | ||
25 | -import org.onosproject.net.flow.TrafficTreatment; | ||
26 | -import org.onosproject.net.flow.criteria.Criterion; | ||
27 | -import org.onosproject.net.flow.instructions.Instruction; | ||
28 | -import org.onosproject.net.flow.instructions.Instructions; | ||
29 | - | ||
30 | -import java.util.Map; | ||
31 | - | ||
32 | -/** | ||
33 | - * Implementation of a Bmv2 flow rule translator configuration for the | ||
34 | - * simple.p4 model. | ||
35 | - */ | ||
36 | -@Beta | ||
37 | -public class Bmv2SimpleTranslatorConfig extends Bmv2DefaultTranslatorConfig { | ||
38 | - | ||
39 | - // Lazily populate field map. | ||
40 | - private static final Map<String, Criterion.Type> FIELD_MAP = ImmutableMap.of( | ||
41 | - "standard_metadata.ingress_port", Criterion.Type.IN_PORT, | ||
42 | - "ethernet.dstAddr", Criterion.Type.ETH_DST, | ||
43 | - "ethernet.srcAddr", Criterion.Type.ETH_SRC, | ||
44 | - "ethernet.etherType", Criterion.Type.ETH_TYPE); | ||
45 | - | ||
46 | - /** | ||
47 | - * Creates a new simple pipeline translator configuration. | ||
48 | - */ | ||
49 | - public Bmv2SimpleTranslatorConfig(Bmv2Model model) { | ||
50 | - // Populate fieldMap. | ||
51 | - super(model, FIELD_MAP); | ||
52 | - } | ||
53 | - | ||
54 | - private static Bmv2Action buildDropAction() { | ||
55 | - return Bmv2Action.builder() | ||
56 | - .withName("_drop") | ||
57 | - .build(); | ||
58 | - } | ||
59 | - | ||
60 | - private static Bmv2Action buildPushToCpAction() { | ||
61 | - return Bmv2Action.builder() | ||
62 | - .withName("send_to_cpu") | ||
63 | - .build(); | ||
64 | - } | ||
65 | - | ||
66 | - private static Bmv2Action buildFwdAction(Instructions.OutputInstruction inst) | ||
67 | - throws Bmv2FlowRuleTranslatorException { | ||
68 | - | ||
69 | - Bmv2Action.Builder actionBuilder = Bmv2Action.builder(); | ||
70 | - | ||
71 | - actionBuilder.withName("fwd"); | ||
72 | - | ||
73 | - if (inst.port().isLogical()) { | ||
74 | - if (inst.port() == PortNumber.CONTROLLER) { | ||
75 | - return buildPushToCpAction(); | ||
76 | - } else { | ||
77 | - throw new Bmv2FlowRuleTranslatorException( | ||
78 | - "Output logic port number not supported: " + inst); | ||
79 | - } | ||
80 | - } | ||
81 | - | ||
82 | - actionBuilder.addParameter( | ||
83 | - ImmutableByteSequence.copyFrom((short) inst.port().toLong())); | ||
84 | - | ||
85 | - return actionBuilder.build(); | ||
86 | - } | ||
87 | - | ||
88 | - @Override | ||
89 | - public Bmv2Action buildAction(TrafficTreatment treatment) | ||
90 | - throws Bmv2FlowRuleTranslatorException { | ||
91 | - | ||
92 | - | ||
93 | - if (treatment.allInstructions().size() == 0) { | ||
94 | - // No instructions means drop. | ||
95 | - return buildDropAction(); | ||
96 | - } else if (treatment.allInstructions().size() > 1) { | ||
97 | - // Otherwise, we understand treatments with only 1 instruction. | ||
98 | - throw new Bmv2FlowRuleTranslatorException( | ||
99 | - "Treatment not supported, more than 1 instructions found: " | ||
100 | - + treatment.toString()); | ||
101 | - } | ||
102 | - | ||
103 | - Instruction instruction = treatment.allInstructions().get(0); | ||
104 | - | ||
105 | - switch (instruction.type()) { | ||
106 | - case OUTPUT: | ||
107 | - return buildFwdAction((Instructions.OutputInstruction) instruction); | ||
108 | - case NOACTION: | ||
109 | - return buildDropAction(); | ||
110 | - default: | ||
111 | - throw new Bmv2FlowRuleTranslatorException( | ||
112 | - "Instruction type not supported: " | ||
113 | - + instruction.type().name()); | ||
114 | - } | ||
115 | - } | ||
116 | -} |
... | @@ -16,14 +16,18 @@ | ... | @@ -16,14 +16,18 @@ |
16 | ~ limitations under the License. | 16 | ~ limitations under the License. |
17 | --> | 17 | --> |
18 | <drivers> | 18 | <drivers> |
19 | - <driver name="bmv2-thrift" manufacturer="p4.org" hwVersion="bmv2" swVersion="unknown"> | 19 | + <driver name="bmv2-thrift" manufacturer="p4.org" hwVersion="bmv2" swVersion="n/a"> |
20 | - <behaviour api="org.onosproject.net.behaviour.PortDiscovery" | 20 | + <behaviour api="org.onosproject.net.device.DeviceDescriptionDiscovery" |
21 | - impl="org.onosproject.drivers.bmv2.Bmv2PortDiscovery"/> | 21 | + impl="org.onosproject.drivers.bmv2.Bmv2DeviceDescriptionDiscovery"/> |
22 | <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable" | 22 | <behaviour api="org.onosproject.net.flow.FlowRuleProgrammable" |
23 | impl="org.onosproject.drivers.bmv2.Bmv2FlowRuleProgrammable"/> | 23 | impl="org.onosproject.drivers.bmv2.Bmv2FlowRuleProgrammable"/> |
24 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" | 24 | <behaviour api="org.onosproject.net.behaviour.Pipeliner" |
25 | impl="org.onosproject.drivers.bmv2.Bmv2Pipeliner"/> | 25 | impl="org.onosproject.drivers.bmv2.Bmv2Pipeliner"/> |
26 | <behaviour api="org.onosproject.net.packet.PacketProgrammable" | 26 | <behaviour api="org.onosproject.net.packet.PacketProgrammable" |
27 | impl="org.onosproject.drivers.bmv2.Bmv2PacketProgrammable"/> | 27 | impl="org.onosproject.drivers.bmv2.Bmv2PacketProgrammable"/> |
28 | + <behaviour api="org.onosproject.net.behaviour.ExtensionSelectorResolver" | ||
29 | + impl="org.onosproject.drivers.bmv2.Bmv2ExtensionSelectorResolver"/> | ||
30 | + <behaviour api="org.onosproject.net.behaviour.ExtensionTreatmentResolver" | ||
31 | + impl="org.onosproject.drivers.bmv2.Bmv2ExtensionTreatmentResolver"/> | ||
28 | </driver> | 32 | </driver> |
29 | </drivers> | 33 | </drivers> | ... | ... |
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.eclipsesource.json.Json; | ||
20 | -import com.eclipsesource.json.JsonObject; | ||
21 | -import com.google.common.testing.EqualsTester; | ||
22 | -import org.junit.Before; | ||
23 | -import org.junit.Test; | ||
24 | -import org.onlab.packet.MacAddress; | ||
25 | -import org.onosproject.bmv2.api.model.Bmv2Model; | ||
26 | -import org.onosproject.bmv2.api.runtime.Bmv2TableEntry; | ||
27 | -import org.onosproject.bmv2.api.runtime.Bmv2TernaryMatchParam; | ||
28 | -import org.onosproject.core.ApplicationId; | ||
29 | -import org.onosproject.core.DefaultApplicationId; | ||
30 | -import org.onosproject.drivers.bmv2.translators.Bmv2DefaultFlowRuleTranslator; | ||
31 | -import org.onosproject.drivers.bmv2.translators.Bmv2FlowRuleTranslator; | ||
32 | -import org.onosproject.drivers.bmv2.translators.Bmv2SimpleTranslatorConfig; | ||
33 | -import org.onosproject.net.DeviceId; | ||
34 | -import org.onosproject.net.PortNumber; | ||
35 | -import org.onosproject.net.flow.DefaultFlowRule; | ||
36 | -import org.onosproject.net.flow.DefaultTrafficSelector; | ||
37 | -import org.onosproject.net.flow.DefaultTrafficTreatment; | ||
38 | -import org.onosproject.net.flow.FlowRule; | ||
39 | -import org.onosproject.net.flow.TrafficSelector; | ||
40 | -import org.onosproject.net.flow.TrafficTreatment; | ||
41 | - | ||
42 | -import java.io.BufferedReader; | ||
43 | -import java.io.IOException; | ||
44 | -import java.io.InputStream; | ||
45 | -import java.io.InputStreamReader; | ||
46 | -import java.util.Random; | ||
47 | - | ||
48 | -import static org.hamcrest.CoreMatchers.equalTo; | ||
49 | -import static org.hamcrest.CoreMatchers.is; | ||
50 | -import static org.hamcrest.MatcherAssert.assertThat; | ||
51 | - | ||
52 | -/** | ||
53 | - * Tests for {@link Bmv2DefaultFlowRuleTranslator}. | ||
54 | - */ | ||
55 | -public class Bmv2DefaultFlowRuleTranslatorTest { | ||
56 | - | ||
57 | - private static final String JSON_CONFIG_PATH = "/simple.json"; | ||
58 | - private Random random = new Random(); | ||
59 | - private Bmv2Model model; | ||
60 | - private Bmv2FlowRuleTranslator.TranslatorConfig config; | ||
61 | - private Bmv2FlowRuleTranslator translator; | ||
62 | - | ||
63 | - @Before | ||
64 | - public void setUp() throws Exception { | ||
65 | - InputStream inputStream = Bmv2SimpleTranslatorConfig.class | ||
66 | - .getResourceAsStream(JSON_CONFIG_PATH); | ||
67 | - InputStreamReader reader = new InputStreamReader(inputStream); | ||
68 | - BufferedReader bufReader = new BufferedReader(reader); | ||
69 | - JsonObject json = null; | ||
70 | - try { | ||
71 | - json = Json.parse(bufReader).asObject(); | ||
72 | - } catch (IOException e) { | ||
73 | - throw new RuntimeException("Unable to parse JSON file: " + e.getMessage()); | ||
74 | - } | ||
75 | - | ||
76 | - this.model = Bmv2Model.parse(json); | ||
77 | - this.config = new Bmv2SimpleTranslatorConfig(model); | ||
78 | - this.translator = new Bmv2DefaultFlowRuleTranslator(config); | ||
79 | - | ||
80 | - } | ||
81 | - | ||
82 | - | ||
83 | - @Test | ||
84 | - public void testCompiler() throws Exception { | ||
85 | - | ||
86 | - DeviceId deviceId = DeviceId.NONE; | ||
87 | - ApplicationId appId = new DefaultApplicationId(1, "test"); | ||
88 | - int tableId = 0; | ||
89 | - MacAddress ethDstMac = MacAddress.valueOf(random.nextLong()); | ||
90 | - MacAddress ethSrcMac = MacAddress.valueOf(random.nextLong()); | ||
91 | - short ethType = (short) (0x0000FFFF & random.nextInt()); | ||
92 | - short outPort = (short) random.nextInt(65); | ||
93 | - short inPort = (short) random.nextInt(65); | ||
94 | - int timeout = random.nextInt(100); | ||
95 | - int priority = random.nextInt(100); | ||
96 | - | ||
97 | - TrafficSelector matchInPort1 = DefaultTrafficSelector | ||
98 | - .builder() | ||
99 | - .matchInPort(PortNumber.portNumber(inPort)) | ||
100 | - .matchEthDst(ethDstMac) | ||
101 | - .matchEthSrc(ethSrcMac) | ||
102 | - .matchEthType(ethType) | ||
103 | - .build(); | ||
104 | - | ||
105 | - TrafficTreatment outPort2 = DefaultTrafficTreatment | ||
106 | - .builder() | ||
107 | - .setOutput(PortNumber.portNumber(outPort)) | ||
108 | - .build(); | ||
109 | - | ||
110 | - FlowRule rule1 = DefaultFlowRule.builder() | ||
111 | - .forDevice(deviceId) | ||
112 | - .forTable(tableId) | ||
113 | - .fromApp(appId) | ||
114 | - .withSelector(matchInPort1) | ||
115 | - .withTreatment(outPort2) | ||
116 | - .makeTemporary(timeout) | ||
117 | - .withPriority(priority) | ||
118 | - .build(); | ||
119 | - | ||
120 | - FlowRule rule2 = DefaultFlowRule.builder() | ||
121 | - .forDevice(deviceId) | ||
122 | - .forTable(tableId) | ||
123 | - .fromApp(appId) | ||
124 | - .withSelector(matchInPort1) | ||
125 | - .withTreatment(outPort2) | ||
126 | - .makeTemporary(timeout) | ||
127 | - .withPriority(priority) | ||
128 | - .build(); | ||
129 | - | ||
130 | - Bmv2TableEntry entry1 = translator.translate(rule1); | ||
131 | - Bmv2TableEntry entry2 = translator.translate(rule1); | ||
132 | - | ||
133 | - // check equality, i.e. same rules must produce same entries | ||
134 | - new EqualsTester() | ||
135 | - .addEqualityGroup(rule1, rule2) | ||
136 | - .addEqualityGroup(entry1, entry2) | ||
137 | - .testEquals(); | ||
138 | - | ||
139 | - int numMatchParams = model.table(0).keys().size(); | ||
140 | - // parse values stored in entry1 | ||
141 | - Bmv2TernaryMatchParam inPortParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(0); | ||
142 | - Bmv2TernaryMatchParam ethDstParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(1); | ||
143 | - Bmv2TernaryMatchParam ethSrcParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(2); | ||
144 | - Bmv2TernaryMatchParam ethTypeParam = (Bmv2TernaryMatchParam) entry1.matchKey().matchParams().get(3); | ||
145 | - double expectedTimeout = (double) (model.table(0).hasTimeouts() ? rule1.timeout() : -1); | ||
146 | - | ||
147 | - // check that the number of parameters in the entry is the same as the number of table keys | ||
148 | - assertThat("Incorrect number of match parameters", | ||
149 | - entry1.matchKey().matchParams().size(), is(equalTo(numMatchParams))); | ||
150 | - | ||
151 | - // check that values stored in entry are the same used for the flow rule | ||
152 | - assertThat("Incorrect inPort match param value", | ||
153 | - inPortParam.value().asReadOnlyBuffer().getShort(), is(equalTo(inPort))); | ||
154 | - assertThat("Incorrect ethDestMac match param value", | ||
155 | - ethDstParam.value().asArray(), is(equalTo(ethDstMac.toBytes()))); | ||
156 | - assertThat("Incorrect ethSrcMac match param value", | ||
157 | - ethSrcParam.value().asArray(), is(equalTo(ethSrcMac.toBytes()))); | ||
158 | - assertThat("Incorrect ethType match param value", | ||
159 | - ethTypeParam.value().asReadOnlyBuffer().getShort(), is(equalTo(ethType))); | ||
160 | - assertThat("Incorrect priority value", | ||
161 | - entry1.priority(), is(equalTo(Integer.MAX_VALUE - rule1.priority()))); | ||
162 | - assertThat("Incorrect timeout value", | ||
163 | - entry1.timeout(), is(equalTo(expectedTimeout))); | ||
164 | - | ||
165 | - } | ||
166 | -} | ||
... | \ No newline at end of file | ... | \ No newline at end of file |
This diff is collapsed. Click to expand it.
... | @@ -41,7 +41,7 @@ | ... | @@ -41,7 +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 | + <module>bmv2</module> |
45 | <module>corsa</module> | 45 | <module>corsa</module> |
46 | <module>optical</module> | 46 | <module>optical</module> |
47 | </modules> | 47 | </modules> | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-bmv2-protocol</artifactId> | 22 | <artifactId>onos-bmv2-protocol</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | <modelVersion>4.0.0</modelVersion> | 27 | <modelVersion>4.0.0</modelVersion> |
27 | 28 | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-bmv2-protocol</artifactId> | 22 | <artifactId>onos-bmv2-protocol</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | <modelVersion>4.0.0</modelVersion> | 27 | <modelVersion>4.0.0</modelVersion> |
27 | 28 | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-protocols</artifactId> | 22 | <artifactId>onos-protocols</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | <modelVersion>4.0.0</modelVersion> | 27 | <modelVersion>4.0.0</modelVersion> |
27 | 28 | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-bmv2-protocol</artifactId> | 22 | <artifactId>onos-bmv2-protocol</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | 27 | ||
27 | <modelVersion>4.0.0</modelVersion> | 28 | <modelVersion>4.0.0</modelVersion> | ... | ... |
... | @@ -22,7 +22,9 @@ | ... | @@ -22,7 +22,9 @@ |
22 | <bundle>mvn:${project.groupId}/onos-bmv2-provider-device/${project.version}</bundle> | 22 | <bundle>mvn:${project.groupId}/onos-bmv2-provider-device/${project.version}</bundle> |
23 | <bundle>mvn:${project.groupId}/onos-bmv2-provider-packet/${project.version}</bundle> | 23 | <bundle>mvn:${project.groupId}/onos-bmv2-provider-packet/${project.version}</bundle> |
24 | <bundle>mvn:org.apache.thrift/libthrift/0.9.3</bundle> | 24 | <bundle>mvn:org.apache.thrift/libthrift/0.9.3</bundle> |
25 | - <bundle>mvn:${project.groupId}/onos-bmv2-protocol/${project.version}</bundle> | 25 | + <bundle>mvn:${project.groupId}/onos-bmv2-protocol-api/${project.version}</bundle> |
26 | + <bundle>mvn:${project.groupId}/onos-bmv2-protocol-ctl/${project.version}</bundle> | ||
27 | + <bundle>mvn:${project.groupId}/onos-bmv2-protocol-thrift-api/${project.version}</bundle> | ||
26 | </feature> | 28 | </feature> |
27 | </features> | 29 | </features> |
28 | 30 | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-bmv2-providers</artifactId> | 22 | <artifactId>onos-bmv2-providers</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | 27 | ||
27 | <modelVersion>4.0.0</modelVersion> | 28 | <modelVersion>4.0.0</modelVersion> |
... | @@ -33,7 +34,7 @@ | ... | @@ -33,7 +34,7 @@ |
33 | 34 | ||
34 | <properties> | 35 | <properties> |
35 | <onos.app.name>org.onosproject.bmv2</onos.app.name> | 36 | <onos.app.name>org.onosproject.bmv2</onos.app.name> |
36 | - <onos.app.title>BMv2 Provider</onos.app.title> | 37 | + <onos.app.title>BMv2 Providers</onos.app.title> |
37 | <onos.app.category>Provider</onos.app.category> | 38 | <onos.app.category>Provider</onos.app.category> |
38 | </properties> | 39 | </properties> |
39 | 40 | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-bmv2-providers</artifactId> | 22 | <artifactId>onos-bmv2-providers</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | <modelVersion>4.0.0</modelVersion> | 27 | <modelVersion>4.0.0</modelVersion> |
27 | 28 | ||
... | @@ -33,12 +34,12 @@ | ... | @@ -33,12 +34,12 @@ |
33 | <dependencies> | 34 | <dependencies> |
34 | <dependency> | 35 | <dependency> |
35 | <groupId>org.onosproject</groupId> | 36 | <groupId>org.onosproject</groupId> |
36 | - <artifactId>onos-drivers-bmv2</artifactId> | 37 | + <artifactId>onos-core-common</artifactId> |
37 | <version>${project.version}</version> | 38 | <version>${project.version}</version> |
38 | </dependency> | 39 | </dependency> |
39 | <dependency> | 40 | <dependency> |
40 | <groupId>org.onosproject</groupId> | 41 | <groupId>org.onosproject</groupId> |
41 | - <artifactId>onos-core-common</artifactId> | 42 | + <artifactId>onos-bmv2-protocol-api</artifactId> |
42 | <version>${project.version}</version> | 43 | <version>${project.version}</version> |
43 | </dependency> | 44 | </dependency> |
44 | </dependencies> | 45 | </dependencies> | ... | ... |
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.provider.bmv2.device.impl; | ||
18 | + | ||
19 | +import com.google.common.collect.Lists; | ||
20 | +import org.apache.commons.lang3.tuple.Pair; | ||
21 | +import org.onosproject.bmv2.api.runtime.Bmv2Action; | ||
22 | +import org.onosproject.bmv2.api.runtime.Bmv2DeviceAgent; | ||
23 | +import org.onosproject.bmv2.api.runtime.Bmv2RuntimeException; | ||
24 | +import org.onosproject.net.Port; | ||
25 | +import org.onosproject.net.device.DefaultPortStatistics; | ||
26 | +import org.onosproject.net.device.PortStatistics; | ||
27 | +import org.slf4j.Logger; | ||
28 | +import org.slf4j.LoggerFactory; | ||
29 | + | ||
30 | +import java.util.Collection; | ||
31 | +import java.util.List; | ||
32 | + | ||
33 | +/** | ||
34 | + * Utility class to read port statistics from a BMv2 device. | ||
35 | + */ | ||
36 | +final class Bmv2PortStatisticsGetter { | ||
37 | + | ||
38 | + // TODO: make counters configuration dependent | ||
39 | + | ||
40 | + private static final String TABLE_NAME = "port_count_table"; | ||
41 | + private static final String ACTION_NAME = "count_packet"; | ||
42 | + private static final String EGRESS_COUNTER = "egress_port_counter"; | ||
43 | + private static final String INGRESS_COUNTER = "ingress_port_counter"; | ||
44 | + | ||
45 | + private static final Logger log = LoggerFactory.getLogger(Bmv2PortStatisticsGetter.class); | ||
46 | + | ||
47 | + private Bmv2PortStatisticsGetter() { | ||
48 | + // ban constructor. | ||
49 | + } | ||
50 | + | ||
51 | + /** | ||
52 | + * Returns a collection of port statistics for given ports using the given BMv2 device agent. | ||
53 | + * | ||
54 | + * @param deviceAgent a device agent | ||
55 | + * @param ports a collection of ports | ||
56 | + * @return a collection of port statistics | ||
57 | + */ | ||
58 | + static Collection<PortStatistics> getPortStatistics(Bmv2DeviceAgent deviceAgent, Collection<Port> ports) { | ||
59 | + | ||
60 | + List<PortStatistics> ps = Lists.newArrayList(); | ||
61 | + | ||
62 | + for (Port port : ports) { | ||
63 | + int portNumber = (int) port.number().toLong(); | ||
64 | + try { | ||
65 | + Pair<Long, Long> egressCounter = deviceAgent.readCounter(EGRESS_COUNTER, portNumber); | ||
66 | + Pair<Long, Long> ingressCounter = deviceAgent.readCounter(INGRESS_COUNTER, portNumber); | ||
67 | + ps.add(DefaultPortStatistics.builder() | ||
68 | + .setPort(portNumber) | ||
69 | + .setBytesSent(egressCounter.getLeft()) | ||
70 | + .setPacketsSent(egressCounter.getRight()) | ||
71 | + .setBytesReceived(ingressCounter.getLeft()) | ||
72 | + .setPacketsReceived(ingressCounter.getRight()) | ||
73 | + .build()); | ||
74 | + } catch (Bmv2RuntimeException e) { | ||
75 | + log.info("Unable to read port statistics from {}: {}", port, e.explain()); | ||
76 | + } | ||
77 | + } | ||
78 | + | ||
79 | + return ps; | ||
80 | + } | ||
81 | + | ||
82 | + /** | ||
83 | + * Initialize port counters on the given device agent. | ||
84 | + * | ||
85 | + * @param deviceAgent a device agent. | ||
86 | + */ | ||
87 | + static void initCounters(Bmv2DeviceAgent deviceAgent) { | ||
88 | + try { | ||
89 | + deviceAgent.setTableDefaultAction(TABLE_NAME, Bmv2Action.builder().withName(ACTION_NAME).build()); | ||
90 | + } catch (Bmv2RuntimeException e) { | ||
91 | + log.debug("Failed to provision counters on {}: {}", deviceAgent.deviceId(), e.explain()); | ||
92 | + } | ||
93 | + } | ||
94 | +} | ||
95 | + |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-bmv2-providers</artifactId> | 22 | <artifactId>onos-bmv2-providers</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | <modelVersion>4.0.0</modelVersion> | 27 | <modelVersion>4.0.0</modelVersion> |
27 | 28 | ||
... | @@ -34,12 +35,12 @@ | ... | @@ -34,12 +35,12 @@ |
34 | <dependencies> | 35 | <dependencies> |
35 | <dependency> | 36 | <dependency> |
36 | <groupId>org.onosproject</groupId> | 37 | <groupId>org.onosproject</groupId> |
37 | - <artifactId>onos-drivers-bmv2</artifactId> | 38 | + <artifactId>onos-core-common</artifactId> |
38 | <version>${project.version}</version> | 39 | <version>${project.version}</version> |
39 | </dependency> | 40 | </dependency> |
40 | <dependency> | 41 | <dependency> |
41 | <groupId>org.onosproject</groupId> | 42 | <groupId>org.onosproject</groupId> |
42 | - <artifactId>onos-core-common</artifactId> | 43 | + <artifactId>onos-bmv2-protocol-api</artifactId> |
43 | <version>${project.version}</version> | 44 | <version>${project.version}</version> |
44 | </dependency> | 45 | </dependency> |
45 | </dependencies> | 46 | </dependencies> | ... | ... |
... | @@ -23,12 +23,14 @@ import org.apache.felix.scr.annotations.Reference; | ... | @@ -23,12 +23,14 @@ import org.apache.felix.scr.annotations.Reference; |
23 | import org.apache.felix.scr.annotations.ReferenceCardinality; | 23 | import org.apache.felix.scr.annotations.ReferenceCardinality; |
24 | import org.onlab.packet.Ethernet; | 24 | import org.onlab.packet.Ethernet; |
25 | import org.onlab.util.ImmutableByteSequence; | 25 | import org.onlab.util.ImmutableByteSequence; |
26 | -import org.onosproject.bmv2.api.runtime.Bmv2ControlPlaneServer; | ||
27 | import org.onosproject.bmv2.api.runtime.Bmv2Device; | 26 | import org.onosproject.bmv2.api.runtime.Bmv2Device; |
27 | +import org.onosproject.bmv2.api.service.Bmv2Controller; | ||
28 | +import org.onosproject.bmv2.api.service.Bmv2PacketListener; | ||
28 | import org.onosproject.core.CoreService; | 29 | import org.onosproject.core.CoreService; |
29 | import org.onosproject.net.ConnectPoint; | 30 | import org.onosproject.net.ConnectPoint; |
30 | import org.onosproject.net.Device; | 31 | import org.onosproject.net.Device; |
31 | import org.onosproject.net.DeviceId; | 32 | import org.onosproject.net.DeviceId; |
33 | +import org.onosproject.net.Port; | ||
32 | import org.onosproject.net.PortNumber; | 34 | import org.onosproject.net.PortNumber; |
33 | import org.onosproject.net.device.DeviceService; | 35 | import org.onosproject.net.device.DeviceService; |
34 | import org.onosproject.net.flow.DefaultTrafficTreatment; | 36 | import org.onosproject.net.flow.DefaultTrafficTreatment; |
... | @@ -49,6 +51,12 @@ import org.slf4j.Logger; | ... | @@ -49,6 +51,12 @@ import org.slf4j.Logger; |
49 | import org.slf4j.LoggerFactory; | 51 | import org.slf4j.LoggerFactory; |
50 | 52 | ||
51 | import java.nio.ByteBuffer; | 53 | import java.nio.ByteBuffer; |
54 | +import java.util.Optional; | ||
55 | + | ||
56 | +import static org.onosproject.net.PortNumber.FLOOD; | ||
57 | +import static org.onosproject.net.flow.DefaultTrafficTreatment.emptyTreatment; | ||
58 | +import static org.onosproject.net.flow.instructions.Instruction.Type.OUTPUT; | ||
59 | +import static org.onosproject.net.flow.instructions.Instructions.OutputInstruction; | ||
52 | 60 | ||
53 | /** | 61 | /** |
54 | * Implementation of a packet provider for BMv2. | 62 | * Implementation of a packet provider for BMv2. |
... | @@ -56,11 +64,11 @@ import java.nio.ByteBuffer; | ... | @@ -56,11 +64,11 @@ import java.nio.ByteBuffer; |
56 | @Component(immediate = true) | 64 | @Component(immediate = true) |
57 | public class Bmv2PacketProvider extends AbstractProvider implements PacketProvider { | 65 | public class Bmv2PacketProvider extends AbstractProvider implements PacketProvider { |
58 | 66 | ||
59 | - private static final Logger LOG = LoggerFactory.getLogger(Bmv2PacketProvider.class); | 67 | + private final Logger log = LoggerFactory.getLogger(Bmv2PacketProvider.class); |
60 | private static final String APP_NAME = "org.onosproject.bmv2"; | 68 | private static final String APP_NAME = "org.onosproject.bmv2"; |
61 | 69 | ||
62 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 70 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
63 | - protected Bmv2ControlPlaneServer controlPlaneServer; | 71 | + protected Bmv2Controller controller; |
64 | 72 | ||
65 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) | 73 | @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY) |
66 | protected CoreService coreService; | 74 | protected CoreService coreService; |
... | @@ -86,28 +94,28 @@ public class Bmv2PacketProvider extends AbstractProvider implements PacketProvid | ... | @@ -86,28 +94,28 @@ public class Bmv2PacketProvider extends AbstractProvider implements PacketProvid |
86 | protected void activate() { | 94 | protected void activate() { |
87 | providerService = providerRegistry.register(this); | 95 | providerService = providerRegistry.register(this); |
88 | coreService.registerApplication(APP_NAME); | 96 | coreService.registerApplication(APP_NAME); |
89 | - controlPlaneServer.addPacketListener(packetListener); | 97 | + controller.addPacketListener(packetListener); |
90 | - LOG.info("Started"); | 98 | + log.info("Started"); |
91 | } | 99 | } |
92 | 100 | ||
93 | @Deactivate | 101 | @Deactivate |
94 | public void deactivate() { | 102 | public void deactivate() { |
95 | - controlPlaneServer.removePacketListener(packetListener); | 103 | + controller.removePacketListener(packetListener); |
96 | providerRegistry.unregister(this); | 104 | providerRegistry.unregister(this); |
97 | providerService = null; | 105 | providerService = null; |
98 | - LOG.info("Stopped"); | 106 | + log.info("Stopped"); |
99 | } | 107 | } |
100 | 108 | ||
101 | @Override | 109 | @Override |
102 | public void emit(OutboundPacket packet) { | 110 | public void emit(OutboundPacket packet) { |
103 | if (packet != null) { | 111 | if (packet != null) { |
104 | - DeviceId did = packet.sendThrough(); | 112 | + DeviceId deviceId = packet.sendThrough(); |
105 | - Device device = deviceService.getDevice(did); | 113 | + Device device = deviceService.getDevice(deviceId); |
106 | if (device.is(PacketProgrammable.class)) { | 114 | if (device.is(PacketProgrammable.class)) { |
107 | PacketProgrammable packetProgrammable = device.as(PacketProgrammable.class); | 115 | PacketProgrammable packetProgrammable = device.as(PacketProgrammable.class); |
108 | packetProgrammable.emit(packet); | 116 | packetProgrammable.emit(packet); |
109 | } else { | 117 | } else { |
110 | - LOG.info("Unable to send packet, no PacketProgrammable behavior for device {}", did); | 118 | + log.info("No PacketProgrammable behavior for device {}", deviceId); |
111 | } | 119 | } |
112 | } | 120 | } |
113 | } | 121 | } |
... | @@ -117,47 +125,75 @@ public class Bmv2PacketProvider extends AbstractProvider implements PacketProvid | ... | @@ -117,47 +125,75 @@ public class Bmv2PacketProvider extends AbstractProvider implements PacketProvid |
117 | */ | 125 | */ |
118 | private class Bmv2PacketContext extends DefaultPacketContext { | 126 | private class Bmv2PacketContext extends DefaultPacketContext { |
119 | 127 | ||
120 | - public Bmv2PacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) { | 128 | + Bmv2PacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) { |
121 | super(time, inPkt, outPkt, block); | 129 | super(time, inPkt, outPkt, block); |
122 | } | 130 | } |
123 | 131 | ||
124 | @Override | 132 | @Override |
125 | public void send() { | 133 | public void send() { |
126 | - if (!this.block()) { | 134 | + |
127 | - if (this.outPacket().treatment() == null) { | 135 | + if (this.block()) { |
128 | - TrafficTreatment treatment = (this.treatmentBuilder() == null) | 136 | + log.info("Unable to send, packet context not blocked"); |
129 | - ? DefaultTrafficTreatment.emptyTreatment() | 137 | + return; |
130 | - : this.treatmentBuilder().build(); | 138 | + } |
131 | - OutboundPacket newPkt = new DefaultOutboundPacket(this.outPacket().sendThrough(), | 139 | + |
132 | - treatment, | 140 | + DeviceId deviceId = outPacket().sendThrough(); |
133 | - this.outPacket().data()); | 141 | + ByteBuffer rawData = outPacket().data(); |
134 | - emit(newPkt); | 142 | + |
143 | + TrafficTreatment treatment; | ||
144 | + if (outPacket().treatment() == null) { | ||
145 | + treatment = (treatmentBuilder() == null) ? emptyTreatment() : treatmentBuilder().build(); | ||
135 | } else { | 146 | } else { |
136 | - emit(outPacket()); | 147 | + treatment = outPacket().treatment(); |
137 | } | 148 | } |
149 | + | ||
150 | + // BMv2 doesn't support FLOOD for packet-outs. | ||
151 | + // Workaround here is to perform multiple emits, one for each device port != packet inPort. | ||
152 | + Optional<OutputInstruction> floodInst = treatment.allInstructions() | ||
153 | + .stream() | ||
154 | + .filter(i -> i.type().equals(OUTPUT)) | ||
155 | + .map(i -> (OutputInstruction) i) | ||
156 | + .filter(i -> i.port().equals(FLOOD)) | ||
157 | + .findAny(); | ||
158 | + | ||
159 | + if (floodInst.isPresent() && treatment.allInstructions().size() == 1) { | ||
160 | + // Only one instruction and is FLOOD. Do the trick. | ||
161 | + PortNumber inPort = inPacket().receivedFrom().port(); | ||
162 | + deviceService.getPorts(outPacket().sendThrough()) | ||
163 | + .stream() | ||
164 | + .map(Port::number) | ||
165 | + .filter(port -> !port.equals(inPort)) | ||
166 | + .map(outPort -> DefaultTrafficTreatment.builder().setOutput(outPort).build()) | ||
167 | + .map(outTreatment -> new DefaultOutboundPacket(deviceId, outTreatment, rawData)) | ||
168 | + .forEach(Bmv2PacketProvider.this::emit); | ||
138 | } else { | 169 | } else { |
139 | - LOG.info("Unable to send, packet context not blocked"); | 170 | + // Not FLOOD treatment, what to do is up to driver. |
171 | + emit(new DefaultOutboundPacket(deviceId, treatment, rawData)); | ||
140 | } | 172 | } |
141 | } | 173 | } |
142 | } | 174 | } |
143 | 175 | ||
144 | /** | 176 | /** |
145 | - * Internal packet listener to get packet events from the Bmv2ControlPlaneServer. | 177 | + * Internal packet listener to handle packet-in events received from the BMv2 controller. |
146 | */ | 178 | */ |
147 | - private class InternalPacketListener implements Bmv2ControlPlaneServer.PacketListener { | 179 | + private class InternalPacketListener implements Bmv2PacketListener { |
180 | + | ||
148 | @Override | 181 | @Override |
149 | public void handlePacketIn(Bmv2Device device, int inputPort, long reason, int tableId, int contextId, | 182 | public void handlePacketIn(Bmv2Device device, int inputPort, long reason, int tableId, int contextId, |
150 | ImmutableByteSequence packet) { | 183 | ImmutableByteSequence packet) { |
184 | + Ethernet ethPkt = new Ethernet(); | ||
185 | + ethPkt.deserialize(packet.asArray(), 0, packet.size()); | ||
186 | + | ||
187 | + DeviceId deviceId = device.asDeviceId(); | ||
188 | + ConnectPoint receivedFrom = new ConnectPoint(deviceId, PortNumber.portNumber(inputPort)); | ||
151 | 189 | ||
152 | - Ethernet eth = new Ethernet(); | 190 | + ByteBuffer rawData = ByteBuffer.wrap(packet.asArray()); |
153 | - eth.deserialize(packet.asArray(), 0, packet.size()); | 191 | + |
192 | + InboundPacket inPkt = new DefaultInboundPacket(receivedFrom, ethPkt, rawData); | ||
193 | + OutboundPacket outPkt = new DefaultOutboundPacket(deviceId, null, rawData); | ||
154 | 194 | ||
155 | - InboundPacket inPkt = new DefaultInboundPacket(new ConnectPoint(device.asDeviceId(), | ||
156 | - PortNumber.portNumber(inputPort)), | ||
157 | - eth, ByteBuffer.wrap(packet.asArray())); | ||
158 | - OutboundPacket outPkt = new DefaultOutboundPacket(device.asDeviceId(), null, | ||
159 | - ByteBuffer.wrap(packet.asArray())); | ||
160 | PacketContext pktCtx = new Bmv2PacketContext(System.currentTimeMillis(), inPkt, outPkt, false); | 195 | PacketContext pktCtx = new Bmv2PacketContext(System.currentTimeMillis(), inPkt, outPkt, false); |
196 | + | ||
161 | providerService.processPacket(pktCtx); | 197 | providerService.processPacket(pktCtx); |
162 | } | 198 | } |
163 | } | 199 | } | ... | ... |
... | @@ -22,6 +22,7 @@ | ... | @@ -22,6 +22,7 @@ |
22 | <artifactId>onos-providers</artifactId> | 22 | <artifactId>onos-providers</artifactId> |
23 | <groupId>org.onosproject</groupId> | 23 | <groupId>org.onosproject</groupId> |
24 | <version>1.6.0-SNAPSHOT</version> | 24 | <version>1.6.0-SNAPSHOT</version> |
25 | + <relativePath>../pom.xml</relativePath> | ||
25 | </parent> | 26 | </parent> |
26 | 27 | ||
27 | <modelVersion>4.0.0</modelVersion> | 28 | <modelVersion>4.0.0</modelVersion> | ... | ... |
... | @@ -46,7 +46,7 @@ | ... | @@ -46,7 +46,7 @@ |
46 | <module>lldpcommon</module> | 46 | <module>lldpcommon</module> |
47 | <module>lldp</module> | 47 | <module>lldp</module> |
48 | <module>netcfglinks</module> | 48 | <module>netcfglinks</module> |
49 | - <!--<module>bmv2</module>--> | 49 | + <module>bmv2</module> |
50 | <module>isis</module> | 50 | <module>isis</module> |
51 | </modules> | 51 | </modules> |
52 | 52 | ... | ... |
-
Please register or login to post a comment