[ONOS-6750]Implement BMv2 PacketProgrammable

Change-Id: Iad3de3eeda764b4942c6db68d25191d2f4946809
This commit is contained in:
Frank Wang 2017-07-18 16:09:28 +08:00 committed by Andrea Campanella
parent 44daf562f9
commit c672c984e8
2 changed files with 57 additions and 17 deletions

View File

@ -35,7 +35,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
@Beta @Beta
public final class PiPacketOperation { public final class PiPacketOperation {
enum Type { public enum Type {
/** /**
* Represents a packet out. * Represents a packet out.
*/ */

View File

@ -16,32 +16,72 @@
package org.onosproject.drivers.bmv2; package org.onosproject.drivers.bmv2;
import org.onlab.util.ImmutableByteSequence;
import org.onosproject.net.Device;
import org.onosproject.net.DeviceId;
import org.onosproject.net.device.DeviceService;
import org.onosproject.net.driver.AbstractHandlerBehaviour; import org.onosproject.net.driver.AbstractHandlerBehaviour;
import org.onosproject.net.packet.OutboundPacket; import org.onosproject.net.packet.OutboundPacket;
import org.onosproject.net.packet.PacketProgrammable; import org.onosproject.net.packet.PacketProgrammable;
import org.onosproject.net.pi.model.PiPipeconf;
import org.onosproject.net.pi.model.PiPipelineInterpreter;
import org.onosproject.net.pi.runtime.PiPacketOperation;
import org.onosproject.net.pi.runtime.PiPipeconfService;
import org.onosproject.p4runtime.api.P4RuntimeClient;
import org.onosproject.p4runtime.api.P4RuntimeController;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import static org.onosproject.net.pi.runtime.PiPacketOperation.Type.PACKET_OUT;
/** /**
* Packet Programmable behaviour for BMv2 devices. * Packet Programmable behaviour for BMv2 devices.
*/ */
public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements PacketProgrammable { public class Bmv2PacketProgrammable extends AbstractHandlerBehaviour implements PacketProgrammable {
private final Logger log = LoggerFactory.getLogger(getClass());
@Override @Override
public void emit(OutboundPacket packet) { public void emit(OutboundPacket packet) {
// TODO: implement using P4runtime client.
// DriverHandler handler = handler(); DeviceId deviceId = handler().data().deviceId();
// GrpcController controller = handler.get(GrpcController.class); P4RuntimeController controller = handler().get(P4RuntimeController.class);
// DeviceId deviceId = handler.data().deviceId(); if (!controller.hasClient(deviceId)) {
// GrpcChannelId channelId = GrpcChannelId.of(deviceId, "bmv2"); log.warn("Unable to find client for {}, aborting the sending packet", deviceId);
// GrpcServiceId serviceId = GrpcServiceId.of(channelId, "p4runtime"); return;
// GrpcStreamObserverId observerId = GrpcStreamObserverId.of(serviceId, }
// this.getClass().getSimpleName());
// Optional<GrpcObserverHandler> manager = controller.getObserverManager(observerId); P4RuntimeClient client = controller.getClient(deviceId);
// if (!manager.isPresent()) { PiPipeconfService piPipeconfService = handler().get(PiPipeconfService.class);
// //this is the first time the behaviour is called
// controller.addObserver(observerId, new Bmv2PacketInObserverHandler()); final PiPipeconf pipeconf;
// } if (piPipeconfService.ofDevice(deviceId).isPresent() &&
// //other already registered the observer for us. piPipeconfService.getPipeconf(piPipeconfService.ofDevice(deviceId).get()).isPresent()) {
// Optional<StreamObserver> observer = manager.get().requestStreamObserver(); pipeconf = piPipeconfService.getPipeconf(piPipeconfService.ofDevice(deviceId).get()).get();
// observer.ifPresent(objectStreamObserver -> objectStreamObserver.onNext(packet)); } else {
log.warn("Unable to get the pipeconf of the {}", deviceId);
return;
}
DeviceService deviceService = handler().get(DeviceService.class);
Device device = deviceService.getDevice(deviceId);
final PiPipelineInterpreter interpreter = device.is(PiPipelineInterpreter.class)
? device.as(PiPipelineInterpreter.class) : null;
if (interpreter == null) {
log.warn("Device {} unable to instantiate interpreter of pipeconf {}", deviceId, pipeconf.id());
return;
}
try {
PiPacketOperation piPacketOperation = PiPacketOperation
.builder()
.withType(PACKET_OUT)
.withData(ImmutableByteSequence.copyFrom(packet.data()))
.withMetadatas(interpreter.mapOutboundPacket(packet, pipeconf))
.build();
client.packetOut(piPacketOperation, pipeconf);
} catch (PiPipelineInterpreter.PiInterpreterException e) {
log.error("Interpreter of pipeconf {} was unable to translate outbound packet: {}",
pipeconf.id(), e.getMessage());
}
} }
} }