21 #ifndef BM_BM_SIM_P4OBJECTS_H_
22 #define BM_BM_SIM_P4OBJECTS_H_
26 #include <unordered_map>
35 #include "phv_forward.h"
39 #include "conditionals.h"
40 #include "checksums.h"
41 #include "control_flow.h"
50 #include "control_action.h"
51 #include "device_id.h"
62 using ConfigOptionMap = std::unordered_map<std::string, std::string>;
66 using header_field_pair = std::pair<std::string, std::string>;
68 enum class ResourceType {
78 friend class P4Objects;
81 void add_field(
const std::string &header_name,
82 const std::string &field_name) {
83 fields.insert(std::make_pair(header_name, field_name));
86 void add_header(
const std::string &header_name) {
87 headers.insert(header_name);
91 std::set<header_field_pair> fields;
92 std::set<std::string> headers;
97 explicit P4Objects(std::ostream &outstream,
bool verbose_output =
false);
100 int init_objects(std::istream *is,
101 LookupStructureFactory *lookup_factory,
102 device_id_t device_id = 0, cxt_id_t cxt_id = 0,
103 std::shared_ptr<TransportIface> transport =
nullptr,
104 const std::set<header_field_pair> &required_fields =
105 std::set<header_field_pair>(),
106 const ForceArith &arith_objects = ForceArith());
108 P4Objects(
const P4Objects &other) =
delete;
109 P4Objects &operator=(
const P4Objects &) =
delete;
112 PHVFactory &get_phv_factory() {
return phv_factory; }
114 LearnEngineIface *get_learn_engine() {
return learn_engine.get(); }
116 std::shared_ptr<TransportIface> get_notifications_transport() {
117 return notifications_transport;
120 AgeingMonitorIface *get_ageing_monitor() {
return ageing_monitor.get(); }
124 void serialize(std::ostream *out)
const;
125 void deserialize(std::istream *in);
127 enum class IdLookupErrorCode {
129 INVALID_RESOURCE_TYPE,
130 INVALID_RESOURCE_NAME
133 IdLookupErrorCode id_from_name(ResourceType type,
const std::string &name,
136 ActionFn *get_action_by_id(p4object_id_t
id)
const {
137 return actions_map.at(
id).get();
141 ActionFn *get_one_action_with_name(
const std::string &name)
const {
142 for (
auto it = actions_map.begin(); it != actions_map.end(); it++) {
143 if (it->second->get_name() == name)
return it->second.get();
148 ActionFn *get_action(
const std::string &table_name,
149 const std::string &action_name)
const {
150 return t_actions_map.at(std::make_pair(table_name, action_name));
153 ActionFn *get_action_for_action_profile(
154 const std::string &act_prof_name,
const std::string &action_name)
const;
156 ActionFn *get_action_rt(
const std::string &table_name,
157 const std::string &action_name)
const;
159 ActionFn *get_action_for_action_profile_rt(
160 const std::string &act_prof_name,
const std::string &action_name)
const;
166 Parser *get_parser(
const std::string &name)
const {
167 return parsers.at(name).get();
170 Parser *get_parser_rt(
const std::string &name)
const;
172 ParseVSet *get_parse_vset(
const std::string &name)
const {
173 return parse_vsets.at(name).get();
176 ParseVSet *get_parse_vset_rt(
const std::string &name)
const;
178 Deparser *get_deparser(
const std::string &name)
const {
179 return deparsers.at(name).get();
182 Deparser *get_deparser_rt(
const std::string &name)
const;
184 MatchTableAbstract *get_abstract_match_table(
const std::string &name)
const {
185 return match_action_tables_map.at(name)->get_match_table();
188 MatchTableAbstract *get_abstract_match_table_rt(
189 const std::string &name)
const;
191 MatchActionTable *get_match_action_table(
const std::string &name)
const {
192 return match_action_tables_map.at(name).get();
195 Conditional *get_conditional(
const std::string &name)
const {
196 return conditionals_map.at(name).get();
199 ControlFlowNode *get_control_node(
const std::string &name)
const {
200 return control_nodes_map.at(name);
203 Pipeline *get_pipeline(
const std::string &name)
const {
204 return pipelines_map.at(name).get();
207 Pipeline *get_pipeline_rt(
const std::string &name)
const;
209 MeterArray *get_meter_array(
const std::string &name)
const {
210 return meter_arrays.at(name).get();
213 MeterArray *get_meter_array_rt(
const std::string &name)
const;
215 CounterArray *get_counter_array(
const std::string &name)
const {
216 return counter_arrays.at(name).get();
219 CounterArray *get_counter_array_rt(
const std::string &name)
const;
221 RegisterArray *get_register_array(
const std::string &name)
const {
222 return register_arrays.at(name).get();
225 RegisterArray *get_register_array_rt(
const std::string &name)
const;
227 NamedCalculation *get_named_calculation(
const std::string &name)
const {
228 return calculations.at(name).get();
231 FieldList *get_field_list(
const p4object_id_t field_list_id)
const {
232 return field_lists.at(field_list_id).get();
235 ExternType *get_extern_instance(
const std::string &name)
const {
236 return extern_instances.at(name).get();
239 ExternType *get_extern_instance_rt(
const std::string &name)
const;
241 ActionProfile *get_action_profile(
const std::string &name)
const {
242 return action_profiles_map.at(name).get();
245 ActionProfile *get_action_profile_rt(
const std::string &name)
const;
247 bool field_exists(
const std::string &header_name,
248 const std::string &field_name)
const;
250 bool header_exists(
const std::string &header_name)
const;
253 ActionPrimitive_ *get_primitive(
const std::string &name);
255 ConfigOptionMap get_config_options()
const;
257 ErrorCodeMap get_error_codes()
const;
259 EnumMap::type_t get_enum_value(
const std::string &name)
const;
260 const std::string &get_enum_name(
const std::string &enum_name,
261 EnumMap::type_t entry_value)
const;
265 static std::string get_json_version_string();
271 void add_header_type(
const std::string &name,
272 std::unique_ptr<HeaderType> header_type);
274 HeaderType *get_header_type_cfg(
const std::string &name);
276 void add_header_id(
const std::string &name, header_id_t header_id);
278 void add_header_stack_id(
const std::string &name,
279 header_stack_id_t header_stack_id);
281 void add_header_union_id(
const std::string &name,
282 header_union_id_t header_union_id);
284 void add_header_union_stack_id(
const std::string &name,
285 header_union_stack_id_t header_union_stack_id);
287 header_id_t get_header_id_cfg(
const std::string &name)
const;
289 header_stack_id_t get_header_stack_id_cfg(
const std::string &name)
const;
291 header_union_id_t get_header_union_id_cfg(
const std::string &name)
const;
293 header_union_stack_id_t get_header_union_stack_id_cfg(
294 const std::string &name)
const;
296 void add_action(p4object_id_t
id, std::unique_ptr<ActionFn> action);
298 void add_action_to_table(
const std::string &table_name,
299 const std::string &action_name, ActionFn *action);
301 void add_action_to_act_prof(
const std::string &act_prof_name,
302 const std::string &action_name,
305 void add_parser(
const std::string &name, std::unique_ptr<Parser> parser);
307 void add_parse_vset(
const std::string &name,
308 std::unique_ptr<ParseVSet> parse_vset);
310 ParseVSet *get_parse_vset_cfg(
const std::string &name)
const;
312 void add_deparser(
const std::string &name,
313 std::unique_ptr<Deparser> deparser);
315 void add_match_action_table(
const std::string &name,
316 std::unique_ptr<MatchActionTable> table);
318 void add_action_profile(
const std::string &name,
319 std::unique_ptr<ActionProfile> action_profile);
321 ActionProfile *get_action_profile_cfg(
const std::string &name)
const;
323 void add_conditional(
const std::string &name,
324 std::unique_ptr<Conditional> conditional);
326 void add_control_action(
const std::string &name,
327 std::unique_ptr<ControlAction> control_action);
329 void add_control_node(
const std::string &name, ControlFlowNode *node);
331 ControlFlowNode *get_control_node_cfg(
const std::string &name)
const;
333 void add_pipeline(
const std::string &name,
334 std::unique_ptr<Pipeline> pipeline);
336 void add_meter_array(
const std::string &name,
337 std::unique_ptr<MeterArray> meter_array);
339 MeterArray *get_meter_array_cfg(
const std::string &name)
const;
341 void add_counter_array(
const std::string &name,
342 std::unique_ptr<CounterArray> counter_array);
344 CounterArray *get_counter_array_cfg(
const std::string &name)
const;
346 void add_register_array(
const std::string &name,
347 std::unique_ptr<RegisterArray> register_array);
349 RegisterArray *get_register_array_cfg(
const std::string &name)
const;
351 void add_named_calculation(
const std::string &name,
352 std::unique_ptr<NamedCalculation> calculation);
354 NamedCalculation *get_named_calculation_cfg(
const std::string &name)
const;
356 void add_field_list(
const p4object_id_t field_list_id,
357 std::unique_ptr<FieldList> field_list);
359 void add_extern_instance(
const std::string &name,
360 std::unique_ptr<ExternType> extern_instance);
362 ExternType *get_extern_instance_cfg(
const std::string &name)
const;
365 void init_enums(
const Json::Value &root);
366 void init_header_types(
const Json::Value &root);
367 void init_headers(
const Json::Value &root);
368 void init_header_stacks(
const Json::Value &root);
369 void init_header_unions(
const Json::Value &root, InitState *);
370 void init_header_union_stacks(
const Json::Value &root, InitState *);
371 void init_extern_instances(
const Json::Value &root);
372 void init_parse_vsets(
const Json::Value &root);
373 void init_errors(
const Json::Value &root);
374 void init_parsers(
const Json::Value &root, InitState *);
375 void init_deparsers(
const Json::Value &root);
376 void init_calculations(
const Json::Value &root);
377 void init_counter_arrays(
const Json::Value &root);
378 void init_meter_arrays(
const Json::Value &root, InitState *);
379 void init_register_arrays(
const Json::Value &root);
380 void init_actions(
const Json::Value &root);
381 void check_next_nodes(
const Json::Value &cfg_next_nodes,
382 const Json::Value &cfg_actions,
383 const std::string &table_name,
384 bool *next_is_hit_miss);
385 void init_pipelines(
const Json::Value &root, LookupStructureFactory *,
387 void init_checksums(
const Json::Value &root);
388 void init_learn_lists(
const Json::Value &root);
389 void init_field_lists(
const Json::Value &root);
391 void build_expression(
const Json::Value &json_expression, Expression *expr);
392 void build_expression(
const Json::Value &json_expression, Expression *expr,
393 ExprType *expr_type);
395 void add_primitive_to_action(
const Json::Value &primitive,
396 ActionFn *action_fn);
397 void process_single_param(ActionFn* action_fn,
398 const Json::Value &cfg_parameter,
399 const std::string &primitive_name);
401 void parse_config_options(
const Json::Value &root);
404 PHVFactory phv_factory{};
406 std::unordered_map<std::string, header_id_t> header_ids_map{};
407 std::unordered_map<std::string, header_stack_id_t> header_stack_ids_map{};
408 std::unordered_map<std::string, header_union_id_t> header_union_ids_map{};
409 std::unordered_map<std::string, header_union_stack_id_t>
410 header_union_stack_ids_map{};
411 std::unordered_map<std::string, HeaderType *> header_to_type_map{};
412 std::unordered_map<std::string, HeaderType *> header_stack_to_type_map{};
414 std::unordered_map<std::string, std::unique_ptr<HeaderType> >
418 std::unordered_map<std::string, std::unique_ptr<MatchActionTable> >
419 match_action_tables_map{};
421 std::unordered_map<std::string, std::unique_ptr<ActionProfile> >
422 action_profiles_map{};
424 std::unordered_map<std::string, std::unique_ptr<Conditional> >
427 std::unordered_map<std::string, std::unique_ptr<ControlAction> >
428 control_actions_map{};
430 std::unordered_map<std::string, ControlFlowNode *> control_nodes_map{};
433 std::unordered_map<std::string, std::unique_ptr<Pipeline> > pipelines_map{};
437 std::unordered_map<p4object_id_t, std::unique_ptr<ActionFn> > actions_map{};
438 using table_action_pair = std::pair<std::string, std::string>;
439 struct TableActionPairKeyHash {
440 std::size_t operator()(
const table_action_pair& p)
const {
441 std::size_t seed = 0;
442 boost::hash_combine(seed, p.first);
443 boost::hash_combine(seed, p.second);
448 std::unordered_map<table_action_pair, ActionFn *, TableActionPairKeyHash>
450 using aprof_action_pair = table_action_pair;
451 using AprofActionPairKeyHash = TableActionPairKeyHash;
452 std::unordered_map<aprof_action_pair, ActionFn *, AprofActionPairKeyHash>
456 std::unordered_map<std::string, std::unique_ptr<Parser> > parsers{};
458 std::vector<std::unique_ptr<ParseState> > parse_states{};
460 std::vector<std::unique_ptr<ActionFn> > parse_methods{};
461 std::vector<std::unique_ptr<ActionFn> > deparse_methods{};
464 std::unordered_map<std::string, std::unique_ptr<ParseVSet> > parse_vsets{};
466 ErrorCodeMap error_codes;
471 std::vector<std::unique_ptr<Checksum> > checksums{};
473 std::unordered_map<std::string, std::unique_ptr<Deparser> > deparsers{};
475 std::unique_ptr<LearnEngineIface> learn_engine{};
477 class LearnList :
public NamedP4Object {
479 LearnList(
const std::string &name, p4object_id_t
id)
480 : NamedP4Object(name, id) { }
482 std::unordered_map<std::string, std::unique_ptr<LearnList> > learn_lists{};
484 std::shared_ptr<TransportIface> notifications_transport{};
486 std::unique_ptr<AgeingMonitorIface> ageing_monitor{};
489 std::unordered_map<std::string, std::unique_ptr<MeterArray> > meter_arrays{};
492 std::unordered_map<std::string, std::unique_ptr<CounterArray> >
496 std::unordered_map<std::string, std::unique_ptr<RegisterArray> >
500 std::unordered_map<std::string, std::unique_ptr<NamedCalculation> >
504 std::unordered_map<p4object_id_t, std::unique_ptr<FieldList> > field_lists{};
507 std::unordered_map<std::string, std::unique_ptr<ExternType> >
510 std::unordered_map<std::string, header_field_pair> field_aliases{};
513 std::unordered_map<p4object_id_t, p4object_id_t> header_id_to_stack_id{};
514 struct HeaderUnionPos {
515 header_union_id_t union_id;
518 std::unordered_map<p4object_id_t, HeaderUnionPos> header_id_to_union_pos{};
519 std::unordered_map<p4object_id_t, header_union_stack_id_t>
520 union_id_to_union_stack_id{};
522 ConfigOptionMap config_options{};
525 std::unordered_map<std::string, std::unique_ptr<ActionPrimitive_>>
528 std::ostream &outstream;
532 int get_field_offset(header_id_t header_id,
533 const std::string &field_name)
const;
534 size_t get_field_bytes(header_id_t header_id,
int field_offset)
const;
535 size_t get_field_bits(header_id_t header_id,
int field_offset)
const;
536 size_t get_header_bits(header_id_t header_id)
const;
537 std::tuple<header_id_t, int> field_info(
const std::string &header_name,
538 const std::string &field_name)
const;
539 bool check_required_fields(
540 const std::set<header_field_pair> &required_fields);
542 std::unique_ptr<CalculationsMap::MyC> check_hash(
543 const std::string &name)
const;
545 void enable_arith(header_id_t header_id,
int field_offset);
546 void enable_arith(header_id_t header_id);
548 std::unique_ptr<Calculation> process_cfg_selector(
549 const Json::Value &cfg_selector)
const;
554 #endif // BM_BM_SIM_P4OBJECTS_H_