@@ -113,6 +113,16 @@ 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 , & oci.LinuxNetDevice {
121
+ Name : dev .Name ,
122
+ })
123
+ }
124
+ }
125
+
116
126
if len (e .Mounts ) > 0 {
117
127
for _ , m := range e .Mounts {
118
128
specgen .RemoveMount (m .ContainerPath )
@@ -162,6 +172,14 @@ func (e *ContainerEdits) Apply(spec *oci.Spec) error {
162
172
return nil
163
173
}
164
174
175
+ func specgenAddLinuxNetDevice (specgen * ocigen.Generator , hostIf string , netDev * oci.LinuxNetDevice ) {
176
+ if specgen == nil || netDev == nil {
177
+ return
178
+ }
179
+ ensureLinuxNetDevices (specgen .Config )
180
+ specgen .Config .Linux .NetDevices [hostIf ] = * netDev
181
+ }
182
+
165
183
// Validate container edits.
166
184
func (e * ContainerEdits ) Validate () error {
167
185
if e == nil || e .ContainerEdits == nil {
@@ -191,6 +209,9 @@ func (e *ContainerEdits) Validate() error {
191
209
return err
192
210
}
193
211
}
212
+ if err := ValidateNetDevices (e .NetDevices ); err != nil {
213
+ return err
214
+ }
194
215
195
216
return nil
196
217
}
@@ -210,6 +231,7 @@ func (e *ContainerEdits) Append(o *ContainerEdits) *ContainerEdits {
210
231
211
232
e .Env = append (e .Env , o .Env ... )
212
233
e .DeviceNodes = append (e .DeviceNodes , o .DeviceNodes ... )
234
+ e .NetDevices = append (e .NetDevices , o .NetDevices ... )
213
235
e .Hooks = append (e .Hooks , o .Hooks ... )
214
236
e .Mounts = append (e .Mounts , o .Mounts ... )
215
237
if o .IntelRdt != nil {
@@ -244,6 +266,9 @@ func (e *ContainerEdits) isEmpty() bool {
244
266
if e .IntelRdt != nil {
245
267
return false
246
268
}
269
+ if e .NetDevices != nil {
270
+ return false
271
+ }
247
272
return true
248
273
}
249
274
@@ -257,6 +282,37 @@ func ValidateEnv(env []string) error {
257
282
return nil
258
283
}
259
284
285
+ // ValidateNetDevices validates the given net devices.
286
+ func ValidateNetDevices (devices []* cdi.NetDevice ) error {
287
+ var (
288
+ hostSeen = map [string ]string {}
289
+ nameSeen = map [string ]string {}
290
+ )
291
+
292
+ for _ , dev := range devices {
293
+ if dev .HostIf == "" {
294
+ return errors .New ("invalid net device, empty HostIf" )
295
+ }
296
+ if dev .Name == "" {
297
+ return errors .New ("invalid net device, empty Name" )
298
+ }
299
+
300
+ if other , ok := hostSeen [dev .HostIf ]; ok {
301
+ return fmt .Errorf ("invalid net device, duplicate HostIf %q with names %q and %q" ,
302
+ dev .HostIf , dev .Name , other )
303
+ }
304
+ hostSeen [dev .HostIf ] = dev .Name
305
+
306
+ if other , ok := nameSeen [dev .Name ]; ok {
307
+ return fmt .Errorf ("invalid net device, duplicate Name %q with HostIf %q and %q" ,
308
+ dev .Name , dev .HostIf , other )
309
+ }
310
+ nameSeen [dev .Name ] = dev .HostIf
311
+ }
312
+
313
+ return nil
314
+ }
315
+
260
316
// DeviceNode is a CDI Spec DeviceNode wrapper, used for validating DeviceNodes.
261
317
type DeviceNode struct {
262
318
* cdi.DeviceNode
@@ -351,6 +407,16 @@ func ensureOCIHooks(spec *oci.Spec) {
351
407
}
352
408
}
353
409
410
+ // Ensure OCI Spec Linux NetDevices map is not nil.
411
+ func ensureLinuxNetDevices (spec * oci.Spec ) {
412
+ if spec .Linux == nil {
413
+ spec .Linux = & oci.Linux {}
414
+ }
415
+ if spec .Linux .NetDevices == nil {
416
+ spec .Linux .NetDevices = map [string ]oci.LinuxNetDevice {}
417
+ }
418
+ }
419
+
354
420
// sortMounts sorts the mounts in the given OCI Spec.
355
421
func sortMounts (specgen * ocigen.Generator ) {
356
422
mounts := specgen .Mounts ()
0 commit comments