@@ -242,42 +242,97 @@ func (c *cniProvider) newNS(ctx context.Context, hostname string) (*cniNS, error
242242 cni .WithArgs ("IgnoreUnknown" , "1" ))
243243 }
244244
245- if _ , err := c .CNI .Setup (context .TODO (), id , nativeID , nsOpts ... ); err != nil {
245+ cniRes , err := c .CNI .Setup (context .TODO (), id , nativeID , nsOpts ... )
246+ if err != nil {
246247 deleteNetNS (nativeID )
247248 return nil , errors .Wrap (err , "CNI setup error" )
248249 }
249250 trace .SpanFromContext (ctx ).AddEvent ("finished setting up network namespace" )
250251 bklog .G (ctx ).Debugf ("finished setting up network namespace %s" , id )
251252
252- return & cniNS {
253+ vethName := ""
254+ for k := range cniRes .Interfaces {
255+ if strings .HasPrefix (k , "veth" ) {
256+ if vethName != "" {
257+ // invalid config
258+ vethName = ""
259+ break
260+ }
261+ vethName = k
262+ }
263+ }
264+
265+ ns := & cniNS {
253266 nativeID : nativeID ,
254267 id : id ,
255268 handle : c .CNI ,
256269 opts : nsOpts ,
257- }, nil
270+ vethName : vethName ,
271+ }
272+
273+ if ns .vethName != "" {
274+ sample , err := ns .sample ()
275+ if err == nil && sample != nil {
276+ ns .canSample = true
277+ ns .offsetSample = sample
278+ }
279+ }
280+
281+ return ns , nil
258282}
259283
260284type cniNS struct {
261- pool * cniPool
262- handle cni.CNI
263- id string
264- nativeID string
265- opts []cni.NamespaceOpts
266- lastUsed time.Time
285+ pool * cniPool
286+ handle cni.CNI
287+ id string
288+ nativeID string
289+ opts []cni.NamespaceOpts
290+ lastUsed time.Time
291+ vethName string
292+ canSample bool
293+ offsetSample * network.Sample
294+ prevSample * network.Sample
267295}
268296
269297func (ns * cniNS ) Set (s * specs.Spec ) error {
270298 return setNetNS (s , ns .nativeID )
271299}
272300
273301func (ns * cniNS ) Close () error {
302+ if ns .prevSample != nil {
303+ ns .offsetSample = ns .prevSample
304+ }
274305 if ns .pool == nil {
275306 return ns .release ()
276307 }
277308 ns .pool .put (ns )
278309 return nil
279310}
280311
312+ func (ns * cniNS ) Sample () (* network.Sample , error ) {
313+ if ! ns .canSample {
314+ return nil , nil
315+ }
316+ s , err := ns .sample ()
317+ if err != nil {
318+ return nil , err
319+ }
320+ if s == nil {
321+ return nil , nil
322+ }
323+ if ns .offsetSample != nil {
324+ s .TxBytes -= ns .offsetSample .TxBytes
325+ s .RxBytes -= ns .offsetSample .RxBytes
326+ s .TxPackets -= ns .offsetSample .TxPackets
327+ s .RxPackets -= ns .offsetSample .RxPackets
328+ s .TxErrors -= ns .offsetSample .TxErrors
329+ s .RxErrors -= ns .offsetSample .RxErrors
330+ s .TxDropped -= ns .offsetSample .TxDropped
331+ s .RxDropped -= ns .offsetSample .RxDropped
332+ }
333+ return s , nil
334+ }
335+
281336func (ns * cniNS ) release () error {
282337 bklog .L .Debugf ("releasing cni network namespace %s" , ns .id )
283338 err := ns .handle .Remove (context .TODO (), ns .id , ns .nativeID , ns .opts ... )
0 commit comments