blob: f289d5d890123074aa41a7a37b762b9125cf4dd5 [file] [log] [blame]
Carmelo Cascone4c289b72019-01-22 15:30:45 -08001/*
2 * Copyright 2019-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.p4runtime.ctl.codec;
18
19import com.google.protobuf.ByteString;
20import org.onlab.util.ImmutableByteSequence;
21import org.onosproject.net.pi.model.PiMatchFieldId;
22import org.onosproject.net.pi.model.PiPipeconf;
23import org.onosproject.net.pi.runtime.PiExactFieldMatch;
24import org.onosproject.net.pi.runtime.PiFieldMatch;
25import org.onosproject.net.pi.runtime.PiLpmFieldMatch;
26import org.onosproject.net.pi.runtime.PiRangeFieldMatch;
27import org.onosproject.net.pi.runtime.PiTernaryFieldMatch;
28import org.onosproject.p4runtime.ctl.utils.P4InfoBrowser;
29import p4.config.v1.P4InfoOuterClass;
30import p4.v1.P4RuntimeOuterClass;
31
32import static java.lang.String.format;
33import static org.onlab.util.ImmutableByteSequence.copyFrom;
34import static org.onosproject.p4runtime.ctl.codec.Utils.assertPrefixLen;
35import static org.onosproject.p4runtime.ctl.codec.Utils.assertSize;
36
37/**
38 * Codec for P4Runtime FieldMatch. Metadata is expected to be a Preamble for
39 * P4Info.Table.
40 */
41public final class FieldMatchCodec
42 extends AbstractCodec<PiFieldMatch, P4RuntimeOuterClass.FieldMatch,
43 P4InfoOuterClass.Preamble> {
44
45 private static final String VALUE_OF_PREFIX = "value of ";
46 private static final String MASK_OF_PREFIX = "mask of ";
47 private static final String HIGH_RANGE_VALUE_OF_PREFIX = "high range value of ";
48 private static final String LOW_RANGE_VALUE_OF_PREFIX = "low range value of ";
49
50 @Override
51 public P4RuntimeOuterClass.FieldMatch encode(
52 PiFieldMatch piFieldMatch, P4InfoOuterClass.Preamble tablePreamble,
53 PiPipeconf pipeconf, P4InfoBrowser browser)
54 throws CodecException, P4InfoBrowser.NotFoundException {
55
56 P4RuntimeOuterClass.FieldMatch.Builder messageBuilder = P4RuntimeOuterClass
57 .FieldMatch.newBuilder();
58
59 // FIXME: check how field names for stacked headers are constructed in P4Runtime.
60 String fieldName = piFieldMatch.fieldId().id();
61 P4InfoOuterClass.MatchField matchFieldInfo = browser.matchFields(
62 tablePreamble.getId()).getByName(fieldName);
63 String entityName = format("field match '%s' of table '%s'",
64 matchFieldInfo.getName(), tablePreamble.getName());
65 int fieldId = matchFieldInfo.getId();
66 int fieldBitwidth = matchFieldInfo.getBitwidth();
67
68 messageBuilder.setFieldId(fieldId);
69
70 switch (piFieldMatch.type()) {
71 case EXACT:
72 PiExactFieldMatch fieldMatch = (PiExactFieldMatch) piFieldMatch;
73 ByteString exactValue = ByteString.copyFrom(fieldMatch.value().asReadOnlyBuffer());
74 assertSize(VALUE_OF_PREFIX + entityName, exactValue, fieldBitwidth);
75 return messageBuilder.setExact(
76 P4RuntimeOuterClass.FieldMatch.Exact
77 .newBuilder()
78 .setValue(exactValue)
79 .build())
80 .build();
81 case TERNARY:
82 PiTernaryFieldMatch ternaryMatch = (PiTernaryFieldMatch) piFieldMatch;
83 ByteString ternaryValue = ByteString.copyFrom(ternaryMatch.value().asReadOnlyBuffer());
84 ByteString ternaryMask = ByteString.copyFrom(ternaryMatch.mask().asReadOnlyBuffer());
85 assertSize(VALUE_OF_PREFIX + entityName, ternaryValue, fieldBitwidth);
86 assertSize(MASK_OF_PREFIX + entityName, ternaryMask, fieldBitwidth);
87 return messageBuilder.setTernary(
88 P4RuntimeOuterClass.FieldMatch.Ternary
89 .newBuilder()
90 .setValue(ternaryValue)
91 .setMask(ternaryMask)
92 .build())
93 .build();
94 case LPM:
95 PiLpmFieldMatch lpmMatch = (PiLpmFieldMatch) piFieldMatch;
96 ByteString lpmValue = ByteString.copyFrom(lpmMatch.value().asReadOnlyBuffer());
97 int lpmPrefixLen = lpmMatch.prefixLength();
98 assertSize(VALUE_OF_PREFIX + entityName, lpmValue, fieldBitwidth);
99 assertPrefixLen(entityName, lpmPrefixLen, fieldBitwidth);
100 return messageBuilder.setLpm(
101 P4RuntimeOuterClass.FieldMatch.LPM.newBuilder()
102 .setValue(lpmValue)
103 .setPrefixLen(lpmPrefixLen)
104 .build())
105 .build();
106 case RANGE:
107 PiRangeFieldMatch rangeMatch = (PiRangeFieldMatch) piFieldMatch;
108 ByteString rangeHighValue = ByteString.copyFrom(rangeMatch.highValue().asReadOnlyBuffer());
109 ByteString rangeLowValue = ByteString.copyFrom(rangeMatch.lowValue().asReadOnlyBuffer());
110 assertSize(HIGH_RANGE_VALUE_OF_PREFIX + entityName, rangeHighValue, fieldBitwidth);
111 assertSize(LOW_RANGE_VALUE_OF_PREFIX + entityName, rangeLowValue, fieldBitwidth);
112 return messageBuilder.setRange(
113 P4RuntimeOuterClass.FieldMatch.Range.newBuilder()
114 .setHigh(rangeHighValue)
115 .setLow(rangeLowValue)
116 .build())
117 .build();
118 default:
119 throw new CodecException(format(
120 "Building of match type %s not implemented", piFieldMatch.type()));
121 }
122 }
123
124 @Override
125 public PiFieldMatch decode(
126 P4RuntimeOuterClass.FieldMatch message, P4InfoOuterClass.Preamble tablePreamble,
127 PiPipeconf pipeconf, P4InfoBrowser browser)
128 throws CodecException, P4InfoBrowser.NotFoundException {
129
130 String fieldMatchName = browser.matchFields(tablePreamble.getId())
131 .getById(message.getFieldId()).getName();
132 PiMatchFieldId headerFieldId = PiMatchFieldId.of(fieldMatchName);
133
134 P4RuntimeOuterClass.FieldMatch.FieldMatchTypeCase typeCase = message.getFieldMatchTypeCase();
135
136 switch (typeCase) {
137 case EXACT:
138 P4RuntimeOuterClass.FieldMatch.Exact exactFieldMatch = message.getExact();
139 ImmutableByteSequence exactValue = copyFrom(exactFieldMatch.getValue().asReadOnlyByteBuffer());
140 return new PiExactFieldMatch(headerFieldId, exactValue);
141 case TERNARY:
142 P4RuntimeOuterClass.FieldMatch.Ternary ternaryFieldMatch = message.getTernary();
143 ImmutableByteSequence ternaryValue = copyFrom(ternaryFieldMatch.getValue().asReadOnlyByteBuffer());
144 ImmutableByteSequence ternaryMask = copyFrom(ternaryFieldMatch.getMask().asReadOnlyByteBuffer());
145 return new PiTernaryFieldMatch(headerFieldId, ternaryValue, ternaryMask);
146 case LPM:
147 P4RuntimeOuterClass.FieldMatch.LPM lpmFieldMatch = message.getLpm();
148 ImmutableByteSequence lpmValue = copyFrom(lpmFieldMatch.getValue().asReadOnlyByteBuffer());
149 int lpmPrefixLen = lpmFieldMatch.getPrefixLen();
150 return new PiLpmFieldMatch(headerFieldId, lpmValue, lpmPrefixLen);
151 case RANGE:
152 P4RuntimeOuterClass.FieldMatch.Range rangeFieldMatch = message.getRange();
153 ImmutableByteSequence rangeHighValue = copyFrom(rangeFieldMatch.getHigh().asReadOnlyByteBuffer());
154 ImmutableByteSequence rangeLowValue = copyFrom(rangeFieldMatch.getLow().asReadOnlyByteBuffer());
155 return new PiRangeFieldMatch(headerFieldId, rangeLowValue, rangeHighValue);
156 default:
157 throw new CodecException(format(
158 "Decoding of field match type '%s' not implemented", typeCase.name()));
159 }
160 }
161}