blob: 6558d804699e722e2669ca55b9ce1a365449fac7 [file] [log] [blame]
Carmelo Cascone87892e22017-11-13 16:01:29 -08001/*
2 * Copyright 2017-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.model;
18
19import com.google.common.collect.ImmutableList;
20import com.google.common.collect.ImmutableMap;
21import com.google.common.collect.ImmutableSet;
22import com.google.common.collect.Maps;
pierventre69329172021-01-10 17:29:03 -080023import com.google.common.hash.Hashing;
24import com.google.common.hash.HashingInputStream;
Carmelo Cascone87892e22017-11-13 16:01:29 -080025import com.google.protobuf.ExtensionRegistry;
26import com.google.protobuf.TextFormat;
27import org.onosproject.net.pi.model.PiActionId;
28import org.onosproject.net.pi.model.PiActionModel;
29import org.onosproject.net.pi.model.PiActionParamId;
30import org.onosproject.net.pi.model.PiActionParamModel;
31import org.onosproject.net.pi.model.PiActionProfileId;
32import org.onosproject.net.pi.model.PiActionProfileModel;
Carmelo Cascone87892e22017-11-13 16:01:29 -080033import org.onosproject.net.pi.model.PiCounterId;
34import org.onosproject.net.pi.model.PiCounterModel;
35import org.onosproject.net.pi.model.PiCounterType;
36import org.onosproject.net.pi.model.PiMatchFieldId;
37import org.onosproject.net.pi.model.PiMatchFieldModel;
38import org.onosproject.net.pi.model.PiMatchType;
39import org.onosproject.net.pi.model.PiMeterId;
40import org.onosproject.net.pi.model.PiMeterModel;
41import org.onosproject.net.pi.model.PiMeterType;
Carmelo Casconea3635ab2019-03-19 12:55:34 -070042import org.onosproject.net.pi.model.PiPacketMetadataId;
43import org.onosproject.net.pi.model.PiPacketMetadataModel;
Carmelo Cascone87892e22017-11-13 16:01:29 -080044import org.onosproject.net.pi.model.PiPacketOperationModel;
45import org.onosproject.net.pi.model.PiPacketOperationType;
46import org.onosproject.net.pi.model.PiPipelineModel;
FrankWang2674e452018-05-24 17:13:35 +080047import org.onosproject.net.pi.model.PiRegisterId;
48import org.onosproject.net.pi.model.PiRegisterModel;
Carmelo Cascone87892e22017-11-13 16:01:29 -080049import org.onosproject.net.pi.model.PiTableId;
50import org.onosproject.net.pi.model.PiTableModel;
51import org.onosproject.net.pi.model.PiTableType;
Carmelo Casconea3635ab2019-03-19 12:55:34 -070052import org.slf4j.Logger;
Carmelo Cascone6af4e172018-06-15 16:01:30 +020053import p4.config.v1.P4InfoOuterClass;
54import p4.config.v1.P4InfoOuterClass.Action;
55import p4.config.v1.P4InfoOuterClass.ActionProfile;
56import p4.config.v1.P4InfoOuterClass.ActionRef;
57import p4.config.v1.P4InfoOuterClass.ControllerPacketMetadata;
58import p4.config.v1.P4InfoOuterClass.Counter;
59import p4.config.v1.P4InfoOuterClass.CounterSpec;
60import p4.config.v1.P4InfoOuterClass.DirectCounter;
61import p4.config.v1.P4InfoOuterClass.DirectMeter;
62import p4.config.v1.P4InfoOuterClass.MatchField;
63import p4.config.v1.P4InfoOuterClass.Meter;
64import p4.config.v1.P4InfoOuterClass.MeterSpec;
65import p4.config.v1.P4InfoOuterClass.P4Info;
66import p4.config.v1.P4InfoOuterClass.Table;
Daniele Moro5c82b0f2020-12-07 20:56:30 +010067import p4.config.v1.P4Types;
Carmelo Cascone87892e22017-11-13 16:01:29 -080068
69import java.io.IOException;
70import java.io.InputStream;
71import java.io.InputStreamReader;
72import java.net.URL;
73import java.util.Map;
74import java.util.Objects;
75import java.util.stream.Collectors;
76
77import static java.lang.String.format;
Carmelo Casconea3635ab2019-03-19 12:55:34 -070078import static org.slf4j.LoggerFactory.getLogger;
Carmelo Cascone87892e22017-11-13 16:01:29 -080079
80/**
81 * Parser of P4Info to PI pipeline model instances.
82 */
83public final class P4InfoParser {
84
Carmelo Casconea3635ab2019-03-19 12:55:34 -070085 private static final Logger log = getLogger(P4InfoParser.class);
86
Carmelo Cascone87892e22017-11-13 16:01:29 -080087 private static final String PACKET_IN = "packet_in";
88 private static final String PACKET_OUT = "packet_out";
89
90 private static final Map<CounterSpec.Unit, PiCounterModel.Unit> COUNTER_UNIT_MAP =
91 new ImmutableMap.Builder<CounterSpec.Unit, PiCounterModel.Unit>()
92 .put(CounterSpec.Unit.BYTES, PiCounterModel.Unit.BYTES)
93 .put(CounterSpec.Unit.PACKETS, PiCounterModel.Unit.PACKETS)
94 .put(CounterSpec.Unit.BOTH, PiCounterModel.Unit.PACKETS_AND_BYTES)
95 // Don't map UNSPECIFIED as we don't support it at the moment.
96 .build();
97
98 private static final Map<MeterSpec.Unit, PiMeterModel.Unit> METER_UNIT_MAP =
99 new ImmutableMap.Builder<MeterSpec.Unit, PiMeterModel.Unit>()
100 .put(MeterSpec.Unit.BYTES, PiMeterModel.Unit.BYTES)
101 .put(MeterSpec.Unit.PACKETS, PiMeterModel.Unit.PACKETS)
102 // Don't map UNSPECIFIED as we don't support it at the moment.
103 .build();
104
105 private static final Map<String, PiPacketOperationType> PACKET_OPERATION_TYPE_MAP =
106 new ImmutableMap.Builder<String, PiPacketOperationType>()
107 .put(PACKET_IN, PiPacketOperationType.PACKET_IN)
108 .put(PACKET_OUT, PiPacketOperationType.PACKET_OUT)
109 .build();
110
111 private static final Map<MatchField.MatchType, PiMatchType> MATCH_TYPE_MAP =
112 new ImmutableMap.Builder<MatchField.MatchType, PiMatchType>()
Carmelo Cascone87892e22017-11-13 16:01:29 -0800113 .put(MatchField.MatchType.EXACT, PiMatchType.EXACT)
114 .put(MatchField.MatchType.LPM, PiMatchType.LPM)
115 .put(MatchField.MatchType.TERNARY, PiMatchType.TERNARY)
116 .put(MatchField.MatchType.RANGE, PiMatchType.RANGE)
117 // Don't map UNSPECIFIED as we don't support it at the moment.
118 .build();
119 public static final int NO_SIZE = -1;
120
121 private P4InfoParser() {
122 // Utility class, hides constructor.
123 }
124
125 /**
126 * Parse the given URL pointing to a P4Info file (in text format) to a PI pipeline model.
127 *
128 * @param p4InfoUrl URL to P4Info in text form
129 * @return PI pipeline model
130 * @throws P4InfoParserException if the P4Info file cannot be parsed (see message)
131 */
132 public static PiPipelineModel parse(URL p4InfoUrl) throws P4InfoParserException {
133
134 final P4Info p4info;
135 try {
136 p4info = getP4InfoMessage(p4InfoUrl);
137 } catch (IOException e) {
138 throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
139 }
140
pierventre69329172021-01-10 17:29:03 -0800141 // Generate fingerprint of the pipeline by hashing p4info file
142 final int fingerprint;
143 try {
144 HashingInputStream hin = new HashingInputStream(Hashing.crc32(), p4InfoUrl.openStream());
145 //noinspection StatementWithEmptyBody
146 while (hin.read() != -1) {
147 // Do nothing. Reading all input stream to update hash.
148 }
149 fingerprint = hin.hash().asInt();
150 } catch (IOException e) {
151 throw new P4InfoParserException("Unable to generate fingerprint " + p4InfoUrl.toString(), e);
152 }
153
Carmelo Cascone87892e22017-11-13 16:01:29 -0800154 // Start by parsing and mapping instances to to their integer P4Info IDs.
155 // Convenient to build the table model at the end.
156
157 // Counters.
158 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
159 counterMap.putAll(parseCounters(p4info));
160 counterMap.putAll(parseDirectCounters(p4info));
161
162 // Meters.
163 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
164 meterMap.putAll(parseMeters(p4info));
165 meterMap.putAll(parseDirectMeters(p4info));
166
FrankWang2674e452018-05-24 17:13:35 +0800167 // Registers.
168 final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
169 registerMap.putAll(parseRegisters(p4info));
170
Carmelo Cascone87892e22017-11-13 16:01:29 -0800171 // Action profiles.
172 final Map<Integer, PiActionProfileModel> actProfileMap = parseActionProfiles(p4info);
173
174 // Actions.
175 final Map<Integer, PiActionModel> actionMap = parseActions(p4info);
176
177 // Controller packet metadatas.
178 final Map<PiPacketOperationType, PiPacketOperationModel> pktOpMap = parseCtrlPktMetadatas(p4info);
179
180 // Finally, parse tables.
181 final ImmutableMap.Builder<PiTableId, PiTableModel> tableImmMapBuilder =
182 ImmutableMap.builder();
183 for (Table tableMsg : p4info.getTablesList()) {
184 final PiTableId tableId = PiTableId.of(tableMsg.getPreamble().getName());
185 // Parse match fields.
186 final ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel> tableFieldMapBuilder =
187 ImmutableMap.builder();
188 for (MatchField fieldMsg : tableMsg.getMatchFieldsList()) {
189 final PiMatchFieldId fieldId = PiMatchFieldId.of(fieldMsg.getName());
190 tableFieldMapBuilder.put(
191 fieldId,
192 new P4MatchFieldModel(fieldId,
Daniele Moro5c82b0f2020-12-07 20:56:30 +0100193 isFieldString(p4info, fieldMsg.getTypeName().getName()) ?
194 P4MatchFieldModel.BIT_WIDTH_UNDEFINED :
195 fieldMsg.getBitwidth(),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800196 mapMatchFieldType(fieldMsg.getMatchType())));
197
198 }
199 // Retrieve action models by inter IDs.
200 final ImmutableMap.Builder<PiActionId, PiActionModel> tableActionMapBuilder =
201 ImmutableMap.builder();
202 tableMsg.getActionRefsList().stream()
203 .map(ActionRef::getId)
204 .map(actionMap::get)
205 .forEach(actionModel -> tableActionMapBuilder.put(actionModel.id(), actionModel));
206 // Retrieve direct meters by integer IDs.
207 final ImmutableMap.Builder<PiMeterId, PiMeterModel> tableMeterMapBuilder =
208 ImmutableMap.builder();
209 tableMsg.getDirectResourceIdsList()
210 .stream()
211 .map(meterMap::get)
212 // Direct resource ID might be that of a counter.
213 // Filter out missed mapping.
214 .filter(Objects::nonNull)
215 .forEach(meterModel -> tableMeterMapBuilder.put(meterModel.id(), meterModel));
216 // Retrieve direct counters by integer IDs.
217 final ImmutableMap.Builder<PiCounterId, PiCounterModel> tableCounterMapBuilder =
218 ImmutableMap.builder();
219 tableMsg.getDirectResourceIdsList()
220 .stream()
221 .map(counterMap::get)
222 // As before, resource ID might be that of a meter.
223 // Filter out missed mapping.
224 .filter(Objects::nonNull)
225 .forEach(counterModel -> tableCounterMapBuilder.put(counterModel.id(), counterModel));
226 tableImmMapBuilder.put(
227 tableId,
228 new P4TableModel(
229 PiTableId.of(tableMsg.getPreamble().getName()),
230 tableMsg.getImplementationId() == 0 ? PiTableType.DIRECT : PiTableType.INDIRECT,
231 actProfileMap.get(tableMsg.getImplementationId()),
232 tableMsg.getSize(),
233 tableCounterMapBuilder.build(),
234 tableMeterMapBuilder.build(),
Carmelo Cascone6af4e172018-06-15 16:01:30 +0200235 !tableMsg.getIdleTimeoutBehavior()
236 .equals(Table.IdleTimeoutBehavior.NO_TIMEOUT),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800237 tableFieldMapBuilder.build(),
238 tableActionMapBuilder.build(),
239 actionMap.get(tableMsg.getConstDefaultActionId()),
Carmelo Cascone33b27bc2018-09-09 22:56:14 -0700240 tableMsg.getIsConstTable()));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800241
242 }
243
244 // Get a map with proper PI IDs for some of those maps we created at the beginning.
245 ImmutableMap<PiCounterId, PiCounterModel> counterImmMap = ImmutableMap.copyOf(
246 counterMap.values().stream()
247 .collect(Collectors.toMap(PiCounterModel::id, c -> c)));
248 ImmutableMap<PiMeterId, PiMeterModel> meterImmMap = ImmutableMap.copyOf(
249 meterMap.values().stream()
250 .collect(Collectors.toMap(PiMeterModel::id, m -> m)));
FrankWang2674e452018-05-24 17:13:35 +0800251 ImmutableMap<PiRegisterId, PiRegisterModel> registerImmMap = ImmutableMap.copyOf(
252 registerMap.values().stream()
253 .collect(Collectors.toMap(PiRegisterModel::id, r -> r)));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800254 ImmutableMap<PiActionProfileId, PiActionProfileModel> actProfileImmMap = ImmutableMap.copyOf(
255 actProfileMap.values().stream()
256 .collect(Collectors.toMap(PiActionProfileModel::id, a -> a)));
257
258 return new P4PipelineModel(
259 tableImmMapBuilder.build(),
260 counterImmMap,
261 meterImmMap,
FrankWang2674e452018-05-24 17:13:35 +0800262 registerImmMap,
Carmelo Cascone87892e22017-11-13 16:01:29 -0800263 actProfileImmMap,
pierventre69329172021-01-10 17:29:03 -0800264 ImmutableMap.copyOf(pktOpMap),
265 fingerprint);
Carmelo Cascone87892e22017-11-13 16:01:29 -0800266 }
267
268
269 private static Map<Integer, PiCounterModel> parseCounters(P4Info p4info)
270 throws P4InfoParserException {
271 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
272 for (Counter counterMsg : p4info.getCountersList()) {
273 counterMap.put(
274 counterMsg.getPreamble().getId(),
275 new P4CounterModel(
276 PiCounterId.of(counterMsg.getPreamble().getName()),
277 PiCounterType.INDIRECT,
278 mapCounterSpecUnit(counterMsg.getSpec()),
279 null,
280 counterMsg.getSize()));
281 }
282 return counterMap;
283 }
284
285 private static Map<Integer, PiCounterModel> parseDirectCounters(P4Info p4info)
286 throws P4InfoParserException {
287 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
288 for (DirectCounter dirCounterMsg : p4info.getDirectCountersList()) {
289 counterMap.put(
290 dirCounterMsg.getPreamble().getId(),
291 new P4CounterModel(
292 PiCounterId.of(dirCounterMsg.getPreamble().getName()),
293 PiCounterType.DIRECT,
294 mapCounterSpecUnit(dirCounterMsg.getSpec()),
295 PiTableId.of(getTableName(dirCounterMsg.getDirectTableId(), p4info)),
296 NO_SIZE));
297 }
298 return counterMap;
299 }
300
301 private static Map<Integer, PiMeterModel> parseMeters(P4Info p4info)
302 throws P4InfoParserException {
303 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
304 for (Meter meterMsg : p4info.getMetersList()) {
305 meterMap.put(
306 meterMsg.getPreamble().getId(),
307 new P4MeterModel(
308 PiMeterId.of(meterMsg.getPreamble().getName()),
309 PiMeterType.INDIRECT,
310 mapMeterSpecUnit(meterMsg.getSpec()),
311 null,
312 meterMsg.getSize()));
313 }
314 return meterMap;
315 }
316
317 private static Map<Integer, PiMeterModel> parseDirectMeters(P4Info p4info)
318 throws P4InfoParserException {
319 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
320 for (DirectMeter dirMeterMsg : p4info.getDirectMetersList()) {
321 meterMap.put(
322 dirMeterMsg.getPreamble().getId(),
323 new P4MeterModel(
324 PiMeterId.of(dirMeterMsg.getPreamble().getName()),
325 PiMeterType.DIRECT,
326 mapMeterSpecUnit(dirMeterMsg.getSpec()),
327 PiTableId.of(getTableName(dirMeterMsg.getDirectTableId(), p4info)),
328 NO_SIZE));
329 }
330 return meterMap;
331 }
332
Carmelo Cascone6af4e172018-06-15 16:01:30 +0200333 private static Map<Integer, PiRegisterModel> parseRegisters(P4Info p4info) {
FrankWang2674e452018-05-24 17:13:35 +0800334 final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
335 for (P4InfoOuterClass.Register registerMsg : p4info.getRegistersList()) {
336 registerMap.put(registerMsg.getPreamble().getId(),
337 new P4RegisterModel(PiRegisterId.of(registerMsg.getPreamble().getName()),
338 registerMsg.getSize()));
339 }
340 return registerMap;
341 }
342
Carmelo Cascone87892e22017-11-13 16:01:29 -0800343 private static Map<Integer, PiActionProfileModel> parseActionProfiles(P4Info p4info)
344 throws P4InfoParserException {
345 final Map<Integer, PiActionProfileModel> actProfileMap = Maps.newHashMap();
346 for (ActionProfile actProfileMsg : p4info.getActionProfilesList()) {
347 final ImmutableSet.Builder<PiTableId> tableIdSetBuilder = ImmutableSet.builder();
348 for (int tableId : actProfileMsg.getTableIdsList()) {
349 tableIdSetBuilder.add(PiTableId.of(getTableName(tableId, p4info)));
350 }
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700351 // TODO: we should copy all annotations to model classes for later
352 // use in the PI framework.
353 // This is a temporary workaround to the inability of p4c to
354 // correctly interpret P4Runtime-defined max_group_size annotation:
355 // https://s3-us-west-2.amazonaws.com/p4runtime/docs/master/
356 // P4Runtime-Spec.html#sec-p4info-action-profile
357 final String maxSizeAnnString = findAnnotation(
358 "max_group_size", actProfileMsg.getPreamble());
359 final int maxSizeAnn = maxSizeAnnString != null
360 ? Integer.valueOf(maxSizeAnnString) : 0;
361 final int maxGroupSize;
362 if (actProfileMsg.getMaxGroupSize() == 0 && maxSizeAnn != 0) {
363 log.warn("Found valid 'max_group_size' annotation for " +
364 "ActionProfile {}, using that...",
365 actProfileMsg.getPreamble().getName());
366 maxGroupSize = maxSizeAnn;
367 } else {
368 maxGroupSize = actProfileMsg.getMaxGroupSize();
369 }
370
Carmelo Cascone87892e22017-11-13 16:01:29 -0800371 actProfileMap.put(
372 actProfileMsg.getPreamble().getId(),
373 new P4ActionProfileModel(
374 PiActionProfileId.of(actProfileMsg.getPreamble().getName()),
375 tableIdSetBuilder.build(),
376 actProfileMsg.getWithSelector(),
Carmelo Cascone99c59db2019-01-17 15:39:35 -0800377 actProfileMsg.getSize(),
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700378 maxGroupSize));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800379 }
380 return actProfileMap;
381 }
382
383 private static Map<Integer, PiActionModel> parseActions(P4Info p4info) {
384 final Map<Integer, PiActionModel> actionMap = Maps.newHashMap();
385 for (Action actionMsg : p4info.getActionsList()) {
386 final ImmutableMap.Builder<PiActionParamId, PiActionParamModel> paramMapBuilder =
387 ImmutableMap.builder();
388 actionMsg.getParamsList().forEach(paramMsg -> {
389 final PiActionParamId paramId = PiActionParamId.of(paramMsg.getName());
390 paramMapBuilder.put(paramId,
Daniele Moro5c82b0f2020-12-07 20:56:30 +0100391 new P4ActionParamModel(
392 PiActionParamId.of(paramMsg.getName()),
393 isFieldString(p4info, paramMsg.getTypeName().getName()) ?
394 P4ActionParamModel.BIT_WIDTH_UNDEFINED :
395 paramMsg.getBitwidth()));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800396 });
397 actionMap.put(
398 actionMsg.getPreamble().getId(),
399 new P4ActionModel(
400 PiActionId.of(actionMsg.getPreamble().getName()),
401 paramMapBuilder.build()));
402
403 }
404 return actionMap;
405 }
406
407 private static Map<PiPacketOperationType, PiPacketOperationModel> parseCtrlPktMetadatas(P4Info p4info)
408 throws P4InfoParserException {
409 final Map<PiPacketOperationType, PiPacketOperationModel> packetOpMap = Maps.newHashMap();
410 for (ControllerPacketMetadata ctrlPktMetaMsg : p4info.getControllerPacketMetadataList()) {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800411 final ImmutableList.Builder<PiPacketMetadataModel> metadataListBuilder =
Carmelo Cascone87892e22017-11-13 16:01:29 -0800412 ImmutableList.builder();
413 ctrlPktMetaMsg.getMetadataList().forEach(metadataMsg -> metadataListBuilder.add(
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800414 new P4PacketMetadataModel(PiPacketMetadataId.of(metadataMsg.getName()),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800415 metadataMsg.getBitwidth())));
416 packetOpMap.put(
417 mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
418 new P4PacketOperationModel(mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
419 metadataListBuilder.build()));
420
421 }
422 return packetOpMap;
423 }
424
425 private static P4Info getP4InfoMessage(URL p4InfoUrl) throws IOException {
426 InputStream p4InfoStream = p4InfoUrl.openStream();
427 P4Info.Builder p4InfoBuilder = P4Info.newBuilder();
428 TextFormat.getParser().merge(new InputStreamReader(p4InfoStream),
429 ExtensionRegistry.getEmptyRegistry(),
430 p4InfoBuilder);
431 return p4InfoBuilder.build();
432 }
433
434 private static String getTableName(int id, P4Info p4info)
435 throws P4InfoParserException {
436 return p4info.getTablesList().stream()
437 .filter(t -> t.getPreamble().getId() == id)
438 .findFirst()
439 .orElseThrow(() -> new P4InfoParserException(format(
440 "Not such table with ID %d", id)))
441 .getPreamble()
442 .getName();
443 }
444
445 private static PiCounterModel.Unit mapCounterSpecUnit(CounterSpec spec)
446 throws P4InfoParserException {
447 if (!COUNTER_UNIT_MAP.containsKey(spec.getUnit())) {
448 throw new P4InfoParserException(format(
449 "Unrecognized counter unit '%s'", spec.getUnit()));
450 }
451 return COUNTER_UNIT_MAP.get(spec.getUnit());
452 }
453
454 private static PiMeterModel.Unit mapMeterSpecUnit(MeterSpec spec)
455 throws P4InfoParserException {
456 if (!METER_UNIT_MAP.containsKey(spec.getUnit())) {
457 throw new P4InfoParserException(format(
458 "Unrecognized meter unit '%s'", spec.getUnit()));
459 }
460 return METER_UNIT_MAP.get(spec.getUnit());
461 }
462
463 private static PiPacketOperationType mapPacketOpType(String name)
464 throws P4InfoParserException {
465 if (!PACKET_OPERATION_TYPE_MAP.containsKey(name)) {
466 throw new P4InfoParserException(format(
467 "Unrecognized controller packet metadata name '%s'", name));
468 }
469 return PACKET_OPERATION_TYPE_MAP.get(name);
470 }
471
472 private static PiMatchType mapMatchFieldType(MatchField.MatchType type)
473 throws P4InfoParserException {
474 if (!MATCH_TYPE_MAP.containsKey(type)) {
475 throw new P4InfoParserException(format(
476 "Unrecognized match field type '%s'", type));
477 }
478 return MATCH_TYPE_MAP.get(type);
479 }
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700480
481 private static String findAnnotation(String name, P4InfoOuterClass.Preamble preamble) {
482 return preamble.getAnnotationsList().stream()
483 .filter(a -> a.startsWith("@" + name))
484 // e.g. @my_annotaion(value)
485 .map(a -> a.substring(name.length() + 2, a.length() - 1))
486 .findFirst()
487 .orElse(null);
488 }
Daniele Moro5c82b0f2020-12-07 20:56:30 +0100489
490 private static boolean isFieldString(P4Info p4info, String fieldTypeName) {
491 P4Types.P4TypeInfo p4TypeInfo = p4info.getTypeInfo();
492 return p4TypeInfo.containsNewTypes(fieldTypeName) &&
493 p4TypeInfo.getNewTypesOrThrow(fieldTypeName).hasTranslatedType() &&
494 p4TypeInfo.getNewTypesOrThrow(fieldTypeName).getTranslatedType().hasSdnString();
495 }
Carmelo Cascone87892e22017-11-13 16:01:29 -0800496}