21 #ifndef BM_BM_SIM_MATCH_TABLES_H_
22 #define BM_BM_SIM_MATCH_TABLES_H_
29 #include <type_traits>
30 #include <unordered_map>
34 #include <boost/thread/shared_mutex.hpp>
36 #include "match_units.h"
38 #include "control_flow.h"
40 #include "action_entry.h"
41 #include "action_profile.h"
45 enum class MatchTableType {
52 class MatchTableAbstract :
public NamedP4Object {
54 friend class handle_iterator;
59 entry_handle_t handle;
60 std::vector<MatchKeyParam> match_key;
61 uint32_t timeout_ms{0};
62 uint32_t time_since_hit_ms{0};
66 class handle_iterator {
68 using iterator_category = std::forward_iterator_tag;
69 using value_type = handle_t;
70 using difference_type = std::ptrdiff_t;
71 using pointer = handle_t*;
72 using reference = handle_t&;
74 handle_iterator(
const MatchTableAbstract *mt,
75 const MatchUnitAbstract_::handle_iterator &it)
78 const entry_handle_t &operator*()
const {
79 ReadLock lock = mt->lock_read();
83 const entry_handle_t *operator->()
const {
84 ReadLock lock = mt->lock_read();
85 return it.operator->();
88 bool operator==(
const handle_iterator &other)
const {
89 ReadLock lock = mt->lock_read();
90 return (it == other.it);
93 bool operator!=(
const handle_iterator &other)
const {
94 ReadLock lock = mt->lock_read();
95 return !(*
this == other);
98 handle_iterator &operator++() {
99 ReadLock lock = mt->lock_read();
104 const handle_iterator operator++(
int) {
106 const handle_iterator old(*
this);
112 const MatchTableAbstract *mt;
113 MatchUnitAbstract_::handle_iterator it;
117 MatchTableAbstract(
const std::string &name, p4object_id_t
id,
118 bool with_counters,
bool with_ageing,
119 MatchUnitAbstract_ *mu);
121 virtual ~MatchTableAbstract() { }
123 const ControlFlowNode *apply_action(Packet *pkt);
125 virtual MatchTableType get_table_type()
const = 0;
127 virtual const ActionEntry &lookup(
const Packet &pkt,
bool *hit,
128 entry_handle_t *handle,
129 const ControlFlowNode **next_node) = 0;
131 virtual size_t get_num_entries()
const = 0;
133 virtual bool is_valid_handle(entry_handle_t handle)
const = 0;
135 MatchErrorCode dump_entry(std::ostream *out,
136 entry_handle_t handle)
const {
137 auto lock = lock_read();
140 auto lock_impl = lock_impl_read();
141 return dump_entry_(out, handle);
144 std::string dump_entry_string(entry_handle_t handle)
const {
145 auto lock = lock_read();
146 auto lock_impl = lock_impl_read();
147 return dump_entry_string_(handle);
150 void reset_state(
bool reset_default_entry =
true);
152 void serialize(std::ostream *out)
const;
153 void deserialize(std::istream *in,
const P4Objects &objs);
155 void set_next_node(p4object_id_t action_id,
const ControlFlowNode *next_node);
156 void set_next_node_hit(
const ControlFlowNode *next_node);
162 void set_next_node_miss(
const ControlFlowNode *next_node);
163 void set_next_node_miss_default(
const ControlFlowNode *next_node);
165 void set_direct_meters(MeterArray *meter_array,
166 header_id_t target_header,
169 MatchErrorCode query_counters(entry_handle_t handle,
170 counter_value_t *bytes,
171 counter_value_t *packets)
const;
172 MatchErrorCode reset_counters();
173 MatchErrorCode write_counters(entry_handle_t handle,
174 counter_value_t bytes,
175 counter_value_t packets);
177 MatchErrorCode set_meter_rates(
178 entry_handle_t handle,
const std::vector<Meter::rate_config_t> &configs);
180 MatchErrorCode get_meter_rates(
181 entry_handle_t handle, std::vector<Meter::rate_config_t> *configs)
const;
183 MatchErrorCode reset_meter_rates(entry_handle_t handle);
185 MatchErrorCode set_entry_ttl(entry_handle_t handle,
unsigned int ttl_ms);
187 void sweep_entries(std::vector<entry_handle_t> *entries)
const;
189 handle_iterator handles_begin()
const;
190 handle_iterator handles_end()
const;
196 void set_default_default_entry(
const ActionFn *action_fn,
197 ActionData action_data,
200 MatchTableAbstract(
const MatchTableAbstract &other) =
delete;
201 MatchTableAbstract &
operator=(
const MatchTableAbstract &other) =
delete;
203 MatchTableAbstract(MatchTableAbstract &&other) =
delete;
204 MatchTableAbstract &
operator=(MatchTableAbstract &&other) =
delete;
207 using ReadLock = boost::shared_lock<boost::shared_mutex>;
208 using WriteLock = boost::unique_lock<boost::shared_mutex>;
211 const ControlFlowNode *get_next_node(p4object_id_t action_id)
const;
212 const ControlFlowNode *get_next_node_default(p4object_id_t action_id)
const;
215 void set_entry_common_info(EntryCommon *entry)
const;
217 ReadLock lock_read()
const {
return ReadLock(t_mutex); }
218 WriteLock lock_write()
const {
return WriteLock(t_mutex); }
223 std::atomic_bool with_counters{
false};
224 std::atomic_bool with_meters{
false};
225 std::atomic_bool with_ageing{
false};
227 std::unordered_map<p4object_id_t, const ControlFlowNode *> next_nodes{};
228 const ControlFlowNode *next_node_hit{
nullptr};
230 const ControlFlowNode *next_node_miss{
nullptr};
233 bool has_next_node_hit{
false};
234 bool has_next_node_miss{
false};
246 ActionEntry default_default_entry{};
247 bool const_default_entry{
false};
249 header_id_t meter_target_header{};
250 int meter_target_offset{};
253 virtual void reset_state_(
bool reset_default_entry) = 0;
255 virtual void serialize_(std::ostream *out)
const = 0;
256 virtual void deserialize_(std::istream *in,
const P4Objects &objs) = 0;
258 virtual MatchErrorCode dump_entry_(std::ostream *out,
259 entry_handle_t handle)
const = 0;
264 virtual void set_default_default_entry_() = 0;
282 virtual ReadLock lock_impl_read()
const {
return ReadLock(); }
283 virtual WriteLock lock_impl_write()
const {
return WriteLock(); }
286 std::string dump_entry_string_(entry_handle_t handle)
const;
289 mutable boost::shared_mutex t_mutex{};
290 MatchUnitAbstract_ *match_unit_{
nullptr};
295 class MatchTable :
public MatchTableAbstract {
297 struct Entry :
public EntryCommon {
298 const ActionFn *action_fn;
299 ActionData action_data;
303 MatchTable(
const std::string &name, p4object_id_t
id,
304 std::unique_ptr<MatchUnitAbstract<ActionEntry> > match_unit,
305 bool with_counters =
false,
bool with_ageing =
false);
307 MatchErrorCode add_entry(
const std::vector<MatchKeyParam> &match_key,
308 const ActionFn *action_fn,
309 ActionData action_data,
310 entry_handle_t *handle,
313 MatchErrorCode delete_entry(entry_handle_t handle);
315 MatchErrorCode modify_entry(entry_handle_t handle,
316 const ActionFn *action_fn,
317 ActionData action_data);
319 MatchErrorCode set_default_action(
const ActionFn *action_fn,
320 ActionData action_data);
322 MatchErrorCode reset_default_entry();
324 MatchErrorCode get_entry(entry_handle_t handle, Entry *entry)
const;
326 MatchErrorCode get_entry_from_key(
const std::vector<MatchKeyParam> &match_key,
327 Entry *entry,
int priority = 1)
const;
329 std::vector<Entry> get_entries()
const;
331 MatchErrorCode get_default_entry(Entry *entry)
const;
333 MatchTableType get_table_type()
const override {
334 return MatchTableType::SIMPLE;
337 const ActionEntry &lookup(
const Packet &pkt,
bool *hit,
338 entry_handle_t *handle,
339 const ControlFlowNode **next_node)
override;
341 size_t get_num_entries()
const override {
342 return match_unit->get_num_entries();
345 bool is_valid_handle(entry_handle_t handle)
const override {
346 return match_unit->valid_handle(handle);
353 void set_const_default_action_fn(
const ActionFn *const_default_action_fn);
355 void set_immutable_entries();
358 static std::unique_ptr<MatchTable> create(
359 const std::string &match_type,
360 const std::string &name,
362 size_t size,
const MatchKeyBuilder &match_key_builder,
363 LookupStructureFactory *lookup_factory,
364 bool with_counters,
bool with_ageing);
367 void reset_state_(
bool reset_default_entry)
override;
369 void serialize_(std::ostream *out)
const override;
370 void deserialize_(std::istream *in,
const P4Objects &objs)
override;
372 MatchErrorCode dump_entry_(std::ostream *out,
373 entry_handle_t handle)
const override;
375 void set_default_default_entry_()
override;
377 MatchErrorCode get_entry_(entry_handle_t handle, Entry *entry)
const;
380 ActionEntry default_entry{};
381 std::unique_ptr<MatchUnitAbstract<ActionEntry> > match_unit;
382 const ActionFn *const_default_action{
nullptr};
383 bool immutable_entries{
false};
386 class MatchTableIndirect :
public MatchTableAbstract {
388 using mbr_hdl_t = ActionProfile::mbr_hdl_t;
390 using IndirectIndex = ActionProfile::IndirectIndex;
392 struct Entry :
public EntryCommon {
398 const std::string &name, p4object_id_t
id,
399 std::unique_ptr<MatchUnitAbstract<IndirectIndex> > match_unit,
400 bool with_counters =
false,
bool with_ageing =
false);
402 void set_action_profile(ActionProfile *action_profile);
404 ActionProfile *get_action_profile()
const;
406 MatchErrorCode add_entry(
const std::vector<MatchKeyParam> &match_key,
408 entry_handle_t *handle,
411 MatchErrorCode delete_entry(entry_handle_t handle);
413 MatchErrorCode modify_entry(entry_handle_t handle, mbr_hdl_t mbr);
415 MatchErrorCode set_default_member(mbr_hdl_t mbr);
417 MatchErrorCode reset_default_entry();
419 MatchErrorCode get_entry(entry_handle_t handle, Entry *entry)
const;
421 MatchErrorCode get_entry_from_key(
const std::vector<MatchKeyParam> &match_key,
422 Entry *entry,
int priority = 1)
const;
424 std::vector<Entry> get_entries()
const;
426 MatchErrorCode get_default_entry(Entry *entry)
const;
428 MatchTableType get_table_type()
const override {
429 return MatchTableType::INDIRECT;
432 const ActionEntry &lookup(
const Packet &pkt,
bool *hit,
433 entry_handle_t *handle,
434 const ControlFlowNode **next_node)
override;
436 size_t get_num_entries()
const override {
437 return match_unit->get_num_entries();
440 bool is_valid_handle(entry_handle_t handle)
const override {
441 return match_unit->valid_handle(handle);
445 static std::unique_ptr<MatchTableIndirect> create(
446 const std::string &match_type,
447 const std::string &name, p4object_id_t
id,
448 size_t size,
const MatchKeyBuilder &match_key_builder,
449 LookupStructureFactory *lookup_factory,
450 bool with_counters,
bool with_ageing);
453 void reset_state_(
bool reset_default_entry)
override;
455 void serialize_(std::ostream *out)
const override;
456 void deserialize_(std::istream *in,
const P4Objects &objs)
override;
458 void dump_(std::ostream *stream)
const;
460 MatchErrorCode dump_entry_(std::ostream *out,
461 entry_handle_t handle)
const override;
463 void set_default_default_entry_()
override;
465 MatchErrorCode get_entry_(entry_handle_t handle, Entry *entry)
const;
467 ReadLock lock_impl_read()
const override;
468 WriteLock lock_impl_write()
const override;
471 IndirectIndex default_index{};
472 std::unique_ptr<MatchUnitAbstract<IndirectIndex> > match_unit;
473 ActionProfile *action_profile{
nullptr};
474 bool default_set{
false};
475 ActionEntry empty_action{};
478 class MatchTableIndirectWS :
public MatchTableIndirect {
480 using grp_hdl_t = ActionProfile::grp_hdl_t;
485 struct Entry :
public EntryCommon {
491 MatchTableIndirectWS(
492 const std::string &name, p4object_id_t
id,
493 std::unique_ptr<MatchUnitAbstract<IndirectIndex> > match_unit,
494 bool with_counters =
false,
bool with_ageing =
false);
496 MatchErrorCode add_entry_ws(
const std::vector<MatchKeyParam> &match_key,
498 entry_handle_t *handle,
501 MatchErrorCode modify_entry_ws(entry_handle_t handle, grp_hdl_t grp);
503 MatchErrorCode set_default_group(grp_hdl_t grp);
505 MatchErrorCode get_entry(entry_handle_t handle, Entry *entry)
const;
507 MatchErrorCode get_entry_from_key(
const std::vector<MatchKeyParam> &match_key,
508 Entry *entry,
int priority = 1)
const;
510 std::vector<Entry> get_entries()
const;
512 MatchErrorCode get_default_entry(Entry *entry)
const;
514 MatchTableType get_table_type()
const override {
515 return MatchTableType::INDIRECT_WS;
518 const ActionEntry &lookup(
const Packet &pkt,
bool *hit,
519 entry_handle_t *handle,
520 const ControlFlowNode **next_node)
override;
523 static std::unique_ptr<MatchTableIndirectWS> create(
524 const std::string &match_type,
525 const std::string &name, p4object_id_t
id,
526 size_t size,
const MatchKeyBuilder &match_key_builder,
527 LookupStructureFactory *lookup_factory,
528 bool with_counters,
bool with_ageing);
531 void serialize_(std::ostream *out)
const override;
532 void deserialize_(std::istream *in,
const P4Objects &objs)
override;
534 MatchErrorCode dump_entry_(std::ostream *out,
535 entry_handle_t handle)
const override;
537 MatchErrorCode get_entry_(entry_handle_t handle, Entry *entry)
const;
542 #endif // BM_BM_SIM_MATCH_TABLES_H_