mirror of
				https://github.com/edera-dev/krata.git
				synced 2025-11-03 23:29:39 +00:00 
			
		
		
		
	hypha: more work on IPv6 support
This commit is contained in:
		@ -9,7 +9,7 @@ use oci_spec::image::{Config, ImageConfiguration};
 | 
				
			|||||||
use std::ffi::{CStr, CString};
 | 
					use std::ffi::{CStr, CString};
 | 
				
			||||||
use std::fs;
 | 
					use std::fs;
 | 
				
			||||||
use std::fs::{File, OpenOptions, Permissions};
 | 
					use std::fs::{File, OpenOptions, Permissions};
 | 
				
			||||||
use std::net::Ipv4Addr;
 | 
					use std::net::{Ipv4Addr, Ipv6Addr};
 | 
				
			||||||
use std::os::fd::AsRawFd;
 | 
					use std::os::fd::AsRawFd;
 | 
				
			||||||
use std::os::linux::fs::MetadataExt;
 | 
					use std::os::linux::fs::MetadataExt;
 | 
				
			||||||
use std::os::unix::fs::{chroot, PermissionsExt};
 | 
					use std::os::unix::fs::{chroot, PermissionsExt};
 | 
				
			||||||
@ -283,52 +283,83 @@ impl ContainerInit {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    async fn network_setup(&mut self, network: &LaunchNetwork) -> Result<()> {
 | 
					    async fn network_setup(&mut self, network: &LaunchNetwork) -> Result<()> {
 | 
				
			||||||
        trace!(
 | 
					        trace!("setting up network for link");
 | 
				
			||||||
            "setting up network for link {} with ipv4 address {} and gateway {}",
 | 
					
 | 
				
			||||||
            network.link,
 | 
					        let etc = PathBuf::from_str("/etc")?;
 | 
				
			||||||
            network.ipv4.address,
 | 
					        if !etc.exists() {
 | 
				
			||||||
            network.ipv4.gateway,
 | 
					            fs::create_dir(etc)?;
 | 
				
			||||||
        );
 | 
					        }
 | 
				
			||||||
 | 
					        let resolv = PathBuf::from_str("/etc/resolv.conf")?;
 | 
				
			||||||
 | 
					        let mut lines = vec!["# hypha resolver configuration".to_string()];
 | 
				
			||||||
 | 
					        for nameserver in &network.resolver.nameservers {
 | 
				
			||||||
 | 
					            lines.push(format!("nameserver {}", nameserver));
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut conf = lines.join("\n");
 | 
				
			||||||
 | 
					        conf.push('\n');
 | 
				
			||||||
 | 
					        fs::write(resolv, conf)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let (connection, handle, _) = rtnetlink::new_connection()?;
 | 
					        let (connection, handle, _) = rtnetlink::new_connection()?;
 | 
				
			||||||
        tokio::spawn(connection);
 | 
					        tokio::spawn(connection);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let ipnet: IpNetwork = network.ipv4.address.parse()?;
 | 
					        let ipv4_network: IpNetwork = network.ipv4.address.parse()?;
 | 
				
			||||||
        let gateway: Ipv4Addr = network.ipv4.gateway.parse()?;
 | 
					        let ipv4_gateway: Ipv4Addr = network.ipv4.gateway.parse()?;
 | 
				
			||||||
 | 
					        let ipv6_network: IpNetwork = network.ipv6.address.parse()?;
 | 
				
			||||||
 | 
					        let ipv6_gateway: Ipv6Addr = network.ipv6.gateway.parse()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut links = handle
 | 
					        let mut links = handle
 | 
				
			||||||
            .link()
 | 
					            .link()
 | 
				
			||||||
            .get()
 | 
					            .get()
 | 
				
			||||||
            .match_name(network.link.clone())
 | 
					            .match_name(network.link.clone())
 | 
				
			||||||
            .execute();
 | 
					            .execute();
 | 
				
			||||||
        if let Some(link) = links.try_next().await? {
 | 
					        let Some(link) = links.try_next().await? else {
 | 
				
			||||||
 | 
					            warn!("unable to find link named {}", network.link);
 | 
				
			||||||
 | 
					            return Ok(());
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        handle
 | 
					        handle
 | 
				
			||||||
            .address()
 | 
					            .address()
 | 
				
			||||||
                .add(link.header.index, ipnet.ip(), ipnet.prefix())
 | 
					            .add(link.header.index, ipv4_network.ip(), ipv4_network.prefix())
 | 
				
			||||||
            .execute()
 | 
					            .execute()
 | 
				
			||||||
            .await?;
 | 
					            .await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let ipv6_result = handle
 | 
				
			||||||
 | 
					            .address()
 | 
				
			||||||
 | 
					            .add(link.header.index, ipv6_network.ip(), ipv6_network.prefix())
 | 
				
			||||||
 | 
					            .execute()
 | 
				
			||||||
 | 
					            .await;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let ipv6_ready = match ipv6_result {
 | 
				
			||||||
 | 
					            Ok(()) => true,
 | 
				
			||||||
 | 
					            Err(error) => {
 | 
				
			||||||
 | 
					                warn!("unable to setup ipv6 network: {}", error);
 | 
				
			||||||
 | 
					                false
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        };
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        handle.link().set(link.header.index).up().execute().await?;
 | 
					        handle.link().set(link.header.index).up().execute().await?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        handle
 | 
					        handle
 | 
				
			||||||
            .route()
 | 
					            .route()
 | 
				
			||||||
            .add()
 | 
					            .add()
 | 
				
			||||||
            .v4()
 | 
					            .v4()
 | 
				
			||||||
                .destination_prefix(Ipv4Addr::new(0, 0, 0, 0), 0)
 | 
					            .destination_prefix(Ipv4Addr::UNSPECIFIED, 0)
 | 
				
			||||||
            .output_interface(link.header.index)
 | 
					            .output_interface(link.header.index)
 | 
				
			||||||
                .gateway(gateway)
 | 
					            .gateway(ipv4_gateway)
 | 
				
			||||||
            .execute()
 | 
					            .execute()
 | 
				
			||||||
            .await?;
 | 
					            .await?;
 | 
				
			||||||
        } else {
 | 
					 | 
				
			||||||
            warn!("unable to find link named {}", network.link);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let etc = PathBuf::from_str("/etc")?;
 | 
					        if ipv6_ready {
 | 
				
			||||||
        if !etc.exists() {
 | 
					            handle
 | 
				
			||||||
            fs::create_dir(etc)?;
 | 
					                .route()
 | 
				
			||||||
 | 
					                .add()
 | 
				
			||||||
 | 
					                .v6()
 | 
				
			||||||
 | 
					                .destination_prefix(Ipv6Addr::UNSPECIFIED, 0)
 | 
				
			||||||
 | 
					                .output_interface(link.header.index)
 | 
				
			||||||
 | 
					                .gateway(ipv6_gateway)
 | 
				
			||||||
 | 
					                .execute()
 | 
				
			||||||
 | 
					                .await?;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        let resolv = PathBuf::from_str("/etc/resolv.conf")?;
 | 
					 | 
				
			||||||
        fs::write(resolv, "nameserver 1.1.1.1\n")?;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -7,7 +7,9 @@ use crate::image::name::ImageName;
 | 
				
			|||||||
use crate::image::{ImageCompiler, ImageInfo};
 | 
					use crate::image::{ImageCompiler, ImageInfo};
 | 
				
			||||||
use advmac::MacAddr6;
 | 
					use advmac::MacAddr6;
 | 
				
			||||||
use anyhow::{anyhow, Result};
 | 
					use anyhow::{anyhow, Result};
 | 
				
			||||||
use hypha::{LaunchInfo, LaunchNetwork, LaunchNetworkIpv4};
 | 
					use hypha::{
 | 
				
			||||||
 | 
					    LaunchInfo, LaunchNetwork, LaunchNetworkIpv4, LaunchNetworkIpv6, LaunchNetworkResolver,
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
use ipnetwork::Ipv4Network;
 | 
					use ipnetwork::Ipv4Network;
 | 
				
			||||||
use loopdev::LoopControl;
 | 
					use loopdev::LoopControl;
 | 
				
			||||||
use std::io::{Read, Write};
 | 
					use std::io::{Read, Write};
 | 
				
			||||||
@ -81,7 +83,10 @@ impl Controller {
 | 
				
			|||||||
        let name = format!("hypha-{uuid}");
 | 
					        let name = format!("hypha-{uuid}");
 | 
				
			||||||
        let image_info = self.compile(image)?;
 | 
					        let image_info = self.compile(image)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let mut mac = MacAddr6::random();
 | 
				
			||||||
 | 
					        mac.set_local(true);
 | 
				
			||||||
        let ipv4 = self.allocate_ipv4()?;
 | 
					        let ipv4 = self.allocate_ipv4()?;
 | 
				
			||||||
 | 
					        let ipv6 = mac.to_link_local_ipv6();
 | 
				
			||||||
        let launch_config = LaunchInfo {
 | 
					        let launch_config = LaunchInfo {
 | 
				
			||||||
            network: Some(LaunchNetwork {
 | 
					            network: Some(LaunchNetwork {
 | 
				
			||||||
                link: "eth0".to_string(),
 | 
					                link: "eth0".to_string(),
 | 
				
			||||||
@ -89,7 +94,18 @@ impl Controller {
 | 
				
			|||||||
                    address: format!("{}/24", ipv4),
 | 
					                    address: format!("{}/24", ipv4),
 | 
				
			||||||
                    gateway: "192.168.42.1".to_string(),
 | 
					                    gateway: "192.168.42.1".to_string(),
 | 
				
			||||||
                },
 | 
					                },
 | 
				
			||||||
                ipv6: None,
 | 
					                ipv6: LaunchNetworkIpv6 {
 | 
				
			||||||
 | 
					                    address: format!("{}/10", ipv6),
 | 
				
			||||||
 | 
					                    gateway: "fe80::1".to_string(),
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
 | 
					                resolver: LaunchNetworkResolver {
 | 
				
			||||||
 | 
					                    nameservers: vec![
 | 
				
			||||||
 | 
					                        "1.1.1.1".to_string(),
 | 
				
			||||||
 | 
					                        "1.0.0.1".to_string(),
 | 
				
			||||||
 | 
					                        "2606:4700:4700::1111".to_string(),
 | 
				
			||||||
 | 
					                        "2606:4700:4700::1001".to_string(),
 | 
				
			||||||
 | 
					                    ],
 | 
				
			||||||
 | 
					                },
 | 
				
			||||||
            }),
 | 
					            }),
 | 
				
			||||||
            env,
 | 
					            env,
 | 
				
			||||||
            run,
 | 
					            run,
 | 
				
			||||||
@ -118,8 +134,6 @@ impl Controller {
 | 
				
			|||||||
        let cmdline_options = [if debug { "debug" } else { "quiet" }, "elevator=noop"];
 | 
					        let cmdline_options = [if debug { "debug" } else { "quiet" }, "elevator=noop"];
 | 
				
			||||||
        let cmdline = cmdline_options.join(" ");
 | 
					        let cmdline = cmdline_options.join(" ");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        let mut mac = MacAddr6::random();
 | 
					 | 
				
			||||||
        mac.set_local(true);
 | 
					 | 
				
			||||||
        let mac = mac.to_string().replace('-', ":");
 | 
					        let mac = mac.to_string().replace('-', ":");
 | 
				
			||||||
        let config = DomainConfig {
 | 
					        let config = DomainConfig {
 | 
				
			||||||
            backend_domid: 0,
 | 
					            backend_domid: 0,
 | 
				
			||||||
 | 
				
			|||||||
@ -12,11 +12,17 @@ pub struct LaunchNetworkIpv6 {
 | 
				
			|||||||
    pub gateway: String,
 | 
					    pub gateway: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[derive(Serialize, Deserialize, Debug)]
 | 
				
			||||||
 | 
					pub struct LaunchNetworkResolver {
 | 
				
			||||||
 | 
					    pub nameservers: Vec<String>,
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, Deserialize, Debug)]
 | 
					#[derive(Serialize, Deserialize, Debug)]
 | 
				
			||||||
pub struct LaunchNetwork {
 | 
					pub struct LaunchNetwork {
 | 
				
			||||||
    pub link: String,
 | 
					    pub link: String,
 | 
				
			||||||
    pub ipv4: LaunchNetworkIpv4,
 | 
					    pub ipv4: LaunchNetworkIpv4,
 | 
				
			||||||
    pub ipv6: Option<LaunchNetworkIpv6>,
 | 
					    pub ipv6: LaunchNetworkIpv6,
 | 
				
			||||||
 | 
					    pub resolver: LaunchNetworkResolver,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#[derive(Serialize, Deserialize, Debug)]
 | 
					#[derive(Serialize, Deserialize, Debug)]
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user