bmv2
Designing your own switch target with bmv2
Loading...
Searching...
No Matches
phv.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_PHV_H_
24#define BM_BM_SIM_PHV_H_
25
26#include <vector>
27#include <unordered_map>
28#include <string>
29#include <functional>
30#include <set>
31#include <unordered_set>
32#include <map>
33#include <memory>
34
35#include <cassert>
36
37#include "fields.h"
38#include "headers.h"
39#include "header_unions.h"
40#include "stacks.h"
41#include "named_p4object.h"
42#include "expressions.h"
43
44namespace bm {
45
46using header_id_t = p4object_id_t;
47
48// forward declaration
49class PHVFactory;
50
68class PHV {
69 using HeaderRef = std::reference_wrapper<Header>;
70 using FieldRef = std::reference_wrapper<Field>;
71
72 public:
73 friend class PHVFactory;
74 friend class Packet;
75
76 using HeaderNamesMap = std::unordered_map<std::string, HeaderRef>;
79 using header_name_iterator = HeaderNamesMap::iterator;
81 using const_header_name_iterator = HeaderNamesMap::const_iterator;
82
83 using FieldNamesMap = std::unordered_map<std::string, FieldRef>;
84
86 using header_iterator = std::vector<Header>::iterator;
88 using const_header_iterator = std::vector<Header>::const_iterator;
89
90 public:
91 PHV() {}
92
93 PHV(size_t num_headers, size_t num_header_stacks,
94 size_t num_header_unions, size_t num_header_union_stacks);
95
97 Header &get_header(header_id_t header_index) {
98 return headers[header_index];
99 }
100
102 const Header &get_header(header_id_t header_index) const {
103 return headers[header_index];
104 }
105
109 Header &get_header(const std::string &header_name) {
110 return headers_map.at(header_name);
111 }
112
114 const Header &get_header(const std::string &header_name) const {
115 return headers_map.at(header_name);
116 }
117
119 bool has_header(const std::string &header_name) const {
120 auto it = headers_map.find(header_name);
121 return (it != headers_map.end());
122 }
123
128 Field &get_field(header_id_t header_index, int field_offset) {
129 return headers[header_index].get_field(field_offset);
130 }
131
133 const Field &get_field(header_id_t header_index, int field_offset) const {
134 return headers[header_index].get_field(field_offset);
135 }
136
140 Field &get_field(const std::string &field_name) {
141 return fields_map.at(field_name);
142 }
143
145 const Field &get_field(const std::string &field_name) const {
146 return fields_map.at(field_name);
147 }
148
151 bool has_field(const std::string &field_name) const {
152 auto it = fields_map.find(field_name);
153 return (it != fields_map.end());
154 }
155
158 HeaderStack &get_header_stack(header_stack_id_t header_stack_index) {
159 return header_stacks[header_stack_index];
160 }
161
164 header_stack_id_t header_stack_index) const {
165 return header_stacks[header_stack_index];
166 }
167
170 HeaderUnion &get_header_union(header_union_id_t header_union_index) {
171 return header_unions[header_union_index];
172 }
173
176 header_union_id_t header_union_index) const {
177 return header_unions[header_union_index];
178 }
179
183 header_union_stack_id_t header_union_stack_index) {
184 return header_union_stacks[header_union_stack_index];
185 }
186
190 header_union_stack_id_t header_union_stack_index) const {
191 return header_union_stacks[header_union_stack_index];
192 }
193
195 void reset();
196
200
205
208
213 void set_written_to(bool written_to_value);
214
216 PHV(const PHV &other) = delete;
218 PHV &operator=(const PHV &other) = delete;
219
221 PHV(PHV &&other) = default;
223 PHV &operator=(PHV &&other) = default;
224
232 void copy_headers(const PHV &src);
233
234 void set_packet_id(const uint64_t id1, const uint64_t id2) {
235 packet_id = {id1, id2};
236 }
237
238 // iterators
239
248 return headers_map.begin();
249 }
250
253 return headers_map.begin();
254 }
255
259 return headers_map.end();
260 }
261
264 return headers_map.end();
265 }
266
272 header_iterator header_begin() { return headers.begin(); }
273
275 const_header_iterator header_begin() const { return headers.begin(); }
276
278 header_iterator header_end() { return headers.end(); }
279
281 const_header_iterator header_end() const { return headers.end(); }
282
284 size_t num_headers() const { return headers.size(); }
285
288 const std::string get_field_name(header_id_t header_index,
289 int field_offset) const;
290
291 private:
292 // To be used only by PHVFactory
293 // all headers need to be pushed back in order (according to header_index) !!!
294 // TODO(antonin): remove this constraint?
295 void push_back_header(const std::string &header_name,
296 header_id_t header_index,
297 const HeaderType &header_type,
298 const std::set<int> &arith_offsets,
299 const bool metadata);
300
301 void push_back_header_stack(const std::string &header_stack_name,
302 header_stack_id_t header_stack_index,
303 const HeaderType &header_type,
304 const std::vector<header_id_t> &header_ids);
305
306 void push_back_header_union(const std::string &header_union_name,
307 header_union_id_t header_union_index,
308 const std::vector<header_id_t> &header_ids);
309
310 void push_back_header_union_stack(
311 const std::string &header_union_stack_name,
312 header_union_stack_id_t header_union_stack_index,
313 const std::vector<header_union_id_t> &header_union_ids);
314
315 // get_field(from) will be equivalent to get_field(to)
316 // 'to' needs to be a valid field name (or a previously inserted alias)
317 // 'from' (the alias) does not need to adhere to the "hdr.f" naming convention
318 void add_field_alias(const std::string &from, const std::string &to);
319
320 private:
321 std::vector<Header> headers{};
322 std::vector<HeaderStack> header_stacks{};
323 std::vector<HeaderUnion> header_unions{};
324 std::vector<HeaderUnionStack> header_union_stacks{};
325 HeaderNamesMap headers_map{};
326 FieldNamesMap fields_map{};
327 size_t capacity{0};
328 size_t capacity_stacks{0};
329 size_t capacity_unions{0};
330 size_t capacity_union_stacks{0};
331 Debugger::PacketId packet_id;
332};
333
334class PHVFactory {
335 private:
336 struct HeaderDesc {
337 const std::string name;
338 header_id_t index;
339 const HeaderType &header_type;
340 std::set<int> arith_offsets{};
341 bool metadata;
342
343 HeaderDesc(const std::string &name, const header_id_t index,
344 const HeaderType &header_type, const bool metadata)
345 : name(name), index(index), header_type(header_type),
346 metadata(metadata) {
347 for (int offset = 0; offset < header_type.get_num_fields(); offset++) {
348 arith_offsets.insert(offset);
349 }
350 }
351 };
352
353 struct HeaderStackDesc {
354 const std::string name;
355 header_stack_id_t index;
356 const HeaderType &header_type;
357 std::vector<header_id_t> headers;
358
359 HeaderStackDesc(const std::string &name, const header_stack_id_t index,
360 const HeaderType &header_type,
361 const std::vector<header_id_t> &headers)
362 : name(name), index(index), header_type(header_type),
363 headers(headers) { }
364 };
365
366 struct HeaderUnionDesc {
367 const std::string name;
368 header_union_id_t index;
369 std::vector<header_id_t> headers;
370
371 HeaderUnionDesc(const std::string &name, const header_union_id_t index,
372 const std::vector<header_id_t> &headers)
373 : name(name), index(index), headers(headers) { }
374 };
375
376 struct HeaderUnionStackDesc {
377 const std::string name;
378 header_union_stack_id_t index;
379 std::vector<header_union_id_t> header_unions;
380
381 HeaderUnionStackDesc(const std::string &name,
382 const header_union_stack_id_t index,
383 const std::vector<header_union_id_t> &header_unions)
384 : name(name), index(index), header_unions(header_unions) { }
385 };
386
387 public:
388 void push_back_header(const std::string &header_name,
389 const header_id_t header_index,
390 const HeaderType &header_type,
391 const bool metadata = false);
392
393 void push_back_header_stack(const std::string &header_stack_name,
394 const header_stack_id_t header_stack_index,
395 const HeaderType &header_type,
396 const std::vector<header_id_t> &headers);
397
398 void push_back_header_union(const std::string &header_union_name,
399 const header_stack_id_t header_union_index,
400 const std::vector<header_id_t> &headers);
401
402 void push_back_header_union_stack(
403 const std::string &header_union_stack_name,
404 const header_union_stack_id_t header_union_stack_index,
405 const std::vector<header_union_id_t> &header_unions);
406
407 void add_field_alias(const std::string &from, const std::string &to);
408
409 const HeaderType &get_header_type(header_id_t header_id) const {
410 return header_descs.at(header_id).header_type;
411 }
412
413 const HeaderType &get_header_stack_type(
414 header_stack_id_t header_stack_id) const {
415 return header_stack_descs.at(header_stack_id).header_type;
416 }
417
418 void enable_field_arith(header_id_t header_id, int field_offset);
419
420 void enable_all_field_arith(header_id_t header_id);
421
422 void disable_field_arith(header_id_t header_id, int field_offset);
423
424 void disable_all_field_arith(header_id_t header_id);
425
426 void enable_stack_field_arith(header_stack_id_t header_stack_id,
427 int field_offset);
428
429 void enable_all_stack_field_arith(header_stack_id_t header_stack_id);
430
431 void enable_union_stack_field_arith(
432 header_union_stack_id_t header_union_stack_id, size_t header_offset,
433 int field_offset);
434
435 void enable_all_union_stack_field_arith(
436 header_union_stack_id_t header_union_stack_id, size_t header_offset);
437
438 void enable_all_union_stack_field_arith(
439 header_union_stack_id_t header_union_stack_id);
440
441 void enable_all_arith();
442
443 std::unique_ptr<PHV> create() const;
444
445 private:
446 std::map<header_id_t, HeaderDesc> header_descs{}; // sorted by header id
447 std::map<header_stack_id_t, HeaderStackDesc> header_stack_descs{};
448 std::map<header_union_id_t, HeaderUnionDesc> header_union_descs{};
449 std::map<header_union_stack_id_t, HeaderUnionStackDesc>
450 header_union_stack_descs{};
451 std::map<std::string, std::string> field_aliases{}; // order does not matter
452 std::unordered_set<std::string> field_names{}; // just for debugging
453};
454
455} // namespace bm
456
457#endif // BM_BM_SIM_PHV_H_
Definition fields.h:46
Definition header_unions.h:51
Definition headers.h:147
Definition phv.h:68
const HeaderUnion & get_header_union(header_union_id_t header_union_index) const
Definition phv.h:175
HeaderNamesMap::const_iterator const_header_name_iterator
Definition phv.h:81
const_header_iterator header_end() const
Returns an iterator to the last element in the PHV. See header_begin().
Definition phv.h:281
const std::string get_field_name(header_id_t header_index, int field_offset) const
header_name_iterator header_name_end()
Definition phv.h:258
const_header_name_iterator header_name_begin() const
Definition phv.h:252
PHV & operator=(const PHV &other)=delete
Deleted copy assignment operator.
void reset_metadata()
const Header & get_header(header_id_t header_index) const
Access the Header with id header_index, with no bound checking.
Definition phv.h:102
const HeaderUnionStack & get_header_union_stack(header_union_stack_id_t header_union_stack_index) const
Definition phv.h:189
HeaderUnion & get_header_union(header_union_id_t header_union_index)
Definition phv.h:170
header_iterator header_begin()
Definition phv.h:272
void reset()
Mark all Header instances in the PHV as invalid.
bool has_header(const std::string &header_name) const
Returns true if there exists a Header with name header_name in this PHV.
Definition phv.h:119
std::vector< Header >::const_iterator const_header_iterator
Used to iterate over headers in ascending id order.
Definition phv.h:88
Field & get_field(header_id_t header_index, int field_offset)
Definition phv.h:128
const Header & get_header(const std::string &header_name) const
Definition phv.h:114
bool has_field(const std::string &field_name) const
Definition phv.h:151
const_header_iterator header_begin() const
Definition phv.h:275
HeaderNamesMap::iterator header_name_iterator
Definition phv.h:79
header_name_iterator header_name_begin()
Definition phv.h:247
const_header_name_iterator header_name_end() const
Definition phv.h:263
Header & get_header(header_id_t header_index)
Access the Header with id header_index, with no bound checking.
Definition phv.h:97
HeaderUnionStack & get_header_union_stack(header_union_stack_id_t header_union_stack_index)
Definition phv.h:182
const Field & get_field(const std::string &field_name) const
Definition phv.h:145
void reset_headers()
Reset all header fields to 0.
std::vector< Header >::iterator header_iterator
Used to iterate over headers in ascending id order.
Definition phv.h:86
PHV(PHV &&other)=default
Default move constructor.
header_iterator header_end()
Returns an iterator to the last element in the PHV. See header_begin().
Definition phv.h:278
Field & get_field(const std::string &field_name)
Definition phv.h:140
Header & get_header(const std::string &header_name)
Definition phv.h:109
HeaderStack & get_header_stack(header_stack_id_t header_stack_index)
Definition phv.h:158
size_t num_headers() const
Returns the number of headers included in the PHV.
Definition phv.h:284
const Field & get_field(header_id_t header_index, int field_offset) const
Definition phv.h:133
void copy_headers(const PHV &src)
void reset_header_stacks()
PHV(const PHV &other)=delete
Deleted copy constructor.
PHV & operator=(PHV &&other)=default
Default move assignment operator.
void set_written_to(bool written_to_value)
const HeaderStack & get_header_stack(header_stack_id_t header_stack_index) const
Definition phv.h:163
Definition packet.h:98
detail::MyStack< Header > HeaderStack
Definition stacks.h:212
detail::MyStack< HeaderUnion > HeaderUnionStack
Definition stacks.h:223