15#ifndef CONTROL_PLANE_BFRUNTIME_H_
16#define CONTROL_PLANE_BFRUNTIME_H_
25#include "control-plane/p4RuntimeSerializer.h"
27#include "lib/error_catalog.h"
29#pragma GCC diagnostic push
30#pragma GCC diagnostic ignored "-Wunused-parameter"
31#pragma GCC diagnostic ignored "-Wpedantic"
32#include "p4/config/v1/p4info.pb.h"
33#pragma GCC diagnostic pop
35namespace p4configv1 = ::p4::config::v1;
48template <
typename T,
typename R>
49static inline constexpr P4Id makeBFRuntimeId(T base, R prefix) {
50 return static_cast<P4Id
>((base & 0xffffff) | (prefix << 24));
53static inline constexpr P4Id getIdPrefix(P4Id
id) {
return ((
id >> 24) & 0xff); }
55static inline Util::JsonObject *findJsonTable(Util::JsonArray *tablesJson, cstring tblName) {
56 for (
auto *t : *tablesJson) {
57 auto *tblObj = t->to<Util::JsonObject>();
58 auto tName = tblObj->getAs<Util::JsonValue>(
"name")->getString();
59 if (tName == tblName) {
66static inline Util::JsonObject *transformAnnotation(
const cstring &annotation) {
67 auto *annotationJson =
new Util::JsonObject();
70 annotationJson->emplace(
"name", annotation.escapeJson());
71 return annotationJson;
75static inline Util::JsonArray *transformAnnotations(
const It &first,
const It &last) {
76 auto *annotations =
new Util::JsonArray();
77 for (
auto it = first; it != last; it++) annotations->append(transformAnnotation(*it));
81static inline Util::JsonArray *transformAnnotations(
const p4configv1::Preamble &pre) {
82 return transformAnnotations(pre.annotations().begin(), pre.annotations().end());
87static inline bool isOfType(P4Id
id, T prefix) {
88 return getIdPrefix(
id) ==
static_cast<P4Id
>(prefix);
94static inline auto findP4InfoObject(
const It &first,
const It &last, P4Id objectId) ->
const
95 typename std::iterator_traits<It>::value_type * {
96 using T =
typename std::iterator_traits<It>::value_type;
97 auto desiredObject = std::find_if(
98 first, last, [&](
const T &
object) {
return object.preamble().id() == objectId; });
99 if (desiredObject == last)
return nullptr;
100 return &*desiredObject;
103static inline const p4configv1::Table *findTable(
const p4configv1::P4Info &p4info, P4Id tableId) {
104 const auto &tables = p4info.tables();
105 return findP4InfoObject(tables.begin(), tables.end(), tableId);
108static inline const p4configv1::Action *findAction(
const p4configv1::P4Info &p4info,
110 const auto &actions = p4info.actions();
111 return Standard::findP4InfoObject(actions.begin(), actions.end(), actionId);
114static inline const p4configv1::ActionProfile *findActionProf(
const p4configv1::P4Info &p4info,
116 const auto &actionProfs = p4info.action_profiles();
117 return findP4InfoObject(actionProfs.begin(), actionProfs.end(), actionProfId);
120static inline const p4configv1::DirectCounter *findDirectCounter(
const p4configv1::P4Info &p4info,
122 const auto &counters = p4info.direct_counters();
123 return findP4InfoObject(counters.begin(), counters.end(), counterId);
126static inline const p4configv1::DirectMeter *findDirectMeter(
const p4configv1::P4Info &p4info,
128 const auto &meters = p4info.direct_meters();
129 return findP4InfoObject(meters.begin(), meters.end(), meterId);
134static inline Util::JsonObject *makeType(cstring type) {
135 auto *typeObj =
new Util::JsonObject();
136 typeObj->emplace(
"type", type);
140template <typename T, typename std::enable_if<std::is_integral<T>::value,
int>::type = 0>
141static inline Util::JsonObject *makeType(cstring type, T defaultValue) {
142 auto *typeObj =
new Util::JsonObject();
143 typeObj->emplace(
"type", type);
144 typeObj->emplace(
"default_value", defaultValue);
148static inline Util::JsonObject *makeTypeBool(std::optional<bool> defaultValue = std::nullopt) {
149 auto *typeObj =
new Util::JsonObject();
150 typeObj->emplace(
"type",
"bool");
151 if (defaultValue != std::nullopt) typeObj->emplace(
"default_value", *defaultValue);
155static inline Util::JsonObject *makeTypeBytes(
int width,
156 std::optional<int64_t> defaultValue = std::nullopt) {
157 auto *typeObj =
new Util::JsonObject();
158 typeObj->emplace(
"type",
"bytes");
159 typeObj->emplace(
"width", width);
160 if (defaultValue != std::nullopt) typeObj->emplace(
"default_value", *defaultValue);
164static inline Util::JsonObject *makeTypeEnum(
const std::vector<cstring> &choices,
165 std::optional<cstring> defaultValue = std::nullopt) {
166 auto *typeObj =
new Util::JsonObject();
167 typeObj->emplace(
"type",
"string");
168 auto *choicesArray =
new Util::JsonArray();
169 for (
auto choice : choices) choicesArray->append(choice);
170 typeObj->emplace(
"choices", choicesArray);
171 if (defaultValue != std::nullopt) typeObj->emplace(
"default_value", *defaultValue);
175static inline void addSingleton(Util::JsonArray *dataJson, Util::JsonObject *dataField,
176 bool mandatory,
bool readOnly) {
177 auto *singletonJson =
new Util::JsonObject();
178 singletonJson->emplace(
"mandatory", mandatory);
179 singletonJson->emplace(
"read_only", readOnly);
180 singletonJson->emplace(
"singleton", dataField);
181 dataJson->append(singletonJson);
184static inline void addOneOf(Util::JsonArray *dataJson, Util::JsonArray *choicesJson,
bool mandatory,
186 auto *oneOfJson =
new Util::JsonObject();
187 oneOfJson->emplace(
"mandatory", mandatory);
188 oneOfJson->emplace(
"read_only", readOnly);
189 oneOfJson->emplace(
"oneof", choicesJson);
190 dataJson->append(oneOfJson);
194static inline std::optional<cstring> transformMatchType(
195 p4configv1::MatchField_MatchType matchType) {
197 case p4configv1::MatchField_MatchType_UNSPECIFIED:
199 case p4configv1::MatchField_MatchType_EXACT:
201 case p4configv1::MatchField_MatchType_LPM:
203 case p4configv1::MatchField_MatchType_TERNARY:
205 case p4configv1::MatchField_MatchType_RANGE:
207 case p4configv1::MatchField_MatchType_OPTIONAL:
208 return "Optional"_cs;
215static inline std::optional<cstring> transformOtherMatchType(std::string matchType) {
216 if (matchType ==
"atcam_partition_index")
return "ATCAM"_cs;
217 if (matchType ==
"dleft_hash")
return "DLEFT_HASH"_cs;
222template <
typename It>
223static std::vector<P4Id> collectTableIds(
const p4configv1::P4Info &p4info,
const It &first,
225 std::vector<P4Id> tableIds;
226 for (
auto it = first; it != last; it++) {
227 auto *table = Standard::findTable(p4info, *it);
228 if (table ==
nullptr) {
229 ::P4::error(ErrorType::ERR_INVALID,
"Invalid table id '%1%'", *it);
232 tableIds.push_back(*it);
248 using Fields = std::vector<Field>;
249 using iterator = Fields::iterator;
250 using const_iterator = Fields::const_iterator;
253 const p4configv1::P4DataTypeSpec &typeSpec,
cstring instanceType,
255 const std::vector<cstring> *fieldNames =
nullptr,
259 iterator begin() {
return fields.begin(); }
260 const_iterator cbegin() {
return fields.cbegin(); }
261 iterator end() {
return fields.end(); }
262 const_iterator cend() {
return fields.cend(); }
263 size_t size() {
return fields.size(); }
266 explicit TypeSpecParser(Fields &&fields) : fields(
std::move(fields)) {}
286 enum TDDataFieldIds : P4Id {
289 TD_DATA_START = (1 << 16),
291 TD_DATA_MATCH_PRIORITY,
294 TD_DATA_ACTION_MEMBER_ID,
295 TD_DATA_SELECTOR_GROUP_ID,
296 TD_DATA_ACTION_MEMBER_STATUS,
297 TD_DATA_MAX_GROUP_SIZE,
300 TD_DATA_ENTRY_HIT_STATE,
302 TD_DATA_METER_SPEC_CIR_KBPS,
303 TD_DATA_METER_SPEC_PIR_KBPS,
304 TD_DATA_METER_SPEC_CBS_KBITS,
305 TD_DATA_METER_SPEC_PBS_KBITS,
307 TD_DATA_METER_SPEC_CIR_PPS,
308 TD_DATA_METER_SPEC_PIR_PPS,
309 TD_DATA_METER_SPEC_CBS_PKTS,
310 TD_DATA_METER_SPEC_PBS_PKTS,
312 TD_DATA_COUNTER_SPEC_BYTES,
313 TD_DATA_COUNTER_SPEC_PKTS,
316 TD_DATA_COUNTER_INDEX,
317 TD_DATA_REGISTER_INDEX,
324 enum Unit { UNSPECIFIED = 0, BYTES = 1, PACKETS = 2, BOTH = 3 };
331 static std::optional<Counter> from(
const p4configv1::Counter &counterInstance);
332 static std::optional<Counter> fromDirect(
const p4configv1::DirectCounter &counterInstance);
337 enum Unit { UNSPECIFIED = 0, BYTES = 1, PACKETS = 2 };
338 enum Type { COLOR_UNAWARE = 0, COLOR_AWARE = 1 };
345 static std::optional<Meter> from(
const p4configv1::Meter &meterInstance);
346 static std::optional<Meter> fromDirect(
const p4configv1::DirectMeter &meterInstance);
355 std::vector<P4Id> tableIds;
357 static P4Id makeActProfId(P4Id implementationId);
358 static std::optional<ActionProf> from(
const p4configv1::P4Info &p4info,
359 const p4configv1::ActionProfile &actionProfile);
366 p4configv1::P4DataTypeSpec typeSpec;
369 static std::optional<Digest> from(
const p4configv1::Digest &digest);
375 std::string dataFieldName;
378 p4configv1::P4DataTypeSpec typeSpec;
381 static std::optional<Register> from(
const p4configv1::Register ®Instance);
385 virtual bool addMatchTypePriority(std::optional<cstring> &matchType)
const;
388 virtual bool addActionProfIds(
const p4configv1::Table &table,
400 virtual void addDirectResources(
const p4configv1::Table &table,
Util::JsonArray *dataJson,
403 P4Id maxActionParamId = 0)
const;
405 virtual std::optional<bool> actProfHasSelector(P4Id actProfId)
const;
412 P4Id *maxActionParamId =
nullptr)
const;
413 virtual std::optional<Counter> getDirectCounter(P4Id counterId)
const;
414 virtual std::optional<Meter> getDirectMeter(P4Id meterId)
const;
425 const p4configv1::P4DataTypeSpec &typeSpec,
427 const std::vector<cstring> *fieldNames =
nullptr,
428 cstring prefix = cstring::empty,
429 cstring suffix = cstring::empty, P4Id idOffset = 1)
const;
440 static void addActionDataField(
Util::JsonArray *dataJson, P4Id
id,
const std::string &name,
459 P4Id idOffset = 1)
const;
461 const p4configv1::P4Info &p4info;
Definition control-plane/bfruntime.h:271
void addRegisterDataFields(Util::JsonArray *dataJson, const Register ®ister_, P4Id idOffset=1) const
Definition control-plane/bfruntime.cpp:412
void serializeBFRuntimeSchema(std::ostream *destination)
Definition control-plane/bfruntime.cpp:874
virtual const Util::JsonObject * genSchema() const
Generates the schema as a Json object for the provided P4Info instance.
Definition control-plane/bfruntime.cpp:853
void transformTypeSpecToDataFields(Util::JsonArray *fieldsJson, const p4configv1::P4DataTypeSpec &typeSpec, cstring instanceType, cstring instanceName, const std::vector< cstring > *fieldNames=nullptr, cstring prefix=cstring::empty, cstring suffix=cstring::empty, P4Id idOffset=1) const
Definition control-plane/bfruntime.cpp:398
Util::JsonArray * makeActionSpecs(const p4configv1::Table &table, P4Id *maxActionParamId=nullptr) const
Definition control-plane/bfruntime.cpp:542
Definition control-plane/bfruntime.h:240
Definition control-plane/bfruntime.h:242
TODO: this is not really specific to BMV2, it should reside somewhere else.
Definition applyOptionsPragmas.cpp:24
void error(const char *format, Args &&...args)
Report an error with the given message.
Definition lib/error.h:51
Definition control-plane/bfruntime.h:351
Common counter representation between PSA and other architectures.
Definition control-plane/bfruntime.h:323
Common digest representation between PSA and other architectures.
Definition control-plane/bfruntime.h:363
Common meter representation between PSA and other architectures.
Definition control-plane/bfruntime.h:336
Common register representation between PSA and other architectures.
Definition control-plane/bfruntime.h:373