blob: b2f662b5d53c36fc7236ead33a6c3e0714b5628b [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)
Daniele Moroc6f2f7f2020-12-18 10:55:57 +0100117 .put(MatchField.MatchType.OPTIONAL, PiMatchType.OPTIONAL)
Carmelo Cascone87892e22017-11-13 16:01:29 -0800118 // Don't map UNSPECIFIED as we don't support it at the moment.
119 .build();
120 public static final int NO_SIZE = -1;
121
122 private P4InfoParser() {
123 // Utility class, hides constructor.
124 }
125
126 /**
127 * Parse the given URL pointing to a P4Info file (in text format) to a PI pipeline model.
128 *
129 * @param p4InfoUrl URL to P4Info in text form
130 * @return PI pipeline model
131 * @throws P4InfoParserException if the P4Info file cannot be parsed (see message)
132 */
133 public static PiPipelineModel parse(URL p4InfoUrl) throws P4InfoParserException {
134
135 final P4Info p4info;
136 try {
137 p4info = getP4InfoMessage(p4InfoUrl);
138 } catch (IOException e) {
139 throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
140 }
141
pierventre69329172021-01-10 17:29:03 -0800142 // Generate fingerprint of the pipeline by hashing p4info file
143 final int fingerprint;
144 try {
145 HashingInputStream hin = new HashingInputStream(Hashing.crc32(), p4InfoUrl.openStream());
146 //noinspection StatementWithEmptyBody
147 while (hin.read() != -1) {
148 // Do nothing. Reading all input stream to update hash.
149 }
150 fingerprint = hin.hash().asInt();
151 } catch (IOException e) {
152 throw new P4InfoParserException("Unable to generate fingerprint " + p4InfoUrl.toString(), e);
153 }
154
Carmelo Cascone87892e22017-11-13 16:01:29 -0800155 // Start by parsing and mapping instances to to their integer P4Info IDs.
156 // Convenient to build the table model at the end.
157
158 // Counters.
159 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
160 counterMap.putAll(parseCounters(p4info));
161 counterMap.putAll(parseDirectCounters(p4info));
162
163 // Meters.
164 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
165 meterMap.putAll(parseMeters(p4info));
166 meterMap.putAll(parseDirectMeters(p4info));
167
FrankWang2674e452018-05-24 17:13:35 +0800168 // Registers.
169 final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
170 registerMap.putAll(parseRegisters(p4info));
171
Carmelo Cascone87892e22017-11-13 16:01:29 -0800172 // Action profiles.
173 final Map<Integer, PiActionProfileModel> actProfileMap = parseActionProfiles(p4info);
174
175 // Actions.
176 final Map<Integer, PiActionModel> actionMap = parseActions(p4info);
177
178 // Controller packet metadatas.
179 final Map<PiPacketOperationType, PiPacketOperationModel> pktOpMap = parseCtrlPktMetadatas(p4info);
180
181 // Finally, parse tables.
182 final ImmutableMap.Builder<PiTableId, PiTableModel> tableImmMapBuilder =
183 ImmutableMap.builder();
184 for (Table tableMsg : p4info.getTablesList()) {
185 final PiTableId tableId = PiTableId.of(tableMsg.getPreamble().getName());
186 // Parse match fields.
187 final ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel> tableFieldMapBuilder =
188 ImmutableMap.builder();
189 for (MatchField fieldMsg : tableMsg.getMatchFieldsList()) {
190 final PiMatchFieldId fieldId = PiMatchFieldId.of(fieldMsg.getName());
191 tableFieldMapBuilder.put(
192 fieldId,
193 new P4MatchFieldModel(fieldId,
Daniele Moro5c82b0f2020-12-07 20:56:30 +0100194 isFieldString(p4info, fieldMsg.getTypeName().getName()) ?
195 P4MatchFieldModel.BIT_WIDTH_UNDEFINED :
196 fieldMsg.getBitwidth(),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800197 mapMatchFieldType(fieldMsg.getMatchType())));
198
199 }
200 // Retrieve action models by inter IDs.
201 final ImmutableMap.Builder<PiActionId, PiActionModel> tableActionMapBuilder =
202 ImmutableMap.builder();
203 tableMsg.getActionRefsList().stream()
204 .map(ActionRef::getId)
205 .map(actionMap::get)
206 .forEach(actionModel -> tableActionMapBuilder.put(actionModel.id(), actionModel));
207 // Retrieve direct meters by integer IDs.
208 final ImmutableMap.Builder<PiMeterId, PiMeterModel> tableMeterMapBuilder =
209 ImmutableMap.builder();
210 tableMsg.getDirectResourceIdsList()
211 .stream()
212 .map(meterMap::get)
213 // Direct resource ID might be that of a counter.
214 // Filter out missed mapping.
215 .filter(Objects::nonNull)
216 .forEach(meterModel -> tableMeterMapBuilder.put(meterModel.id(), meterModel));
217 // Retrieve direct counters by integer IDs.
218 final ImmutableMap.Builder<PiCounterId, PiCounterModel> tableCounterMapBuilder =
219 ImmutableMap.builder();
220 tableMsg.getDirectResourceIdsList()
221 .stream()
222 .map(counterMap::get)
223 // As before, resource ID might be that of a meter.
224 // Filter out missed mapping.
225 .filter(Objects::nonNull)
226 .forEach(counterModel -> tableCounterMapBuilder.put(counterModel.id(), counterModel));
227 tableImmMapBuilder.put(
228 tableId,
229 new P4TableModel(
230 PiTableId.of(tableMsg.getPreamble().getName()),
231 tableMsg.getImplementationId() == 0 ? PiTableType.DIRECT : PiTableType.INDIRECT,
232 actProfileMap.get(tableMsg.getImplementationId()),
233 tableMsg.getSize(),
234 tableCounterMapBuilder.build(),
235 tableMeterMapBuilder.build(),
Carmelo Cascone6af4e172018-06-15 16:01:30 +0200236 !tableMsg.getIdleTimeoutBehavior()
237 .equals(Table.IdleTimeoutBehavior.NO_TIMEOUT),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800238 tableFieldMapBuilder.build(),
239 tableActionMapBuilder.build(),
240 actionMap.get(tableMsg.getConstDefaultActionId()),
Carmelo Cascone33b27bc2018-09-09 22:56:14 -0700241 tableMsg.getIsConstTable()));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800242
243 }
244
245 // Get a map with proper PI IDs for some of those maps we created at the beginning.
246 ImmutableMap<PiCounterId, PiCounterModel> counterImmMap = ImmutableMap.copyOf(
247 counterMap.values().stream()
248 .collect(Collectors.toMap(PiCounterModel::id, c -> c)));
249 ImmutableMap<PiMeterId, PiMeterModel> meterImmMap = ImmutableMap.copyOf(
250 meterMap.values().stream()
251 .collect(Collectors.toMap(PiMeterModel::id, m -> m)));
FrankWang2674e452018-05-24 17:13:35 +0800252 ImmutableMap<PiRegisterId, PiRegisterModel> registerImmMap = ImmutableMap.copyOf(
253 registerMap.values().stream()
254 .collect(Collectors.toMap(PiRegisterModel::id, r -> r)));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800255 ImmutableMap<PiActionProfileId, PiActionProfileModel> actProfileImmMap = ImmutableMap.copyOf(
256 actProfileMap.values().stream()
257 .collect(Collectors.toMap(PiActionProfileModel::id, a -> a)));
258
259 return new P4PipelineModel(
260 tableImmMapBuilder.build(),
261 counterImmMap,
262 meterImmMap,
FrankWang2674e452018-05-24 17:13:35 +0800263 registerImmMap,
Carmelo Cascone87892e22017-11-13 16:01:29 -0800264 actProfileImmMap,
pierventre69329172021-01-10 17:29:03 -0800265 ImmutableMap.copyOf(pktOpMap),
266 fingerprint);
Carmelo Cascone87892e22017-11-13 16:01:29 -0800267 }
268
269
270 private static Map<Integer, PiCounterModel> parseCounters(P4Info p4info)
271 throws P4InfoParserException {
272 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
273 for (Counter counterMsg : p4info.getCountersList()) {
274 counterMap.put(
275 counterMsg.getPreamble().getId(),
276 new P4CounterModel(
277 PiCounterId.of(counterMsg.getPreamble().getName()),
278 PiCounterType.INDIRECT,
279 mapCounterSpecUnit(counterMsg.getSpec()),
280 null,
281 counterMsg.getSize()));
282 }
283 return counterMap;
284 }
285
286 private static Map<Integer, PiCounterModel> parseDirectCounters(P4Info p4info)
287 throws P4InfoParserException {
288 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
289 for (DirectCounter dirCounterMsg : p4info.getDirectCountersList()) {
290 counterMap.put(
291 dirCounterMsg.getPreamble().getId(),
292 new P4CounterModel(
293 PiCounterId.of(dirCounterMsg.getPreamble().getName()),
294 PiCounterType.DIRECT,
295 mapCounterSpecUnit(dirCounterMsg.getSpec()),
296 PiTableId.of(getTableName(dirCounterMsg.getDirectTableId(), p4info)),
297 NO_SIZE));
298 }
299 return counterMap;
300 }
301
302 private static Map<Integer, PiMeterModel> parseMeters(P4Info p4info)
303 throws P4InfoParserException {
304 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
305 for (Meter meterMsg : p4info.getMetersList()) {
306 meterMap.put(
307 meterMsg.getPreamble().getId(),
308 new P4MeterModel(
309 PiMeterId.of(meterMsg.getPreamble().getName()),
310 PiMeterType.INDIRECT,
311 mapMeterSpecUnit(meterMsg.getSpec()),
312 null,
313 meterMsg.getSize()));
314 }
315 return meterMap;
316 }
317
318 private static Map<Integer, PiMeterModel> parseDirectMeters(P4Info p4info)
319 throws P4InfoParserException {
320 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
321 for (DirectMeter dirMeterMsg : p4info.getDirectMetersList()) {
322 meterMap.put(
323 dirMeterMsg.getPreamble().getId(),
324 new P4MeterModel(
325 PiMeterId.of(dirMeterMsg.getPreamble().getName()),
326 PiMeterType.DIRECT,
327 mapMeterSpecUnit(dirMeterMsg.getSpec()),
328 PiTableId.of(getTableName(dirMeterMsg.getDirectTableId(), p4info)),
329 NO_SIZE));
330 }
331 return meterMap;
332 }
333
Carmelo Cascone6af4e172018-06-15 16:01:30 +0200334 private static Map<Integer, PiRegisterModel> parseRegisters(P4Info p4info) {
FrankWang2674e452018-05-24 17:13:35 +0800335 final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
336 for (P4InfoOuterClass.Register registerMsg : p4info.getRegistersList()) {
337 registerMap.put(registerMsg.getPreamble().getId(),
338 new P4RegisterModel(PiRegisterId.of(registerMsg.getPreamble().getName()),
339 registerMsg.getSize()));
340 }
341 return registerMap;
342 }
343
Carmelo Cascone87892e22017-11-13 16:01:29 -0800344 private static Map<Integer, PiActionProfileModel> parseActionProfiles(P4Info p4info)
345 throws P4InfoParserException {
346 final Map<Integer, PiActionProfileModel> actProfileMap = Maps.newHashMap();
347 for (ActionProfile actProfileMsg : p4info.getActionProfilesList()) {
348 final ImmutableSet.Builder<PiTableId> tableIdSetBuilder = ImmutableSet.builder();
349 for (int tableId : actProfileMsg.getTableIdsList()) {
350 tableIdSetBuilder.add(PiTableId.of(getTableName(tableId, p4info)));
351 }
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700352 // TODO: we should copy all annotations to model classes for later
353 // use in the PI framework.
354 // This is a temporary workaround to the inability of p4c to
355 // correctly interpret P4Runtime-defined max_group_size annotation:
356 // https://s3-us-west-2.amazonaws.com/p4runtime/docs/master/
357 // P4Runtime-Spec.html#sec-p4info-action-profile
358 final String maxSizeAnnString = findAnnotation(
359 "max_group_size", actProfileMsg.getPreamble());
360 final int maxSizeAnn = maxSizeAnnString != null
361 ? Integer.valueOf(maxSizeAnnString) : 0;
362 final int maxGroupSize;
363 if (actProfileMsg.getMaxGroupSize() == 0 && maxSizeAnn != 0) {
364 log.warn("Found valid 'max_group_size' annotation for " +
365 "ActionProfile {}, using that...",
366 actProfileMsg.getPreamble().getName());
367 maxGroupSize = maxSizeAnn;
368 } else {
369 maxGroupSize = actProfileMsg.getMaxGroupSize();
370 }
371
Carmelo Cascone87892e22017-11-13 16:01:29 -0800372 actProfileMap.put(
373 actProfileMsg.getPreamble().getId(),
374 new P4ActionProfileModel(
375 PiActionProfileId.of(actProfileMsg.getPreamble().getName()),
376 tableIdSetBuilder.build(),
377 actProfileMsg.getWithSelector(),
Carmelo Cascone99c59db2019-01-17 15:39:35 -0800378 actProfileMsg.getSize(),
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700379 maxGroupSize));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800380 }
381 return actProfileMap;
382 }
383
384 private static Map<Integer, PiActionModel> parseActions(P4Info p4info) {
385 final Map<Integer, PiActionModel> actionMap = Maps.newHashMap();
386 for (Action actionMsg : p4info.getActionsList()) {
387 final ImmutableMap.Builder<PiActionParamId, PiActionParamModel> paramMapBuilder =
388 ImmutableMap.builder();
389 actionMsg.getParamsList().forEach(paramMsg -> {
390 final PiActionParamId paramId = PiActionParamId.of(paramMsg.getName());
391 paramMapBuilder.put(paramId,
Daniele Moro5c82b0f2020-12-07 20:56:30 +0100392 new P4ActionParamModel(
393 PiActionParamId.of(paramMsg.getName()),
394 isFieldString(p4info, paramMsg.getTypeName().getName()) ?
395 P4ActionParamModel.BIT_WIDTH_UNDEFINED :
396 paramMsg.getBitwidth()));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800397 });
398 actionMap.put(
399 actionMsg.getPreamble().getId(),
400 new P4ActionModel(
401 PiActionId.of(actionMsg.getPreamble().getName()),
402 paramMapBuilder.build()));
403
404 }
405 return actionMap;
406 }
407
408 private static Map<PiPacketOperationType, PiPacketOperationModel> parseCtrlPktMetadatas(P4Info p4info)
409 throws P4InfoParserException {
410 final Map<PiPacketOperationType, PiPacketOperationModel> packetOpMap = Maps.newHashMap();
411 for (ControllerPacketMetadata ctrlPktMetaMsg : p4info.getControllerPacketMetadataList()) {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800412 final ImmutableList.Builder<PiPacketMetadataModel> metadataListBuilder =
Carmelo Cascone87892e22017-11-13 16:01:29 -0800413 ImmutableList.builder();
414 ctrlPktMetaMsg.getMetadataList().forEach(metadataMsg -> metadataListBuilder.add(
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800415 new P4PacketMetadataModel(PiPacketMetadataId.of(metadataMsg.getName()),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800416 metadataMsg.getBitwidth())));
417 packetOpMap.put(
418 mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
419 new P4PacketOperationModel(mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
420 metadataListBuilder.build()));
421
422 }
423 return packetOpMap;
424 }
425
426 private static P4Info getP4InfoMessage(URL p4InfoUrl) throws IOException {
427 InputStream p4InfoStream = p4InfoUrl.openStream();
428 P4Info.Builder p4InfoBuilder = P4Info.newBuilder();
429 TextFormat.getParser().merge(new InputStreamReader(p4InfoStream),
430 ExtensionRegistry.getEmptyRegistry(),
431 p4InfoBuilder);
432 return p4InfoBuilder.build();
433 }
434
435 private static String getTableName(int id, P4Info p4info)
436 throws P4InfoParserException {
437 return p4info.getTablesList().stream()
438 .filter(t -> t.getPreamble().getId() == id)
439 .findFirst()
440 .orElseThrow(() -> new P4InfoParserException(format(
441 "Not such table with ID %d", id)))
442 .getPreamble()
443 .getName();
444 }
445
446 private static PiCounterModel.Unit mapCounterSpecUnit(CounterSpec spec)
447 throws P4InfoParserException {
448 if (!COUNTER_UNIT_MAP.containsKey(spec.getUnit())) {
449 throw new P4InfoParserException(format(
450 "Unrecognized counter unit '%s'", spec.getUnit()));
451 }
452 return COUNTER_UNIT_MAP.get(spec.getUnit());
453 }
454
455 private static PiMeterModel.Unit mapMeterSpecUnit(MeterSpec spec)
456 throws P4InfoParserException {
457 if (!METER_UNIT_MAP.containsKey(spec.getUnit())) {
458 throw new P4InfoParserException(format(
459 "Unrecognized meter unit '%s'", spec.getUnit()));
460 }
461 return METER_UNIT_MAP.get(spec.getUnit());
462 }
463
464 private static PiPacketOperationType mapPacketOpType(String name)
465 throws P4InfoParserException {
466 if (!PACKET_OPERATION_TYPE_MAP.containsKey(name)) {
467 throw new P4InfoParserException(format(
468 "Unrecognized controller packet metadata name '%s'", name));
469 }
470 return PACKET_OPERATION_TYPE_MAP.get(name);
471 }
472
473 private static PiMatchType mapMatchFieldType(MatchField.MatchType type)
474 throws P4InfoParserException {
475 if (!MATCH_TYPE_MAP.containsKey(type)) {
476 throw new P4InfoParserException(format(
477 "Unrecognized match field type '%s'", type));
478 }
479 return MATCH_TYPE_MAP.get(type);
480 }
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700481
482 private static String findAnnotation(String name, P4InfoOuterClass.Preamble preamble) {
483 return preamble.getAnnotationsList().stream()
484 .filter(a -> a.startsWith("@" + name))
485 // e.g. @my_annotaion(value)
486 .map(a -> a.substring(name.length() + 2, a.length() - 1))
487 .findFirst()
488 .orElse(null);
489 }
Daniele Moro5c82b0f2020-12-07 20:56:30 +0100490
491 private static boolean isFieldString(P4Info p4info, String fieldTypeName) {
492 P4Types.P4TypeInfo p4TypeInfo = p4info.getTypeInfo();
493 return p4TypeInfo.containsNewTypes(fieldTypeName) &&
494 p4TypeInfo.getNewTypesOrThrow(fieldTypeName).hasTranslatedType() &&
495 p4TypeInfo.getNewTypesOrThrow(fieldTypeName).getTranslatedType().hasSdnString();
496 }
Carmelo Cascone87892e22017-11-13 16:01:29 -0800497}