@@ -404,14 +404,15 @@ func (l *Local) Allocate(ctx context.Context, cni *daemon.CNI, request ResourceR
404
404
expectV4 := 0
405
405
expectV6 := 0
406
406
407
+ var ipv4 , ipv6 * IP
407
408
if l .enableIPv4 {
408
409
if localIPRequest .NoCache {
409
410
if len (l .ipv4 )+ l .allocatingV4 .Len () >= l .cap {
410
411
return nil , []Trace {{Condition : Full }}
411
412
}
412
413
expectV4 = 1
413
414
} else {
414
- ipv4 : = l .ipv4 .PeekAvailable (cni .PodID )
415
+ ipv4 = l .ipv4 .PeekAvailable (cni .PodID )
415
416
if ipv4 == nil && len (l .ipv4 )+ l .allocatingV4 .Len () >= l .cap {
416
417
return nil , []Trace {{Condition : Full }}
417
418
} else if ipv4 == nil {
@@ -427,7 +428,7 @@ func (l *Local) Allocate(ctx context.Context, cni *daemon.CNI, request ResourceR
427
428
}
428
429
expectV6 = 1
429
430
} else {
430
- ipv6 : = l .ipv6 .PeekAvailable (cni .PodID )
431
+ ipv6 = l .ipv6 .PeekAvailable (cni .PodID )
431
432
if ipv6 == nil && len (l .ipv6 )+ l .allocatingV6 .Len () >= l .cap {
432
433
return nil , []Trace {{Condition : Full }}
433
434
} else if ipv6 == nil {
@@ -441,6 +442,30 @@ func (l *Local) Allocate(ctx context.Context, cni *daemon.CNI, request ResourceR
441
442
return nil , []Trace {{Condition : InsufficientVSwitchIP , Reason : fmt .Sprintf ("alloc inhibit, expire at %s" , l .ipAllocInhibitExpireAt .String ())}}
442
443
}
443
444
445
+ ok1 := l .enableIPv4 && ipv4 != nil || ! l .enableIPv4
446
+ ok2 := l .enableIPv6 && ipv6 != nil || ! l .enableIPv6
447
+
448
+ if ok1 && ok2 {
449
+ // direct return
450
+ respCh := make (chan * AllocResp )
451
+ // assign ip to pod , as we are ready
452
+ // this must be protected by local
453
+ if ipv4 != nil {
454
+ ipv4 .Allocate (cni .PodID )
455
+ }
456
+ if ipv6 != nil {
457
+ ipv6 .Allocate (cni .PodID )
458
+ }
459
+
460
+ go func () {
461
+ l .cond .L .Lock ()
462
+ defer l .cond .L .Unlock ()
463
+
464
+ l .commit (ctx , respCh , ipv4 , ipv6 , cni .PodID )
465
+ }()
466
+ return respCh , nil
467
+ }
468
+
444
469
for i := 0 ; i < expectV4 ; i ++ {
445
470
l .allocatingV4 = append (l .allocatingV4 , localIPRequest )
446
471
}
@@ -590,10 +615,7 @@ func (l *Local) allocWorker(ctx context.Context, cni *daemon.CNI, request *Local
590
615
return
591
616
default :
592
617
}
593
-
594
- resp := & AllocResp {}
595
-
596
- var ip types.IPSet2
618
+
597
619
var ipv4 , ipv6 * IP
598
620
if l .enableIPv4 {
599
621
ipv4 = l .ipv4 .PeekAvailable (cni .PodID )
@@ -602,42 +624,16 @@ func (l *Local) allocWorker(ctx context.Context, cni *daemon.CNI, request *Local
602
624
l .cond .Wait ()
603
625
continue
604
626
}
605
- ip .IPv4 = ipv4 .ip
606
627
}
607
628
if l .enableIPv6 {
608
629
ipv6 = l .ipv6 .PeekAvailable (cni .PodID )
609
630
if ipv6 == nil {
610
631
l .cond .Wait ()
611
632
continue
612
633
}
613
- ip .IPv6 = ipv6 .ip
614
634
}
615
635
616
- resp .NetworkConfigs = append (resp .NetworkConfigs , & LocalIPResource {
617
- ENI : * l .eni ,
618
- IP : ip ,
619
- })
620
-
621
- log .Info ("allocWorker got ip" , "eni" , l .eni .ID , "ipv4" , ip .IPv4 .String (), "ipv6" , ip .IPv6 .String ())
622
-
623
- select {
624
- case <- ctx .Done ():
625
- continue
626
- case respCh <- resp :
627
- // mark the ip as allocated
628
- if ipv4 != nil {
629
- ipv4 .Allocate (cni .PodID )
630
- if cni .PodID != "" {
631
- metric .ResourcePoolIdle .WithLabelValues (metric .ResourcePoolTypeLocal , string (types .IPStackIPv4 )).Dec ()
632
- }
633
- }
634
- if ipv6 != nil {
635
- ipv6 .Allocate (cni .PodID )
636
- if cni .PodID != "" {
637
- metric .ResourcePoolIdle .WithLabelValues (metric .ResourcePoolTypeLocal , string (types .IPStackIPv6 )).Dec ()
638
- }
639
- }
640
- }
636
+ l .commit (ctx , respCh , ipv4 , ipv6 , cni .PodID )
641
637
642
638
return
643
639
}
@@ -1045,6 +1041,47 @@ func (l *Local) Status() Status {
1045
1041
return s
1046
1042
}
1047
1043
1044
+ // commit send the allocated ip result to respCh
1045
+ // if ctx canceled, the respCh will be closed
1046
+ func (l * Local ) commit (ctx context.Context , respCh chan * AllocResp , ipv4 , ipv6 * IP , podID string ) {
1047
+ var ip types.IPSet2
1048
+ if ipv4 != nil {
1049
+ ip .IPv4 = ipv4 .ip
1050
+ ipv4 .Allocate (podID )
1051
+ if podID != "" {
1052
+ metric .ResourcePoolIdle .WithLabelValues (metric .ResourcePoolTypeLocal , string (types .IPStackIPv4 )).Dec ()
1053
+ }
1054
+ }
1055
+ if ipv6 != nil {
1056
+ ip .IPv6 = ipv6 .ip
1057
+ ipv6 .Allocate (podID )
1058
+ if podID != "" {
1059
+ metric .ResourcePoolIdle .WithLabelValues (metric .ResourcePoolTypeLocal , string (types .IPStackIPv6 )).Dec ()
1060
+ }
1061
+ }
1062
+ resp := & AllocResp {}
1063
+ resp .NetworkConfigs = append (resp .NetworkConfigs , & LocalIPResource {
1064
+ ENI : * l .eni ,
1065
+ IP : ip ,
1066
+ })
1067
+ select {
1068
+ case <- ctx .Done ():
1069
+ if ipv4 != nil {
1070
+ ipv4 .Release (podID )
1071
+ }
1072
+ if ipv6 != nil {
1073
+ ipv6 .Release (podID )
1074
+ }
1075
+
1076
+ // parent cancel the context, so close the ch
1077
+ close (respCh )
1078
+
1079
+ return
1080
+ case respCh <- resp :
1081
+ logr .FromContextOrDiscard (ctx ).Info ("allocWorker got ip" , "eni" , l .eni .ID , "ipv4" , ip .IPv4 .String (), "ipv6" , ip .IPv6 .String ())
1082
+ }
1083
+ }
1084
+
1048
1085
// syncIPLocked will mark ip as invalid , if not found in remote
1049
1086
func syncIPLocked (lo Set , remote []netip.Addr ) {
1050
1087
s := sets .New [netip.Addr ](remote ... )
0 commit comments