bmv2
Designing your own switch target with bmv2
|
Public Member Functions | |
packet_id_t | get_packet_id () const |
int | get_egress_port () const |
int | get_ingress_port () const |
Get the ingress_port of the packet. More... | |
void | set_egress_port (int port) |
Set the egress_port of the packet, which is the target responsibility. More... | |
copy_id_t | get_copy_id () const |
const std::string | get_unique_id () const |
int | get_ingress_length () const |
void | set_ingress_length (int length) |
size_t | get_data_size () const |
char * | data () |
const char * | data () const |
const buffer_state_t | save_buffer_state () const |
void | restore_buffer_state (const buffer_state_t &state) |
See save_buffer_state() More... | |
void | truncate (size_t length) |
uint64_t | get_signature () const |
Get a 64-bit hash of the incoming packet data. More... | |
PHV * | get_phv () |
Get a pointer to the packet's phv. More... | |
const PHV * | get_phv () const |
Get a pointer to the packet's phv. More... | |
void | set_register (size_t idx, uint64_t v) |
Write to general purpose register at index idx . More... | |
uint64_t | get_register (size_t idx) |
Read general purpose register at index idx . More... | |
size_t | get_entry_index () const |
ErrorCode | get_error_code () const |
bool | get_checksum_error () const |
void | mark_for_exit () |
void | reset_exit () |
bool | is_marked_for_exit () const |
void | change_context (cxt_id_t new_cxt) |
cxt_id_t | get_context () const |
Returns the id of the Context this packet currently belongs to. More... | |
Packet | clone_with_phv () const |
std::unique_ptr< Packet > | clone_with_phv_ptr () const |
Packet | clone_with_phv_reset_metadata () const |
std::unique_ptr< Packet > | clone_with_phv_reset_metadata_ptr () const |
Packet | clone_no_phv () const |
std::unique_ptr< Packet > | clone_no_phv_ptr () const |
Packet | clone_choose_context (cxt_id_t new_cxt) const |
std::unique_ptr< Packet > | clone_choose_context_ptr (cxt_id_t new_cxt) const |
Packet (const Packet &other)=delete | |
Deleted copy constructor. More... | |
Packet & | operator= (const Packet &other)=delete |
Deleted copy assignment operator. More... | |
Packet (Packet &&other) noexcept | |
Move constructor. More... | |
Packet & | operator= (Packet &&other) noexcept |
Move assignment operator. More... | |
Static Public Attributes | |
static constexpr size_t | nb_registers = 4u |
Number of general purpose registers per packet. More... | |
One of the most fundamental classes of bmv2. Used to represent a data packet while it traverses the switch. Even when a packet is parsed / deparsed mutliple times, the same Packet instance is used to represent it. If a Packet needs to be duplicated (for cloning, multicast, ...), a new Packet instance is created, using one of the available clone functions.
This class is final
, so if the Packet class needs to be extended in your target, you will need to use composition, not inheritance. We weigh the pros and cons, and in the end we decided that preventing the Packet class from being subclassed was safer. It does come at a cost though (in action primitives, you can access the Packet instance, but not your target-specific packet class).
Note that in your target implementation, Packet instances should be created using SwitchWContexts::new_packet() / SwitchWContexts::new_packet_ptr() or Switch::new_packet() / Switch::new_packet_ptr() depending on your target design.
|
delete |
Deleted copy constructor.
|
noexcept |
Move constructor.
void bm::Packet::change_context | ( | cxt_id_t | new_cxt | ) |
Changes the context of the packet. You will only need to call this function if you target switch leverages the Context class and if your Packet instance changes contexts during its lifetime. This is needed because one can configure different contexts to support different header types, and the PHV templates for different contexts will therefore be different. When changing contexts, it is up to the user to 1) deparse the Packet in the old Context 2) call change_context 3) re-parse the Packet in the new Context. For example:
if new_cxt == cxt_id
, then this is a no-op, otherwise, release the old PHV and replace it with a new one, compatible with the new context
Packet bm::Packet::clone_choose_context | ( | cxt_id_t | new_cxt | ) | const |
Same as clone_no_phv(), but also changes the context id for the clone. See change_context() for more information on how a Packet instance belongs to a specific Context
std::unique_ptr<Packet> bm::Packet::clone_choose_context_ptr | ( | cxt_id_t | new_cxt | ) | const |
Same as clone_no_phv(), but also changes the context id for the clone. See change_context() for more information on how a Packet instance belongs to a specific Context
Packet bm::Packet::clone_no_phv | ( | ) | const |
Clone the current packet, without the PHV. The value of the fields in the clone will be undefined and should not be accessed before setting it first.
std::unique_ptr<Packet> bm::Packet::clone_no_phv_ptr | ( | ) | const |
Clone the current packet, without the PHV. The value of the fields in the clone will be undefined and should not be accessed before setting it first.
Packet bm::Packet::clone_with_phv | ( | ) | const |
Clone the current packet, along with its PHV. The value of all the fields (metadata and regular) will remain the same int the clone.
std::unique_ptr<Packet> bm::Packet::clone_with_phv_ptr | ( | ) | const |
Clone the current packet, along with its PHV. The value of all the fields (metadata and regular) will remain the same int the clone.
Packet bm::Packet::clone_with_phv_reset_metadata | ( | ) | const |
Clone the current packet, along with regular headers, but resets all the metadata fields (i.e. sets them to 0
) in the clone.
std::unique_ptr<Packet> bm::Packet::clone_with_phv_reset_metadata_ptr | ( | ) | const |
Clone the current packet, along with regular headers, but resets all the metadata fields (i.e. sets them to 0
) in the clone.
|
inline |
Returns a pointer to the packet data. Just after instantiating the packet, this will point to all the received packet data. After parsing, this will just be the packet payload. After deparsing, this will be data which needs to be sent out.
|
inline |
Returns a pointer to the packet data. Just after instantiating the packet, this will point to all the received packet data. After parsing, this will just be the packet payload. After deparsing, this will be data which needs to be sent out.
|
inline |
|
inline |
Returns the id of the Context this packet currently belongs to.
|
inline |
Obtains the copy_id of a packet, used to differentiate all the clones generated from the same incoming data packet. See get_packet_id() for more information.
|
inline |
Returns the amount of packet data in the buffer (in bytes). This function will notably be called after deparsing, when the target is ready to transmit the packet.
|
inline |
Get the egress_port of this Packet. The egress_port needs to be set by the target using set_egress_port().
|
inline |
Get the index of the entry returned by the last match table lookup, or Packet::INVALID_ENTRY_INDEX if lookup was a miss.
|
inline |
|
inline |
Get the ingress_length for the packet, which is set when instantiating the packet. As the name indicates, this is the original length of the packet. This is not updated as headers are marked valid / invalid and the length of the outgoing packet may be different.
|
inline |
Get the ingress_port of the packet.
|
inline |
Obtain the packet_id. The packet_id is the one assigned by the target when the packet was instantiated. We recommend using a counter initialized to 0
and incremented every time a new packet is received "on the
wire". Packet instances obtained by cloning a given packet receives the same packet_id as that packet. In other words, this packet_id identifies all Packet instances produced by the switch in response to the same incoming data packet. The clones can be differentiated using the copy_id.
|
inline |
Get a pointer to the packet's phv.
|
inline |
Get a pointer to the packet's phv.
|
inline |
Read general purpose register at index idx
.
|
inline |
Get a 64-bit hash of the incoming packet data.
|
inline |
Get a unique string id for this packet. It is simply packet_id + "." + copy_id
.
|
inline |
Returns true iff the packet is marked for exit (i.e. mark_for_exit() was called on the packet).
|
inline |
Mark the packet for exit by setting an exit flag. If this is called from an action, the current pipeline will be interrupted as soon as the current table is done processing the packet. This effectively skips the rest of the pipeline. Do not forget to call reset_exit() at the end of the pipeline, if you intend the packet to go through another pipeline afterwards; otherwise this other pipeline will just be skipped as well. If this method is called from outside of an action, the flag will take effect at the next pipeline, which will be skipped entirely (not a single table will be applied).
|
inline |
Clear the exit flag, which may have been set by an earlier call to mark_for_exit().
|
inline |
|
inline |
Saves the current state of the packet data buffer. Even if the buffer state is then modified, the state can be restored by providing the return value of this function to restore_buffer_state().
|
inline |
Set the egress_port of the packet, which is the target responsibility.
|
inline |
Sets the ingress_length. This may be needed for some architectures, although usually it is better to create a new Packet object. See get_ingress_length() for more information about ingress_length.
|
inline |
Write to general purpose register at index idx
.
|
inline |
Truncate the packet to the given length
. The truncation will only be enforced when calling get_data_size(). When calling truncate multiple times, the smallest provided length
value will be used.
|
staticconstexpr |
Number of general purpose registers per packet.