Create a new isolated network namespace with veth pair. Sets up: - A new network namespace named `sandbox-{uuid}` - A veth pair connecting host and sandbox - IP addresses on both ends (10.200.0.1/24 and 10.200.0.2/24) - Default route in sandbox pointing to host # Errors Returns an error if namespace creation or network setup fails.
()
| 61 | /// |
| 62 | /// Returns an error if namespace creation or network setup fails. |
| 63 | pub fn create() -> Result<Self> { |
| 64 | let id = Uuid::new_v4(); |
| 65 | let short_id = &id.to_string()[..8]; |
| 66 | let name = format!("sandbox-{short_id}"); |
| 67 | let veth_host = format!("veth-h-{short_id}"); |
| 68 | let veth_sandbox = format!("veth-s-{short_id}"); |
| 69 | |
| 70 | let host_ip: IpAddr = format!("{SUBNET_PREFIX}.{HOST_IP_SUFFIX}").parse().unwrap(); |
| 71 | let sandbox_ip: IpAddr = format!("{SUBNET_PREFIX}.{SANDBOX_IP_SUFFIX}") |
| 72 | .parse() |
| 73 | .unwrap(); |
| 74 | |
| 75 | openshell_ocsf::ocsf_emit!( |
| 76 | openshell_ocsf::ConfigStateChangeBuilder::new(openshell_ocsf::ctx::ctx()) |
| 77 | .severity(openshell_ocsf::SeverityId::Informational) |
| 78 | .status(openshell_ocsf::StatusId::Success) |
| 79 | .state(openshell_ocsf::StateId::Enabled, "creating") |
| 80 | .message(format!( |
| 81 | "Creating network namespace [ns:{name} host_veth:{veth_host} sandbox_veth:{veth_sandbox}]" |
| 82 | )) |
| 83 | .build() |
| 84 | ); |
| 85 | |
| 86 | // Create the namespace |
| 87 | run_ip(&["netns", "add", &name])?; |
| 88 | |
| 89 | // Create veth pair |
| 90 | if let Err(e) = run_ip(&[ |
| 91 | "link", |
| 92 | "add", |
| 93 | &veth_host, |
| 94 | "type", |
| 95 | "veth", |
| 96 | "peer", |
| 97 | "name", |
| 98 | &veth_sandbox, |
| 99 | ]) { |
| 100 | // Cleanup namespace on failure |
| 101 | let _ = run_ip(&["netns", "delete", &name]); |
| 102 | return Err(e); |
| 103 | } |
| 104 | |
| 105 | // Move sandbox veth into namespace |
| 106 | if let Err(e) = run_ip(&["link", "set", &veth_sandbox, "netns", &name]) { |
| 107 | let _ = run_ip(&["link", "delete", &veth_host]); |
| 108 | let _ = run_ip(&["netns", "delete", &name]); |
| 109 | return Err(e); |
| 110 | } |
| 111 | |
| 112 | // Configure host side |
| 113 | let host_cidr = format!("{host_ip}/24"); |
| 114 | if let Err(e) = run_ip(&["addr", "add", &host_cidr, "dev", &veth_host]) { |
| 115 | let _ = run_ip(&["link", "delete", &veth_host]); |
| 116 | let _ = run_ip(&["netns", "delete", &name]); |
| 117 | return Err(e); |
| 118 | } |
| 119 | |
| 120 | if let Err(e) = run_ip(&["link", "set", &veth_host, "up"]) { |
no test coverage detected