Skip to content

[feature] ASIC-focused multicast replication and dendrite API #14

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

Merged
merged 28 commits into from
Jul 16, 2025
Merged
Show file tree
Hide file tree
Changes from 26 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
df62508
[feature] ASIC-focused 1st draft of multicast PRE
zeeshanlakhani Mar 4, 2025
4a945a8
[fix] change stage max
zeeshanlakhani Apr 15, 2025
bb876fa
update chaos tables, revert any p4 formatting for review
zeeshanlakhani Apr 16, 2025
2dcb98e
[minor] comments/align
zeeshanlakhani Apr 16, 2025
3ef78f0
Merge remote-tracking branch 'origin/multicast' into zl/p4-mcast-3
zeeshanlakhani Apr 21, 2025
37498e4
[review] address first pass of review
zeeshanlakhani Apr 21, 2025
d4953df
[review+] meta -> metadata, fix test issues
zeeshanlakhani Apr 21, 2025
dbe684f
[stages] test back to 14
zeeshanlakhani Apr 21, 2025
5537794
..
zeeshanlakhani Apr 22, 2025
1e29a70
[review] validation and underlying api transactions
zeeshanlakhani Apr 23, 2025
8a9fd45
[major changes] Rework groups+dataplane to handle external/underlay/b…
zeeshanlakhani Apr 23, 2025
105a296
Merge remote-tracking branch 'origin/multicast' into zl/p4-mcast
zeeshanlakhani May 22, 2025
1c0e660
[minor] chaos and remove pub
zeeshanlakhani May 22, 2025
57804d1
[minor] openapi update
zeeshanlakhani May 22, 2025
e55ddbc
[update] link-local hop limit handling + counter categories
zeeshanlakhani Jun 3, 2025
09fcec0
Change API into internal/replication vs external
zeeshanlakhani Jun 19, 2025
e3dda26
Merge remote-tracking branch 'origin/multicast' into zl/p4-mcast
zeeshanlakhani Jun 21, 2025
da0c3b3
..
zeeshanlakhani Jun 22, 2025
7158e91
..
zeeshanlakhani Jun 23, 2025
5a26a07
[review] updates on lock handling, ipv6 use, more
zeeshanlakhani Jun 29, 2025
5c096e9
..
zeeshanlakhani Jun 30, 2025
8167280
..
zeeshanlakhani Jun 30, 2025
91cd396
..
zeeshanlakhani Jul 1, 2025
4d6d726
..
zeeshanlakhani Jul 1, 2025
21d9274
[review] updates: locking cleanup and scoped free id(s)
zeeshanlakhani Jul 3, 2025
6f4082e
[review] keep mcast group lock for entire action
zeeshanlakhani Jul 4, 2025
9660726
[review] last bits++
zeeshanlakhani Jul 10, 2025
a3a8abb
minor: squiggly
zeeshanlakhani Jul 10, 2025
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
6 changes: 3 additions & 3 deletions .github/buildomat/jobs/image.sh
Original file line number Diff line number Diff line change
Expand Up @@ -101,11 +101,11 @@ pfexec chown "$UID" /out

banner "P4 Codegen"
# Add gcc-12 so the p4 compiler can find cpp
# The tofino2 has 20 stages, but the current sidecar.p4 will fit into 14. We
# add the "--stages 14" here to detect if/when the program grows beyond that
# The tofino2 has 20 stages, but the current sidecar.p4 will fit into 18. We
# add the "--stages 18" here to detect if/when the program grows beyond that
# limit. It's not necessarily a problem if we grow, but given the limited space
# on the ASIC, we want to grow deliberatately and thoughtfully.
PATH=/opt/gcc-12/bin:$PATH cargo xtask codegen --stages 14
PATH=/opt/gcc-12/bin:$PATH cargo xtask codegen --stages 18

# Preserve all the diagnostics spit out by the compiler
mkdir -p /out/p4c-diags
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ p4_artifacts*
# Editor config
.vscode
.dir-locals.el
bacon.toml
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be removed?

Copy link
Contributor Author

@zeeshanlakhani zeeshanlakhani Jul 16, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I had been using it (and it is a tool, but fine to remove it).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's harmless. I just wasn't sure if you meant to leave it in or not. If you want to keep it, feel free.


# OS artifacts
.DS_Store
Expand Down
16 changes: 8 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ omicron-common = { git = "https://github.com/oxidecomputer/omicron", branch= "ma
oximeter = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
oximeter-producer = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
oximeter-instruments = { git = "https://github.com/oxidecomputer/omicron", branch = "main", default-features = false, features = ["kstat"] }
oxnet = { version = "0.1.1", default-features = false, features = ["schemars", "serde"] }
oxnet = { version = "0.1.2", default-features = false, features = ["schemars", "serde"] }
propolis = { git = "https://github.com/oxidecomputer/propolis" }
sled-agent-client = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
smf = { git = "https://github.com/illumos/smf-rs" }
Expand Down
25 changes: 23 additions & 2 deletions aal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,9 +202,15 @@ pub trait AsicOps {
/// For a given multicast group, return the number of ports assigned to it.
fn mc_port_count(&self, group_id: u16) -> AsicResult<usize>;

/// Add a port to a multicast group. The port is identified using its ASIC
/// Add a port to a multicast group. The port is identified using its ASIC
/// identifier.
fn mc_port_add(&self, group_id: u16, port: AsicId) -> AsicResult<()>;
fn mc_port_add(
&self,
group_id: u16,
port: AsicId,
rid: u16,
level_1_excl_id: u16,
) -> AsicResult<()>;

/// Remove a port from a multicast group. The port is identified using its ASIC
/// identifier.
Expand All @@ -216,6 +222,21 @@ pub trait AsicOps {
/// Destroy a multicast group.
fn mc_group_destroy(&self, group_id: u16) -> AsicResult<()>;

/// Check if a multicast group exists.
fn mc_group_exists(&self, group_id: u16) -> bool {
self.mc_domains().contains(&group_id)
}

/// Get the total number of multicast groups.
fn mc_groups_count(&self) -> AsicResult<usize>;

/// Set the maximum number of multicast nodes.
fn mc_set_max_nodes(
&self,
max_nodes: u32,
max_link_aggregated_nodes: u32,
) -> AsicResult<()>;

/// Get sidecar identifiers of the device being managed.
fn get_sidecar_identifiers(&self) -> AsicResult<impl SidecarIdentifiers>;

Expand Down
23 changes: 22 additions & 1 deletion aal/src/match_action.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ impl MatchData {
/// The MatchParse trait defines the behavior needed to convert a high-level
/// Match field into our intermediate representation.
pub trait MatchParse {
/// Return all the name sand values of the key fields as strings
/// Return all the names and values of the key fields as strings
fn key_values(&self) -> BTreeMap<String, String>;
/// Convert the key Struct to a MatchData struct
fn key_to_ir(&self) -> AsicResult<MatchData>;
Expand Down Expand Up @@ -452,6 +452,27 @@ impl From<bool> for ValueTypes {
}
}

impl TryFrom<&ValueTypes> for bool {
type Error = &'static str;

fn try_from(v: &ValueTypes) -> Result<Self, Self::Error> {
match v {
ValueTypes::U64(v) => {
if *v == 0 {
Ok(false)
} else if *v == 1 {
Ok(true)
} else {
Err("value not a boolean")
}
}
_ => Err("value not a boolean"),
}
}
}

unwrap_value_entry!(bool);

#[derive(Debug, Hash, Clone)]
pub enum ValueTypes {
U64(u64),
Expand Down
41 changes: 39 additions & 2 deletions asic/src/chaos/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,18 @@ impl TableChaos {
(table::SWITCH_IPV4_ADDR, v),
(table::SWITCH_IPV6_ADDR, v),
(table::NAT_INGRESS_IPV4, v),
(table::NAT_INGRESS_IPV6, v)
(table::NAT_INGRESS_IPV6, v),
(table::MCAST_NAT_INGRESS_IPV4, v),
(table::MCAST_NAT_INGRESS_IPV6, v),
(table::MCAST_REPLICATION_IPV4, v),
(table::MCAST_REPLICATION_IPV6, v),
(table::MCAST_SRC_FILTER_IPV4, v),
(table::MCAST_SRC_FILTER_IPV6, v),
(table::MCAST_ROUTE_IPV4, v),
(table::MCAST_ROUTE_IPV6, v),
(table::MCAST_MAC_REWRITE, v),
(table::MCAST_DECAP_PORTS, v),
(table::MCAST_PORT_ID_MAPPING, v)
)
}

Expand Down Expand Up @@ -141,6 +152,8 @@ pub struct AsicConfig {
pub mc_port_remove: Chaos,
pub mc_group_create: Chaos,
pub mc_group_destroy: Chaos,
pub mc_groups_count: Chaos,
pub mc_set_max_nodes: Chaos,
pub get_sidecar_identifiers: Chaos,
pub table_new: TableChaos,
pub table_clear: TableChaos,
Expand Down Expand Up @@ -177,6 +190,8 @@ impl AsicConfig {
mc_port_remove: Chaos::new(v),
mc_group_create: Chaos::new(v),
mc_group_destroy: Chaos::new(v),
mc_groups_count: Chaos::new(v),
mc_set_max_nodes: Chaos::new(v),
get_sidecar_identifiers: Chaos::new(v),
table_new: TableChaos::uniform(v),
table_clear: TableChaos::uniform(v),
Expand All @@ -203,6 +218,7 @@ impl AsicConfig {
port_enable_get: Chaos::new(v),
connector_avail_channels: Chaos::new(v),
mc_port_count: Chaos::new(v),
mc_groups_count: Chaos::new(v),
get_sidecar_identifiers: Chaos::new(v),
..Default::default()
}
Expand All @@ -224,6 +240,7 @@ impl AsicConfig {
mc_port_remove: Chaos::new(v),
mc_group_create: Chaos::new(v),
mc_group_destroy: Chaos::new(v),
mc_set_max_nodes: Chaos::new(v),
// TODO this can cause dpd to fail to start
//table_clear: TableChaos::uniform(v),
table_default_set: TableChaos::uniform(v),
Expand Down Expand Up @@ -476,7 +493,13 @@ impl AsicOps for Handle {
Ok(self.ports.lock().unwrap().len())
}

fn mc_port_add(&self, _group_id: u16, _port: u16) -> AsicResult<()> {
fn mc_port_add(
&self,
_group_id: u16,
_port: u16,
_rid: u16,
_level1_excl_id: u16,
) -> AsicResult<()> {
unfurl!(self, mc_port_add);
Err(AsicError::OperationUnsupported)
}
Expand All @@ -496,6 +519,20 @@ impl AsicOps for Handle {
Ok(())
}

fn mc_groups_count(&self) -> AsicResult<usize> {
unfurl!(self, mc_groups_count);
Ok(self.ports.lock().unwrap().len())
}

fn mc_set_max_nodes(
&self,
_max_nodes: u32,
_max_link_aggregated_nodes: u32,
) -> AsicResult<()> {
unfurl!(self, mc_set_max_nodes);
Ok(())
}

fn get_sidecar_identifiers(&self) -> AsicResult<impl SidecarIdentifiers> {
unfurl!(self, get_sidecar_identifiers);
Ok(Identifiers::default())
Expand Down
22 changes: 22 additions & 0 deletions asic/src/chaos/table.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,28 @@ pub const SWITCH_IPV4_ADDR: &str = "pipe.Ingress.filter.switch_ipv4_addr";
pub const SWITCH_IPV6_ADDR: &str = "pipe.Ingress.filter.switch_ipv6_addr";
pub const NAT_INGRESS_IPV4: &str = "pipe.Ingress.nat_ingress.ingress_ipv4";
pub const NAT_INGRESS_IPV6: &str = "pipe.Ingress.nat_ingress.ingress_ipv6";
pub(crate) const MCAST_NAT_INGRESS_IPV4: &str =
"pipe.Ingress.nat_ingress.ingress_ipv4_mcast";
pub(crate) const MCAST_NAT_INGRESS_IPV6: &str =
"pipe.Ingress.nat_ingress.ingress_ipv6_mcast";
pub(crate) const MCAST_REPLICATION_IPV4: &str =
"pipe.Ingress.mcast_ingress.mcast_replication_ipv4";
pub(crate) const MCAST_REPLICATION_IPV6: &str =
"pipe.Ingress.mcast_ingress.mcast_replication_ipv6";
pub(crate) const MCAST_SRC_FILTER_IPV4: &str =
"pipe.Ingress.mcast_ingress.mcast_source_filter_ipv4";
pub(crate) const MCAST_SRC_FILTER_IPV6: &str =
"pipe.Ingress.mcast_ingress.mcast_source_filter_ipv6";
pub(crate) const MCAST_ROUTE_IPV4: &str =
"pipe.Ingress.l3_router.MulticastRouter4.tbl";
pub(crate) const MCAST_ROUTE_IPV6: &str =
"pipe.Ingress.l3_router.MulticastRouter6.tbl";
pub(crate) const MCAST_MAC_REWRITE: &str =
"pipe.Egress.mac_rewrite.mac_rewrite";
pub(crate) const MCAST_DECAP_PORTS: &str =
"pipe.Egress.mcast_egress.tbl_decap_ports";
pub(crate) const MCAST_PORT_ID_MAPPING: &str =
"pipe.Egress.mcast_egress.asic_id_to_port";

pub struct Table {
name: String,
Expand Down
20 changes: 19 additions & 1 deletion asic/src/softnpu/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -349,7 +349,13 @@ impl AsicOps for Handle {
Ok(self.ports.lock().unwrap().len())
}

fn mc_port_add(&self, _group_id: u16, _port: u16) -> AsicResult<()> {
fn mc_port_add(
&self,
_group_id: u16,
_port: u16,
_rid: u16,
_level1_excl_id: u16,
) -> AsicResult<()> {
Err(AsicError::OperationUnsupported)
}

Expand All @@ -365,6 +371,18 @@ impl AsicOps for Handle {
Ok(())
}

fn mc_groups_count(&self) -> AsicResult<usize> {
Ok(self.ports.lock().unwrap().len())
}

fn mc_set_max_nodes(
&self,
_max_nodes: u32,
_max_link_aggregated_nodes: u32,
) -> AsicResult<()> {
Ok(())
}

fn get_sidecar_identifiers(&self) -> AsicResult<impl SidecarIdentifiers> {
Ok(Identifiers {
id: Uuid::new_v4(),
Expand Down
2 changes: 2 additions & 0 deletions asic/src/tofino_asic/imported_bf_functions
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,13 @@ bf_mc_create_session
bf_mc_destroy_session
bf_mc_mgrp_create
bf_mc_mgrp_destroy
bf_mc_mgrp_get_count
bf_mc_node_create
bf_mc_node_destroy
bf_mc_node_update
bf_mc_associate_node
bf_mc_dissociate_node
bf_mc_set_max_node_threshold

# bf_rt calls
bf_rt_table_from_name_get
Expand Down
Loading