Skip to content

Commit ad219fe

Browse files
authored
Make MTU configurable for Netlink (#204)
Here we add the implementation to make MTU value configurable instead of hardcoding in `linkSet`.
1 parent d16893d commit ad219fe

8 files changed

Lines changed: 231 additions & 111 deletions

File tree

Sources/Containerization/Agent/Vminitd.swift

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -198,10 +198,11 @@ extension Vminitd: VirtualMachineAgent {
198198
_ = try await client.deleteProcess(request)
199199
}
200200

201-
public func up(name: String) async throws {
201+
public func up(name: String, mtu: UInt32? = nil) async throws {
202202
let request = Com_Apple_Containerization_Sandbox_V3_IpLinkSetRequest.with {
203203
$0.interface = name
204204
$0.up = true
205+
if let mtu { $0.mtu = mtu }
205206
}
206207
_ = try await client.ipLinkSet(request)
207208
}

Sources/Containerization/LinuxContainer.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -504,7 +504,7 @@ extension LinuxContainer {
504504
for (index, i) in self.interfaces.enumerated() {
505505
let name = "eth\(index)"
506506
try await agent.addressAdd(name: name, address: i.address)
507-
try await agent.up(name: name)
507+
try await agent.up(name: name, mtu: 1280)
508508
if let gateway = i.gateway {
509509
try await agent.routeAddDefault(name: name, gateway: gateway)
510510
}

Sources/Containerization/SandboxContext/SandboxContext.pb.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -658,9 +658,20 @@ public struct Com_Apple_Containerization_Sandbox_V3_IpLinkSetRequest: Sendable {
658658

659659
public var up: Bool = false
660660

661+
public var mtu: UInt32 {
662+
get {return _mtu ?? 0}
663+
set {_mtu = newValue}
664+
}
665+
/// Returns true if `mtu` has been explicitly set.
666+
public var hasMtu: Bool {return self._mtu != nil}
667+
/// Clears the value of `mtu`. Subsequent reads from it will return its default value.
668+
public mutating func clearMtu() {self._mtu = nil}
669+
661670
public var unknownFields = SwiftProtobuf.UnknownStorage()
662671

663672
public init() {}
673+
674+
fileprivate var _mtu: UInt32? = nil
664675
}
665676

666677
public struct Com_Apple_Containerization_Sandbox_V3_IpLinkSetResponse: Sendable {
@@ -1992,6 +2003,7 @@ extension Com_Apple_Containerization_Sandbox_V3_IpLinkSetRequest: SwiftProtobuf.
19922003
public static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
19932004
1: .same(proto: "interface"),
19942005
2: .same(proto: "up"),
2006+
3: .same(proto: "mtu"),
19952007
]
19962008

19972009
public mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
@@ -2002,24 +2014,33 @@ extension Com_Apple_Containerization_Sandbox_V3_IpLinkSetRequest: SwiftProtobuf.
20022014
switch fieldNumber {
20032015
case 1: try { try decoder.decodeSingularStringField(value: &self.interface) }()
20042016
case 2: try { try decoder.decodeSingularBoolField(value: &self.up) }()
2017+
case 3: try { try decoder.decodeSingularUInt32Field(value: &self._mtu) }()
20052018
default: break
20062019
}
20072020
}
20082021
}
20092022

20102023
public func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
2024+
// The use of inline closures is to circumvent an issue where the compiler
2025+
// allocates stack space for every if/case branch local when no optimizations
2026+
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
2027+
// https://github.com/apple/swift-protobuf/issues/1182
20112028
if !self.interface.isEmpty {
20122029
try visitor.visitSingularStringField(value: self.interface, fieldNumber: 1)
20132030
}
20142031
if self.up != false {
20152032
try visitor.visitSingularBoolField(value: self.up, fieldNumber: 2)
20162033
}
2034+
try { if let v = self._mtu {
2035+
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 3)
2036+
} }()
20172037
try unknownFields.traverse(visitor: &visitor)
20182038
}
20192039

20202040
public static func ==(lhs: Com_Apple_Containerization_Sandbox_V3_IpLinkSetRequest, rhs: Com_Apple_Containerization_Sandbox_V3_IpLinkSetRequest) -> Bool {
20212041
if lhs.interface != rhs.interface {return false}
20222042
if lhs.up != rhs.up {return false}
2043+
if lhs._mtu != rhs._mtu {return false}
20232044
if lhs.unknownFields != rhs.unknownFields {return false}
20242045
return true
20252046
}

Sources/Containerization/SandboxContext/SandboxContext.proto

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,7 @@ message MkdirResponse {}
193193
message IpLinkSetRequest {
194194
string interface = 1;
195195
bool up = 2;
196+
optional uint32 mtu = 3;
196197
}
197198

198199
message IpLinkSetResponse {}

Sources/Containerization/VirtualMachineAgent.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public protocol VirtualMachineAgent: Sendable {
5353
func deleteProcess(id: String, containerID: String?) async throws
5454

5555
// Networking
56-
func up(name: String) async throws
56+
func up(name: String, mtu: UInt32?) async throws
5757
func down(name: String) async throws
5858
func addressAdd(name: String, address: String) async throws
5959
func routeAddDefault(name: String, gateway: String) async throws

Sources/ContainerizationNetlink/NetlinkSession.swift

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -67,12 +67,17 @@ public struct NetlinkSession {
6767
/// - Parameters:
6868
/// - interface: The name of the interface.
6969
/// - up: The value to set the interface state to.
70-
public func linkSet(interface: String, up: Bool) throws {
70+
public func linkSet(interface: String, up: Bool, mtu: UInt32? = nil) throws {
7171
// ip link set dev [interface] [up|down]
7272
let interfaceIndex = try getInterfaceIndex(interface)
73-
let mtuAttr = RTAttribute(
74-
len: UInt16(RTAttribute.size + MemoryLayout<UInt32>.size), type: LinkAttributeType.IFLA_MTU)
75-
let requestSize = NetlinkMessageHeader.size + InterfaceInfo.size + mtuAttr.paddedLen
73+
// build the attribute only when mtu is supplied
74+
let attr: RTAttribute? =
75+
(mtu != nil)
76+
? RTAttribute(
77+
len: UInt16(RTAttribute.size + MemoryLayout<UInt32>.size),
78+
type: LinkAttributeType.IFLA_MTU)
79+
: nil
80+
let requestSize = NetlinkMessageHeader.size + InterfaceInfo.size + (attr?.paddedLen ?? 0)
7681
var requestBuffer = [UInt8](repeating: 0, count: requestSize)
7782
var requestOffset = 0
7883

@@ -91,16 +96,16 @@ public struct NetlinkSession {
9196
change: InterfaceFlags.DEFAULT_CHANGE)
9297
requestOffset = try requestInfo.appendBuffer(&requestBuffer, offset: requestOffset)
9398

94-
requestOffset = try mtuAttr.appendBuffer(&requestBuffer, offset: requestOffset)
95-
guard
96-
let newRequestOffset = requestBuffer.copyIn(
97-
as: UInt32.self,
98-
value: Self.mtu,
99-
offset: requestOffset)
100-
else {
101-
throw NetlinkDataError.sendMarshalFailure
99+
if let attr = attr, let m = mtu {
100+
requestOffset = try attr.appendBuffer(&requestBuffer, offset: requestOffset)
101+
guard
102+
let newRequestOffset =
103+
requestBuffer.copyIn(as: UInt32.self, value: m, offset: requestOffset)
104+
else {
105+
throw NetlinkDataError.sendMarshalFailure
106+
}
107+
requestOffset = newRequestOffset
102108
}
103-
requestOffset = newRequestOffset
104109

105110
guard requestOffset == requestSize else {
106111
throw Error.unexpectedOffset(offset: requestOffset, size: requestSize)

0 commit comments

Comments
 (0)