mirror of
https://github.com/edera-dev/krata.git
synced 2025-08-02 21:00:55 +00:00
network: implement proper IPv6 networking
This commit is contained in:
parent
6773640a39
commit
2c7879ad45
@ -350,7 +350,7 @@ impl ContainerInit {
|
||||
.await?;
|
||||
|
||||
if ipv6_ready {
|
||||
handle
|
||||
let ipv6_gw_result = handle
|
||||
.route()
|
||||
.add()
|
||||
.v6()
|
||||
@ -358,7 +358,11 @@ impl ContainerInit {
|
||||
.output_interface(link.header.index)
|
||||
.gateway(ipv6_gateway)
|
||||
.execute()
|
||||
.await?;
|
||||
.await;
|
||||
|
||||
if let Err(error) = ipv6_gw_result {
|
||||
warn!("failed to add ipv6 gateway route: {}", error);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -5,7 +5,7 @@ use hyphanet::icmp::{IcmpClient, IcmpProtocol};
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let client = IcmpClient::new(IcmpProtocol::Icmp6)?;
|
||||
let client = IcmpClient::new(IcmpProtocol::Icmpv6)?;
|
||||
let payload: [u8; 4] = [12u8, 14u8, 16u8, 32u8];
|
||||
let result = client
|
||||
.ping6(
|
||||
|
@ -114,7 +114,7 @@ impl NetworkBackend {
|
||||
let proxy = Box::new(ProxyNatHandlerFactory::new());
|
||||
let ipv4 = IpCidr::from_str(&self.ipv4)
|
||||
.map_err(|_| anyhow!("failed to parse ipv4 cidr: {}", self.ipv4))?;
|
||||
let ipv6 = IpCidr::from_str(&self.ipv4)
|
||||
let ipv6 = IpCidr::from_str(&self.ipv6)
|
||||
.map_err(|_| anyhow!("failed to parse ipv6 cidr: {}", self.ipv6))?;
|
||||
let addresses: Vec<IpCidr> = vec![ipv4, ipv6];
|
||||
let mut kdev =
|
||||
|
@ -21,15 +21,15 @@ use tokio::{
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum IcmpProtocol {
|
||||
Icmp4,
|
||||
Icmp6,
|
||||
Icmpv4,
|
||||
Icmpv6,
|
||||
}
|
||||
|
||||
impl IcmpProtocol {
|
||||
pub fn to_socket_protocol(&self) -> RawSocketProtocol {
|
||||
match self {
|
||||
IcmpProtocol::Icmp4 => RawSocketProtocol::Icmpv4,
|
||||
IcmpProtocol::Icmp6 => RawSocketProtocol::Icmpv6,
|
||||
IcmpProtocol::Icmpv4 => RawSocketProtocol::Icmpv4,
|
||||
IcmpProtocol::Icmpv6 => RawSocketProtocol::Icmpv6,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -88,7 +88,7 @@ impl IcmpClient {
|
||||
let packet = &buffer[0..size];
|
||||
|
||||
let (token, reply) = match protocol {
|
||||
IcmpProtocol::Icmp4 => {
|
||||
IcmpProtocol::Icmpv4 => {
|
||||
let sliced = match SlicedPacket::from_ip(packet) {
|
||||
Ok(sliced) => sliced,
|
||||
Err(error) => {
|
||||
@ -126,7 +126,7 @@ impl IcmpClient {
|
||||
(token, reply)
|
||||
}
|
||||
|
||||
IcmpProtocol::Icmp6 => {
|
||||
IcmpProtocol::Icmpv6 => {
|
||||
let Ok(icmpv6) = Icmpv6Slice::from_slice(packet) else {
|
||||
continue;
|
||||
};
|
||||
|
@ -3,6 +3,8 @@ use async_trait::async_trait;
|
||||
use etherparse::Ethernet2Slice;
|
||||
use etherparse::Icmpv4Header;
|
||||
use etherparse::Icmpv4Type;
|
||||
use etherparse::Icmpv6Header;
|
||||
use etherparse::Icmpv6Type;
|
||||
use etherparse::IpNumber;
|
||||
use etherparse::IpPayloadSlice;
|
||||
use etherparse::Ipv4Slice;
|
||||
@ -220,6 +222,11 @@ impl NatRouter {
|
||||
.await?;
|
||||
}
|
||||
|
||||
IpNumber::IPV6_ICMP => {
|
||||
self.process_icmpv6(data, ether, source_addr, dest_addr, ipv6.payload())
|
||||
.await?;
|
||||
}
|
||||
|
||||
_ => {}
|
||||
}
|
||||
|
||||
@ -295,6 +302,31 @@ impl NatRouter {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn process_icmpv6<'a>(
|
||||
&mut self,
|
||||
data: &'a [u8],
|
||||
ether: &Ethernet2Slice<'a>,
|
||||
source_addr: IpAddress,
|
||||
dest_addr: IpAddress,
|
||||
payload: &IpPayloadSlice<'a>,
|
||||
) -> Result<()> {
|
||||
let (header, _) = Icmpv6Header::from_slice(payload.payload)?;
|
||||
let Icmpv6Type::EchoRequest(_) = header.icmp_type else {
|
||||
return Ok(());
|
||||
};
|
||||
let source = IpEndpoint::new(source_addr, 0);
|
||||
let dest = IpEndpoint::new(dest_addr, 0);
|
||||
let key = NatKey {
|
||||
protocol: NatKeyProtocol::Icmp,
|
||||
client_mac: EthernetAddress(ether.source()),
|
||||
local_mac: EthernetAddress(ether.destination()),
|
||||
client_ip: source,
|
||||
external_ip: dest,
|
||||
};
|
||||
self.process_nat(data, key).await?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub async fn process_nat(&mut self, data: &[u8], key: NatKey) -> Result<()> {
|
||||
for cidr in &self.local_cidrs {
|
||||
if cidr.contains_addr(&key.external_ip.addr) {
|
||||
|
@ -48,7 +48,10 @@ impl ProxyIcmpHandler {
|
||||
context: NatHandlerContext,
|
||||
rx_receiver: Receiver<Vec<u8>>,
|
||||
) -> Result<()> {
|
||||
let client = IcmpClient::new(IcmpProtocol::Icmp4)?;
|
||||
let client = IcmpClient::new(match context.key.external_ip.addr {
|
||||
IpAddress::Ipv4(_) => IcmpProtocol::Icmpv4,
|
||||
IpAddress::Ipv6(_) => IcmpProtocol::Icmpv6,
|
||||
})?;
|
||||
tokio::spawn(async move {
|
||||
if let Err(error) = ProxyIcmpHandler::process(client, rx_receiver, context).await {
|
||||
warn!("processing of icmp proxy failed: {}", error);
|
||||
@ -157,7 +160,7 @@ impl ProxyIcmpHandler {
|
||||
ipv6: &Ipv6Slice<'_>,
|
||||
client: &IcmpClient,
|
||||
) -> Result<()> {
|
||||
if ipv6.header().next_header() != IpNumber::ICMP {
|
||||
if ipv6.header().next_header() != IpNumber::IPV6_ICMP {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user