@@ -68,7 +68,7 @@ func (csh cniServerHandler) configureDpdkNic(podName, podNamespace, provider, ne
6868 return ovs .SetInterfaceBandwidth (podName , podNamespace , ifaceID , egress , ingress )
6969}
7070
71- func (csh cniServerHandler ) configureNic (podName , podNamespace , provider , netns , containerID , vfDriver , ifName , mac string , mtu int , ip , gateway string , isDefaultRoute , detectIPConflict bool , routes []request.Route , _ , _ []string , ingress , egress , deviceID , nicType , latency , limit , loss , jitter string , gwCheckMode int , u2oInterconnectionIP , oldPodName string ) ([]request.Route , error ) {
71+ func (csh cniServerHandler ) configureNic (podName , podNamespace , provider , netns , containerID , vfDriver , ifName , mac string , mtu int , ip , gateway string , isDefaultRoute , vmMigration bool , routes []request.Route , _ , _ []string , ingress , egress , deviceID , nicType , latency , limit , loss , jitter string , gwCheckMode int , u2oInterconnectionIP , oldPodName string ) ([]request.Route , error ) {
7272 var err error
7373 var hostNicName , containerNicName , pfPci string
7474 var vfID int
@@ -197,7 +197,7 @@ func (csh cniServerHandler) configureNic(podName, podNamespace, provider, netns,
197197 klog .Error (err )
198198 return nil , err
199199 }
200- finalRoutes , err := csh .configureContainerNic (podName , podNamespace , containerNicName , ifName , ip , gateway , isDefaultRoute , detectIPConflict , routes , macAddr , podNS , mtu , nicType , gwCheckMode , u2oInterconnectionIP )
200+ finalRoutes , err := csh .configureContainerNic (podName , podNamespace , containerNicName , ifName , ip , gateway , isDefaultRoute , vmMigration , routes , macAddr , podNS , mtu , nicType , gwCheckMode , u2oInterconnectionIP )
201201 if err != nil {
202202 klog .Error (err )
203203 return nil , err
@@ -380,7 +380,7 @@ func configureHostNic(nicName string) error {
380380 return nil
381381}
382382
383- func (csh cniServerHandler ) configureContainerNic (podName , podNamespace , nicName , ifName , ipAddr , gateway string , isDefaultRoute , detectIPConflict bool , routes []request.Route , macAddr net.HardwareAddr , netns ns.NetNS , mtu int , nicType string , gwCheckMode int , u2oInterconnectionIP string ) ([]request.Route , error ) {
383+ func (csh cniServerHandler ) configureContainerNic (podName , podNamespace , nicName , ifName , ipAddr , gateway string , isDefaultRoute , vmMigration bool , routes []request.Route , macAddr net.HardwareAddr , netns ns.NetNS , mtu int , nicType string , gwCheckMode int , u2oInterconnectionIP string ) ([]request.Route , error ) {
384384 containerLink , err := netlink .LinkByName (nicName )
385385 if err != nil {
386386 return nil , fmt .Errorf ("can not find container nic %s: %w" , nicName , err )
@@ -397,9 +397,14 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName
397397 return nil , fmt .Errorf ("failed to move link to netns: %w" , err )
398398 }
399399
400+ // do not perform ipv4/ipv6 duplicate address detection during VM live migration
401+ checkIPv6DAD := ! vmMigration
402+ detectIPv4Conflict := ! vmMigration && csh .Config .EnableArpDetectIPConflict
400403 var finalRoutes []request.Route
401404 err = ns .WithNetNSPath (netns .Path (), func (_ ns.NetNS ) error {
405+ interfaceName := nicName
402406 if nicType != util .InternalType {
407+ interfaceName = ifName
403408 if err = netlink .LinkSetName (containerLink , ifName ); err != nil {
404409 klog .Error (err )
405410 return err
@@ -415,12 +420,12 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName
415420 klog .Error (err )
416421 return err
417422 }
418- if err = configureNic (nicName , ipAddr , macAddr , mtu , detectIPConflict , false , false ); err != nil {
423+ if err = configureNic (nicName , ipAddr , macAddr , mtu , detectIPv4Conflict , false , false ); err != nil {
419424 klog .Error (err )
420425 return err
421426 }
422427 } else {
423- if err = configureNic (ifName , ipAddr , macAddr , mtu , detectIPConflict , true , false ); err != nil {
428+ if err = configureNic (ifName , ipAddr , macAddr , mtu , detectIPv4Conflict , true , false ); err != nil {
424429 klog .Error (err )
425430 return err
426431 }
@@ -501,22 +506,35 @@ func (csh cniServerHandler) configureContainerNic(podName, podNamespace, nicName
501506 }
502507
503508 if gwCheckMode != gatewayCheckModeDisabled {
504- var (
505- underlayGateway = gwCheckMode == gatewayCheckModeArping || gwCheckMode == gatewayCheckModeArpingNotConcerned
506- interfaceName = nicName
507- )
509+ underlayGateway := gwCheckMode == gatewayCheckModeArping || gwCheckMode == gatewayCheckModeArpingNotConcerned
510+ if u2oInterconnectionIP != "" {
511+ if err = csh .checkGatewayReady (podName , podNamespace , gwCheckMode , interfaceName , ipAddr , u2oInterconnectionIP , false , true ); err != nil {
512+ klog .Error (err )
513+ return err
514+ }
515+ }
516+ if err = csh .checkGatewayReady (podName , podNamespace , gwCheckMode , interfaceName , ipAddr , gateway , underlayGateway , true ); err != nil {
517+ klog .Error (err )
518+ return err
519+ }
520+ }
508521
509- if nicType != util .InternalType {
510- interfaceName = ifName
522+ if checkIPv6DAD {
523+ // check whether the ipv6 address has a dadfailed flag
524+ addresses , err := netlink .AddrList (containerLink , netlink .FAMILY_V6 )
525+ if err != nil {
526+ err = fmt .Errorf ("failed to get ipv6 addresses of link %s: %w" , interfaceName , err )
527+ klog .Error (err )
528+ return err
511529 }
512530
513- if u2oInterconnectionIP != "" {
514- if err := csh .checkGatewayReady (podName , podNamespace , gwCheckMode , interfaceName , ipAddr , u2oInterconnectionIP , false , true ); err != nil {
531+ for _ , addr := range addresses {
532+ if addr .Flags & syscall .IFA_F_DADFAILED != 0 {
533+ err = fmt .Errorf ("IPv6 address %s has a dadfailed flag, please check whether it has been used by another host" , addr .IP .String ())
515534 klog .Error (err )
516535 return err
517536 }
518537 }
519- return csh .checkGatewayReady (podName , podNamespace , gwCheckMode , interfaceName , ipAddr , gateway , underlayGateway , true )
520538 }
521539
522540 return nil
@@ -1122,7 +1140,7 @@ func macToLinkLocalIPv6(mac net.HardwareAddr) (net.IP, error) {
11221140 return linkLocalIPv6 , nil
11231141}
11241142
1125- func configureNic (link , ip string , macAddr net.HardwareAddr , mtu int , detectIPConflict , setUfoOff , ipv6LinkLocalOn bool ) error {
1143+ func configureNic (link , ip string , macAddr net.HardwareAddr , mtu int , detectIPv4Conflict , setUfoOff , ipv6LinkLocalOn bool ) error {
11261144 nodeLink , err := netlink .LinkByName (link )
11271145 if err != nil {
11281146 klog .Error (err )
@@ -1207,22 +1225,23 @@ func configureNic(link, ip string, macAddr net.HardwareAddr, mtu int, detectIPCo
12071225 }
12081226 }
12091227 for ip , addr := range ipAddMap {
1210- if detectIPConflict && addr .IP .To4 () != nil {
1211- ip := addr .IP .String ()
1212- mac , err := util .ArpDetectIPConflict (link , ip , macAddr )
1213- if err != nil {
1214- err = fmt .Errorf ("failed to detect address conflict for %s on link %s: %w" , ip , link , err )
1215- klog .Error (err )
1216- return err
1217- }
1218- if mac != nil {
1219- return fmt .Errorf ("IP address %s has already been used by host with MAC %s" , ip , mac )
1220- }
1221- }
1222- if addr .IP .To4 () != nil && ! detectIPConflict {
1223- // when detectIPConflict is true, free arp is already broadcast in the step of announcement
1224- if err := util .AnnounceArpAddress (link , addr .IP .String (), macAddr , 1 , 1 * time .Second ); err != nil {
1225- klog .Warningf ("failed to broadcast free arp with err %v" , err )
1228+ if addr .IP .To4 () != nil {
1229+ if detectIPv4Conflict {
1230+ ip := addr .IP .String ()
1231+ mac , err := util .ArpDetectIPConflict (link , ip , macAddr )
1232+ if err != nil {
1233+ err = fmt .Errorf ("failed to detect address conflict for %s on link %s: %w" , ip , link , err )
1234+ klog .Error (err )
1235+ return err
1236+ }
1237+ if mac != nil {
1238+ return fmt .Errorf ("IP address %s has already been used by host with MAC %s" , ip , mac )
1239+ }
1240+ } else {
1241+ // when detectIPConflict is true, free arp is already broadcast in the step of announcement
1242+ if err := util .AnnounceArpAddress (link , addr .IP .String (), macAddr , 1 , 1 * time .Second ); err != nil {
1243+ klog .Warningf ("failed to broadcast free arp with err %v" , err )
1244+ }
12261245 }
12271246 }
12281247
0 commit comments