Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SAIP4] Model multicast. #547

Closed
wants to merge 3 commits into from
Closed
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion sai_p4/fixed/BUILD.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ filegroup(
name = "fixed",
srcs = [
"bitwidths.p4",
"drop_martians.p4",
"bmv2_intrinsics.h",
"drop_martians.p4",
"headers.p4",
"ids.h",
"ipv4_checksum.p4",
Expand Down
6 changes: 6 additions & 0 deletions sai_p4/fixed/bitwidths.p4
Original file line number Diff line number Diff line change
Expand Up @@ -45,4 +45,10 @@
#define TUNNEL_ID_BITWIDTH 16
#endif

// Inherited from v1model, see `standard_metadata_t.mcast_grp`.
#define MULTICAST_GROUP_ID_BITWIDTH 16

// Inherited from v1model, see `standard_metadata_t.egress_rid`.
#define REPLICA_INSTANCE_BITWIDTH 16

#endif // SAI_BITWIDTHS_P4_
15 changes: 15 additions & 0 deletions sai_p4/fixed/bmv2_intrinsics.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
#ifndef PINS_INFRA_SAI_P4_FIXED_BMV2_INTRINSICS_H_
#define PINS_INFRA_SAI_P4_FIXED_BMV2_INTRINSICS_H_

// Possible values of the v1model `standard_metadata_t` field `instance_type` in
// BMv2. The semantics of these values is explained here:
// https://github.com/p4lang/behavioral-model/blob/main/docs/simple_switch.md
#define PKT_INSTANCE_TYPE_NORMAL 0
#define PKT_INSTANCE_TYPE_INGRESS_CLONE 1
#define PKT_INSTANCE_TYPE_EGRESS_CLONE 2
#define PKT_INSTANCE_TYPE_COALESCED 3
#define PKT_INSTANCE_TYPE_INGRESS_RECIRC 4
#define PKT_INSTANCE_TYPE_REPLICATION 5
#define PKT_INSTANCE_TYPE_RESUBMIT 6

#endif // PINS_INFRA_SAI_P4_FIXED_BMV2_INTRINSICS_H_
10 changes: 8 additions & 2 deletions sai_p4/fixed/ids.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@
#define ROUTING_IPV4_TABLE_ID 0x02000044 // 33554500
#define ROUTING_IPV6_TABLE_ID 0x02000045 // 33554501
#define ROUTING_VRF_TABLE_ID 0x0200004A // 33554506
#define ROUTING_MULTICAST_SRC_MAC_TABLE_ID 0x0200004C // 33554508
#define MIRROR_SESSION_TABLE_ID 0x02000046 // 33554502
#define L3_ADMIT_TABLE_ID 0x02000047 // 33554503
#define MIRROR_PORT_TO_PRE_SESSION_TABLE_ID 0x02000048 // 33554504
#define ECMP_HASHING_TABLE_ID 0x02000049 // 33554505
#define ROUTING_TUNNEL_TABLE_ID 0x02000050 // 33554512
#define IPV6_TUNNEL_TERMINATION_TABLE_ID 0x0200004B // 33554507
// Next available table id: 0x0200004C (33554508)
// Next available table id: 0x0200004D (33554509)

// --- Actions -----------------------------------------------------------------

Expand All @@ -37,10 +38,15 @@
#define ROUTING_SET_WCMP_GROUP_ID_ACTION_ID 0x01000004 // 16777220
#define ROUTING_SET_WCMP_GROUP_ID_AND_METADATA_ACTION_ID 0x01000011 // 16777233
#define ROUTING_SET_NEXTHOP_ID_ACTION_ID 0x01000005 // 16777221
#define ROUTING_SET_IP_NEXTHOP_AND_DISABLE_REWRITES_ACTION_ID \
0x01000017
// 16777239
#define ROUTING_SET_NEXTHOP_ID_AND_METADATA_ACTION_ID 0x01000010 // 16777232
#define ROUTING_DROP_ACTION_ID 0x01000006 // 16777222
#define ROUTING_SET_P2P_TUNNEL_ENCAP_NEXTHOP_ACTION_ID 0x01000012 // 16777234
#define ROUTING_MARK_FOR_P2P_TUNNEL_ENCAP_ACTION_ID 0x01000013 // 16777235
#define ROUTING_SET_MULTICAST_GROUP_ID_ACTION_ID 0x01000018 // 16777240
#define ROUTING_SET_MULTICAST_SRC_MAC_ACTION_ID 0x01000019 // 16777241
#define MIRRORING_MIRROR_AS_IPV4_ERSPAN_ACTION_ID 0x01000007 // 16777223
#define L3_ADMIT_ACTION_ID 0x01000008 // 16777224
#define MIRRORING_SET_PRE_SESSION_ACTION_ID 0x01000009 // 16777225
Expand All @@ -52,7 +58,7 @@
#define TRAP_ACTION_ID 0x0100000F // 16777231
#define ROUTING_SET_METADATA_AND_DROP_ACTION_ID 0x01000015 // 16777237
#define MARK_FOR_TUNNEL_DECAP_AND_SET_VRF_ACTION_ID 0x01000016 // 16777238
// Next available action id: 0x01000017 (16777239)
// Next available action id: 0x0100001A (16777242)

// --- Action Profiles and Selectors (8 most significant bits = 0x11) ----------
// This value should ideally be 0x11000001, but we currently have this value for
Expand Down
8 changes: 8 additions & 0 deletions sai_p4/fixed/metadata.p4
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,8 @@ type bit<QOS_QUEUE_BITWIDTH> qos_queue_t;

typedef bit<ROUTE_METADATA_BITWIDTH> route_metadata_t;
typedef bit<ACL_METADATA_BITWIDTH> acl_metadata_t;
typedef bit<MULTICAST_GROUP_ID_BITWIDTH> multicast_group_id_t;
typedef bit<REPLICA_INSTANCE_BITWIDTH> replica_instance_t;

// -- Meters -------------------------------------------------------------------

Expand Down Expand Up @@ -197,7 +199,13 @@ struct local_metadata_t {
bool vlan_id_valid; // True iff `vlan_id` is valid.
bool admit_to_l3;
vrf_id_t vrf_id;

// Rewrite related fields.
bool enable_ttl_rewrite;
bool enable_src_mac_rewrite;
bool enable_dst_mac_rewrite;
packet_rewrites_t packet_rewrites;

bit<16> l4_src_port;
bit<16> l4_dst_port;
bit<WCMP_SELECTOR_INPUT_BITWIDTH> wcmp_selector_input;
Expand Down
4 changes: 4 additions & 0 deletions sai_p4/fixed/minimum_guaranteed_sizes.p4
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@
#define ROUTING_TUNNEL_TABLE_MINIMUM_GUARANTEED_SIZE 0
#endif

#ifndef ROUTING_MULTICAST_SOURCE_MAC_TABLE_MINIMUM_GUARANTEED_SIZE
#define ROUTING_MULTICAST_SOURCE_MAC_TABLE_MINIMUM_GUARANTEED_SIZE 0
#endif

#ifndef L3_ADMIT_TABLE_MINIMUM_GUARANTEED_SIZE
#define L3_ADMIT_TABLE_MINIMUM_GUARANTEED_SIZE 0
#endif
Expand Down
111 changes: 99 additions & 12 deletions sai_p4/fixed/packet_rewrites.p4
Original file line number Diff line number Diff line change
Expand Up @@ -5,31 +5,118 @@
#include "headers.p4"
#include "metadata.p4"
#include "minimum_guaranteed_sizes.p4"
#include "bmv2_intrinsics.h"

// This control block applies the rewrites computed during the the ingress
// To be applied only for multicast-replicated packets, i.e. packets with
// `standard_metadata.instance_type == PKT_INSTANCE_TYPE_REPLICATION`.
// In P4Runtime, these are packets created by a `Replica` of a
// `MulticastGroupEntry`.
control multicast_rewrites(inout local_metadata_t local_metadata,
in standard_metadata_t standard_metadata) {
// The egress port of the multicast-replicated packet.
// In P4Runtime, equal to the `port` value of the `Replica` of the
// `MulticastGroupEntry` that created this packet.
port_id_t multicast_replica_port = (port_id_t) standard_metadata.egress_port;

// The instance number of the multicast-replicated packet.
// In P4Runtime, equal to the `instance` value of the `Replica` of the
// `MulticastGroupEntry` that created this packet.
replica_instance_t multicast_replica_instance =
standard_metadata.egress_rid;

@id(ROUTING_SET_MULTICAST_SRC_MAC_ACTION_ID)
action set_multicast_src_mac(@id(1) @format(MAC_ADDRESS)
ethernet_addr_t src_mac) {
local_metadata.enable_src_mac_rewrite = true;
local_metadata.packet_rewrites.src_mac = src_mac;
}

// Rewrites the source MAC of the multicast-replicated packet.
//
// This is a logical table that does not exist in SAI and that is managed by
// Orchagent. There is a many-to-one correspondence between entries in this
// table and SAI Router Interfaces (RIFs). Each entry corresponds to a RIF
// with the following attributes:
// * `SAI_ROUTER_INTERFACE_ATTR_PORT_ID` is equal to `multicast_replica_port`.
// * `SAI_ROUTER_INTERFACE_ATTR_SRC_MAC_ADDRESS` is equal to the `src_mac`
// parameter of the `set_multicast_src_mac` action.
//
// Orchagent maintains a mapping from entries to RIFs, creating and destroying
// (possibly shared) RIFs as entries are inserted and deleted.
//
// When creating a multicast group member (`SAI_IPMC_GROUP_MEMBER`) from a
// P4Runtime `Replica`, Orchagent will use this table to set the value of the
// `SAI_IPMC_GROUP_MEMBER_ATTR_IPMC_OUTPUT_ID` attribute: it will expect to
// find an entry for the replica's port and instance in this table, and will
// use the ID of the RIF associated with that entry.
// This will cause the source MAC of packets generated by the group member to
// be rewritten to the `src_mac` of the `set_multicast_src_mac` action of the
// entry.
//
// TODO: Remove `@unsupported` annotation once the switch stack
// supports this table.
@unsupported
@p4runtime_role(P4RUNTIME_ROLE_ROUTING)
@id(ROUTING_MULTICAST_SRC_MAC_TABLE_ID)
table multicast_source_mac_table {
key = {
multicast_replica_port : exact
// TODO: Add this once supported by PDPI and its customers.
// @referenced_by(multicast_group_table, replica.port)
@id(1);
multicast_replica_instance : exact
// TODO: Add this once supported by PDPI and its customers.
// @referenced_by(multicast_group_table, replica.instance)
@id(2);
}
actions = {
@proto_id(1) set_multicast_src_mac;
}
size = ROUTING_MULTICAST_SOURCE_MAC_TABLE_MINIMUM_GUARANTEED_SIZE;
}

apply {
multicast_source_mac_table.apply();
}
} // control multicast_rewrites

// This control block applies the rewrites computed during the ingress
// stage to the actual packet.
control packet_rewrites(inout headers_t headers,
in local_metadata_t local_metadata,
inout local_metadata_t local_metadata,
inout standard_metadata_t standard_metadata) {
apply {
if (local_metadata.admit_to_l3) {
headers.ethernet.src_addr = local_metadata.packet_rewrites.src_mac;
headers.ethernet.dst_addr = local_metadata.packet_rewrites.dst_mac;
if (standard_metadata.instance_type == PKT_INSTANCE_TYPE_REPLICATION) {
// TODO: Remove guard once p4-symbolic suports assertions.
#ifndef PLATFORM_P4SYMBOLIC
assert(local_metadata.admit_to_l3);
#endif
local_metadata.enable_ttl_rewrite = true;
multicast_rewrites.apply(local_metadata, standard_metadata);
}

if (local_metadata.admit_to_l3){
if (local_metadata.enable_src_mac_rewrite) {
headers.ethernet.src_addr = local_metadata.packet_rewrites.src_mac;
}
if (local_metadata.enable_dst_mac_rewrite) {
headers.ethernet.dst_addr = local_metadata.packet_rewrites.dst_mac;
}
if (headers.ipv4.isValid()) {
if (headers.ipv4.ttl <= 1) {
mark_to_drop(standard_metadata);
} else {
if (headers.ipv4.ttl > 0 && local_metadata.enable_ttl_rewrite) {
headers.ipv4.ttl = headers.ipv4.ttl - 1;
}
// TODO: Verify this is accurate when TTL rewrite is
// disabled and update this code if not.
if (headers.ipv4.ttl == 0) mark_to_drop(standard_metadata);
}

if (headers.ipv6.isValid()) {
if (headers.ipv6.hop_limit <= 1) {
mark_to_drop(standard_metadata);
} else {
if (headers.ipv6.hop_limit > 0 && local_metadata.enable_ttl_rewrite) {
headers.ipv6.hop_limit = headers.ipv6.hop_limit - 1;
}
// TODO: Verify this is accurate when TTL rewrite is
// disabled and update this code if not.
if (headers.ipv6.hop_limit == 0) mark_to_drop(standard_metadata);
}
}
}
Expand Down
3 changes: 3 additions & 0 deletions sai_p4/fixed/parser.p4
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,9 @@ parser packet_parser(packet_in packet, out headers_t headers,
// Initialize local metadata fields.
local_metadata.admit_to_l3 = false;
local_metadata.vrf_id = kDefaultVrf;
local_metadata.enable_ttl_rewrite = false;
local_metadata.enable_src_mac_rewrite = false;
local_metadata.enable_dst_mac_rewrite = false;
local_metadata.packet_rewrites.src_mac = 0;
local_metadata.packet_rewrites.dst_mac = 0;
local_metadata.l4_src_port = 0;
Expand Down
Loading
Loading