21 #ifndef BM_BM_SIM_MATCH_UNITS_H_
22 #define BM_BM_SIM_MATCH_UNITS_H_
30 #include <unordered_map>
34 #include "match_key_types.h"
35 #include "match_error_codes.h"
39 #include "handle_mgr.h"
42 #include "phv_forward.h"
49 struct MatchKeyParam {
63 MatchKeyParam(
const Type &type, std::string key)
64 : type(type), key(std::move(key)) { }
66 MatchKeyParam(
const Type &type, std::string key, std::string mask)
67 : type(type), key(std::move(key)), mask(std::move(mask)) { }
69 MatchKeyParam(
const Type &type, std::string key,
int prefix_length)
70 : type(type), key(std::move(key)), prefix_length(prefix_length) { }
72 friend std::ostream& operator<<(std::ostream &out,
const MatchKeyParam &p);
74 static std::string type_to_string(Type t);
85 class MatchKeyBuilderHelper;
91 class MatchKeyBuilder {
92 friend class detail::MatchKeyBuilderHelper;
94 void push_back_field(header_id_t header,
int field_offset,
size_t nbits,
95 MatchKeyParam::Type mtype,
const std::string &name =
"");
97 void push_back_field(header_id_t header,
int field_offset,
size_t nbits,
98 const ByteContainer &mask, MatchKeyParam::Type mtype,
99 const std::string &name =
"");
101 void push_back_valid_header(header_id_t header,
const std::string &name =
"");
103 void apply_big_mask(ByteContainer *key)
const;
105 void operator()(
const PHV &phv, ByteContainer *key)
const;
107 std::vector<std::string> key_to_fields(
const ByteContainer &key)
const;
109 std::string key_to_string(
const ByteContainer &key,
110 std::string separator =
"",
111 bool upper_case =
false)
const;
115 template <
typename E>
116 std::vector<MatchKeyParam> entry_to_match_params(
const E &entry)
const;
118 template <
typename E>
119 E match_params_to_entry(
const std::vector<MatchKeyParam> ¶ms)
const;
121 bool match_params_sanity_check(
122 const std::vector<MatchKeyParam> ¶ms)
const;
124 size_t get_nbytes_key()
const {
return nbytes_key; }
127 size_t get_size_key()
const {
return key_input.size(); }
129 const std::string &get_name(
size_t idx)
const {
return name_map.get(idx); }
131 size_t max_name_size()
const {
return name_map.max_size(); }
137 MatchKeyParam::Type mtype;
142 void push_back(
const std::string &name);
143 const std::string &get(
size_t idx)
const;
144 size_t max_size()
const;
146 std::vector<std::string> names{};
151 void push_back(KeyF &&input,
const ByteContainer &mask,
152 const std::string &name);
154 std::vector<KeyF> key_input{};
155 size_t nbytes_key{0};
156 bool has_big_mask{
false};
157 ByteContainer big_mask{};
161 std::vector<size_t> key_mapping{};
163 std::vector<size_t> inv_mapping{};
164 std::vector<size_t> key_offsets{};
167 std::vector<ByteContainer> masks{};
170 namespace MatchUnit {
172 struct AtomicTimestamp {
173 std::atomic<uint64_t> ms_{};
175 AtomicTimestamp() { }
177 template <
typename T>
178 explicit AtomicTimestamp(
const T &tp) {
179 ms_ = std::chrono::duration_cast<std::chrono::milliseconds>(
180 tp.time_since_epoch()).count();
183 explicit AtomicTimestamp(uint64_t ms)
186 template <
typename T>
187 void set(
const T &tp) {
188 ms_ = std::chrono::duration_cast<std::chrono::milliseconds>(
189 tp.time_since_epoch()).count();
192 void set(uint64_t ms) {
196 uint64_t get_ms()
const {
201 AtomicTimestamp(
const AtomicTimestamp &other) =
delete;
202 AtomicTimestamp &operator=(
const AtomicTimestamp &other) =
delete;
205 AtomicTimestamp(AtomicTimestamp &&other)
206 : ms_(other.ms_.load()) { }
207 AtomicTimestamp &operator=(AtomicTimestamp &&other) {
208 ms_ = other.ms_.load();
214 using clock = Packet::clock;
216 AtomicTimestamp ts{};
217 uint32_t timeout_ms{0};
222 counter.reset_counter();
223 ts.set(clock::now());
229 class MatchUnitAbstract_ {
231 friend class handle_iterator;
235 class handle_iterator {
237 using iterator_category = std::forward_iterator_tag;
238 using value_type = handle_t;
239 using difference_type = std::ptrdiff_t;
240 using pointer = handle_t*;
241 using reference = handle_t&;
243 handle_iterator(
const MatchUnitAbstract_ *mu, HandleMgr::const_iterator it);
245 const entry_handle_t &operator*()
const {
246 assert(it != mu->handles.end() &&
"Invalid iterator dereference.");
250 const entry_handle_t *operator->()
const {
251 assert(it != mu->handles.end() &&
"Invalid iterator dereference.");
255 bool operator==(
const handle_iterator &other)
const {
256 return (mu == other.mu) && (it == other.it);
259 bool operator!=(
const handle_iterator &other)
const {
260 return !(*
this == other);
263 handle_iterator &operator++();
265 const handle_iterator operator++(
int) {
267 const handle_iterator old(*
this);
273 const MatchUnitAbstract_ *mu{
nullptr};
274 HandleMgr::const_iterator it;
275 entry_handle_t handle{};
279 MatchUnitAbstract_(
size_t size,
const MatchKeyBuilder &key_builder);
281 size_t get_num_entries()
const {
return num_entries; }
283 size_t get_size()
const {
return size; }
285 size_t get_nbytes_key()
const {
return nbytes_key; }
287 size_t get_size_key()
const {
return size_key; }
289 bool valid_handle(entry_handle_t handle)
const;
291 MatchUnit::EntryMeta &get_entry_meta(entry_handle_t handle);
292 const MatchUnit::EntryMeta &get_entry_meta(entry_handle_t handle)
const;
294 void reset_counters();
296 void set_direct_meters(MeterArray *meter_array);
298 Meter &get_meter(entry_handle_t handle);
300 MatchErrorCode set_entry_ttl(entry_handle_t handle,
unsigned int ttl_ms);
302 void sweep_entries(std::vector<entry_handle_t> *entries)
const;
304 void dump_key_params(std::ostream *out,
305 const std::vector<MatchKeyParam> ¶ms,
306 int priority = -1)
const;
309 handle_iterator handles_begin()
const;
310 handle_iterator handles_end()
const;
313 MatchErrorCode get_and_set_handle(internal_handle_t *handle);
314 MatchErrorCode unset_handle(internal_handle_t handle);
315 bool valid_handle_(internal_handle_t handle)
const;
317 void build_key(
const PHV &phv, ByteContainer *key)
const {
318 match_key_builder(phv, key);
321 std::string key_to_string(
const ByteContainer &key)
const {
322 return match_key_builder.key_to_string(key);
325 std::string key_to_string_with_names(
const ByteContainer &key)
const;
327 void update_counters(Counter *c,
const Packet &pkt) {
328 c->increment_counter(pkt);
331 void update_ts(MatchUnit::AtomicTimestamp *ts,
const Packet &pkt) {
332 ts->set(pkt.get_ingress_ts_ms());
336 ~MatchUnitAbstract_() { }
340 size_t num_entries{0};
344 MatchKeyBuilder match_key_builder;
345 std::vector<MatchUnit::EntryMeta> entry_meta{};
347 MeterArray *direct_meters{
nullptr};
350 template <
typename V>
351 class MatchUnitAbstract :
public MatchUnitAbstract_ {
353 struct MatchUnitLookup {
354 MatchUnitLookup(entry_handle_t handle,
const V *value)
355 : handle(handle), value(value) { }
357 bool found()
const {
return (value !=
nullptr); }
359 static MatchUnitLookup empty_entry() {
return MatchUnitLookup(0,
nullptr); }
361 entry_handle_t handle{0};
362 const V *value{
nullptr};
366 MatchUnitAbstract(
size_t size,
const MatchKeyBuilder &match_key_builder)
367 : MatchUnitAbstract_(size, match_key_builder) { }
369 virtual ~MatchUnitAbstract() { }
371 MatchUnitLookup lookup(
const Packet &pkt);
373 MatchErrorCode add_entry(
const std::vector<MatchKeyParam> &match_key,
375 entry_handle_t *handle,
378 MatchErrorCode delete_entry(entry_handle_t handle);
380 MatchErrorCode modify_entry(entry_handle_t handle, V value);
382 MatchErrorCode get_value(entry_handle_t handle,
const V **value);
384 MatchErrorCode get_entry(entry_handle_t handle,
385 std::vector<MatchKeyParam> *match_key,
386 const V **value,
int *priority =
nullptr)
const;
388 MatchErrorCode retrieve_handle(
const std::vector<MatchKeyParam> &match_key,
389 entry_handle_t *handle,
390 int priority = -1)
const;
401 std::string entry_to_string(entry_handle_t handle)
const;
403 MatchErrorCode dump_match_entry(std::ostream *out,
404 entry_handle_t handle)
const;
408 void serialize(std::ostream *out)
const {
412 void deserialize(std::istream *in,
const P4Objects &objs) {
413 deserialize_(in, objs);
417 virtual MatchErrorCode add_entry_(
const std::vector<MatchKeyParam> &match_key,
419 entry_handle_t *handle,
422 virtual MatchErrorCode delete_entry_(entry_handle_t handle) = 0;
424 virtual MatchErrorCode modify_entry_(entry_handle_t handle, V value) = 0;
426 virtual MatchErrorCode get_value_(entry_handle_t handle,
const V **value) = 0;
428 virtual MatchErrorCode get_entry_(entry_handle_t handle,
429 std::vector<MatchKeyParam> *match_key,
430 const V **value,
int *priority)
const = 0;
432 virtual MatchErrorCode retrieve_handle_(
433 const std::vector<MatchKeyParam> &match_key,
434 entry_handle_t *handle,
435 int priority)
const = 0;
437 virtual MatchErrorCode dump_match_entry_(std::ostream *out,
438 entry_handle_t handle)
const = 0;
440 virtual void reset_state_() = 0;
442 virtual MatchUnitLookup lookup_key(
const ByteContainer &key)
const = 0;
444 virtual void serialize_(std::ostream *out)
const = 0;
445 virtual void deserialize_(std::istream *in,
const P4Objects &objs) = 0;
449 template <
typename K,
typename V>
450 class MatchUnitGeneric :
public MatchUnitAbstract<V> {
452 using MatchUnitLookup =
typename MatchUnitAbstract<V>::MatchUnitLookup;
455 Entry(K key, V value)
456 : key(std::move(key)), value(std::move(value)) {}
462 MatchUnitGeneric(
size_t size,
const MatchKeyBuilder &match_key_builder,
463 LookupStructureFactory *lookup_factory)
464 : MatchUnitAbstract<V>(size, match_key_builder), entries(size),
466 LookupStructureFactory::create<K>(
467 lookup_factory, size, match_key_builder.get_nbytes_key())) {}
470 MatchErrorCode add_entry_(
const std::vector<MatchKeyParam> &match_key,
472 entry_handle_t *handle,
473 int priority)
override;
475 MatchErrorCode delete_entry_(entry_handle_t handle)
override;
477 MatchErrorCode modify_entry_(entry_handle_t handle, V value)
override;
479 MatchErrorCode get_value_(entry_handle_t handle,
const V **value)
override;
481 MatchErrorCode get_entry_(entry_handle_t handle,
482 std::vector<MatchKeyParam> *match_key,
483 const V **value,
int *priority)
const override;
485 MatchErrorCode retrieve_handle_(
const std::vector<MatchKeyParam> &match_key,
486 entry_handle_t *handle,
487 int priority)
const override;
489 MatchErrorCode dump_match_entry_(std::ostream *out,
490 entry_handle_t handle)
const override;
492 void reset_state_()
override;
494 MatchUnitLookup lookup_key(
const ByteContainer &key)
const override;
496 void serialize_(std::ostream *out)
const override;
497 void deserialize_(std::istream *in,
const P4Objects &objs)
override;
499 MatchErrorCode build_entry_from_match_key(
500 const std::vector<MatchKeyParam> &match_key,
int priority,
504 std::vector<Entry> entries{};
505 std::unique_ptr<LookupStructure<K>> lookup_structure{
nullptr};
511 template <
typename V>
512 using MatchUnitExact = MatchUnitGeneric<ExactMatchKey, V>;
514 template <
typename V>
515 using MatchUnitLPM = MatchUnitGeneric<LPMMatchKey, V>;
517 template <
typename V>
518 using MatchUnitTernary = MatchUnitGeneric<TernaryMatchKey, V>;
520 template <
typename V>
521 using MatchUnitRange = MatchUnitGeneric<RangeMatchKey, V>;
526 #endif // BM_BM_SIM_MATCH_UNITS_H_