@@ -66,82 +66,86 @@ func NewSriovManager() Manager {
6666// SetupVF sets up a VF in Pod netns
6767func (s * sriovManager ) SetupVF (conf * sriovtypes.NetConf , podifName string , netns ns.NetNS ) error {
6868 linkName := conf .OrigVfState .HostIFName
69+ // Save the original NS in case we need to restore it
70+ // after an error occurs
71+ initns , _ := ns .GetCurrentNS ()
72+ tempNS , err := ns .TempNetNS ()
73+ if err != nil {
74+ return fmt .Errorf ("failed to create tempNS: %v" , err )
75+ }
76+ defer tempNS .Close ()
6977
7078 linkObj , err := s .nLink .LinkByName (linkName )
7179 if err != nil {
72- return fmt .Errorf ("error getting VF netdevice with name %s" , linkName )
80+ return fmt .Errorf ("error: %v. Failed to get VF netdevice with name %s" , err , linkName )
7381 }
7482
7583 // Save the original effective MAC address before overriding it
7684 conf .OrigVfState .EffectiveMAC = linkObj .Attrs ().HardwareAddr .String ()
7785
78- // tempName used as intermediary name to avoid name conflicts
79- tempName := fmt .Sprintf ("%s%d" , "temp_" , linkObj .Attrs ().Index )
80-
81- // 1. Set link down
82- logging .Debug ("1. Set link down" ,
86+ // 1.Move interface to tempNS
87+ logging .Debug ("1. Move the interface to tempNS" ,
8388 "func" , "SetupVF" ,
8489 "linkObj" , linkObj )
85- if err := s .nLink .LinkSetDown (linkObj ); err != nil {
86- return fmt .Errorf ("failed to down vf device %q: %v" , linkName , err )
87- }
88-
89- // 2. Set temp name
90- logging .Debug ("2. Set temp name" ,
91- "func" , "SetupVF" ,
92- "linkObj" , linkObj ,
93- "tempName" , tempName )
94- if err := s .nLink .LinkSetName (linkObj , tempName ); err != nil {
95- return fmt .Errorf ("error setting temp IF name %s for %s" , tempName , linkName )
90+ if err = s .nLink .LinkSetNsFd (linkObj , int (tempNS .Fd ())); err != nil {
91+ return fmt .Errorf ("failed to move %q to tempNS: %v" , linkName , err )
9692 }
93+ err = tempNS .Do (func (linkNS ns.NetNS ) error {
94+ // lookup the device in tempNS (index might have changed)
95+ tempNSLinkObj , err := s .nLink .LinkByName (linkName )
96+ if err != nil {
97+ return fmt .Errorf ("failed to find %q in tempNS: %v" , linkName , err )
98+ }
99+ // Rename the interface to pod interface name
100+ if err = s .nLink .LinkSetName (tempNSLinkObj , podifName ); err != nil {
101+ return fmt .Errorf ("failed to rename host device %q to %q: %v" , linkName , podifName , err )
102+ }
97103
98- // 3. Remove alt name from the nic
99- logging .Debug ("3. Remove interface original name from alt names" ,
100- "func" , "SetupVF" ,
101- "linkObj" , linkObj ,
102- "OriginalLinkName" , linkName ,
103- "tempName" , tempName )
104- linkObj , err = s .nLink .LinkByName (tempName )
105- if err != nil {
106- return fmt .Errorf ("error getting VF netdevice with name %s: %v" , tempName , err )
107- }
108- for _ , altName := range linkObj .Attrs ().AltNames {
109- if altName == linkName {
110- if err := s .nLink .LinkDelAltName (linkObj , linkName ); err != nil {
111- return fmt .Errorf ("error removing VF altname %s: %v" , linkName , err )
104+ // 3. Remove alt name from the nic
105+ logging .Debug ("3. Remove interface original name from alt names" ,
106+ "func" , "SetupVF" ,
107+ "tempNSObj" , tempNSLinkObj ,
108+ "OriginalLinkName" , linkName )
109+ for _ , altName := range tempNSLinkObj .Attrs ().AltNames {
110+ if altName == linkName {
111+ if err = s .nLink .LinkDelAltName (tempNSLinkObj , linkName ); err != nil {
112+ return fmt .Errorf ("error removing VF altname %s: %v" , linkName , err )
113+ }
112114 }
113115 }
114- }
115116
116- // 4. Change netns
117- logging .Debug ("4. Change netns" ,
118- "func" , "SetupVF" ,
119- "linkObj" , linkObj ,
120- "netns.Fd()" , int (netns .Fd ()))
121- if err := s .nLink .LinkSetNsFd (linkObj , int (netns .Fd ())); err != nil {
122- return fmt .Errorf ("failed to move IF %s to netns: %q" , tempName , err )
117+ // 4. Change netns
118+ logging .Debug ("4. Change netns" ,
119+ "func" , "SetupVF" ,
120+ "tempNSObj" , tempNSLinkObj ,
121+ "netns.Fd()" , int (netns .Fd ()))
122+ if err = s .nLink .LinkSetNsFd (tempNSLinkObj , int (netns .Fd ())); err != nil {
123+ return fmt .Errorf ("failed to move IF %s to netns: %w" , podifName , err )
124+ }
125+ return nil
126+ })
127+ if err != nil {
128+ logging .Debug ("Move the interface back to initNS because of " , "error" , err )
129+ s .moveAndRenameLink (tempNS , podifName , linkName , initns )
130+ return err
123131 }
124132
125- if err := netns .Do (func (_ ns.NetNS ) error {
126- // 5. Set Pod IF name
127- logging .Debug ("5. Set Pod IF name" ,
128- "func" , "SetupVF" ,
129- "linkObj" , linkObj ,
130- "podifName" , podifName )
131- if err := s .nLink .LinkSetName (linkObj , podifName ); err != nil {
132- return fmt .Errorf ("error setting container interface name %s for %s" , linkName , tempName )
133+ err = netns .Do (func (_ ns.NetNS ) error {
134+ netNSLinkObj , err := s .nLink .LinkByName (podifName )
135+ if err != nil {
136+ return fmt .Errorf ("error: %v. Failed to get VF netdevice with name %s" , err , podifName )
133137 }
134138
135- // 6 . Enable IPv4 ARP notify and IPv6 Network Discovery notify
139+ // 5 . Enable IPv4 ARP notify and IPv6 Network Discovery notify
136140 // Error is ignored here because enabling this feature is only a performance enhancement.
137- logging .Debug ("6 . Enable IPv4 ARP notify and IPv6 Network Discovery notify" ,
141+ logging .Debug ("5 . Enable IPv4 ARP notify and IPv6 Network Discovery notify" ,
138142 "func" , "SetupVF" ,
139143 "podifName" , podifName )
140144 _ = s .utils .EnableArpAndNdiscNotify (podifName )
141145
142- // 7 . Set MAC address
146+ // 6 . Set MAC address
143147 if conf .MAC != "" {
144- logging .Debug ("7 . Set MAC address" ,
148+ logging .Debug ("6 . Set MAC address" ,
145149 "func" , "SetupVF" ,
146150 "s.nLink" , s .nLink ,
147151 "podifName" , podifName ,
@@ -152,31 +156,57 @@ func (s *sriovManager) SetupVF(conf *sriovtypes.NetConf, podifName string, netns
152156 }
153157 }
154158
155- logging .Debug ("8 . Enable Optimistic DAD for IPv6 addresses" , "func" , "SetupVF" ,
156- "linkObj" , linkObj )
159+ logging .Debug ("7 . Enable Optimistic DAD for IPv6 addresses" , "func" , "SetupVF" ,
160+ "linkObj" , netNSLinkObj )
157161 _ = s .utils .EnableOptimisticDad (podifName )
158162
159- // 9 . Bring IF up in Pod netns
160- logging .Debug ("9 . Bring IF up in Pod netns" ,
163+ // 8 . Bring IF up in Pod netns
164+ logging .Debug ("8 . Bring IF up in Pod netns" ,
161165 "func" , "SetupVF" ,
162- "linkObj" , linkObj )
163- if err : = s .nLink .LinkSetUp (linkObj ); err != nil {
166+ "linkObj" , netNSLinkObj )
167+ if err = s .nLink .LinkSetUp (netNSLinkObj ); err != nil {
164168 return fmt .Errorf ("error bringing interface up in container ns: %q" , err )
165169 }
166170
167171 return nil
168- }); err != nil {
169- return fmt .Errorf ("error setting up interface in container namespace: %q" , err )
172+ })
173+ if err != nil {
174+ // Cleanup: try to move interface back to tempNS
175+ logging .Debug ("Move the interface back to tempNS because of " , "error" , err )
176+ // Restore the original link name in case of error in renaming
177+ s .moveAndRenameLink (netns , podifName , linkName , initns )
178+ return err
170179 }
171180
172181 // Copy the MTU value to a new variable
173182 // and use it as a pointer
174183 vfMTU := linkObj .Attrs ().MTU
175184 conf .MTU = & vfMTU
176-
177185 return nil
178186}
179187
188+ // moveAndRenameLink restores the original link name and moves it back to initns
189+ func (s * sriovManager ) moveAndRenameLink (sourceNM ns.NetNS , podifName , linkName string , initns ns.NetNS ) {
190+ _ = sourceNM .Do (func (_ ns.NetNS ) error {
191+ // Restore the original link name in case of error in renaming
192+ if nsLinkObj , err := s .nLink .LinkByName (podifName ); err == nil {
193+ linkSetNameError := s .nLink .LinkSetName (nsLinkObj , linkName )
194+ if linkSetNameError != nil {
195+ logging .Warning ("LinkSetName failed when trying to restore original name" , "error" , linkSetNameError )
196+ }
197+ }
198+
199+ // Try to move interface back to initns
200+ if nsLinkObj , e := s .nLink .LinkByName (linkName ); e == nil {
201+ linkSetNsFdError := s .nLink .LinkSetNsFd (nsLinkObj , int (initns .Fd ()))
202+ if linkSetNsFdError != nil {
203+ logging .Warning ("LinkSetNsFd failed when trying to move back to initns in case of an error" , "error" , linkSetNsFdError )
204+ }
205+ }
206+ return nil
207+ })
208+ }
209+
180210// ReleaseVF reset a VF from Pod netns and return it to init netns
181211func (s * sriovManager ) ReleaseVF (conf * sriovtypes.NetConf , podifName string , netns ns.NetNS ) error {
182212 initns , err := ns .GetCurrentNS ()
@@ -273,7 +303,6 @@ func (s *sriovManager) ApplyVFConfig(conf *sriovtypes.NetConf) error {
273303 return fmt .Errorf ("failed to set vf %d vlan configuration - id %d, qos %d and proto %s: %v" , conf .VFID , * conf .Vlan , * conf .VlanQoS , * conf .VlanProto , err )
274304 }
275305 }
276-
277306 // 2. Set mac address
278307 if conf .MAC != "" {
279308 // when we restore the original hardware mac address we may get a device or resource busy. so we introduce retry
0 commit comments