bmv2
Designing your own switch target with bmv2
context.h
Go to the documentation of this file.
1 /* Copyright 2013-present Barefoot Networks, Inc.
2  *
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 /*
17  * Antonin Bas (antonin@barefootnetworks.com)
18  *
19  */
20 
48 
49 #ifndef BM_BM_SIM_CONTEXT_H_
50 #define BM_BM_SIM_CONTEXT_H_
51 
52 #include <atomic>
53 #include <iosfwd>
54 #include <memory>
55 #include <mutex>
56 #include <set>
57 #include <string>
58 #include <typeindex>
59 #include <unordered_map>
60 #include <utility>
61 #include <vector>
62 
63 #include "P4Objects.h"
64 #include "action_profile.h"
65 #include "match_tables.h"
66 #include "runtime_interface.h"
67 #include "lookup_structures.h"
68 #include "device_id.h"
69 
70 namespace bm {
71 
74  public:
75  ExternSafeAccess(boost::shared_lock<boost::shared_mutex> &&lock,
76  ExternType *instance)
77  : lock(std::move(lock)), instance(instance) { }
78 
80  ExternType *get() const { return instance; }
81 
82  private:
83  boost::shared_lock<boost::shared_mutex> lock;
84  ExternType *instance;
85 };
86 
90 class Context final {
91  friend class SwitchWContexts;
92 
93  public:
94  using mbr_hdl_t = RuntimeInterface::mbr_hdl_t;
95  using grp_hdl_t = RuntimeInterface::grp_hdl_t;
96 
97  using MeterErrorCode = RuntimeInterface::MeterErrorCode;
98  using RegisterErrorCode = RuntimeInterface::RegisterErrorCode;
99 
100  using ErrorCode = RuntimeInterface::ErrorCode;
101 
102  public:
103  // needs to be default constructible if I want to put it in a std::vector
104  Context();
105 
110  template<typename T>
111  bool add_component(std::shared_ptr<T> ptr) {
112  std::shared_ptr<void> ptr_ = std::static_pointer_cast<void>(ptr);
113  const auto &r = components.insert({std::type_index(typeid(T)), ptr_});
114  return r.second;
115  }
116 
119  template<typename T>
120  std::shared_ptr<T> get_component() {
121  const auto &search = components.find(std::type_index(typeid(T)));
122  if (search == components.end()) return nullptr;
123  return std::static_pointer_cast<T>(search->second);
124  }
125 
126  // do these methods need any protection?
127  // TODO(antonin): should I return shared_ptrs instead of raw_ptrs?
128 
131  Pipeline *get_pipeline(const std::string &name) {
132  return p4objects->get_pipeline_rt(name);
133  }
134 
137  Parser *get_parser(const std::string &name) {
138  return p4objects->get_parser_rt(name);
139  }
140 
143  Deparser *get_deparser(const std::string &name) {
144  return p4objects->get_deparser_rt(name);
145  }
146 
149  FieldList *get_field_list(const p4object_id_t field_list_id) {
150  return p4objects->get_field_list(field_list_id);
151  }
152 
156  ExternSafeAccess get_extern_instance(const std::string &name);
157 
158  // Added for testing, other "object types" can be added if needed
159  p4object_id_t get_table_id(const std::string &name) {
160  return p4objects->get_match_action_table(name)->get_id();
161  }
162 
163  p4object_id_t get_action_id(const std::string &table_name,
164  const std::string &action_name) {
165  return p4objects->get_action(table_name, action_name)->get_id();
166  }
167 
168  private:
169  // ---------- runtime interfaces ----------
170 
171  MatchErrorCode
172  mt_get_num_entries(const std::string &table_name, size_t *num_entries) const;
173 
174  MatchErrorCode
175  mt_clear_entries(const std::string &table_name, bool reset_default_entry);
176 
177  MatchErrorCode
178  mt_add_entry(const std::string &table_name,
179  const std::vector<MatchKeyParam> &match_key,
180  const std::string &action_name,
181  ActionData action_data,
182  entry_handle_t *handle,
183  int priority = -1 /*only used for ternary*/);
184 
185  MatchErrorCode
186  mt_set_default_action(const std::string &table_name,
187  const std::string &action_name,
188  ActionData action_data);
189 
190  MatchErrorCode
191  mt_reset_default_entry(const std::string &table_name);
192 
193  MatchErrorCode
194  mt_delete_entry(const std::string &table_name,
195  entry_handle_t handle);
196 
197  MatchErrorCode
198  mt_modify_entry(const std::string &table_name,
199  entry_handle_t handle,
200  const std::string &action_name,
201  ActionData action_data);
202 
203  MatchErrorCode
204  mt_set_entry_ttl(const std::string &table_name,
205  entry_handle_t handle,
206  unsigned int ttl_ms);
207 
208  // action profiles
209 
210  MatchErrorCode
211  mt_act_prof_add_member(const std::string &act_prof_name,
212  const std::string &action_name,
213  ActionData action_data, mbr_hdl_t *mbr);
214 
215  MatchErrorCode
216  mt_act_prof_delete_member(const std::string &act_prof_name, mbr_hdl_t mbr);
217 
218  MatchErrorCode
219  mt_act_prof_modify_member(const std::string &act_prof_name, mbr_hdl_t mbr,
220  const std::string &action_name,
221  ActionData action_data);
222 
223  MatchErrorCode
224  mt_act_prof_create_group(const std::string &act_prof_name, grp_hdl_t *grp);
225 
226  MatchErrorCode
227  mt_act_prof_delete_group(const std::string &act_prof_name, grp_hdl_t grp);
228 
229  MatchErrorCode
230  mt_act_prof_add_member_to_group(const std::string &act_prof_name,
231  mbr_hdl_t mbr, grp_hdl_t grp);
232 
233  MatchErrorCode
234  mt_act_prof_remove_member_from_group(const std::string &act_prof_name,
235  mbr_hdl_t mbr, grp_hdl_t grp);
236 
237  std::vector<ActionProfile::Member>
238  mt_act_prof_get_members(const std::string &act_prof_name) const;
239 
240  MatchErrorCode
241  mt_act_prof_get_member(const std::string &act_prof_name, grp_hdl_t grp,
242  ActionProfile::Member *member) const;
243 
244  std::vector<ActionProfile::Group>
245  mt_act_prof_get_groups(const std::string &act_prof_name) const;
246 
247  MatchErrorCode
248  mt_act_prof_get_group(const std::string &act_prof_name, grp_hdl_t grp,
249  ActionProfile::Group *group) const;
250 
251  // indirect tables
252 
253  MatchErrorCode
254  mt_indirect_add_entry(const std::string &table_name,
255  const std::vector<MatchKeyParam> &match_key,
256  mbr_hdl_t mbr,
257  entry_handle_t *handle,
258  int priority = 1);
259 
260  MatchErrorCode
261  mt_indirect_modify_entry(const std::string &table_name,
262  entry_handle_t handle,
263  mbr_hdl_t mbr);
264 
265  MatchErrorCode
266  mt_indirect_delete_entry(const std::string &table_name,
267  entry_handle_t handle);
268 
269  MatchErrorCode
270  mt_indirect_set_entry_ttl(const std::string &table_name,
271  entry_handle_t handle,
272  unsigned int ttl_ms);
273 
274  MatchErrorCode
275  mt_indirect_set_default_member(const std::string &table_name,
276  mbr_hdl_t mbr);
277 
278  MatchErrorCode
279  mt_indirect_reset_default_entry(const std::string &table_name);
280 
281  MatchErrorCode
282  mt_indirect_ws_add_entry(const std::string &table_name,
283  const std::vector<MatchKeyParam> &match_key,
284  grp_hdl_t grp,
285  entry_handle_t *handle,
286  int priority = 1);
287 
288  MatchErrorCode
289  mt_indirect_ws_modify_entry(const std::string &table_name,
290  entry_handle_t handle,
291  grp_hdl_t grp);
292 
293  MatchErrorCode
294  mt_indirect_ws_set_default_group(const std::string &table_name,
295  grp_hdl_t grp);
296 
297  MatchTableType
298  mt_get_type(const std::string &table_name) const;
299 
300  template <typename T>
301  std::vector<typename T::Entry>
302  mt_get_entries(const std::string &table_name) const;
303 
304  template <typename T>
305  MatchErrorCode
306  mt_get_entry(const std::string &table_name, entry_handle_t handle,
307  typename T::Entry *entry) const;
308 
309  template <typename T>
310  MatchErrorCode
311  mt_get_default_entry(const std::string &table_name,
312  typename T::Entry *default_entry) const;
313 
314  template <typename T>
315  MatchErrorCode
316  mt_get_entry_from_key(const std::string &table_name,
317  const std::vector<MatchKeyParam> &match_key,
318  typename T::Entry *entry,
319  int priority = 1) const;
320 
321  MatchErrorCode
322  mt_read_counters(const std::string &table_name,
323  entry_handle_t handle,
324  MatchTableAbstract::counter_value_t *bytes,
325  MatchTableAbstract::counter_value_t *packets);
326 
327  MatchErrorCode
328  mt_reset_counters(const std::string &table_name);
329 
330  MatchErrorCode
331  mt_write_counters(const std::string &table_name,
332  entry_handle_t handle,
333  MatchTableAbstract::counter_value_t bytes,
334  MatchTableAbstract::counter_value_t packets);
335 
336  MatchErrorCode
337  mt_set_meter_rates(const std::string &table_name, entry_handle_t handle,
338  const std::vector<Meter::rate_config_t> &configs);
339 
340  MatchErrorCode
341  mt_get_meter_rates(const std::string &table_name, entry_handle_t handle,
342  std::vector<Meter::rate_config_t> *configs);
343 
344  MatchErrorCode
345  mt_reset_meter_rates(const std::string &table_name, entry_handle_t handle);
346 
347  Counter::CounterErrorCode
348  read_counters(const std::string &counter_name,
349  size_t index,
350  MatchTableAbstract::counter_value_t *bytes,
351  MatchTableAbstract::counter_value_t *packets);
352 
353  Counter::CounterErrorCode
354  reset_counters(const std::string &counter_name);
355 
356  Counter::CounterErrorCode
357  write_counters(const std::string &counter_name,
358  size_t index,
359  MatchTableAbstract::counter_value_t bytes,
360  MatchTableAbstract::counter_value_t packets);
361 
362  MeterErrorCode
363  meter_array_set_rates(
364  const std::string &meter_name,
365  const std::vector<Meter::rate_config_t> &configs);
366 
367  MeterErrorCode
368  meter_set_rates(const std::string &meter_name, size_t idx,
369  const std::vector<Meter::rate_config_t> &configs);
370 
371  MeterErrorCode
372  meter_get_rates(const std::string &meter_name, size_t idx,
373  std::vector<Meter::rate_config_t> *configs);
374 
375  MeterErrorCode
376  meter_reset_rates(const std::string &meter_name, size_t idx);
377 
378  RegisterErrorCode
379  register_read(const std::string &register_name,
380  const size_t idx, Data *value);
381 
382  std::vector<Data>
383  register_read_all(const std::string &register_name);
384 
385  RegisterErrorCode
386  register_write(const std::string &register_name,
387  const size_t idx, Data value);
388 
389  RegisterErrorCode
390  register_write_range(const std::string &register_name,
391  const size_t start, const size_t end, Data value);
392 
393  RegisterErrorCode
394  register_reset(const std::string &register_name);
395 
396  ParseVSet::ErrorCode
397  parse_vset_add(const std::string &parse_vset_name,
398  const ByteContainer &value);
399 
400  ParseVSet::ErrorCode
401  parse_vset_remove(const std::string &parse_vset_name,
402  const ByteContainer &value);
403 
404  ParseVSet::ErrorCode
405  parse_vset_get(const std::string &parse_vset_name,
406  std::vector<ByteContainer> *values);
407 
408  ParseVSet::ErrorCode
409  parse_vset_clear(const std::string &parse_vset_name);
410 
411  P4Objects::IdLookupErrorCode p4objects_id_from_name(
412  P4Objects::ResourceType type, const std::string &name,
413  p4object_id_t *id) const;
414 
415  template <typename T>
416  CustomCrcErrorCode
417  set_crc_custom_parameters(
418  const std::string &calc_name,
419  const typename CustomCrcMgr<T>::crc_config_t &crc_config);
420 
421  ToeplitzErrorCode
422  set_toeplitz_key(
423  const std::string &calc_name,
424  const ToeplitzMgr::key_t &key);
425 
426  bool set_group_selector(
427  const std::string &act_prof_name,
428  std::shared_ptr<ActionProfile::GroupSelectionIface> selector);
429 
430  // ---------- End runtime interfaces ----------
431 
432  using ReadLock = std::unique_lock<std::mutex>;
433  using WriteLock = std::unique_lock<std::mutex>;
434 
435  Context(const Context &other) = delete;
436  Context &operator=(const Context &other) = delete;
437 
438  private:
439  enum SwapStatus {
440  NEW_CONFIG_LOADED = 0,
441  SWAP_REQUESTED = 1,
442  SWAP_COMPLETED = 2,
443  SWAP_CANCELLED = 3
444  };
445 
446  MatchErrorCode get_mt_indirect(const std::string &table_name,
447  MatchTableIndirect **table) const;
448  MatchErrorCode get_mt_indirect_ws(const std::string &table_name,
449  MatchTableIndirectWS **table) const;
450 
451  bool field_exists(const std::string &header_name,
452  const std::string &field_name) const {
453  return p4objects->field_exists(header_name, field_name);
454  }
455 
456  PHVFactory &get_phv_factory();
457 
458  LearnEngineIface *get_learn_engine();
459 
460  AgeingMonitorIface *get_ageing_monitor();
461 
462  void set_notifications_transport(std::shared_ptr<TransportIface> transport);
463 
464  void set_device_id(device_id_t device_id);
465 
466  void set_cxt_id(cxt_id_t cxt_id);
467 
468  void set_force_arith(bool force_arith);
469 
470  using header_field_pair = P4Objects::header_field_pair;
471  using ForceArith = P4Objects::ForceArith;
472  int init_objects(std::istream *is,
473  LookupStructureFactory * lookup_factory,
474  const std::set<header_field_pair> &required_fields =
475  std::set<header_field_pair>(),
476  const ForceArith &arith_objects = ForceArith());
477 
478  ErrorCode load_new_config(
479  std::istream *is,
480  LookupStructureFactory * lookup_factory,
481  const std::set<header_field_pair> &required_fields =
482  std::set<header_field_pair>(),
483  const ForceArith &arith_objects = ForceArith());
484 
485  ErrorCode swap_configs();
486 
487  ErrorCode reset_state();
488 
489  ErrorCode serialize(std::ostream *out);
490  ErrorCode deserialize(std::istream *in);
491 
492  int do_swap();
493 
494  int swap_requested() { return swap_ordered; }
495 
498  ConfigOptionMap get_config_options() const;
499 
502  ErrorCodeMap get_error_codes() const;
503 
504  void send_swap_status_notification(SwapStatus status);
505 
506  private: // data members
507  cxt_id_t cxt_id{};
508 
509  device_id_t device_id{0};
510 
511  std::shared_ptr<P4Objects> p4objects{nullptr};
512  std::shared_ptr<P4Objects> p4objects_rt{nullptr};
513 
514  std::unordered_map<std::type_index, std::shared_ptr<void> > components{};
515 
516  std::shared_ptr<TransportIface> notifications_transport{nullptr};
517 
518  mutable boost::shared_mutex request_mutex{};
519 
520  std::atomic<bool> swap_ordered{false};
521 
522  bool force_arith{false};
523 };
524 
525 } // namespace bm
526 
527 #endif // BM_BM_SIM_CONTEXT_H_
lookup_structures.h
bm::FieldList
Definition: field_lists.h:43
bm::ExternSafeAccess
Provides safe access to an extern instance for control plane calls.
Definition: context.h:73
bm::Context::get_pipeline
Pipeline * get_pipeline(const std::string &name)
Definition: context.h:131
bm::SwitchWContexts
Definition: switch.h:100
bm::Context::get_field_list
FieldList * get_field_list(const p4object_id_t field_list_id)
Definition: context.h:149
bm::Context::add_component
bool add_component(std::shared_ptr< T > ptr)
Definition: context.h:111
bm::Context::get_parser
Parser * get_parser(const std::string &name)
Definition: context.h:137
bm::Context::get_deparser
Deparser * get_deparser(const std::string &name)
Definition: context.h:143
bm::Context
Definition: context.h:90
bm::Context::get_component
std::shared_ptr< T > get_component()
Definition: context.h:120
bm::ExternSafeAccess::get
ExternType * get() const
Get a pointer to the extern instance itself.
Definition: context.h:80
bm::Pipeline
Definition: pipeline.h:36
bm::Context::get_extern_instance
ExternSafeAccess get_extern_instance(const std::string &name)
bm::Context::get_config_options
ConfigOptionMap get_config_options() const
bm::Parser
Implements a P4 parser.
Definition: parser.h:324
bm::Deparser
Definition: deparser.h:50
bm::Context::get_error_codes
ErrorCodeMap get_error_codes() const