bmv2
Designing your own switch target with bmv2
Loading...
Searching...
No Matches
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
37namespace bm {
38
39using header_type_id_t = p4object_id_t;
40
41class VLHeaderExpression;
42class ArithExpression;
43
44class HeaderUnion;
45
46class 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
147class 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
182
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_
Definition fields.h:46
Definition header_unions.h:51
Definition headers.h:147
const std::string & get_field_name(int field_offset) const
Returns a reference to the name of the field at the given offset.
const_reference operator[](size_type n) const
Definition headers.h:256
iterator end()
NC.
Definition headers.h:243
Field & get_field(int field_offset)
Definition headers.h:200
const std::string get_field_full_name(int field_offset) const
void mark_valid()
Marks the header as valid.
reference operator[](size_type n)
Definition headers.h:250
void set_written_to(bool written_to_value)
const Field & get_field(int field_offset) const
Definition headers.h:205
iterator begin()
NC.
Definition headers.h:237
size_type size() const noexcept
Returns the number of fields in the header.
Definition headers.h:232
const_iterator begin() const
NC.
Definition headers.h:240
void mark_invalid()
Marks the header as not-valid.
int get_nbytes_packet() const
Definition headers.h:164
header_type_id_t get_header_type_id() const
Definition headers.h:214
bool is_metadata() const
Returns true if this header represents metadata.
Definition headers.h:176
bool is_valid() const
Returns true if this header is marked valid.
Definition headers.h:171
bool is_VL_header() const
Definition headers.h:221
void reset()
Sets all the fields in the header to value 0.
const_iterator end() const
NC.
Definition headers.h:246
Definition named_p4object.h:39
p4object_id_t get_id() const
Get the compiler-provided id.
Definition named_p4object.h:53
Definition phv.h:68