blob: f38b504760bcdd04189bbbabab1769e3c877612e [file] [log] [blame]
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -04001/*
Carmelo Casconee44592f2018-09-12 02:24:47 -07002 * Copyright 2018-present Open Networking Foundation
Carmelo Casconeb2e3dba2017-07-27 12:07: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
Andrea Campanella0288c872017-08-07 18:32:51 +020017package org.onosproject.drivers.p4runtime;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040018
Carmelo Cascone58136812018-07-19 03:40:16 +020019import com.google.common.collect.ImmutableList;
Carmelo Cascone26600972018-09-10 00:23:20 -070020import com.google.common.collect.Lists;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040021import org.onosproject.net.DeviceId;
Carmelo Casconee44592f2018-09-12 02:24:47 -070022import org.onosproject.net.driver.AbstractHandlerBehaviour;
Yi Tseng82512da2017-08-16 19:46:36 -070023import org.onosproject.net.group.Group;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040024import org.onosproject.net.group.GroupOperation;
25import org.onosproject.net.group.GroupOperations;
26import org.onosproject.net.group.GroupProgrammable;
Yi Tseng82512da2017-08-16 19:46:36 -070027import org.slf4j.Logger;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040028
Yi Tseng82512da2017-08-16 19:46:36 -070029import java.util.Collection;
30import java.util.Collections;
Carmelo Cascone26600972018-09-10 00:23:20 -070031import java.util.List;
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -040032
Carmelo Cascone26600972018-09-10 00:23:20 -070033import static com.google.common.base.Preconditions.checkArgument;
Yi Tseng82512da2017-08-16 19:46:36 -070034import static org.slf4j.LoggerFactory.getLogger;
35
36/**
Carmelo Casconee44592f2018-09-12 02:24:47 -070037 * Implementation of GroupProgrammable for P4Runtime devices that uses two
38 * different implementation of the same behavior to handle both action profile
Carmelo Cascone9db4d5c2019-04-16 17:36:33 -070039 * groups and PRE entries.
Yi Tseng82512da2017-08-16 19:46:36 -070040 */
Carmelo Casconee75b7942017-11-21 17:14:49 -080041public class P4RuntimeGroupProgrammable
Carmelo Casconee44592f2018-09-12 02:24:47 -070042 extends AbstractHandlerBehaviour implements GroupProgrammable {
Carmelo Casconee75b7942017-11-21 17:14:49 -080043
Carmelo Casconee44592f2018-09-12 02:24:47 -070044 private final Logger log = getLogger(this.getClass());
Carmelo Casconee75b7942017-11-21 17:14:49 -080045
Carmelo Casconee44592f2018-09-12 02:24:47 -070046 private void doPerformGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
47 // TODO: fix GroupProgrammable API, passing the device ID is ambiguous
48 checkArgument(deviceId.equals(data().deviceId()),
49 "passed deviceId must be the same assigned to this behavior");
50 final List<GroupOperation> actionGroups = Lists.newArrayList();
Carmelo Cascone9db4d5c2019-04-16 17:36:33 -070051 final List<GroupOperation> preGroups = Lists.newArrayList();
Carmelo Casconee44592f2018-09-12 02:24:47 -070052 groupOps.operations().forEach(op -> {
Carmelo Cascone9db4d5c2019-04-16 17:36:33 -070053 switch (op.groupType()) {
54 case SELECT:
55 actionGroups.add(op);
56 break;
57 case ALL:
58 case CLONE:
59 preGroups.add(op);
60 break;
61 case FAILOVER:
62 case INDIRECT:
63 default:
64 log.warn("{} group type not supported [{}]", op.groupType(), op);
Carmelo Casconee44592f2018-09-12 02:24:47 -070065 }
66 });
67 if (!actionGroups.isEmpty()) {
68 actionProgrammable().performGroupOperation(
69 deviceId, new GroupOperations(actionGroups));
Carmelo Casconee75b7942017-11-21 17:14:49 -080070 }
Carmelo Cascone9db4d5c2019-04-16 17:36:33 -070071 if (!preGroups.isEmpty()) {
72 replicationProgrammable().performGroupOperation(
73 deviceId, new GroupOperations(preGroups));
Carmelo Casconee44592f2018-09-12 02:24:47 -070074 }
75 }
76
77 private Collection<Group> doGetGroups() {
78 return new ImmutableList.Builder<Group>()
79 .addAll(actionProgrammable().getGroups())
Carmelo Cascone9db4d5c2019-04-16 17:36:33 -070080 .addAll(replicationProgrammable().getGroups())
Carmelo Casconee44592f2018-09-12 02:24:47 -070081 .build();
82 }
83
84 private P4RuntimeActionGroupProgrammable actionProgrammable() {
85 P4RuntimeActionGroupProgrammable prog = new P4RuntimeActionGroupProgrammable();
86 prog.setData(data());
87 prog.setHandler(handler());
88 return prog;
89 }
90
Carmelo Cascone9db4d5c2019-04-16 17:36:33 -070091 private P4RuntimeReplicationGroupProgrammable replicationProgrammable() {
92 P4RuntimeReplicationGroupProgrammable prog = new P4RuntimeReplicationGroupProgrammable();
Carmelo Casconee44592f2018-09-12 02:24:47 -070093 prog.setData(data());
94 prog.setHandler(handler());
95 return prog;
Carmelo Casconee75b7942017-11-21 17:14:49 -080096 }
97
98 @Override
Carmelo Casconee44592f2018-09-12 02:24:47 -070099 public void performGroupOperation(DeviceId deviceId, GroupOperations groupOps) {
100 try {
101 doPerformGroupOperation(deviceId, groupOps);
102 } catch (Throwable ex) {
103 log.error("Unhandled exception on performGroupOperation", ex);
Yi Tseng82512da2017-08-16 19:46:36 -0700104 }
Yi Tseng82512da2017-08-16 19:46:36 -0700105 }
106
Yi Tseng82512da2017-08-16 19:46:36 -0700107 @Override
108 public Collection<Group> getGroups() {
Carmelo Casconee44592f2018-09-12 02:24:47 -0700109 try {
110 return doGetGroups();
111 } catch (Throwable ex) {
112 log.error("Unhandled exception on getGroups", ex);
Carmelo Cascone87b9b392017-10-02 18:33:20 +0200113 return Collections.emptyList();
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -0400114 }
Carmelo Casconee75b7942017-11-21 17:14:49 -0800115 }
Carmelo Casconeb2e3dba2017-07-27 12:07:09 -0400116}