blob: cfbf95e4b3dd2a76a2808a1c225d6ebaa1939bb0 [file] [log] [blame]
Daniele Moro8d630f12021-06-15 20:53:22 +02001/*
2 * Copyright 2021-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.pipelines.fabric.impl.behaviour.upf;
18
19import org.apache.commons.lang3.tuple.Pair;
20import org.onlab.packet.Ip4Address;
21import org.onlab.packet.Ip4Prefix;
22import org.onlab.util.ImmutableByteSequence;
23import org.onosproject.net.behaviour.upf.UpfProgrammableException;
24import org.onosproject.net.flow.FlowRule;
25import org.onosproject.net.flow.criteria.Criterion;
26import org.onosproject.net.flow.criteria.PiCriterion;
27import org.onosproject.net.flow.instructions.Instruction;
28import org.onosproject.net.flow.instructions.PiInstruction;
29import org.onosproject.net.pi.model.PiActionParamId;
30import org.onosproject.net.pi.model.PiMatchFieldId;
31import org.onosproject.net.pi.model.PiMatchType;
32import org.onosproject.net.pi.runtime.PiAction;
33import org.onosproject.net.pi.runtime.PiActionParam;
34import org.onosproject.net.pi.runtime.PiExactFieldMatch;
35import org.onosproject.net.pi.runtime.PiFieldMatch;
36import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
37import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
38import org.onosproject.net.pi.runtime.PiTableAction;
39import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
40
41import java.util.Optional;
42
43/**
44 * Utility class for manipulation of FlowRules and PiTableEntry objects specific to fabric-tna.
45 */
46final class FabricUpfTranslatorUtil {
47
48 private FabricUpfTranslatorUtil() {
49 }
50
51 static ImmutableByteSequence getFieldValue(PiFieldMatch field, PiMatchFieldId fieldId)
52 throws UpfProgrammableException {
53 if (field == null) {
54 throw new UpfProgrammableException(
55 String.format("Unable to find field %s where expected!", fieldId.toString()));
56 }
57 if (field.type() == PiMatchType.EXACT) {
58 return ((PiExactFieldMatch) field).value();
59 } else if (field.type() == PiMatchType.LPM) {
60 return ((PiLpmFieldMatch) field).value();
61 } else if (field.type() == PiMatchType.TERNARY) {
62 return ((PiTernaryFieldMatch) field).value();
63 } else if (field.type() == PiMatchType.RANGE) {
64 return ((PiRangeFieldMatch) field).lowValue();
65 } else {
66 throw new UpfProgrammableException(
67 String.format("Field %s has unknown match type: %s", fieldId.toString(), field.type().toString()));
68 }
69 }
70
71 static ImmutableByteSequence getFieldValue(PiCriterion criterion, PiMatchFieldId fieldId)
72 throws UpfProgrammableException {
73 return getFieldValue(criterion.fieldMatch(fieldId).orElse(null), fieldId);
74 }
75
76 static boolean fieldIsPresent(PiCriterion criterion, PiMatchFieldId fieldId) {
77 return criterion.fieldMatch(fieldId).isPresent();
78 }
79
80 static ImmutableByteSequence getParamValue(PiAction action, PiActionParamId paramId)
81 throws UpfProgrammableException {
82
83 for (PiActionParam param : action.parameters()) {
84 if (param.id().equals(paramId)) {
85 return param.value();
86 }
87 }
88 throw new UpfProgrammableException(
89 String.format("Unable to find parameter %s where expected!", paramId.toString()));
90 }
91
92 static int getFieldInt(PiCriterion criterion, PiMatchFieldId fieldId)
93 throws UpfProgrammableException {
94 return byteSeqToInt(getFieldValue(criterion, fieldId));
95 }
96
Daniele Moro08c9e7f2021-07-28 18:53:34 +020097 static byte getFieldByte(PiCriterion criterion, PiMatchFieldId fieldId)
98 throws UpfProgrammableException {
99 return byteSeqToByte(getFieldValue(criterion, fieldId));
100 }
101
Daniele Moro8d630f12021-06-15 20:53:22 +0200102 static int getParamInt(PiAction action, PiActionParamId paramId)
103 throws UpfProgrammableException {
104 return byteSeqToInt(getParamValue(action, paramId));
105 }
106
Daniele Moro08c9e7f2021-07-28 18:53:34 +0200107 static byte getParamByte(PiAction action, PiActionParamId paramId)
108 throws UpfProgrammableException {
109 return byteSeqToByte(getParamValue(action, paramId));
110 }
111
Daniele Moro8d630f12021-06-15 20:53:22 +0200112 static Ip4Address getParamAddress(PiAction action, PiActionParamId paramId)
113 throws UpfProgrammableException {
114 return Ip4Address.valueOf(getParamValue(action, paramId).asArray());
115 }
116
117 static Ip4Prefix getFieldPrefix(PiCriterion criterion, PiMatchFieldId fieldId) {
118 Optional<PiFieldMatch> optField = criterion.fieldMatch(fieldId);
119 if (optField.isEmpty()) {
120 return null;
121 }
122 PiLpmFieldMatch field = (PiLpmFieldMatch) optField.get();
123 Ip4Address address = Ip4Address.valueOf(field.value().asArray());
124 return Ip4Prefix.valueOf(address, field.prefixLength());
125 }
126
127 static Ip4Address getFieldAddress(PiCriterion criterion, PiMatchFieldId fieldId)
128 throws UpfProgrammableException {
129 return Ip4Address.valueOf(getFieldValue(criterion, fieldId).asArray());
130 }
131
132 static int byteSeqToInt(ImmutableByteSequence sequence) {
133 try {
134 return sequence.fit(32).asReadOnlyBuffer().getInt();
135 } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
136 throw new IllegalArgumentException("Attempted to convert a >4 byte wide sequence to an integer!");
137 }
138 }
139
Daniele Moro08c9e7f2021-07-28 18:53:34 +0200140 static byte byteSeqToByte(ImmutableByteSequence sequence) {
141 try {
142 return sequence.fit(8).asReadOnlyBuffer().get();
143 } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
144 throw new IllegalArgumentException("Attempted to convert a >1 byte wide sequence to a byte!");
145 }
146 }
147
Daniele Moro8d630f12021-06-15 20:53:22 +0200148 static Pair<PiCriterion, PiTableAction> fabricEntryToPiPair(FlowRule entry) {
149 PiCriterion match = (PiCriterion) entry.selector().getCriterion(Criterion.Type.PROTOCOL_INDEPENDENT);
150 PiTableAction action = null;
151 for (Instruction instruction : entry.treatment().allInstructions()) {
152 if (instruction.type() == Instruction.Type.PROTOCOL_INDEPENDENT) {
153 PiInstruction piInstruction = (PiInstruction) instruction;
154 action = piInstruction.action();
155 break;
156 }
157 }
158 return Pair.of(match, action);
159 }
160}