Carmelo Cascone
Committed by Gerrit Code Review

ONOS-4420 Implemented BMv2 packet provider

Also, moved DeviceId generation logic from Bmv2DeviceProvider to
Bmv2Device.

Change-Id: I0a7af6d558d054604038a858dce67a2d287bcde3
...@@ -17,6 +17,10 @@ ...@@ -17,6 +17,10 @@
17 package org.onosproject.bmv2.api.runtime; 17 package org.onosproject.bmv2.api.runtime;
18 18
19 import com.google.common.base.Objects; 19 import com.google.common.base.Objects;
20 +import org.onosproject.net.DeviceId;
21 +
22 +import java.net.URI;
23 +import java.net.URISyntaxException;
20 24
21 import static com.google.common.base.Preconditions.checkNotNull; 25 import static com.google.common.base.Preconditions.checkNotNull;
22 26
...@@ -25,6 +29,10 @@ import static com.google.common.base.Preconditions.checkNotNull; ...@@ -25,6 +29,10 @@ import static com.google.common.base.Preconditions.checkNotNull;
25 */ 29 */
26 public final class Bmv2Device { 30 public final class Bmv2Device {
27 31
32 + public static final String SCHEME = "bmv2";
33 + public static final String MANUFACTURER = "p4.org";
34 + public static final String HW_VERSION = "bmv2";
35 +
28 private final String thriftServerHost; 36 private final String thriftServerHost;
29 private final int thriftServerPort; 37 private final int thriftServerPort;
30 private final int internalDeviceId; 38 private final int internalDeviceId;
...@@ -66,10 +74,24 @@ public final class Bmv2Device { ...@@ -66,10 +74,24 @@ public final class Bmv2Device {
66 * 74 *
67 * @return an integer value 75 * @return an integer value
68 */ 76 */
69 - public int getInternalDeviceId() { 77 + public int internalDeviceId() {
70 return internalDeviceId; 78 return internalDeviceId;
71 } 79 }
72 80
81 + /**
82 + * Returns a new ONOS device ID for this device.
83 + *
84 + * @return a new device ID
85 + */
86 + public DeviceId asDeviceId() {
87 + try {
88 + // TODO: include internalDeviceId number in the deviceId URI
89 + return DeviceId.deviceId(new URI(SCHEME, this.thriftServerHost + ":" + this.thriftServerPort, null));
90 + } catch (URISyntaxException e) {
91 + throw new IllegalArgumentException("Unable to build deviceID for device " + this.toString(), e);
92 + }
93 + }
94 +
73 @Override 95 @Override
74 public int hashCode() { 96 public int hashCode() {
75 return Objects.hashCode(thriftServerHost, thriftServerPort, internalDeviceId); 97 return Objects.hashCode(thriftServerHost, thriftServerPort, internalDeviceId);
......
...@@ -20,6 +20,7 @@ ...@@ -20,6 +20,7 @@
20 <feature>onos-drivers-bmv2</feature> 20 <feature>onos-drivers-bmv2</feature>
21 <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle> 21 <bundle>mvn:${project.groupId}/${project.artifactId}/${project.version}</bundle>
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:org.apache.thrift/libthrift/0.9.3</bundle> 24 <bundle>mvn:org.apache.thrift/libthrift/0.9.3</bundle>
24 <bundle>mvn:${project.groupId}/onos-bmv2-protocol/${project.version}</bundle> 25 <bundle>mvn:${project.groupId}/onos-bmv2-protocol/${project.version}</bundle>
25 </feature> 26 </feature>
......
...@@ -43,6 +43,11 @@ ...@@ -43,6 +43,11 @@
43 <artifactId>onos-bmv2-provider-device</artifactId> 43 <artifactId>onos-bmv2-provider-device</artifactId>
44 <version>${project.version}</version> 44 <version>${project.version}</version>
45 </dependency> 45 </dependency>
46 + <dependency>
47 + <groupId>org.onosproject</groupId>
48 + <artifactId>onos-bmv2-provider-packet</artifactId>
49 + <version>${project.version}</version>
50 + </dependency>
46 </dependencies> 51 </dependencies>
47 52
48 </project> 53 </project>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -39,7 +39,7 @@ ...@@ -39,7 +39,7 @@
39 <dependency> 39 <dependency>
40 <groupId>org.onosproject</groupId> 40 <groupId>org.onosproject</groupId>
41 <artifactId>onos-core-common</artifactId> 41 <artifactId>onos-core-common</artifactId>
42 - <version>1.6.0-SNAPSHOT</version> 42 + <version>${project.version}</version>
43 </dependency> 43 </dependency>
44 </dependencies> 44 </dependencies>
45 </project> 45 </project>
...\ No newline at end of file ...\ No newline at end of file
......
...@@ -50,8 +50,6 @@ import org.onosproject.net.device.PortDescription; ...@@ -50,8 +50,6 @@ import org.onosproject.net.device.PortDescription;
50 import org.onosproject.net.provider.ProviderId; 50 import org.onosproject.net.provider.ProviderId;
51 import org.slf4j.Logger; 51 import org.slf4j.Logger;
52 52
53 -import java.net.URI;
54 -import java.net.URISyntaxException;
55 import java.util.List; 53 import java.util.List;
56 import java.util.concurrent.ConcurrentMap; 54 import java.util.concurrent.ConcurrentMap;
57 import java.util.concurrent.ExecutorService; 55 import java.util.concurrent.ExecutorService;
...@@ -63,6 +61,9 @@ import static org.onosproject.bmv2.ctl.Bmv2ThriftClient.forceDisconnectOf; ...@@ -63,6 +61,9 @@ import static org.onosproject.bmv2.ctl.Bmv2ThriftClient.forceDisconnectOf;
63 import static org.onosproject.bmv2.ctl.Bmv2ThriftClient.ping; 61 import static org.onosproject.bmv2.ctl.Bmv2ThriftClient.ping;
64 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY; 62 import static org.onosproject.net.config.basics.SubjectFactories.APP_SUBJECT_FACTORY;
65 import static org.slf4j.LoggerFactory.getLogger; 63 import static org.slf4j.LoggerFactory.getLogger;
64 +import static org.onosproject.bmv2.api.runtime.Bmv2Device.SCHEME;
65 +import static org.onosproject.bmv2.api.runtime.Bmv2Device.MANUFACTURER;
66 +import static org.onosproject.bmv2.api.runtime.Bmv2Device.HW_VERSION;
66 67
67 /** 68 /**
68 * BMv2 device provider. 69 * BMv2 device provider.
...@@ -72,9 +73,6 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider { ...@@ -72,9 +73,6 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
72 73
73 private static final Logger LOG = getLogger(Bmv2DeviceProvider.class); 74 private static final Logger LOG = getLogger(Bmv2DeviceProvider.class);
74 75
75 - public static final String MANUFACTURER = "p4.org";
76 - public static final String HW_VERSION = "bmv2";
77 - public static final String SCHEME = "bmv2";
78 private static final String APP_NAME = "org.onosproject.bmv2"; 76 private static final String APP_NAME = "org.onosproject.bmv2";
79 private static final String UNKNOWN = "unknown"; 77 private static final String UNKNOWN = "unknown";
80 private static final int POLL_INTERVAL = 5; // seconds 78 private static final int POLL_INTERVAL = 5; // seconds
...@@ -108,25 +106,6 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider { ...@@ -108,25 +106,6 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
108 super(new ProviderId("bmv2", "org.onosproject.provider.device")); 106 super(new ProviderId("bmv2", "org.onosproject.provider.device"));
109 } 107 }
110 108
111 - private static DeviceId deviceIdOf(String ip, int port) {
112 - try {
113 - return DeviceId.deviceId(new URI(SCHEME, ip + ":" + port, null));
114 - } catch (URISyntaxException e) {
115 - throw new IllegalArgumentException("Unable to build deviceID for device " + ip + ":" + port, e);
116 - }
117 - }
118 -
119 - /**
120 - * Creates a new device ID for the given BMv2 device.
121 - *
122 - * @param device a BMv2 device object
123 - *
124 - * @return a new device ID
125 - */
126 - public static DeviceId deviceIdOf(Bmv2Device device) {
127 - return deviceIdOf(device.thriftServerHost(), device.thriftServerPort());
128 - }
129 -
130 @Override 109 @Override
131 protected void activate() { 110 protected void activate() {
132 appId = coreService.registerApplication(APP_NAME); 111 appId = coreService.registerApplication(APP_NAME);
...@@ -258,7 +237,9 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider { ...@@ -258,7 +237,9 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
258 if (cfg != null) { 237 if (cfg != null) {
259 try { 238 try {
260 cfg.getDevicesInfo().stream().forEach(info -> { 239 cfg.getDevicesInfo().stream().forEach(info -> {
261 - triggerProbe(deviceIdOf(info.ip().toString(), info.port())); 240 + // TODO: require also bmv2 internal device id from net-cfg (now is default 0)
241 + Bmv2Device bmv2Device = new Bmv2Device(info.ip().toString(), info.port(), 0);
242 + triggerProbe(bmv2Device.asDeviceId());
262 }); 243 });
263 } catch (ConfigException e) { 244 } catch (ConfigException e) {
264 LOG.error("Unable to read config: " + e); 245 LOG.error("Unable to read config: " + e);
...@@ -283,7 +264,7 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider { ...@@ -283,7 +264,7 @@ public class Bmv2DeviceProvider extends AbstractDeviceProvider {
283 @Override 264 @Override
284 public void handleHello(Bmv2Device device) { 265 public void handleHello(Bmv2Device device) {
285 log.debug("Received hello from {}", device); 266 log.debug("Received hello from {}", device);
286 - triggerProbe(deviceIdOf(device)); 267 + triggerProbe(device.asDeviceId());
287 } 268 }
288 } 269 }
289 270
......
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 + <parent>
22 + <artifactId>onos-bmv2-providers</artifactId>
23 + <groupId>org.onosproject</groupId>
24 + <version>1.6.0-SNAPSHOT</version>
25 + </parent>
26 + <modelVersion>4.0.0</modelVersion>
27 +
28 + <artifactId>onos-bmv2-provider-packet</artifactId>
29 +
30 + <packaging>bundle</packaging>
31 +
32 + <description>ONOS BMv2 packet provider</description>
33 +
34 + <dependencies>
35 + <dependency>
36 + <groupId>org.onosproject</groupId>
37 + <artifactId>onos-drivers-bmv2</artifactId>
38 + <version>${project.version}</version>
39 + </dependency>
40 + <dependency>
41 + <groupId>org.onosproject</groupId>
42 + <artifactId>onos-core-common</artifactId>
43 + <version>${project.version}</version>
44 + </dependency>
45 + </dependencies>
46 +</project>
...\ No newline at end of file ...\ No newline at end of file
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.packet.impl;
18 +
19 +import org.apache.felix.scr.annotations.Activate;
20 +import org.apache.felix.scr.annotations.Component;
21 +import org.apache.felix.scr.annotations.Deactivate;
22 +import org.apache.felix.scr.annotations.Reference;
23 +import org.apache.felix.scr.annotations.ReferenceCardinality;
24 +import org.onlab.packet.Ethernet;
25 +import org.onlab.util.ImmutableByteSequence;
26 +import org.onosproject.bmv2.api.runtime.Bmv2ControlPlaneServer;
27 +import org.onosproject.bmv2.api.runtime.Bmv2Device;
28 +import org.onosproject.core.CoreService;
29 +import org.onosproject.net.ConnectPoint;
30 +import org.onosproject.net.Device;
31 +import org.onosproject.net.DeviceId;
32 +import org.onosproject.net.PortNumber;
33 +import org.onosproject.net.device.DeviceService;
34 +import org.onosproject.net.flow.DefaultTrafficTreatment;
35 +import org.onosproject.net.flow.TrafficTreatment;
36 +import org.onosproject.net.packet.DefaultInboundPacket;
37 +import org.onosproject.net.packet.DefaultOutboundPacket;
38 +import org.onosproject.net.packet.DefaultPacketContext;
39 +import org.onosproject.net.packet.InboundPacket;
40 +import org.onosproject.net.packet.OutboundPacket;
41 +import org.onosproject.net.packet.PacketContext;
42 +import org.onosproject.net.packet.PacketProgrammable;
43 +import org.onosproject.net.packet.PacketProvider;
44 +import org.onosproject.net.packet.PacketProviderRegistry;
45 +import org.onosproject.net.packet.PacketProviderService;
46 +import org.onosproject.net.provider.AbstractProvider;
47 +import org.onosproject.net.provider.ProviderId;
48 +import org.slf4j.Logger;
49 +import org.slf4j.LoggerFactory;
50 +
51 +import java.nio.ByteBuffer;
52 +
53 +/**
54 + * Implementation of a packet provider for BMv2.
55 + */
56 +@Component(immediate = true)
57 +public class Bmv2PacketProvider extends AbstractProvider implements PacketProvider {
58 +
59 + private static final Logger LOG = LoggerFactory.getLogger(Bmv2PacketProvider.class);
60 + private static final String APP_NAME = "org.onosproject.bmv2";
61 +
62 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
63 + protected Bmv2ControlPlaneServer controlPlaneServer;
64 +
65 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
66 + protected CoreService coreService;
67 +
68 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
69 + protected PacketProviderRegistry providerRegistry;
70 +
71 + @Reference(cardinality = ReferenceCardinality.MANDATORY_UNARY)
72 + protected DeviceService deviceService;
73 +
74 + private PacketProviderService providerService;
75 +
76 + private InternalPacketListener packetListener = new InternalPacketListener();
77 +
78 + /**
79 + * Creates a new BMv2 packet provider.
80 + */
81 + public Bmv2PacketProvider() {
82 + super(new ProviderId("bmv2", "org.onosproject.provider.packet"));
83 + }
84 +
85 + @Activate
86 + protected void activate() {
87 + providerService = providerRegistry.register(this);
88 + coreService.registerApplication(APP_NAME);
89 + controlPlaneServer.addPacketListener(packetListener);
90 + LOG.info("Started");
91 + }
92 +
93 + @Deactivate
94 + public void deactivate() {
95 + controlPlaneServer.removePacketListener(packetListener);
96 + providerRegistry.unregister(this);
97 + providerService = null;
98 + LOG.info("Stopped");
99 + }
100 +
101 + @Override
102 + public void emit(OutboundPacket packet) {
103 + if (packet != null) {
104 + DeviceId did = packet.sendThrough();
105 + Device device = deviceService.getDevice(did);
106 + if (device.is(PacketProgrammable.class)) {
107 + PacketProgrammable packetProgrammable = device.as(PacketProgrammable.class);
108 + packetProgrammable.emit(packet);
109 + } else {
110 + LOG.info("Unable to send packet, no PacketProgrammable behavior for device {}", did);
111 + }
112 + }
113 + }
114 +
115 + /**
116 + * Internal packet context implementation.
117 + */
118 + private class Bmv2PacketContext extends DefaultPacketContext {
119 +
120 + public Bmv2PacketContext(long time, InboundPacket inPkt, OutboundPacket outPkt, boolean block) {
121 + super(time, inPkt, outPkt, block);
122 + }
123 +
124 + @Override
125 + public void send() {
126 + if (!this.block()) {
127 + if (this.outPacket().treatment() == null) {
128 + TrafficTreatment treatment = (this.treatmentBuilder() == null)
129 + ? DefaultTrafficTreatment.emptyTreatment()
130 + : this.treatmentBuilder().build();
131 + OutboundPacket newPkt = new DefaultOutboundPacket(this.outPacket().sendThrough(),
132 + treatment,
133 + this.outPacket().data());
134 + emit(newPkt);
135 + } else {
136 + emit(outPacket());
137 + }
138 + } else {
139 + LOG.info("Unable to send, packet context not blocked");
140 + }
141 + }
142 + }
143 +
144 + /**
145 + * Internal packet listener to get packet events from the Bmv2ControlPlaneServer.
146 + */
147 + private class InternalPacketListener implements Bmv2ControlPlaneServer.PacketListener {
148 + @Override
149 + public void handlePacketIn(Bmv2Device device, int inputPort, long reason, int tableId, int contextId,
150 + ImmutableByteSequence packet) {
151 +
152 + Ethernet eth = new Ethernet();
153 + eth.deserialize(packet.asArray(), 0, packet.size());
154 +
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);
161 + providerService.processPacket(pktCtx);
162 + }
163 + }
164 +}
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 + * Provider that use Thrift as a mean of listening for packet-ins and emitting packet-outs.
19 + */
20 +package org.onosproject.provider.bmv2.packet.impl;
...\ No newline at end of file ...\ No newline at end of file
...@@ -34,6 +34,7 @@ ...@@ -34,6 +34,7 @@
34 <modules> 34 <modules>
35 <module>app</module> 35 <module>app</module>
36 <module>device</module> 36 <module>device</module>
37 + <module>packet</module>
37 </modules> 38 </modules>
38 39
39 </project> 40 </project>
...\ No newline at end of file ...\ No newline at end of file
......