blob: c7d76c07d9390bff942ac59d55876d746931893a [file] [log] [blame]
Carmelo Casconed61fdb32017-10-30 10:09:57 -07001/*
2 * Copyright 2017-present Open Networking Foundation
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
17package org.onosproject.drivers.p4runtime;
18
19import org.onlab.util.SharedExecutors;
20import org.onosproject.net.DeviceId;
Carmelo Cascone87892e22017-11-13 16:01:29 -080021import org.onosproject.net.behaviour.PiPipelineProgrammable;
Carmelo Casconee5b28722018-06-22 17:28:28 +020022import org.onosproject.net.pi.model.PiPipeconf;
Carmelo Casconed61fdb32017-10-30 10:09:57 -070023import org.onosproject.p4runtime.api.P4RuntimeClient;
24import org.onosproject.p4runtime.api.P4RuntimeController;
25import org.slf4j.Logger;
26
27import java.nio.ByteBuffer;
28import java.util.Optional;
29import java.util.concurrent.CompletableFuture;
Carmelo Casconed61fdb32017-10-30 10:09:57 -070030
31import static org.slf4j.LoggerFactory.getLogger;
32
33/**
34 * Abstract implementation of the PiPipelineProgrammable behaviours for a P4Runtime device.
35 */
Carmelo Casconee5b28722018-06-22 17:28:28 +020036public abstract class AbstractP4RuntimePipelineProgrammable
37 extends AbstractP4RuntimeHandlerBehaviour
Carmelo Casconed61fdb32017-10-30 10:09:57 -070038 implements PiPipelineProgrammable {
39
40 protected final Logger log = getLogger(getClass());
41
42 /**
43 * Returns a byte buffer representing the target-specific device data to be used in the SetPipelineConfig message.
44 *
45 * @param pipeconf pipeconf
46 * @return byte buffer
47 */
48 public abstract ByteBuffer createDeviceDataBuffer(PiPipeconf pipeconf);
49
50 @Override
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070051 public CompletableFuture<Boolean> setPipeconf(PiPipeconf pipeconf) {
Carmelo Casconed61fdb32017-10-30 10:09:57 -070052 return CompletableFuture.supplyAsync(
53 () -> doDeployConfig(pipeconf),
54 SharedExecutors.getPoolThreadExecutor());
55 }
56
57 private boolean doDeployConfig(PiPipeconf pipeconf) {
58
59 DeviceId deviceId = handler().data().deviceId();
60 P4RuntimeController controller = handler().get(P4RuntimeController.class);
61
Carmelo Cascone158b8c42018-07-04 19:42:37 +020062 P4RuntimeClient client = controller.getClient(deviceId);
63 if (client == null) {
Carmelo Casconed61fdb32017-10-30 10:09:57 -070064 log.warn("Unable to find client for {}, aborting pipeconf deploy", deviceId);
65 return false;
66 }
Carmelo Casconed61fdb32017-10-30 10:09:57 -070067
68 ByteBuffer deviceDataBuffer = createDeviceDataBuffer(pipeconf);
69 if (deviceDataBuffer == null) {
70 // Hopefully the child class logged the problem.
71 return false;
72 }
73
Carmelo Casconee5b28722018-06-22 17:28:28 +020074 final Boolean deploySuccess = getFutureWithDeadline(
75 client.setPipelineConfig(pipeconf, deviceDataBuffer),
76 "deploying pipeconf", null);
77 if (deploySuccess == null) {
78 return false;
79 } else if (!deploySuccess) {
80 log.warn("Unable to deploy pipeconf {} to {}", pipeconf.id(), deviceId);
Yi Tseng3e7f1452017-10-20 10:31:53 -070081 return false;
82 }
Carmelo Casconee5b28722018-06-22 17:28:28 +020083
Carmelo Casconed61fdb32017-10-30 10:09:57 -070084 return true;
85 }
86
87 @Override
Carmelo Cascone9e4972c2018-08-30 00:29:16 -070088 public boolean isPipeconfSet(PiPipeconf pipeconf) {
89 DeviceId deviceId = handler().data().deviceId();
90 P4RuntimeController controller = handler().get(P4RuntimeController.class);
91
92 P4RuntimeClient client = controller.getClient(deviceId);
93 if (client == null) {
94 log.warn("Unable to find client for {}, cannot check if pipeconf is set", deviceId);
95 return false;
96 }
97
98 ByteBuffer deviceDataBuffer = createDeviceDataBuffer(pipeconf);
99 if (deviceDataBuffer == null) {
100 // Hopefully the child class logged the problem.
101 return false;
102 }
103
104 return client.isPipelineConfigSet(pipeconf, deviceDataBuffer);
105 }
106
107 @Override
Carmelo Casconed61fdb32017-10-30 10:09:57 -0700108 public abstract Optional<PiPipeconf> getDefaultPipeconf();
109}