bmv2
Designing your own switch target with bmv2
headers.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 
22 
23 #ifndef BM_BM_SIM_HEADERS_H_
24 #define BM_BM_SIM_HEADERS_H_
25 
26 #include <bm/config.h>
27 
28 #include <memory>
29 #include <set>
30 #include <string>
31 #include <vector>
32 
33 #include "fields.h"
34 #include "named_p4object.h"
35 #include "phv_forward.h"
36 
37 namespace bm {
38 
39 using header_type_id_t = p4object_id_t;
40 
41 class VLHeaderExpression;
42 class ArithExpression;
43 
44 class HeaderUnion;
45 
46 class HeaderType : public NamedP4Object {
47  public:
48  // do not specify custome values for enum entries, the value is used directly
49  // as an offset...
50  enum class HiddenF {
51  VALID
52  };
53 
54  struct FInfo {
55  std::string name;
56  int bitwidth;
57  bool is_signed;
58  bool is_saturating;
59  bool is_VL;
60  bool is_hidden;
61  };
62 
63  size_t get_hidden_offset(HiddenF hf) const {
64  return fields_info.size() - 1 - static_cast<size_t>(hf);
65  }
66 
67  HeaderType(const std::string &name, p4object_id_t id);
68 
69  // returns field offset
70  int push_back_field(const std::string &field_name, int field_bit_width,
71  bool is_signed = false, bool is_saturating = false,
72  bool is_VL = false);
73 
74  // if field_length_expr is nullptr it means that the length will have to be
75  // provided to extract
76  int push_back_VL_field(
77  const std::string &field_name,
78  int max_header_bytes,
79  std::unique_ptr<VLHeaderExpression> field_length_expr,
80  bool is_signed = false,
81  bool is_saturating = false);
82 
83  const FInfo &get_finfo(int field_offset) const {
84  return fields_info.at(field_offset);
85  }
86 
87  int get_bit_width(int field_offset) const {
88  return fields_info.at(field_offset).bitwidth;
89  }
90 
91  int get_bit_width() const {
92  int bitwidth = 0;
93  for (const auto &f_info : fields_info)
94  bitwidth += f_info.bitwidth;
95  return bitwidth;
96  }
97 
98  const std::string &get_field_name(int field_offset) const {
99  return fields_info.at(field_offset).name;
100  }
101 
102  bool is_field_signed(int field_offset) const {
103  return fields_info.at(field_offset).is_signed;
104  }
105 
106  header_type_id_t get_type_id() const {
107  return get_id();
108  }
109 
110  int get_num_fields() const {
111  return fields_info.size();
112  }
113 
114  int get_field_offset(const std::string &field_name) const {
115  for (size_t res = 0; res < fields_info.size(); res++) {
116  if (field_name == fields_info[res].name) return res;
117  }
118  return -1;
119  }
120 
121  bool is_VL_header() const {
122  return (VL_offset >= 0);
123  }
124 
125  bool has_VL_expr() const;
126 
127  std::unique_ptr<ArithExpression> resolve_VL_expr(header_id_t header_id) const;
128 
129  const std::vector<int> &get_VL_input_offsets() const;
130 
131  int get_VL_offset() const {
132  return VL_offset;
133  }
134 
135  int get_VL_max_header_bytes() const;
136 
137  private:
138  std::vector<FInfo> fields_info;
139  // used for VL headers only
140  std::unique_ptr<VLHeaderExpression> VL_expr_raw;
141  int VL_offset{-1};
142  int VL_max_header_bytes{0};
143 };
144 
147 class Header : public NamedP4Object {
148  public:
149  using iterator = std::vector<Field>::iterator;
150  using const_iterator = std::vector<Field>::const_iterator;
151  using reference = std::vector<Field>::reference;
152  using const_reference = std::vector<Field>::const_reference;
153  using size_type = size_t;
154 
155  friend class PHV;
156 
157  public:
158  Header(const std::string &name, p4object_id_t id,
159  const HeaderType &header_type, const std::set<int> &arith_offsets,
160  const bool metadata = false);
161 
164  int get_nbytes_packet() const {
165  return nbytes_packet;
166  }
167 
168  int recompute_nbytes_packet();
169 
171  bool is_valid() const {
172  return (metadata || valid);
173  }
174 
176  bool is_metadata() const {
177  return metadata;
178  }
179 
181  void mark_valid();
182 
184  void mark_invalid();
185 
187  void reset();
188 
189  void reset_VL_header();
190 
195  void set_written_to(bool written_to_value);
196 
200  Field &get_field(int field_offset) {
201  return fields.at(field_offset);
202  }
203 
205  const Field &get_field(int field_offset) const {
206  return fields.at(field_offset);
207  }
208 
209  const HeaderType &get_header_type() const { return header_type; }
210 
214  header_type_id_t get_header_type_id() const {
215  return header_type.get_type_id();
216  }
217 
221  bool is_VL_header() const { return header_type.is_VL_header(); }
222 
223  // phv needed for variable length extraction
224  void extract(const char *data, const PHV &phv);
225 
226  // extract a VL header for which the bitwidth of the VL field is already known
227  void extract_VL(const char *data, int VL_nbits);
228 
229  void deparse(char *data) const;
230 
232  size_type size() const noexcept { return fields.size(); }
233 
234  // iterators
235 
237  iterator begin() { return fields.begin(); }
238 
240  const_iterator begin() const { return fields.begin(); }
241 
243  iterator end() { return fields.end(); }
244 
246  const_iterator end() const { return fields.end(); }
247 
250  reference operator[](size_type n) {
251  assert(n < fields.size());
252  return fields[n];
253  }
254 
256  const_reference operator[](size_type n) const {
257  assert(n < fields.size());
258  return fields[n];
259  }
260 
261  // useful for header stacks
262  void swap_values(Header *other);
263 
264  void copy_fields(const Header &src);
265 
266  // compare to another header instance; returns true iff headers have the same
267  // type, are both valid (irrelevant for metadata) and all the fields have the
268  // same value.
269  bool cmp(const Header &other) const;
270 
271 #ifdef BM_DEBUG_ON
272  void set_packet_id(const Debugger::PacketId *id);
273 #else
274  void set_packet_id(const Debugger::PacketId *) { }
275 #endif
276 
278  const std::string &get_field_name(int field_offset) const;
279 
282  const std::string get_field_full_name(int field_offset) const;
283 
284  Header(const Header &other) = delete;
285  Header &operator=(const Header &other) = delete;
286 
287  Header(Header &&other) = default;
288  // because of reference member, this is not possible
289  Header &operator=(Header &&other) = delete;
290 
291  private:
292  void extract_VL(const char *data, const PHV &phv);
293  template <typename Fn>
294  void extract_VL_common(const char *data, const Fn &VL_fn);
295 
296  // called by the PHV class
297  void set_union_membership(HeaderUnion *header_union, size_t idx);
298 
299  private:
300  struct UnionMembership {
301  UnionMembership(HeaderUnion *header_union, size_t idx);
302 
303  void make_valid();
304  void make_invalid();
305 
306  HeaderUnion *header_union;
307  size_t idx;
308  };
309 
310  const HeaderType &header_type;
311  std::vector<Field> fields{};
312  bool valid{false};
313  // is caching this pointer here really useful?
314  Field *valid_field{nullptr};
315  bool metadata{false};
316  int nbytes_packet{0};
317  std::unique_ptr<ArithExpression> VL_expr;
318  std::unique_ptr<UnionMembership> union_membership{nullptr};
319 #ifdef BM_DEBUG_ON
320  const Debugger::PacketId *packet_id{&Debugger::dummy_PacketId};
321 #endif
322 };
323 
324 } // namespace bm
325 
326 #endif // BM_BM_SIM_HEADERS_H_
bm::NamedP4Object
Definition: named_p4object.h:39
bm::Header::get_header_type_id
header_type_id_t get_header_type_id() const
Definition: headers.h:214
bm::Header::mark_valid
void mark_valid()
Marks the header as valid.
bm::Header::get_field
const Field & get_field(int field_offset) const
Definition: headers.h:205
bm::Header::get_field
Field & get_field(int field_offset)
Definition: headers.h:200
bm::Header::begin
const_iterator begin() const
NC.
Definition: headers.h:240
bm::Header::reset
void reset()
Sets all the fields in the header to value 0.
bm::Header::set_written_to
void set_written_to(bool written_to_value)
named_p4object.h
bm::Header::is_valid
bool is_valid() const
Returns true if this header is marked valid.
Definition: headers.h:171
bm::Header::operator[]
const_reference operator[](size_type n) const
Definition: headers.h:256
bm::Header::get_field_full_name
const std::string get_field_full_name(int field_offset) const
bm::Header::end
iterator end()
NC.
Definition: headers.h:243
bm::Field
Definition: fields.h:46
bm::Header::get_field_name
const std::string & get_field_name(int field_offset) const
Returns a reference to the name of the field at the given offset.
bm::Header::size
size_type size() const noexcept
Returns the number of fields in the header.
Definition: headers.h:232
bm::Header::begin
iterator begin()
NC.
Definition: headers.h:237
bm::NamedP4Object::get_id
p4object_id_t get_id() const
Get the compiler-provided id.
Definition: named_p4object.h:53
bm::Header::get_nbytes_packet
int get_nbytes_packet() const
Definition: headers.h:164
fields.h
bm::Header::mark_invalid
void mark_invalid()
Marks the header as not-valid.
bm::Header::end
const_iterator end() const
NC.
Definition: headers.h:246
bm::Header
Definition: headers.h:147
bm::Header::is_metadata
bool is_metadata() const
Returns true if this header represents metadata.
Definition: headers.h:176
bm::PHV
Definition: phv.h:68
bm::Header::operator[]
reference operator[](size_type n)
Definition: headers.h:250
bm::Header::is_VL_header
bool is_VL_header() const
Definition: headers.h:221