Skip to content

Commit 8958c4e

Browse files
authored
Fixup QCMP ping (#1095)
1 parent 089fe1d commit 8958c4e

File tree

11 files changed

+53
-64
lines changed

11 files changed

+53
-64
lines changed

.ci/xdp/veth-integ-test.sh

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,21 +27,30 @@ ip link add veth-cs type veth peer name veth-proxy
2727
ip link set veth-cs netns cs
2828
ip link set veth-proxy netns proxy
2929

30+
PROXY_IP="10.0.0.2"
31+
OUTSIDE_IP="10.0.0.1"
32+
3033
echo "::notice file=$source,line=$LINENO::Adding IPs"
31-
ip -n cs addr add 10.0.0.1/24 dev veth-cs
32-
ip -n proxy addr add 10.0.0.2/24 dev veth-proxy
34+
ip -n cs addr add $OUTSIDE_IP/24 dev veth-cs
35+
ip -n proxy addr add $PROXY_IP/24 dev veth-proxy
3336

3437
echo "::notice file=$source,line=$LINENO::Creating network namespaces"
3538
ip -n cs link set veth-cs up
3639
ip -n proxy link set veth-proxy up
3740

41+
# XDP on a veth has a bit of an annoying requirement in newer kernel versions,
42+
# both sides need to have an XDP program attached for traffic to appear on the
43+
# one we actually want to test
44+
ROOT=$(git rev-parse --show-toplevel)
45+
echo "Adding dummy program"
46+
ip -n cs link set veth-cs xdpgeneric obj "$ROOT/crates/xdp/bin/dummy.bin" sec xdp
47+
3848
ip netns exec cs fortio udp-echo&
39-
ip netns exec proxy ./target/debug/quilkin proxy --to 10.0.0.1:8078 --publish.udp.xdp&
49+
ip netns exec proxy ./target/debug/quilkin --service.udp --service.qcmp proxy --to $OUTSIDE_IP:8078 --service.udp.xdp --service.udp.xdp.network-interface veth-proxy&
4050

4151
echo "::notice file=$source,line=$LINENO::Launching client"
42-
ip netns exec cs fortio load -n 10 udp://10.0.0.2:7777 2> ./target/logs.txt
52+
ip netns exec cs fortio load -n 10 udp://$PROXY_IP:7777 2> ./target/logs.txt
4353
logs=$(cat ./target/logs.txt)
44-
echo "$logs"
4554

4655
regex="Total Bytes sent: ([0-9]+), received: ([0-9]+)"
4756

@@ -52,6 +61,10 @@ if [[ $logs =~ $regex ]]; then
5261
# even consistently get that on my local machine so I doubt CI will fair better
5362
if [[ $recv -ne "0" ]]; then
5463
echo "::notice file=$source,line=$LINENO::Successfully sent ${send}B and received ${recv}B"
64+
65+
# Now test QCMP pings which was also enabled in the proxy
66+
ip netns exec cs ./target/debug/quilkin qcmp ping $PROXY_IP:7600
67+
5568
exit 0
5669
fi
5770

crates/ebpf/Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ edition = "2021"
66

77
[dependencies]
88
aya-ebpf = "0.1.1"
9+
#aya-log-ebpf = "0.1"
910
network-types = "0.0.7"
1011

1112
[[bin]]

crates/ebpf/build.sh

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,9 @@ ROOT=$(git rev-parse --show-toplevel)
99
EBPF_ROOT="$ROOT/crates/ebpf"
1010

1111
cargo +nightly build -Z build-std=core --release --target bpfel-unknown-none --manifest-path "$EBPF_ROOT/Cargo.toml"
12+
clang -target bpf -Wall -O2 -g -c "$EBPF_ROOT/src/dummy.c" -o "$EBPF_ROOT/target/bpfel-unknown-none/release/dummy"
1213

1314
if [[ $1 == '--update' ]]; then
1415
cp "$EBPF_ROOT/target/bpfel-unknown-none/release/packet-router" "$ROOT/crates/xdp/bin/packet-router.bin"
16+
cp "$EBPF_ROOT/target/bpfel-unknown-none/release/dummy" "$ROOT/crates/xdp/bin/dummy.bin"
1517
fi

crates/ebpf/src/dummy.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
#include <linux/bpf.h>
2+
#include <bpf/bpf_helpers.h>
3+
4+
SEC("xdp")
5+
int socket_router(struct xdp_md *ctx)
6+
{
7+
return XDP_PASS;
8+
}

crates/xdp/bin/dummy.bin

4.05 KB
Binary file not shown.

crates/xdp/src/lib.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -187,9 +187,10 @@ impl EbpfProgram {
187187
nic: NicIndex,
188188
flags: aya::programs::XdpFlags,
189189
) -> Result<aya::programs::xdp::XdpLinkId, aya::programs::ProgramError> {
190-
// Would be good to enable this if we do end up adding log messages to
191-
// the eBPF program
192190
if let Err(_error) = aya_log::EbpfLogger::init(&mut self.bpf) {
191+
// Would be good to enable this if we do end up adding log messages to
192+
// the eBPF program, right now we don't so this will error as the ring
193+
// buffer used to transfer log messages is not created if there are none
193194
//tracing::warn!(%error, "failed to initialize eBPF logging");
194195
}
195196

src/cli.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,6 @@ impl Cli {
269269
let locality = self.locality.locality();
270270
self.providers
271271
.spawn_providers(&config, ready.clone(), locality.clone());
272-
self.service.spawn_services(&config, &shutdown_rx)?;
273272

274273
match self.command {
275274
Some(Commands::Agent(agent)) => {
@@ -307,7 +306,10 @@ impl Cli {
307306
relay.run(locality, config, old_ready, shutdown_rx).await
308307
}
309308
Some(_) => unreachable!(),
310-
None => shutdown_rx.changed().await.map_err(From::from),
309+
None => {
310+
self.service.spawn_services(&config, &shutdown_rx)?;
311+
shutdown_rx.changed().await.map_err(From::from)
312+
}
311313
}
312314
}
313315

src/cli/proxy.rs

Lines changed: 1 addition & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ use crate::filters::FilterFactory;
2222

2323
use crate::signal::ShutdownRx;
2424

25-
pub use crate::components::proxy::Ready;
25+
pub use crate::{cli::service::XdpOptions, components::proxy::Ready};
2626

2727
define_port!(7777);
2828

@@ -65,55 +65,6 @@ pub struct Proxy {
6565
pub xdp_opts: XdpOptions,
6666
}
6767

68-
/// XDP (eXpress Data Path) options
69-
#[derive(clap::Args, Clone, Debug)]
70-
pub struct XdpOptions {
71-
/// The name of the network interface to bind the XDP socket(s) to.
72-
///
73-
/// If not specified quilkin will attempt to determine the most appropriate
74-
/// network interface to use. Quilkin will exit with an error if the network
75-
/// interface does not exist, or a suitable default cannot be determined.
76-
#[clap(long = "publish.udp.xdp.network-interface")]
77-
pub network_interface: Option<String>,
78-
/// Forces the use of XDP.
79-
///
80-
/// If XDP is not available on the chosen NIC, Quilkin exits with an error.
81-
/// If false, io-uring will be used as the fallback implementation.
82-
#[clap(long = "publish.udp.xdp")]
83-
pub force_xdp: bool,
84-
/// Forces the use of [`XDP_ZEROCOPY`](https://www.kernel.org/doc/html/latest/networking/af_xdp.html#xdp-copy-and-xdp-zerocopy-bind-flags)
85-
///
86-
/// If zero copy is not available on the chosen NIC, Quilkin exits with an error
87-
#[clap(long = "publish.udp.xdp.zerocopy")]
88-
pub force_zerocopy: bool,
89-
/// Forces the use of [TX checksum offload](https://docs.kernel.org/6.8/networking/xsk-tx-metadata.html)
90-
///
91-
/// TX checksum offload is an optional feature allowing the data portion of
92-
/// a packet to have its internet checksum calculation offloaded to the NIC,
93-
/// as otherwise this is done in software
94-
#[clap(long = "publish.udp.xdp.tco")]
95-
pub force_tx_checksum_offload: bool,
96-
/// The maximum amount of memory mapped for packet buffers, in bytes
97-
///
98-
/// If not specified, this defaults to 4MiB (2k allocated packets of 2k each at a time)
99-
/// per NIC queue, ie 128MiB on a 32 queue NIC
100-
#[clap(long = "publish.udp.xdp.memory-limit")]
101-
pub maximum_memory: Option<u64>,
102-
}
103-
104-
#[allow(clippy::derivable_impls)]
105-
impl Default for XdpOptions {
106-
fn default() -> Self {
107-
Self {
108-
network_interface: None,
109-
force_xdp: false,
110-
force_zerocopy: false,
111-
force_tx_checksum_offload: false,
112-
maximum_memory: None,
113-
}
114-
}
115-
}
116-
11768
impl Default for Proxy {
11869
fn default() -> Self {
11970
Self {

src/cli/qcmp.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,9 @@ impl Ping {
102102
"final results"
103103
);
104104
}
105-
None => tracing::error!("no successful results"),
105+
None => {
106+
eyre::bail!("no successful results");
107+
}
106108
}
107109

108110
Ok(())

src/cli/service.rs

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,11 @@ impl Service {
196196
self
197197
}
198198

199+
pub fn xdp(mut self, xdp_opts: XdpOptions) -> Self {
200+
self.xdp = xdp_opts;
201+
self
202+
}
203+
199204
/// Sets the xDS service port.
200205
pub fn any_service_enabled(&self) -> bool {
201206
self.udp_enabled
@@ -367,7 +372,7 @@ impl Service {
367372
return Err(err);
368373
}
369374

370-
tracing::debug!(
375+
tracing::warn!(
371376
?err,
372377
"failed to spawn XDP I/O loop, falling back to io-uring"
373378
);
@@ -439,15 +444,18 @@ impl Service {
439444
eyre::bail!("XDP currently disabled by default");
440445
}
441446

442-
tracing::info!(port=%self.mds_port, "setting up xdp module");
447+
let udp_port = if self.udp_enabled { self.udp_port } else { 0 };
448+
let qcmp_port = if self.qcmp_enabled { self.qcmp_port } else { 0 };
449+
450+
tracing::info!(udp_port, qcmp_port, "setting up xdp module");
443451
let workers = xdp::setup_xdp_io(xdp::XdpConfig {
444452
nic: self
445453
.xdp
446454
.network_interface
447455
.as_deref()
448456
.map_or(xdp::NicConfig::Default, xdp::NicConfig::Name),
449-
external_port: if self.udp_enabled { self.udp_port } else { 0 },
450-
qcmp_port: if self.qcmp_enabled { self.qcmp_port } else { 0 },
457+
external_port: udp_port,
458+
qcmp_port,
451459
maximum_packet_memory: self.xdp.maximum_memory,
452460
require_zero_copy: self.xdp.force_zerocopy,
453461
require_tx_checksum: self.xdp.force_tx_checksum_offload,

0 commit comments

Comments
 (0)