Skip to content

Commit

Permalink
MGS/sp-sim: Give simulated SPs a multicast group to join
Browse files Browse the repository at this point in the history
  • Loading branch information
jgallagher committed Apr 15, 2022
1 parent e309703 commit 3aa03c0
Show file tree
Hide file tree
Showing 6 changed files with 62 additions and 20 deletions.
3 changes: 3 additions & 0 deletions gateway/tests/sp_sim_config.test.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,17 +8,20 @@
# concurrently.
#
[[simulated_sps.sidecar]]
multicast_addr = "::1"
bind_addrs = ["[::1]:0", "[::1]:0"]
serial_number = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

[[simulated_sps.gimlet]]
multicast_addr = "::1"
bind_addrs = ["[::1]:0", "[::1]:0"]
serial_number = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
[[simulated_sps.gimlet.components]]
name = "sp3"
serial_console = "[::1]:0"

[[simulated_sps.gimlet]]
multicast_addr = "::1"
bind_addrs = ["[::1]:0", "[::1]:0"]
serial_number = [4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7]
[[simulated_sps.gimlet.components]]
Expand Down
3 changes: 3 additions & 0 deletions sp-sim/examples/config.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,20 @@
#

[[simulated_sps.sidecar]]
multicast_addr = "ff15:0:1de::0"
bind_addrs = ["[::1]:33300", "[::1]:33301"]
serial_number = [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]

[[simulated_sps.gimlet]]
multicast_addr = "ff15:0:1de::1"
bind_addrs = ["[::1]:33310", "[::1]:33311"]
serial_number = [0, 0, 0, 0, 1, 1, 1, 1, 2, 2, 2, 2, 3, 3, 3, 3]
[[simulated_sps.gimlet.components]]
name = "sp3"
serial_console = "[::1]:33312"

[[simulated_sps.gimlet]]
multicast_addr = "ff15:0:1de::2"
bind_addrs = ["[::1]:33320", "[::1]:33321"]
serial_number = [4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7]
[[simulated_sps.gimlet.components]]
Expand Down
6 changes: 5 additions & 1 deletion sp-sim/src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,16 @@ use dropshot::ConfigLogging;
use gateway_messages::SerialNumber;
use serde::{Deserialize, Serialize};
use std::{
net::SocketAddr,
net::{Ipv6Addr, SocketAddr},
path::{Path, PathBuf},
};
use thiserror::Error;

/// Configuration of a simulated sidecar SP
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct SidecarConfig {
/// IPv6 multicast address to join.
pub multicast_addr: Ipv6Addr,
/// UDP address of the two (fake) KSZ8463 ports
pub bind_addrs: [SocketAddr; 2],
/// Fake serial number
Expand All @@ -26,6 +28,8 @@ pub struct SidecarConfig {
/// Configuration of a simulated gimlet SP
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
pub struct GimletConfig {
/// IPv6 multicast address to join.
pub multicast_addr: Ipv6Addr,
/// UDP address of the two (fake) KSZ8463 ports
pub bind_addrs: [SocketAddr; 2],
/// Fake serial number
Expand Down
4 changes: 2 additions & 2 deletions sp-sim/src/gimlet.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,8 +69,8 @@ impl Gimlet {
// bind to our two local "KSZ" ports
assert_eq!(gimlet.bind_addrs.len(), 2); // gimlet SP always has 2 ports
let servers = future::try_join(
UdpServer::new(gimlet.bind_addrs[0]),
UdpServer::new(gimlet.bind_addrs[1]),
UdpServer::new(gimlet.bind_addrs[0], gimlet.multicast_addr, &log),
UdpServer::new(gimlet.bind_addrs[1], gimlet.multicast_addr, &log),
)
.await?;
let servers = [servers.0, servers.1];
Expand Down
26 changes: 24 additions & 2 deletions sp-sim/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,10 @@ use crate::config::Config;
use anyhow::{bail, Context, Result};
use gateway_messages::{Request, SerializedSize};
use slog::{debug, error, Logger};
use std::{net::SocketAddr, sync::Arc};
use std::{
net::{Ipv6Addr, SocketAddr},
sync::Arc,
};
use tokio::net::UdpSocket;

/// Thin wrapper pairing a [`UdpSocket`] with a buffer sized for [`Request`]s.
Expand All @@ -17,14 +20,33 @@ pub(crate) struct UdpServer {
}

impl UdpServer {
pub(crate) async fn new(bind_address: SocketAddr) -> Result<Self> {
pub(crate) async fn new(
bind_address: SocketAddr,
multicast_addr: Ipv6Addr,
log: &Logger,
) -> Result<Self> {
let sock =
Arc::new(UdpSocket::bind(bind_address).await.with_context(
|| format!("failed to bind to {}", bind_address),
)?);

// In some environments where sp-sim runs (e.g., some CI runners),
// we're not able to join ipv6 multicast groups. In those cases, we're
// configured with a "multicast_addr" that isn't actually multicast, so
// don't try to join the group if we have such an address.
if multicast_addr.is_multicast() {
sock.join_multicast_v6(&multicast_addr, 0).with_context(|| {
format!("failed to join multicast group {}", multicast_addr)
})?;
}

let local_addr = sock
.local_addr()
.with_context(|| "failed to get local address of bound socket")?;
debug!(log, "UDP socket bound";
"local_addr" => %local_addr,
"multicast_addr" => %multicast_addr,
);

Ok(Self { sock, local_addr, buf: [0; Request::MAX_SIZE] })
}
Expand Down
40 changes: 25 additions & 15 deletions sp-sim/src/sidecar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,25 +4,35 @@

use std::net::SocketAddr;

use crate::config::{Config, SidecarConfig};
use crate::config::Config;
use crate::config::SidecarConfig;
use crate::ignition_id;
use crate::server::UdpServer;
use crate::{ignition_id, Responsiveness, SimulatedSp};
use crate::Responsiveness;
use crate::SimulatedSp;
use anyhow::anyhow;
use anyhow::Context;
use anyhow::Result;
use async_trait::async_trait;
use futures::future;
use gateway_messages::sp_impl::{SpHandler, SpServer};
use gateway_messages::{
BulkIgnitionState, IgnitionCommand, IgnitionFlags, IgnitionState,
ResponseError, SerialNumber, SpState,
};
use slog::{debug, info, warn, Logger};
use tokio::sync::{mpsc, oneshot};
use tokio::{
select,
task::{self, JoinHandle},
};
use gateway_messages::sp_impl::SpHandler;
use gateway_messages::sp_impl::SpServer;
use gateway_messages::BulkIgnitionState;
use gateway_messages::IgnitionCommand;
use gateway_messages::IgnitionFlags;
use gateway_messages::IgnitionState;
use gateway_messages::ResponseError;
use gateway_messages::SerialNumber;
use gateway_messages::SpState;
use slog::debug;
use slog::info;
use slog::warn;
use slog::Logger;
use tokio::select;
use tokio::sync::mpsc;
use tokio::sync::oneshot;
use tokio::task;
use tokio::task::JoinHandle;

pub struct Sidecar {
local_addrs: [SocketAddr; 2],
Expand Down Expand Up @@ -69,8 +79,8 @@ impl Sidecar {
// bind to our two local "KSZ" ports
assert_eq!(sidecar.bind_addrs.len(), 2);
let servers = future::try_join(
UdpServer::new(sidecar.bind_addrs[0]),
UdpServer::new(sidecar.bind_addrs[1]),
UdpServer::new(sidecar.bind_addrs[0], sidecar.multicast_addr, &log),
UdpServer::new(sidecar.bind_addrs[1], sidecar.multicast_addr, &log),
)
.await?;
let servers = [servers.0, servers.1];
Expand Down

0 comments on commit 3aa03c0

Please sign in to comment.