Skip to content

Commit 11bbbbb

Browse files
authored
Support a default route without a gateway (#628)
Adds the support for a default route without a gateway. ``` / # ip route show default default dev eth0 scope link ```
1 parent 4040ce2 commit 11bbbbb

6 files changed

Lines changed: 30 additions & 14 deletions

File tree

Sources/Containerization/LinuxContainer.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -598,6 +598,9 @@ extension LinuxContainer {
598598
try await agent.routeAddLink(name: name, dstIPv4Addr: ipv4Gateway, srcIPv4Addr: i.ipv4Address.address)
599599
}
600600
try await agent.routeAddDefault(name: name, ipv4Gateway: ipv4Gateway)
601+
} else {
602+
self.logger?.debug("no gateway for \(name)")
603+
try await agent.routeAddDefault(name: name, ipv4Gateway: nil)
601604
}
602605
}
603606

Sources/Containerization/LinuxPod.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -457,6 +457,9 @@ extension LinuxPod {
457457
try await agent.routeAddLink(name: name, dstIPv4Addr: ipv4Gateway, srcIPv4Addr: nil)
458458
}
459459
try await agent.routeAddDefault(name: name, ipv4Gateway: ipv4Gateway)
460+
} else {
461+
self.logger?.debug("no gateway for \(name)")
462+
try await agent.routeAddDefault(name: name, ipv4Gateway: nil)
460463
}
461464
}
462465

Sources/Containerization/VirtualMachineAgent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ public protocol VirtualMachineAgent: Sendable {
6969
func down(name: String) async throws
7070
func addressAdd(name: String, ipv4Address: CIDRv4) async throws
7171
func routeAddLink(name: String, dstIPv4Addr: IPv4Address, srcIPv4Addr: IPv4Address?) async throws
72-
func routeAddDefault(name: String, ipv4Gateway: IPv4Address) async throws
72+
func routeAddDefault(name: String, ipv4Gateway: IPv4Address?) async throws
7373
func configureDNS(config: DNS, location: String) async throws
7474
func configureHosts(config: Hosts, location: String) async throws
7575

Sources/Containerization/Vminitd.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -398,11 +398,11 @@ extension Vminitd {
398398
}
399399

400400
/// Set the default route in the sandbox's environment.
401-
public func routeAddDefault(name: String, ipv4Gateway: IPv4Address) async throws {
401+
public func routeAddDefault(name: String, ipv4Gateway: IPv4Address?) async throws {
402402
_ = try await client.ipRouteAddDefault(
403403
.with {
404404
$0.interface = name
405-
$0.ipv4Gateway = ipv4Gateway.description
405+
$0.ipv4Gateway = ipv4Gateway?.description ?? ""
406406
})
407407
}
408408

Sources/ContainerizationNetlink/NetlinkSession.swift

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -348,14 +348,20 @@ public struct NetlinkSession {
348348
/// Adds a default IPv4 route to an interface.
349349
/// - Parameters:
350350
/// - interface: The name of the interface.
351-
/// - ipv4Gateway: The gateway address.
351+
/// - ipv4Gateway: The gateway address, or nil.
352352
public func routeAddDefault(
353353
interface: String,
354-
ipv4Gateway: IPv4Address
354+
ipv4Gateway: IPv4Address?
355355
) throws {
356-
// ip route add default via [dst-address] src [src-address]
357-
let dstAddrBytes = ipv4Gateway.bytes
358-
let dstAddrAttrSize = RTAttribute.size + dstAddrBytes.count
356+
// ip route add default via [gateway] dev [interface] or
357+
// ip route add default dev [interface]
358+
let dstAddrBytes = ipv4Gateway?.bytes
359+
let dstAddrAttrSize: Int
360+
if let dstAddrBytes {
361+
dstAddrAttrSize = RTAttribute.size + dstAddrBytes.count
362+
} else {
363+
dstAddrAttrSize = 0
364+
}
359365

360366
let interfaceAttrSize = RTAttribute.size + MemoryLayout<UInt32>.size
361367
let interfaceIndex = try getInterfaceIndex(interface)
@@ -379,16 +385,20 @@ public struct NetlinkSession {
379385
tos: 0,
380386
table: RouteTable.MAIN,
381387
proto: RouteProtocol.BOOT,
382-
scope: RouteScope.UNIVERSE,
388+
scope: ipv4Gateway != nil ? RouteScope.UNIVERSE : RouteScope.LINK,
383389
type: RouteType.UNICAST,
384390
flags: 0)
385391
requestOffset = try requestInfo.appendBuffer(&requestBuffer, offset: requestOffset)
386392

387-
let dstAddrAttr = RTAttribute(len: UInt16(dstAddrAttrSize), type: RouteAttributeType.GATEWAY)
388-
requestOffset = try dstAddrAttr.appendBuffer(&requestBuffer, offset: requestOffset)
389-
guard var requestOffset = requestBuffer.copyIn(buffer: dstAddrBytes, offset: requestOffset) else {
390-
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_GATEWAY")
393+
if let dstAddrBytes {
394+
let dstAddrAttr = RTAttribute(len: UInt16(dstAddrAttrSize), type: RouteAttributeType.GATEWAY)
395+
requestOffset = try dstAddrAttr.appendBuffer(&requestBuffer, offset: requestOffset)
396+
guard let newOffset = requestBuffer.copyIn(buffer: dstAddrBytes, offset: requestOffset) else {
397+
throw BindError.sendMarshalFailure(type: "RTAttribute", field: "RTA_GATEWAY")
398+
}
399+
requestOffset = newOffset
391400
}
401+
392402
let interfaceAttr = RTAttribute(len: UInt16(interfaceAttrSize), type: RouteAttributeType.OIF)
393403
requestOffset = try interfaceAttr.appendBuffer(&requestBuffer, offset: requestOffset)
394404
guard

vminitd/Sources/vminitd/Server+GRPC.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1177,7 +1177,7 @@ extension Initd: Com_Apple_Containerization_Sandbox_V3_SandboxContextAsyncProvid
11771177
do {
11781178
let socket = try DefaultNetlinkSocket()
11791179
let session = NetlinkSession(socket: socket, log: log)
1180-
let ipv4Gateway = try IPv4Address(request.ipv4Gateway)
1180+
let ipv4Gateway = !request.ipv4Gateway.isEmpty ? try IPv4Address(request.ipv4Gateway) : nil
11811181
try session.routeAddDefault(interface: request.interface, ipv4Gateway: ipv4Gateway)
11821182
} catch {
11831183
log.error(

0 commit comments

Comments
 (0)