blob: a931f1ff2c04516a4b2cd383ca8051bdd6b9506b [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
97 static int getParamInt(PiAction action, PiActionParamId paramId)
98 throws UpfProgrammableException {
99 return byteSeqToInt(getParamValue(action, paramId));
100 }
101
102 static Ip4Address getParamAddress(PiAction action, PiActionParamId paramId)
103 throws UpfProgrammableException {
104 return Ip4Address.valueOf(getParamValue(action, paramId).asArray());
105 }
106
107 static Ip4Prefix getFieldPrefix(PiCriterion criterion, PiMatchFieldId fieldId) {
108 Optional<PiFieldMatch> optField = criterion.fieldMatch(fieldId);
109 if (optField.isEmpty()) {
110 return null;
111 }
112 PiLpmFieldMatch field = (PiLpmFieldMatch) optField.get();
113 Ip4Address address = Ip4Address.valueOf(field.value().asArray());
114 return Ip4Prefix.valueOf(address, field.prefixLength());
115 }
116
117 static Ip4Address getFieldAddress(PiCriterion criterion, PiMatchFieldId fieldId)
118 throws UpfProgrammableException {
119 return Ip4Address.valueOf(getFieldValue(criterion, fieldId).asArray());
120 }
121
122 static int byteSeqToInt(ImmutableByteSequence sequence) {
123 try {
124 return sequence.fit(32).asReadOnlyBuffer().getInt();
125 } catch (ImmutableByteSequence.ByteSequenceTrimException e) {
126 throw new IllegalArgumentException("Attempted to convert a >4 byte wide sequence to an integer!");
127 }
128 }
129
130 static Pair<PiCriterion, PiTableAction> fabricEntryToPiPair(FlowRule entry) {
131 PiCriterion match = (PiCriterion) entry.selector().getCriterion(Criterion.Type.PROTOCOL_INDEPENDENT);
132 PiTableAction action = null;
133 for (Instruction instruction : entry.treatment().allInstructions()) {
134 if (instruction.type() == Instruction.Type.PROTOCOL_INDEPENDENT) {
135 PiInstruction piInstruction = (PiInstruction) instruction;
136 action = piInstruction.action();
137 break;
138 }
139 }
140 return Pair.of(match, action);
141 }
142}