Skip to content

Commit 94e91ca

Browse files
[multicast] Narrow admin-scoped to admin-local only (ff04::/16)
Previously, internal multicast groups accepted admin-scoped addresses including admin-local (ff04), site-local (ff05), and org-local (ff08). This narrows the scope to only admin-local (ff04::/16), which is what Omicron *now* dictates. - [ ] This should be merged after oxidecomputer/omicron#9450 is reviewed and merged into Omicron. We now make Dendrite/Dpd match Omicron consistently for validation. Key changes: - Remove IPV6_SITE_LOCAL_PATTERN and IPV6_ORG_SCOPE_PATTERN from P4 - Update P4 table entries to only match admin-local (size 4→2) - Add ADMIN_LOCAL_PREFIX const to dpd-types with RFC doc links - Update validation to use `is_admin_local_multicast()` from oxnet v0.1.4 - Bump to API version 2 for doc changes (only) - Update README with OpenAPI generation instructions - Use new multicast subnet constants from `omicron-common` for validation
1 parent 0aef4d5 commit 94e91ca

File tree

15 files changed

+10475
-243
lines changed

15 files changed

+10475
-243
lines changed

Cargo.lock

Lines changed: 664 additions & 86 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,11 @@ ispf = { git = "https://github.com/oxidecomputer/ispf" }
4646
gateway-client = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
4747
gateway-types = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
4848
nexus-client = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
49-
omicron-common = { git = "https://github.com/oxidecomputer/omicron", branch= "main" }
50-
oximeter = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
51-
oximeter-producer = { git = "https://github.com/oxidecomputer/omicron", branch = "main" }
52-
oximeter-instruments = { git = "https://github.com/oxidecomputer/omicron", branch = "main", default-features = false, features = ["kstat"] }
53-
oxnet = { version = "0.1.3", default-features = false, features = ["schemars", "serde"] }
49+
omicron-common = { git = "https://github.com/oxidecomputer/omicron", branch= "zl/mcast-implicit-lifecycle" }
50+
oximeter = { git = "https://github.com/oxidecomputer/omicron", branch = "zl/mcast-implicit-lifecycle" }
51+
oximeter-producer = { git = "https://github.com/oxidecomputer/omicron", branch = "zl/mcast-implicit-lifecycle" }
52+
oximeter-instruments = { git = "https://github.com/oxidecomputer/omicron", branch = "zl/mcast-implicit-lifecycle", default-features = false, features = ["kstat"] }
53+
oxnet = { version = "0.1.4", default-features = false, features = ["schemars", "serde"] }
5454
propolis = { git = "https://github.com/oxidecomputer/propolis" }
5555
smf = { git = "https://github.com/illumos/smf-rs" }
5656
softnpu-lib = { git = "https://github.com/oxidecomputer/softnpu" , package = "softnpu" , branch = "main"}

README.md

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -341,5 +341,14 @@ proxy_arp:
341341
3. run `SDE=/opt/oxide/tofino_sde cargo test --features=<feature>` to execute
342342
the tests.
343343

344-
If regenerating the openapi specifications, set `EXPECTORATE=overwrite` when
345-
runnning the tests with the `tofino_asic` feature.
344+
### OpenAPI Generation
345+
346+
`dpd-api/src/lib.rs` contains endpoint [dropshot][dropshot-gh] definitions and
347+
controls API versioning for the `dpd` OpenAPI interface. If you add/remove or
348+
edit API points and/or documentation, you can update the API version and
349+
regenerate the latest OpenAPI specification bindings by running
350+
`cargo xtask openapi generate`. Use `cargo xtask openapi check` to verify
351+
specs are up-to-date.
352+
353+
354+
[dropshot-gh]: https://github.com/oxidecomputer/dropshot

dpd-api/src/lib.rs

Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ api_versions!([
5656
// | example for the next person.
5757
// v
5858
// (next_int, IDENT),
59+
(2, MCAST_DOCS_ADMIN_LOCAL),
5960
(1, INITIAL),
6061
]);
6162

@@ -1431,7 +1432,7 @@ pub trait DpdApi {
14311432
/**
14321433
* Create an external-only multicast group configuration.
14331434
*
1434-
* External-only groups are used for IPv4 and non-admin-scoped IPv6 multicast
1435+
* External-only groups are used for IPv4 and non-admin-local IPv6 multicast
14351436
* traffic that doesn't require replication infrastructure. These groups use
14361437
* simple forwarding tables and require a NAT target.
14371438
*/
@@ -1450,9 +1451,10 @@ pub trait DpdApi {
14501451
/**
14511452
* Create an underlay (internal) multicast group configuration.
14521453
*
1453-
* Underlay groups are used for admin-scoped IPv6 multicast traffic that
1454-
* requires replication infrastructure. These groups support both external
1455-
* and underlay members with full replication capabilities.
1454+
* Underlay groups are used for admin-local IPv6 multicast traffic
1455+
* (ff04::/16, as defined in RFC 7346 and RFC 4291) that requires
1456+
* replication infrastructure. These groups support both external and
1457+
* underlay members with full replication capabilities.
14561458
*/
14571459
#[endpoint {
14581460
method = POST,
@@ -1502,10 +1504,10 @@ pub trait DpdApi {
15021504
) -> Result<HttpResponseOk<mcast::MulticastGroupResponse>, HttpError>;
15031505

15041506
/**
1505-
* Get an underlay (internal) multicast group configuration by admin-scoped
1507+
* Get an underlay (internal) multicast group configuration by admin-local
15061508
* IPv6 address.
15071509
*
1508-
* Underlay groups handle admin-scoped IPv6 multicast traffic with
1510+
* Underlay groups handle admin-local IPv6 multicast traffic (ff04::/16) with
15091511
* replication infrastructure for external and underlay members.
15101512
*/
15111513
#[endpoint {
@@ -1521,8 +1523,8 @@ pub trait DpdApi {
15211523
* Update an underlay (internal) multicast group configuration for a given
15221524
* group IP address.
15231525
*
1524-
* Underlay groups are used for admin-scoped IPv6 multicast traffic that
1525-
* requires replication infrastructure with external and underlay members.
1526+
* Underlay groups are used for admin-local IPv6 multicast traffic (ff04::/16)
1527+
* that requires replication infrastructure with external and underlay members.
15261528
*/
15271529
#[endpoint {
15281530
method = PUT,
@@ -1537,7 +1539,7 @@ pub trait DpdApi {
15371539
/**
15381540
* Update an external-only multicast group configuration for a given group IP address.
15391541
*
1540-
* External-only groups are used for IPv4 and non-admin-scoped IPv6 multicast
1542+
* External-only groups are used for IPv4 and non-admin-local IPv6 multicast
15411543
* traffic that doesn't require replication infrastructure.
15421544
*/
15431545
#[endpoint {
@@ -2270,8 +2272,11 @@ pub struct MulticastGroupIpParam {
22702272
pub group_ip: IpAddr,
22712273
}
22722274

2273-
/// Used to identify an underlay (internal) multicast group by admin-scoped IPv6
2274-
/// address.
2275+
/// Used to identify an underlay (internal) multicast group by admin-local IPv6
2276+
/// address (ff04::/16, as defined in [RFC 7346] and [RFC 4291]).
2277+
///
2278+
/// [RFC 7346]: https://www.rfc-editor.org/rfc/rfc7346.html
2279+
/// [RFC 4291]: https://www.rfc-editor.org/rfc/rfc4291.html
22752280
#[derive(Deserialize, Serialize, JsonSchema)]
22762281
pub struct MulticastUnderlayGroupIpParam {
22772282
pub group_ip: mcast::AdminScopedIpv6,

dpd-client/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ packet = { path = "../packet" }
3333
pcap = { path = "../pcap" }
3434
asic = { path = "../asic" }
3535
anyhow.workspace = true
36+
dpd-types.workspace = true
3637
lazy_static.workspace = true
3738
parking_lot.workspace = true
3839
rand.workspace = true

dpd-client/tests/integration_tests/mcast.rs

Lines changed: 42 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ use crate::integration_tests::common::prelude::*;
1515
use ::common::network::MacAddr;
1616
use anyhow::anyhow;
1717
use dpd_client::{Error, types};
18+
use dpd_types::mcast::ADMIN_LOCAL_PREFIX;
1819
use futures::TryStreamExt;
1920
use oxnet::{Ipv4Net, MulticastMac};
2021
use packet::{Endpoint, eth, geneve, ipv4, ipv6, udp};
@@ -25,7 +26,8 @@ const MULTICAST_TEST_IPV6: Ipv6Addr =
2526
const MULTICAST_TEST_IPV4_SSM: Ipv4Addr = Ipv4Addr::new(232, 123, 45, 67);
2627
const MULTICAST_TEST_IPV6_SSM: Ipv6Addr =
2728
Ipv6Addr::new(0xff3e, 0, 0, 0, 0, 0, 0, 0x1111);
28-
const MULTICAST_NAT_IP: Ipv6Addr = Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 1);
29+
const MULTICAST_NAT_IP: Ipv6Addr =
30+
Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 1);
2931
const GIMLET_MAC: &str = "11:22:33:44:55:66";
3032
const GIMLET_IP: Ipv6Addr =
3133
Ipv6Addr::new(0xfd00, 0x1122, 0x7788, 0x0101, 0, 0, 0, 4);
@@ -121,12 +123,12 @@ async fn create_test_multicast_group(
121123
}
122124
IpAddr::V6(ipv6) => {
123125
if oxnet::Ipv6Net::new_unchecked(ipv6, 128)
124-
.is_admin_scoped_multicast()
126+
.is_admin_local_multicast()
125127
{
126-
// Admin-scoped IPv6 groups are internal
127-
let admin_scoped_ip = types::AdminScopedIpv6(ipv6);
128+
// Admin-local IPv6 groups are internal
129+
let admin_local_ip = types::AdminScopedIpv6(ipv6);
128130
let internal_entry = types::MulticastGroupCreateUnderlayEntry {
129-
group_ip: admin_scoped_ip,
131+
group_ip: admin_local_ip,
130132
tag: tag.map(String::from),
131133
members,
132134
};
@@ -146,7 +148,7 @@ async fn create_test_multicast_group(
146148
underlay_group_id: resp.underlay_group_id,
147149
}
148150
} else {
149-
// Non-admin-scoped IPv6 groups are external-only and require NAT targets
151+
// Non-admin-local IPv6 groups are external-only and require NAT targets
150152
let external_entry = types::MulticastGroupCreateExternalEntry {
151153
group_ip,
152154
tag: tag.map(String::from),
@@ -1154,9 +1156,9 @@ async fn test_api_internal_ipv6_underlay_only() -> TestResult {
11541156

11551157
let (port_id, link_id) = switch.link_id(PhysPort(11)).unwrap();
11561158

1157-
// Create admin-scoped IPv6 group with only underlay members
1159+
// Create admin-local IPv6 group with only underlay members
11581160
let underlay_only_group = types::MulticastGroupCreateUnderlayEntry {
1159-
group_ip: "ff05::200".parse().unwrap(),
1161+
group_ip: "ff04::200".parse().unwrap(),
11601162
tag: Some("test_underlay_only".to_string()),
11611163
members: vec![types::MulticastGroupMember {
11621164
port_id: port_id.clone(),
@@ -1169,7 +1171,7 @@ async fn test_api_internal_ipv6_underlay_only() -> TestResult {
11691171
.client
11701172
.multicast_group_create_underlay(&underlay_only_group)
11711173
.await
1172-
.expect("Should create underlay-only admin-scoped group")
1174+
.expect("Should create underlay-only admin-local group")
11731175
.into_inner();
11741176

11751177
// Verify only underlay members
@@ -1186,10 +1188,10 @@ async fn test_api_internal_ipv6_external_only() -> TestResult {
11861188

11871189
let (port_id, link_id) = switch.link_id(PhysPort(11)).unwrap();
11881190

1189-
// Create admin-scoped IPv6 group with only external members
1191+
// Create admin-local IPv6 group with only external members
11901192
let external_members_only_group =
11911193
types::MulticastGroupCreateUnderlayEntry {
1192-
group_ip: "ff08::300".parse().unwrap(),
1194+
group_ip: "ff04::300".parse().unwrap(),
11931195
tag: Some("test_external_members_only".to_string()),
11941196
members: vec![types::MulticastGroupMember {
11951197
port_id: port_id.clone(),
@@ -1292,10 +1294,10 @@ async fn test_api_invalid_combinations() -> TestResult {
12921294
match result {
12931295
Error::ErrorResponse(inner) => {
12941296
assert_eq!(inner.status(), 400);
1295-
assert!(inner.message.contains("admin-scoped multicast address"));
1297+
assert!(inner.message.contains("admin-local multicast address"));
12961298
}
12971299
_ => panic!(
1298-
"Expected ErrorResponse for admin-scoped external group creation"
1300+
"Expected ErrorResponse for admin-local external group creation"
12991301
),
13001302
}
13011303

@@ -3538,8 +3540,8 @@ async fn test_multicast_reset_all_tables() -> TestResult {
35383540
)
35393541
.await;
35403542

3541-
// 2b. Admin-scoped IPv6 group to test internal API with custom replication parameters
3542-
let ipv6 = Ipv6Addr::new(0xff04, 0, 0, 0, 0, 0, 0, 2);
3543+
// 2b. Admin-local IPv6 group to test internal API with custom replication parameters
3544+
let ipv6 = Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 2);
35433545

35443546
let group_entry2b = types::MulticastGroupCreateUnderlayEntry {
35453547
group_ip: types::AdminScopedIpv6(ipv6),
@@ -4249,7 +4251,7 @@ async fn test_ipv6_multicast_scope_validation() {
42494251
"Admin-local scope (ff04::/16) should work with internal API"
42504252
);
42514253

4252-
// Site-local scope (ff05::/16) - should work with internal API
4254+
// Site-local scope (ff05::/16) - should be rejected (only admin-local ff04 allowed)
42534255
let site_local_group = types::MulticastGroupCreateUnderlayEntry {
42544256
group_ip: "ff05::200".parse().unwrap(),
42554257
tag: Some("test_site_local".to_string()),
@@ -4265,11 +4267,11 @@ async fn test_ipv6_multicast_scope_validation() {
42654267
.multicast_group_create_underlay(&site_local_group)
42664268
.await;
42674269
assert!(
4268-
site_local_result.is_ok(),
4269-
"Site-local scope (ff05::/16) should work with internal API"
4270+
site_local_result.is_err(),
4271+
"Site-local scope (ff05::/16) should be rejected - only admin-local (ff04) allowed"
42704272
);
42714273

4272-
// Organization-local scope (ff08::/16) - should work with internal API
4274+
// Organization-local scope (ff08::/16) - should be rejected (only admin-local ff04 allowed)
42734275
let org_local_group = types::MulticastGroupCreateUnderlayEntry {
42744276
group_ip: "ff08::300".parse().unwrap(),
42754277
tag: Some("test_org_local".to_string()),
@@ -4285,8 +4287,8 @@ async fn test_ipv6_multicast_scope_validation() {
42854287
.multicast_group_create_underlay(&org_local_group)
42864288
.await;
42874289
assert!(
4288-
org_local_result.is_ok(),
4289-
"Organization-local scope (ff08::/16) should work with internal API"
4290+
org_local_result.is_err(),
4291+
"Organization-local scope (ff08::/16) should be rejected - only admin-local (ff04) allowed"
42904292
);
42914293

42924294
// Global scope (ff0e::/16) - should be rejected by server-side validation
@@ -4353,31 +4355,19 @@ async fn test_ipv6_multicast_scope_validation() {
43534355
let external_error_msg =
43544356
format!("{:?}", admin_external_result.unwrap_err());
43554357
assert!(
4356-
external_error_msg.contains("admin-scoped multicast address"),
4357-
"Error should indicate admin-scoped addresses require internal API"
4358+
external_error_msg.contains("admin-local multicast address"),
4359+
"Error should indicate admin-local addresses require internal API"
43584360
);
43594361

43604362
// Cleanup all created groups
43614363
let admin_local_group = admin_local_result.unwrap().into_inner();
4362-
let site_local_group = site_local_result.unwrap().into_inner();
4363-
let org_local_group = org_local_result.unwrap().into_inner();
43644364
let target_group = target_result.into_inner();
43654365

43664366
switch
43674367
.client
43684368
.multicast_group_delete(&admin_local_group.group_ip.to_ip_addr())
43694369
.await
43704370
.ok();
4371-
switch
4372-
.client
4373-
.multicast_group_delete(&site_local_group.group_ip.to_ip_addr())
4374-
.await
4375-
.ok();
4376-
switch
4377-
.client
4378-
.multicast_group_delete(&org_local_group.group_ip.to_ip_addr())
4379-
.await
4380-
.ok();
43814371
switch
43824372
.client
43834373
.multicast_group_delete(&target_group.group_ip.to_ip_addr())
@@ -4391,9 +4381,12 @@ async fn test_multicast_group_id_recycling() -> TestResult {
43914381
let switch = &*get_switch().await;
43924382

43934383
// Use admin-scoped IPv6 addresses that get group IDs assigned
4394-
let group1_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 10));
4395-
let group2_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 11));
4396-
let group3_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 12));
4384+
let group1_ip =
4385+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 10));
4386+
let group2_ip =
4387+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 11));
4388+
let group3_ip =
4389+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 12));
43974390

43984391
// Create first group and capture its group IDs
43994392
let group1 = create_test_multicast_group(
@@ -4486,7 +4479,8 @@ async fn test_multicast_group_id_recycling() -> TestResult {
44864479
"Group2 should be deleted"
44874480
);
44884481

4489-
let group4_ip = IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 13));
4482+
let group4_ip =
4483+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 13));
44904484
let group4 = create_test_multicast_group(
44914485
switch,
44924486
group4_ip,
@@ -4515,7 +4509,7 @@ async fn test_multicast_empty_then_add_members_ipv6() -> TestResult {
45154509
let switch = &*get_switch().await;
45164510

45174511
let internal_group_ip =
4518-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 100));
4512+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 100));
45194513
let external_group_ip =
45204514
IpAddr::V6(Ipv6Addr::new(0xff0e, 0, 0, 0, 0, 0, 0, 100));
45214515

@@ -4878,7 +4872,7 @@ async fn test_multicast_empty_then_add_members_ipv4() -> TestResult {
48784872
let switch = &*get_switch().await;
48794873

48804874
let internal_group_ip =
4881-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 101));
4875+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 101));
48824876
let external_group_ip = IpAddr::V4(Ipv4Addr::new(224, 1, 2, 100));
48834877

48844878
// Create internal admin-scoped group (empty, no members)
@@ -5244,7 +5238,7 @@ async fn test_multicast_rollback_external_group_creation_failure() -> TestResult
52445238
let switch = &*get_switch().await;
52455239

52465240
let internal_group_ip =
5247-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 102));
5241+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 102));
52485242
let external_group_ip = IpAddr::V4(Ipv4Addr::new(224, 1, 2, 102));
52495243

52505244
// Create internal group with members first
@@ -5398,7 +5392,7 @@ async fn test_multicast_rollback_member_update_failure() -> TestResult {
53985392
let switch = &*get_switch().await;
53995393

54005394
let internal_group_ip =
5401-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 103));
5395+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 103));
54025396

54035397
// Create internal group with initial members
54045398
create_test_multicast_group(
@@ -5478,7 +5472,7 @@ async fn test_multicast_rollback_nat_transition_failure() -> TestResult {
54785472
let switch = &*get_switch().await;
54795473

54805474
let internal_group_ip =
5481-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 104));
5475+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 104));
54825476
let external_group_ip = IpAddr::V4(Ipv4Addr::new(224, 1, 2, 104));
54835477

54845478
// Create internal group
@@ -5621,7 +5615,7 @@ async fn test_multicast_rollback_vlan_propagation_consistency() {
56215615
let switch = &*get_switch().await;
56225616

56235617
let internal_group_ip =
5624-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 105));
5618+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 105));
56255619
let external_group_ip = IpAddr::V4(Ipv4Addr::new(224, 1, 2, 105));
56265620

56275621
// Create internal group with members (so bitmap entry get created)
@@ -5857,7 +5851,7 @@ async fn test_multicast_rollback_partial_member_addition() -> TestResult {
58575851
let switch = &*get_switch().await;
58585852

58595853
let internal_group_ip =
5860-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 106));
5854+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 106));
58615855

58625856
// Create internal group with initial members
58635857
create_test_multicast_group(
@@ -5956,7 +5950,7 @@ async fn test_multicast_rollback_table_operation_failure() {
59565950
let switch = &*get_switch().await;
59575951

59585952
let internal_group_ip =
5959-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 107));
5953+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 107));
59605954
let external_group_ip = IpAddr::V4(Ipv4Addr::new(224, 1, 2, 107));
59615955

59625956
// Create internal group first
@@ -6091,7 +6085,7 @@ async fn test_multicast_group_get_underlay() -> TestResult {
60916085
let switch = &*get_switch().await;
60926086

60936087
let internal_group_ip =
6094-
IpAddr::V6(Ipv6Addr::new(0xff05, 0, 0, 0, 0, 0, 0, 200));
6088+
IpAddr::V6(Ipv6Addr::new(ADMIN_LOCAL_PREFIX, 0, 0, 0, 0, 0, 0, 200));
60956089

60966090
// Create an internal/underlay group
60976091
let _created_group = create_test_multicast_group(

0 commit comments

Comments
 (0)