@@ -113,6 +113,14 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
113
113
}
114
114
}
115
115
116
+ if e .NetDevices != nil {
117
+ // specgen is currently missing functionality to set Linux NetDevices,
118
+ // so we use a locally rolled function for now.
119
+ for _ , dev := range e .NetDevices {
120
+ specgenAddLinuxNetDevice (& specgen , dev .HostIf , (& LinuxNetDevice {dev }).toOCI ())
121
+ }
122
+ }
123
+
116
124
if len (e .Mounts ) > 0 {
117
125
for _ , m := range e .Mounts {
118
126
specgen .RemoveMount (m .ContainerPath )
@@ -162,6 +170,24 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
162
170
return nil
163
171
}
164
172
173
+ func specgenAddLinuxNetDevice (specgen * ocigen.Generator , hostIf string , netDev * oci.LinuxNetDevice ) {
174
+ if specgen == nil || netDev == nil {
175
+ return
176
+ }
177
+ ensureLinuxNetDevices (specgen .Config )
178
+ specgen .Config .Linux .NetDevices [hostIf ] = * netDev
179
+ }
180
+
181
+ // Ensure OCI Spec Linux NetDevices map is not nil.
182
+ func ensureLinuxNetDevices (spec * oci.Spec ) {
183
+ if spec .Linux == nil {
184
+ spec .Linux = & oci.Linux {}
185
+ }
186
+ if spec .Linux .NetDevices == nil {
187
+ spec .Linux .NetDevices = map [string ]oci.LinuxNetDevice {}
188
+ }
189
+ }
190
+
165
191
// Validate container edits.
166
192
func (e * ContainerEdits ) Validate () error {
167
193
if e == nil || e .ContainerEdits == nil {
@@ -191,6 +217,9 @@ func (e *ContainerEdits) Validate() error {
191
217
return err
192
218
}
193
219
}
220
+ if err := ValidateNetDevices (e .NetDevices ); err != nil {
221
+ return err
222
+ }
194
223
195
224
return nil
196
225
}
@@ -210,6 +239,7 @@ func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits {
210
239
211
240
e .Env = append (e .Env , o .Env ... )
212
241
e .DeviceNodes = append (e .DeviceNodes , o .DeviceNodes ... )
242
+ e .NetDevices = append (e .NetDevices , o .NetDevices ... )
213
243
e .Hooks = append (e .Hooks , o .Hooks ... )
214
244
e .Mounts = append (e .Mounts , o .Mounts ... )
215
245
if o .IntelRdt != nil {
@@ -244,6 +274,9 @@ func (e *ContainerEdits) isEmpty() bool {
244
274
if e .IntelRdt != nil {
245
275
return false
246
276
}
277
+ if e .NetDevices != nil {
278
+ return false
279
+ }
247
280
return true
248
281
}
249
282
@@ -257,6 +290,46 @@ func ValidateEnv(env []string) error {
257
290
return nil
258
291
}
259
292
293
+ // ValidateNetDevices validates the given net devices.
294
+ func ValidateNetDevices (devices []* cdi.LinuxNetDevice ) error {
295
+ var (
296
+ hostSeen = map [string ]string {}
297
+ nameSeen = map [string ]string {}
298
+ )
299
+
300
+ for _ , dev := range devices {
301
+ if other , ok := hostSeen [dev .HostIf ]; ok {
302
+ return fmt .Errorf ("invalid linux net device, duplicate HostIf %q with names %q and %q" ,
303
+ dev .HostIf , dev .Name , other )
304
+ }
305
+ hostSeen [dev .HostIf ] = dev .Name
306
+
307
+ if other , ok := nameSeen [dev .Name ]; ok {
308
+ return fmt .Errorf ("invalid linux net device, duplicate Name %q with HostIf %q and %q" ,
309
+ dev .Name , dev .HostIf , other )
310
+ }
311
+ nameSeen [dev .Name ] = dev .HostIf
312
+ }
313
+
314
+ return nil
315
+ }
316
+
317
+ // LinuxNetDevice is a CDI Spec LinuxNetDevice wrapper, used for OCI conversion and validating.
318
+ type LinuxNetDevice struct {
319
+ * cdi.LinuxNetDevice
320
+ }
321
+
322
+ // Validate LinuxNetDevice.
323
+ func (d * LinuxNetDevice ) Validate () error {
324
+ if d .HostIf == "" {
325
+ return errors .New ("invalid linux net device, empty HostIf" )
326
+ }
327
+ if d .Name == "" {
328
+ return errors .New ("invalid linux net device, empty Name" )
329
+ }
330
+ return nil
331
+ }
332
+
260
333
// DeviceNode is a CDI Spec DeviceNode wrapper, used for validating DeviceNodes.
261
334
type DeviceNode struct {
262
335
* cdi.DeviceNode
0 commit comments