blob: bf882388e40bf67c61880bfea49cd3b1e1317e67 [file] [log] [blame]
Carmelo Cascone59f57de2017-07-11 19:55:09 -04001/*
Brian O'Connora09fe5b2017-08-03 21:12:30 -07002 * Copyright 2017-present Open Networking Foundation
Carmelo Cascone59f57de2017-07-11 19:55:09 -04003 *
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.bmv2;
18
19import org.onlab.util.SharedExecutors;
20import org.onosproject.net.DeviceId;
21import org.onosproject.net.driver.AbstractHandlerBehaviour;
22import org.onosproject.net.pi.model.PiPipeconf;
23import org.onosproject.net.pi.model.PiPipelineProgrammable;
24import org.onosproject.p4runtime.api.P4RuntimeClient;
25import org.onosproject.p4runtime.api.P4RuntimeController;
Carmelo Casconeca94bcf2017-10-27 14:16:59 -070026import org.onosproject.pipelines.basic.PipeconfLoader;
Carmelo Cascone59f57de2017-07-11 19:55:09 -040027import org.slf4j.Logger;
28
Carmelo Cascone59f57de2017-07-11 19:55:09 -040029import java.util.Optional;
30import java.util.concurrent.CompletableFuture;
31import java.util.concurrent.ExecutionException;
32
33import static org.onosproject.net.pi.model.PiPipeconf.ExtensionType.BMV2_JSON;
Carmelo Cascone59f57de2017-07-11 19:55:09 -040034import static org.slf4j.LoggerFactory.getLogger;
35
36/**
37 * Implementation of the PiPipelineProgrammable for BMv2.
38 */
39public class Bmv2PipelineProgrammable extends AbstractHandlerBehaviour implements PiPipelineProgrammable {
40
Carmelo Cascone59f57de2017-07-11 19:55:09 -040041 private final Logger log = getLogger(getClass());
42
43 @Override
44 public CompletableFuture<Boolean> deployPipeconf(PiPipeconf pipeconf) {
45
46 CompletableFuture<Boolean> result = new CompletableFuture<>();
47
48 SharedExecutors.getPoolThreadExecutor().submit(() -> result.complete(doDeployConfig(pipeconf)));
49
50 return result;
51 }
52
53 private boolean doDeployConfig(PiPipeconf pipeconf) {
54
55 P4RuntimeController controller = handler().get(P4RuntimeController.class);
56
57 DeviceId deviceId = handler().data().deviceId();
58
59 if (!controller.hasClient(deviceId)) {
60 log.warn("Unable to find client for {}, aborting pipeconf deploy", deviceId);
61 return false;
62
63 }
64
65 P4RuntimeClient client = controller.getClient(deviceId);
66
Carmelo Cascone59f57de2017-07-11 19:55:09 -040067 try {
Carmelo Cascone8d99b172017-07-18 17:26:31 -040068 if (!client.setPipelineConfig(pipeconf, BMV2_JSON).get()) {
Carmelo Cascone59f57de2017-07-11 19:55:09 -040069 log.warn("Unable to deploy pipeconf {} to {}", pipeconf.id(), deviceId);
70 return false;
71 }
72
73 // It would be more logical to have this performed at device handshake, but P4runtime would reject any
74 // command if a P4info has not been set first.
75 if (!client.initStreamChannel().get()) {
76 log.warn("Unable to init stream channel to {}.", deviceId);
77 return false;
78 }
79
80 } catch (InterruptedException | ExecutionException e) {
81 throw new RuntimeException(e);
82 }
83
84 return true;
85 }
86
87 @Override
88 public Optional<PiPipeconf> getDefaultPipeconf() {
Carmelo Casconeca94bcf2017-10-27 14:16:59 -070089 return Optional.of(PipeconfLoader.BASIC_PIPECONF);
Carmelo Cascone59f57de2017-07-11 19:55:09 -040090 }
91}