Skip to content

Commit 3aa0fe1

Browse files
committed
feat(dhcpv6): Add DHCPv6 support for macvlan and bridge drivers
This commit introduces full support for stateful IPv6 address assignment via DHCPv6, resolving the issue where containers would not receive a global IPv6 address on macvlan networks. The implementation follows the standard IPv6 design of separating gateway discovery (via Router Advertisements) from stateful address assignment (via DHCPv6). Key changes include: - **Kernel Configuration:** Netavark now configures the container's kernel to accept Router Advertisements (`accept_ra=2`) for automatic gateway discovery, while disabling SLAAC (`autoconf=0`) to ensure a managed, deterministic network environment. - **DHCPv6 Service:** A new `DhcpV6Service` is added to the DHCP proxy. It uses the `mozim` library to acquire IPv6 leases and correctly generates a stable DUID-LL from the container's static MAC address to ensure a persistent network identity. - **gRPC Layer:** The gRPC `Lease` object and its `From` implementations have been updated to act as a universal carrier for both IPv4 and IPv6 lease information. - **Generic Proxy Logic:** Core functions like `process_client_stream` and `update_lease_ip` have been refactored to handle both DHCPv4 and DHCPv6 services generically, with conditional logic to correctly handle the differences between the protocols (e.g., gateway handling). Signed-off-by: Rishikpulhani <[email protected]>
1 parent 4ee9f34 commit 3aa0fe1

File tree

8 files changed

+446
-90
lines changed

8 files changed

+446
-90
lines changed

Cargo.lock

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

Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ futures-core = "0.3.31"
6161
futures-util = "0.3.31"
6262
tower = { version = "0.5.2", features = ["util"] }
6363
hyper-util = "0.1.16"
64+
hex = "0.4.3"
65+
dhcproto = "0.12.0"
6466

6567
[build-dependencies]
6668
chrono = { version = "0.4.41", default-features = false, features = ["clock"] }

src/commands/dhcp_proxy.rs

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
#![cfg_attr(not(unix), allow(unused_imports))]
22

33
use crate::dhcp_proxy::cache::{Clear, LeaseCache};
4-
use crate::dhcp_proxy::dhcp_service::{process_client_stream, DhcpV4Service};
4+
use crate::dhcp_proxy::dhcp_service::{
5+
process_client_stream, DhcpService, DhcpV4Service, DhcpV6Service,
6+
};
57
use crate::dhcp_proxy::ip;
68
use crate::dhcp_proxy::lib::g_rpc::netavark_proxy_server::{NetavarkProxy, NetavarkProxyServer};
79
use crate::dhcp_proxy::lib::g_rpc::{
@@ -14,6 +16,7 @@ use crate::error::{NetavarkError, NetavarkResult};
1416
use crate::network::core_utils;
1517
use clap::Parser;
1618
use log::{debug, error, warn};
19+
use mozim::DhcpV6IaType;
1720
use tokio::task::AbortHandle;
1821

1922
use std::collections::HashMap;
@@ -422,16 +425,25 @@ async fn process_setup<W: Write + Clear>(
422425
let mut service = DhcpV4Service::new(network_config, timeout)?;
423426

424427
let lease = service.get_lease().await?;
425-
let task = tokio::spawn(process_client_stream(service));
428+
let task = tokio::spawn(process_client_stream(DhcpService::V4(service)));
426429
tasks
427430
.lock()
428431
.expect("lock tasks")
429432
.insert(mac.to_string(), task.abort_handle());
430433
lease
431434
}
432-
//V6 TODO implement DHCPv6
433435
1 => {
434-
return Err(Status::new(InvalidArgument, "ipv6 not yet supported"));
436+
// ia_type for conatainers is generally NonTemporaryAddresses
437+
let mut service =
438+
DhcpV6Service::new(network_config, timeout, DhcpV6IaType::NonTemporaryAddresses)?;
439+
let lease = service.get_lease().await?;
440+
// service in the generic DhcpService enum.
441+
let task = tokio::spawn(process_client_stream(DhcpService::V6(service)));
442+
tasks
443+
.lock()
444+
.expect("lock tasks")
445+
.insert(mac.to_string(), task.abort_handle());
446+
lease
435447
}
436448
_ => {
437449
return Err(Status::new(InvalidArgument, "invalid protocol version"));

0 commit comments

Comments
 (0)