blob: 7c1fd1a53d8b6b5c78ffa0ffc0051fb3c32e3996 [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;
pierventre4d2a5422021-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;
Carmelo Cascone87892e22017-11-13 16:01:29 -080067
68import java.io.IOException;
69import java.io.InputStream;
70import java.io.InputStreamReader;
71import java.net.URL;
72import java.util.Map;
73import java.util.Objects;
74import java.util.stream.Collectors;
75
76import static java.lang.String.format;
Carmelo Casconea3635ab2019-03-19 12:55:34 -070077import static org.slf4j.LoggerFactory.getLogger;
Carmelo Cascone87892e22017-11-13 16:01:29 -080078
79/**
80 * Parser of P4Info to PI pipeline model instances.
81 */
82public final class P4InfoParser {
83
Carmelo Casconea3635ab2019-03-19 12:55:34 -070084 private static final Logger log = getLogger(P4InfoParser.class);
85
Carmelo Cascone87892e22017-11-13 16:01:29 -080086 private static final String PACKET_IN = "packet_in";
87 private static final String PACKET_OUT = "packet_out";
88
89 private static final Map<CounterSpec.Unit, PiCounterModel.Unit> COUNTER_UNIT_MAP =
90 new ImmutableMap.Builder<CounterSpec.Unit, PiCounterModel.Unit>()
91 .put(CounterSpec.Unit.BYTES, PiCounterModel.Unit.BYTES)
92 .put(CounterSpec.Unit.PACKETS, PiCounterModel.Unit.PACKETS)
93 .put(CounterSpec.Unit.BOTH, PiCounterModel.Unit.PACKETS_AND_BYTES)
94 // Don't map UNSPECIFIED as we don't support it at the moment.
95 .build();
96
97 private static final Map<MeterSpec.Unit, PiMeterModel.Unit> METER_UNIT_MAP =
98 new ImmutableMap.Builder<MeterSpec.Unit, PiMeterModel.Unit>()
99 .put(MeterSpec.Unit.BYTES, PiMeterModel.Unit.BYTES)
100 .put(MeterSpec.Unit.PACKETS, PiMeterModel.Unit.PACKETS)
101 // Don't map UNSPECIFIED as we don't support it at the moment.
102 .build();
103
104 private static final Map<String, PiPacketOperationType> PACKET_OPERATION_TYPE_MAP =
105 new ImmutableMap.Builder<String, PiPacketOperationType>()
106 .put(PACKET_IN, PiPacketOperationType.PACKET_IN)
107 .put(PACKET_OUT, PiPacketOperationType.PACKET_OUT)
108 .build();
109
110 private static final Map<MatchField.MatchType, PiMatchType> MATCH_TYPE_MAP =
111 new ImmutableMap.Builder<MatchField.MatchType, PiMatchType>()
Carmelo Cascone87892e22017-11-13 16:01:29 -0800112 .put(MatchField.MatchType.EXACT, PiMatchType.EXACT)
113 .put(MatchField.MatchType.LPM, PiMatchType.LPM)
114 .put(MatchField.MatchType.TERNARY, PiMatchType.TERNARY)
115 .put(MatchField.MatchType.RANGE, PiMatchType.RANGE)
116 // Don't map UNSPECIFIED as we don't support it at the moment.
117 .build();
118 public static final int NO_SIZE = -1;
119
120 private P4InfoParser() {
121 // Utility class, hides constructor.
122 }
123
124 /**
125 * Parse the given URL pointing to a P4Info file (in text format) to a PI pipeline model.
126 *
127 * @param p4InfoUrl URL to P4Info in text form
128 * @return PI pipeline model
129 * @throws P4InfoParserException if the P4Info file cannot be parsed (see message)
130 */
131 public static PiPipelineModel parse(URL p4InfoUrl) throws P4InfoParserException {
132
133 final P4Info p4info;
134 try {
135 p4info = getP4InfoMessage(p4InfoUrl);
136 } catch (IOException e) {
137 throw new P4InfoParserException("Unable to parse protobuf " + p4InfoUrl.toString(), e);
138 }
139
pierventre4d2a5422021-01-10 17:29:03 -0800140 // Generate fingerprint of the pipeline by hashing p4info file
141 final int fingerprint;
142 try {
143 HashingInputStream hin = new HashingInputStream(Hashing.crc32(), p4InfoUrl.openStream());
144 //noinspection StatementWithEmptyBody
145 while (hin.read() != -1) {
146 // Do nothing. Reading all input stream to update hash.
147 }
148 fingerprint = hin.hash().asInt();
149 } catch (IOException e) {
150 throw new P4InfoParserException("Unable to generate fingerprint " + p4InfoUrl.toString(), e);
151 }
152
Carmelo Cascone87892e22017-11-13 16:01:29 -0800153 // Start by parsing and mapping instances to to their integer P4Info IDs.
154 // Convenient to build the table model at the end.
155
156 // Counters.
157 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
158 counterMap.putAll(parseCounters(p4info));
159 counterMap.putAll(parseDirectCounters(p4info));
160
161 // Meters.
162 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
163 meterMap.putAll(parseMeters(p4info));
164 meterMap.putAll(parseDirectMeters(p4info));
165
FrankWang2674e452018-05-24 17:13:35 +0800166 // Registers.
167 final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
168 registerMap.putAll(parseRegisters(p4info));
169
Carmelo Cascone87892e22017-11-13 16:01:29 -0800170 // Action profiles.
171 final Map<Integer, PiActionProfileModel> actProfileMap = parseActionProfiles(p4info);
172
173 // Actions.
174 final Map<Integer, PiActionModel> actionMap = parseActions(p4info);
175
176 // Controller packet metadatas.
177 final Map<PiPacketOperationType, PiPacketOperationModel> pktOpMap = parseCtrlPktMetadatas(p4info);
178
179 // Finally, parse tables.
180 final ImmutableMap.Builder<PiTableId, PiTableModel> tableImmMapBuilder =
181 ImmutableMap.builder();
182 for (Table tableMsg : p4info.getTablesList()) {
183 final PiTableId tableId = PiTableId.of(tableMsg.getPreamble().getName());
184 // Parse match fields.
185 final ImmutableMap.Builder<PiMatchFieldId, PiMatchFieldModel> tableFieldMapBuilder =
186 ImmutableMap.builder();
187 for (MatchField fieldMsg : tableMsg.getMatchFieldsList()) {
188 final PiMatchFieldId fieldId = PiMatchFieldId.of(fieldMsg.getName());
189 tableFieldMapBuilder.put(
190 fieldId,
191 new P4MatchFieldModel(fieldId,
192 fieldMsg.getBitwidth(),
193 mapMatchFieldType(fieldMsg.getMatchType())));
194
195 }
196 // Retrieve action models by inter IDs.
197 final ImmutableMap.Builder<PiActionId, PiActionModel> tableActionMapBuilder =
198 ImmutableMap.builder();
199 tableMsg.getActionRefsList().stream()
200 .map(ActionRef::getId)
201 .map(actionMap::get)
202 .forEach(actionModel -> tableActionMapBuilder.put(actionModel.id(), actionModel));
203 // Retrieve direct meters by integer IDs.
204 final ImmutableMap.Builder<PiMeterId, PiMeterModel> tableMeterMapBuilder =
205 ImmutableMap.builder();
206 tableMsg.getDirectResourceIdsList()
207 .stream()
208 .map(meterMap::get)
209 // Direct resource ID might be that of a counter.
210 // Filter out missed mapping.
211 .filter(Objects::nonNull)
212 .forEach(meterModel -> tableMeterMapBuilder.put(meterModel.id(), meterModel));
213 // Retrieve direct counters by integer IDs.
214 final ImmutableMap.Builder<PiCounterId, PiCounterModel> tableCounterMapBuilder =
215 ImmutableMap.builder();
216 tableMsg.getDirectResourceIdsList()
217 .stream()
218 .map(counterMap::get)
219 // As before, resource ID might be that of a meter.
220 // Filter out missed mapping.
221 .filter(Objects::nonNull)
222 .forEach(counterModel -> tableCounterMapBuilder.put(counterModel.id(), counterModel));
223 tableImmMapBuilder.put(
224 tableId,
225 new P4TableModel(
226 PiTableId.of(tableMsg.getPreamble().getName()),
227 tableMsg.getImplementationId() == 0 ? PiTableType.DIRECT : PiTableType.INDIRECT,
228 actProfileMap.get(tableMsg.getImplementationId()),
229 tableMsg.getSize(),
230 tableCounterMapBuilder.build(),
231 tableMeterMapBuilder.build(),
Carmelo Cascone6af4e172018-06-15 16:01:30 +0200232 !tableMsg.getIdleTimeoutBehavior()
233 .equals(Table.IdleTimeoutBehavior.NO_TIMEOUT),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800234 tableFieldMapBuilder.build(),
235 tableActionMapBuilder.build(),
236 actionMap.get(tableMsg.getConstDefaultActionId()),
Carmelo Cascone33b27bc2018-09-09 22:56:14 -0700237 tableMsg.getIsConstTable()));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800238
239 }
240
241 // Get a map with proper PI IDs for some of those maps we created at the beginning.
242 ImmutableMap<PiCounterId, PiCounterModel> counterImmMap = ImmutableMap.copyOf(
243 counterMap.values().stream()
244 .collect(Collectors.toMap(PiCounterModel::id, c -> c)));
245 ImmutableMap<PiMeterId, PiMeterModel> meterImmMap = ImmutableMap.copyOf(
246 meterMap.values().stream()
247 .collect(Collectors.toMap(PiMeterModel::id, m -> m)));
FrankWang2674e452018-05-24 17:13:35 +0800248 ImmutableMap<PiRegisterId, PiRegisterModel> registerImmMap = ImmutableMap.copyOf(
249 registerMap.values().stream()
250 .collect(Collectors.toMap(PiRegisterModel::id, r -> r)));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800251 ImmutableMap<PiActionProfileId, PiActionProfileModel> actProfileImmMap = ImmutableMap.copyOf(
252 actProfileMap.values().stream()
253 .collect(Collectors.toMap(PiActionProfileModel::id, a -> a)));
254
255 return new P4PipelineModel(
256 tableImmMapBuilder.build(),
257 counterImmMap,
258 meterImmMap,
FrankWang2674e452018-05-24 17:13:35 +0800259 registerImmMap,
Carmelo Cascone87892e22017-11-13 16:01:29 -0800260 actProfileImmMap,
pierventre4d2a5422021-01-10 17:29:03 -0800261 ImmutableMap.copyOf(pktOpMap),
262 fingerprint);
Carmelo Cascone87892e22017-11-13 16:01:29 -0800263 }
264
265
266 private static Map<Integer, PiCounterModel> parseCounters(P4Info p4info)
267 throws P4InfoParserException {
268 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
269 for (Counter counterMsg : p4info.getCountersList()) {
270 counterMap.put(
271 counterMsg.getPreamble().getId(),
272 new P4CounterModel(
273 PiCounterId.of(counterMsg.getPreamble().getName()),
274 PiCounterType.INDIRECT,
275 mapCounterSpecUnit(counterMsg.getSpec()),
276 null,
277 counterMsg.getSize()));
278 }
279 return counterMap;
280 }
281
282 private static Map<Integer, PiCounterModel> parseDirectCounters(P4Info p4info)
283 throws P4InfoParserException {
284 final Map<Integer, PiCounterModel> counterMap = Maps.newHashMap();
285 for (DirectCounter dirCounterMsg : p4info.getDirectCountersList()) {
286 counterMap.put(
287 dirCounterMsg.getPreamble().getId(),
288 new P4CounterModel(
289 PiCounterId.of(dirCounterMsg.getPreamble().getName()),
290 PiCounterType.DIRECT,
291 mapCounterSpecUnit(dirCounterMsg.getSpec()),
292 PiTableId.of(getTableName(dirCounterMsg.getDirectTableId(), p4info)),
293 NO_SIZE));
294 }
295 return counterMap;
296 }
297
298 private static Map<Integer, PiMeterModel> parseMeters(P4Info p4info)
299 throws P4InfoParserException {
300 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
301 for (Meter meterMsg : p4info.getMetersList()) {
302 meterMap.put(
303 meterMsg.getPreamble().getId(),
304 new P4MeterModel(
305 PiMeterId.of(meterMsg.getPreamble().getName()),
306 PiMeterType.INDIRECT,
307 mapMeterSpecUnit(meterMsg.getSpec()),
308 null,
309 meterMsg.getSize()));
310 }
311 return meterMap;
312 }
313
314 private static Map<Integer, PiMeterModel> parseDirectMeters(P4Info p4info)
315 throws P4InfoParserException {
316 final Map<Integer, PiMeterModel> meterMap = Maps.newHashMap();
317 for (DirectMeter dirMeterMsg : p4info.getDirectMetersList()) {
318 meterMap.put(
319 dirMeterMsg.getPreamble().getId(),
320 new P4MeterModel(
321 PiMeterId.of(dirMeterMsg.getPreamble().getName()),
322 PiMeterType.DIRECT,
323 mapMeterSpecUnit(dirMeterMsg.getSpec()),
324 PiTableId.of(getTableName(dirMeterMsg.getDirectTableId(), p4info)),
325 NO_SIZE));
326 }
327 return meterMap;
328 }
329
Carmelo Cascone6af4e172018-06-15 16:01:30 +0200330 private static Map<Integer, PiRegisterModel> parseRegisters(P4Info p4info) {
FrankWang2674e452018-05-24 17:13:35 +0800331 final Map<Integer, PiRegisterModel> registerMap = Maps.newHashMap();
332 for (P4InfoOuterClass.Register registerMsg : p4info.getRegistersList()) {
333 registerMap.put(registerMsg.getPreamble().getId(),
334 new P4RegisterModel(PiRegisterId.of(registerMsg.getPreamble().getName()),
335 registerMsg.getSize()));
336 }
337 return registerMap;
338 }
339
Carmelo Cascone87892e22017-11-13 16:01:29 -0800340 private static Map<Integer, PiActionProfileModel> parseActionProfiles(P4Info p4info)
341 throws P4InfoParserException {
342 final Map<Integer, PiActionProfileModel> actProfileMap = Maps.newHashMap();
343 for (ActionProfile actProfileMsg : p4info.getActionProfilesList()) {
344 final ImmutableSet.Builder<PiTableId> tableIdSetBuilder = ImmutableSet.builder();
345 for (int tableId : actProfileMsg.getTableIdsList()) {
346 tableIdSetBuilder.add(PiTableId.of(getTableName(tableId, p4info)));
347 }
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700348 // TODO: we should copy all annotations to model classes for later
349 // use in the PI framework.
350 // This is a temporary workaround to the inability of p4c to
351 // correctly interpret P4Runtime-defined max_group_size annotation:
352 // https://s3-us-west-2.amazonaws.com/p4runtime/docs/master/
353 // P4Runtime-Spec.html#sec-p4info-action-profile
354 final String maxSizeAnnString = findAnnotation(
355 "max_group_size", actProfileMsg.getPreamble());
356 final int maxSizeAnn = maxSizeAnnString != null
357 ? Integer.valueOf(maxSizeAnnString) : 0;
358 final int maxGroupSize;
359 if (actProfileMsg.getMaxGroupSize() == 0 && maxSizeAnn != 0) {
360 log.warn("Found valid 'max_group_size' annotation for " +
361 "ActionProfile {}, using that...",
362 actProfileMsg.getPreamble().getName());
363 maxGroupSize = maxSizeAnn;
364 } else {
365 maxGroupSize = actProfileMsg.getMaxGroupSize();
366 }
367
Carmelo Cascone87892e22017-11-13 16:01:29 -0800368 actProfileMap.put(
369 actProfileMsg.getPreamble().getId(),
370 new P4ActionProfileModel(
371 PiActionProfileId.of(actProfileMsg.getPreamble().getName()),
372 tableIdSetBuilder.build(),
373 actProfileMsg.getWithSelector(),
Carmelo Cascone99c59db2019-01-17 15:39:35 -0800374 actProfileMsg.getSize(),
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700375 maxGroupSize));
Carmelo Cascone87892e22017-11-13 16:01:29 -0800376 }
377 return actProfileMap;
378 }
379
380 private static Map<Integer, PiActionModel> parseActions(P4Info p4info) {
381 final Map<Integer, PiActionModel> actionMap = Maps.newHashMap();
382 for (Action actionMsg : p4info.getActionsList()) {
383 final ImmutableMap.Builder<PiActionParamId, PiActionParamModel> paramMapBuilder =
384 ImmutableMap.builder();
385 actionMsg.getParamsList().forEach(paramMsg -> {
386 final PiActionParamId paramId = PiActionParamId.of(paramMsg.getName());
387 paramMapBuilder.put(paramId,
388 new P4ActionParamModel(PiActionParamId.of(paramMsg.getName()),
389 paramMsg.getBitwidth()));
390 });
391 actionMap.put(
392 actionMsg.getPreamble().getId(),
393 new P4ActionModel(
394 PiActionId.of(actionMsg.getPreamble().getName()),
395 paramMapBuilder.build()));
396
397 }
398 return actionMap;
399 }
400
401 private static Map<PiPacketOperationType, PiPacketOperationModel> parseCtrlPktMetadatas(P4Info p4info)
402 throws P4InfoParserException {
403 final Map<PiPacketOperationType, PiPacketOperationModel> packetOpMap = Maps.newHashMap();
404 for (ControllerPacketMetadata ctrlPktMetaMsg : p4info.getControllerPacketMetadataList()) {
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800405 final ImmutableList.Builder<PiPacketMetadataModel> metadataListBuilder =
Carmelo Cascone87892e22017-11-13 16:01:29 -0800406 ImmutableList.builder();
407 ctrlPktMetaMsg.getMetadataList().forEach(metadataMsg -> metadataListBuilder.add(
Carmelo Cascone4c289b72019-01-22 15:30:45 -0800408 new P4PacketMetadataModel(PiPacketMetadataId.of(metadataMsg.getName()),
Carmelo Cascone87892e22017-11-13 16:01:29 -0800409 metadataMsg.getBitwidth())));
410 packetOpMap.put(
411 mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
412 new P4PacketOperationModel(mapPacketOpType(ctrlPktMetaMsg.getPreamble().getName()),
413 metadataListBuilder.build()));
414
415 }
416 return packetOpMap;
417 }
418
419 private static P4Info getP4InfoMessage(URL p4InfoUrl) throws IOException {
420 InputStream p4InfoStream = p4InfoUrl.openStream();
421 P4Info.Builder p4InfoBuilder = P4Info.newBuilder();
422 TextFormat.getParser().merge(new InputStreamReader(p4InfoStream),
423 ExtensionRegistry.getEmptyRegistry(),
424 p4InfoBuilder);
425 return p4InfoBuilder.build();
426 }
427
428 private static String getTableName(int id, P4Info p4info)
429 throws P4InfoParserException {
430 return p4info.getTablesList().stream()
431 .filter(t -> t.getPreamble().getId() == id)
432 .findFirst()
433 .orElseThrow(() -> new P4InfoParserException(format(
434 "Not such table with ID %d", id)))
435 .getPreamble()
436 .getName();
437 }
438
439 private static PiCounterModel.Unit mapCounterSpecUnit(CounterSpec spec)
440 throws P4InfoParserException {
441 if (!COUNTER_UNIT_MAP.containsKey(spec.getUnit())) {
442 throw new P4InfoParserException(format(
443 "Unrecognized counter unit '%s'", spec.getUnit()));
444 }
445 return COUNTER_UNIT_MAP.get(spec.getUnit());
446 }
447
448 private static PiMeterModel.Unit mapMeterSpecUnit(MeterSpec spec)
449 throws P4InfoParserException {
450 if (!METER_UNIT_MAP.containsKey(spec.getUnit())) {
451 throw new P4InfoParserException(format(
452 "Unrecognized meter unit '%s'", spec.getUnit()));
453 }
454 return METER_UNIT_MAP.get(spec.getUnit());
455 }
456
457 private static PiPacketOperationType mapPacketOpType(String name)
458 throws P4InfoParserException {
459 if (!PACKET_OPERATION_TYPE_MAP.containsKey(name)) {
460 throw new P4InfoParserException(format(
461 "Unrecognized controller packet metadata name '%s'", name));
462 }
463 return PACKET_OPERATION_TYPE_MAP.get(name);
464 }
465
466 private static PiMatchType mapMatchFieldType(MatchField.MatchType type)
467 throws P4InfoParserException {
468 if (!MATCH_TYPE_MAP.containsKey(type)) {
469 throw new P4InfoParserException(format(
470 "Unrecognized match field type '%s'", type));
471 }
472 return MATCH_TYPE_MAP.get(type);
473 }
Carmelo Casconea3635ab2019-03-19 12:55:34 -0700474
475 private static String findAnnotation(String name, P4InfoOuterClass.Preamble preamble) {
476 return preamble.getAnnotationsList().stream()
477 .filter(a -> a.startsWith("@" + name))
478 // e.g. @my_annotaion(value)
479 .map(a -> a.substring(name.length() + 2, a.length() - 1))
480 .findFirst()
481 .orElse(null);
482 }
Carmelo Cascone87892e22017-11-13 16:01:29 -0800483}