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