@@ -110,11 +110,24 @@ func NewTransparentVlanEndpointClient(
110110return client
111111}
112112
113+ // cleanupInterfaceIfExists checks if an interface exists and deletes it if found
114+ // Returns an error if the deletion fails
115+ func (client * TransparentVlanEndpointClient ) cleanupInterfaceIfExists (interfaceName string ) error {
116+ _ , ifExists := client .netioshim .GetNetworkInterfaceByName (interfaceName )
117+ if ifExists == nil {
118+ logger .Info ("Interface exists, deleting" , zap .String ("interfaceName" , interfaceName ))
119+ if err := client .netlink .DeleteLink (interfaceName ); err != nil {
120+ return errors .Wrapf (err , "failed to clean up %s" , interfaceName )
121+ }
122+ }
123+ return nil
124+ }
125+
113126// Adds interfaces to the vnet (created if not existing) and vm namespace
114127func (client * TransparentVlanEndpointClient ) AddEndpoints (epInfo * EndpointInfo ) error {
115128// VM Namespace
116129if err := client .ensureCleanPopulateVM (); err != nil {
117- return errors .Wrap (err , "failed to ensure both network namespace and vlan veth were present or both absent" )
130+ return errors .Wrap (err , "failed to ensure both network namespace and vlan interface were present or both absent" )
118131}
119132if err := client .PopulateVM (epInfo ); err != nil {
120133return err
@@ -131,7 +144,7 @@ func (client *TransparentVlanEndpointClient) AddEndpoints(epInfo *EndpointInfo)
131144// Called from AddEndpoints, Namespace: VM and Vnet
132145func (client * TransparentVlanEndpointClient ) ensureCleanPopulateVM () error {
133146// Clean up vlan interface in the VM namespace and ensure the network namespace (if it exists) has a vlan interface
134- logger .Info ("Checking if NS and vlan veth exists..." )
147+ logger .Info ("Checking if NS and vlan interface exists..." )
135148var existingErr error
136149client .vnetNSFileDescriptor , existingErr = client .netnsClient .GetFromName (client .vnetNSName )
137150if existingErr == nil {
@@ -146,18 +159,14 @@ func (client *TransparentVlanEndpointClient) ensureCleanPopulateVM() error {
146159logger .Info ("vlan interface doesn't exist even though network namespace exists, deleting network namespace..." , zap .String ("message" , vlanIfErr .Error ()))
147160delErr := client .netnsClient .DeleteNamed (client .vnetNSName )
148161if delErr != nil {
149- return errors .Wrap (delErr , "failed to cleanup/delete ns after noticing vlan veth does not exist" )
162+ return errors .Wrap (delErr , "failed to cleanup/delete ns after noticing vlan interface does not exist" )
150163}
151164}
152165}
153166// Delete the vlan interface in the VM namespace if it exists
154- _ , vlanIfInVMErr := client .netioshim .GetNetworkInterfaceByName (client .vlanIfName )
155- if vlanIfInVMErr == nil {
156- // The vlan interface exists in the VM ns because it failed to move into the network ns previously and needs to be cleaned up
157- logger .Info ("vlan interface exists on the VM namespace, deleting" , zap .String ("vlanIfName" , client .vlanIfName ))
158- if delErr := client .netlink .DeleteLink (client .vlanIfName ); delErr != nil {
159- return errors .Wrap (delErr , "failed to clean up vlan interface" )
160- }
167+ // The vlan interface exists in the VM ns because it failed to move into the network ns previously and needs to be cleaned up
168+ if delErr := client .cleanupInterfaceIfExists (client .vlanIfName ); delErr != nil {
169+ return errors .Wrap (delErr , "failed to clean up vlan interface" )
161170}
162171return nil
163172}
@@ -183,24 +192,24 @@ func (client *TransparentVlanEndpointClient) createNetworkNamespace(vmNS int) er
183192return errors .Wrap (errNamespaceCreation , "vnet and vm namespace are the same" )
184193}
185194
186- // Called from PopulateVM, Namespace: VM and namespace represented by fd
187- func (client * TransparentVlanEndpointClient ) setLinkNetNSAndConfirm (name string , fd uintptr ) error {
195+ // Called from PopulateVM, Namespace: VM and namespace represented by fd (which is named nsName)
196+ func (client * TransparentVlanEndpointClient ) setLinkNetNSAndConfirm (name string , fd uintptr , nsName string ) error {
188197logger .Info ("Move link to NS" , zap .String ("ifName" , name ), zap .Any ("NSFileDescriptor" , fd ))
189198err := client .netlink .SetLinkNetNs (name , fd )
190199if err != nil {
191- return errors .Wrapf (err , "failed to set %v inside namespace %v" , name , fd )
200+ return errors .Wrapf (err , "failed to set %v inside namespace %v (%s) " , name , fd , nsName )
192201}
193202
194203// confirm veth was moved successfully
195204err = RunWithRetries (func () error {
196205// retry checking in the namespace if the interface is not detected
197- return ExecuteInNS (client .nsClient , client . vnetNSName , func () error {
198- _ , ifDetectedErr := client .netioshim .GetNetworkInterfaceByName (client . vlanIfName )
199- return errors .Wrap (ifDetectedErr , "failed to get vlan veth in namespace" )
206+ return ExecuteInNS (client .nsClient , nsName , func () error {
207+ _ , ifDetectedErr := client .netioshim .GetNetworkInterfaceByName (name )
208+ return errors .Wrap (ifDetectedErr , "failed to confirm interface moved in namespace" )
200209})
201210}, numRetries , sleepInMs )
202211if err != nil {
203- return errors .Wrapf (err , "failed to detect %v inside namespace %v" , name , fd )
212+ return errors .Wrapf (err , "failed to detect %v inside namespace %v (%s) " , name , fd , nsName )
204213}
205214return nil
206215}
@@ -215,7 +224,7 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
215224var existingErr error
216225client .vnetNSFileDescriptor , existingErr = client .netnsClient .GetFromName (client .vnetNSName )
217226// If the ns does not exist, the below code will trigger to create it
218- // This will also (we assume) mean the vlan veth does not exist
227+ // This will also (we assume) mean the vlan interface does not exist
219228if existingErr != nil {
220229// We assume the only possible error is that the namespace doesn't exist
221230logger .Info ("No existing NS detected. Creating the vnet namespace and switching to it" , zap .String ("message" , existingErr .Error ()))
@@ -234,15 +243,15 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
234243logger .Info ("[transparent vlan] removing vnet ns due to failure..." )
235244err = client .netnsClient .DeleteNamed (client .vnetNSName )
236245if err != nil {
237- logger .Error ("failed to cleanup/delete ns after failing to create vlan veth " )
246+ logger .Error ("failed to cleanup/delete ns after failing to create vlan interface " )
238247}
239248}
240249}()
241250if deleteNSIfNotNilErr != nil {
242251return errors .Wrap (deleteNSIfNotNilErr , "failed to set current ns to vm" )
243252}
244253
245- // Now create vlan veth
254+ // Now create vlan interface
246255logger .Info ("Create the host vlan link after getting eth0" , zap .String ("primaryHostIfName" , client .primaryHostIfName ))
247256// Get parent interface index. Index is consistent across libraries.
248257eth0 , deleteNSIfNotNilErr := client .netioshim .GetNetworkInterfaceByName (client .primaryHostIfName )
@@ -258,7 +267,7 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
258267VlanId : client .vlanID ,
259268}
260269logger .Info ("Attempting to create link in VM NS" , zap .String ("vlanIfName" , client .vlanIfName ))
261- // Create vlan veth
270+ // Create vlan interface
262271deleteNSIfNotNilErr = vishnetlink .LinkAdd (link )
263272if deleteNSIfNotNilErr != nil {
264273// ignore link already exists error
@@ -271,35 +280,35 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
271280}
272281defer func () {
273282if deleteNSIfNotNilErr != nil {
274- logger .Info ("removing vlan veth due to failure..." )
283+ logger .Info ("removing vlan interface due to failure..." )
275284if delErr := client .netlink .DeleteLink (client .vlanIfName ); delErr != nil {
276- logger .Error ("deleting vlan veth failed on addendpoint failure with" , zap .Any ("error:" , delErr .Error ()))
285+ logger .Error ("deleting vlan interface failed on addendpoint failure with" , zap .Any ("error:" , delErr .Error ()))
277286}
278287}
279288}()
280289
281290// sometimes there is slight delay in interface creation. check if it exists
282291err = RunWithRetries (func () error {
283292_ , err = client .netioshim .GetNetworkInterfaceByName (client .vlanIfName )
284- return errors .Wrap (err , "failed to get vlan veth " )
293+ return errors .Wrap (err , "failed to get vlan interface " )
285294}, numRetries , sleepInMs )
286295
287296if err != nil {
288- deleteNSIfNotNilErr = errors .Wrapf (err , "failed to get vlan veth interface:%s" , client .vlanIfName )
297+ deleteNSIfNotNilErr = errors .Wrapf (err , "failed to get vlan interface: %s" , client .vlanIfName )
289298return deleteNSIfNotNilErr
290299}
291300
292301deleteNSIfNotNilErr = client .netUtilsClient .DisableRAForInterface (client .vlanIfName )
293302if deleteNSIfNotNilErr != nil {
294303return errors .Wrap (deleteNSIfNotNilErr , "failed to disable router advertisements for vlan vnet link" )
295304}
296- // vlan veth was created successfully, so move the vlan veth you created
305+ // vlan interface was created successfully, so move the vlan interface you created
297306logger .Info ("Move vlan link to vnet NS" , zap .String ("vlanIfName" , client .vlanIfName ), zap .Any ("vnetNSFileDescriptor" , uintptr (client .vnetNSFileDescriptor )))
298- deleteNSIfNotNilErr = client .setLinkNetNSAndConfirm (client .vlanIfName , uintptr (client .vnetNSFileDescriptor ))
307+ deleteNSIfNotNilErr = client .setLinkNetNSAndConfirm (client .vlanIfName , uintptr (client .vnetNSFileDescriptor ), client . vnetNSName )
299308if deleteNSIfNotNilErr != nil {
300- return errors .Wrap (deleteNSIfNotNilErr , "failed to move or detect vlan veth inside vnet namespace" )
309+ return errors .Wrap (deleteNSIfNotNilErr , "failed to move or detect vlan interface inside vnet namespace" )
301310}
302- logger .Info ("Moving vlan veth into namespace confirmed" )
311+ logger .Info ("Moving vlan interface into namespace confirmed" )
303312} else {
304313logger .Info ("Existing NS detected. vlan interface should exist or namespace would've been deleted." , zap .String ("vnetNSName" , client .vnetNSName ), zap .String ("vlanIfName" , client .vlanIfName ))
305314}
@@ -310,6 +319,14 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
310319logger .Info ("Failed to parse the mac address" , zap .String ("defaultHostVethHwAddr" , defaultHostVethHwAddr ))
311320}
312321
322+ // Proactively clean up any leftover veth interfaces before creating new ones
323+ if vnetDelErr := client .cleanupInterfaceIfExists (client .vnetVethName ); vnetDelErr != nil {
324+ logger .Info ("Could not proactively clean up vnet veth" , zap .String ("vnetVethName" , client .vnetVethName ), zap .Error (vnetDelErr ))
325+ }
326+ if containerDelErr := client .cleanupInterfaceIfExists (client .containerVethName ); containerDelErr != nil {
327+ logger .Info ("Could not proactively clean up container veth" , zap .String ("containerVethName" , client .containerVethName ), zap .Error (containerDelErr ))
328+ }
329+
313330// Create veth pair
314331if err = client .netUtilsClient .CreateEndpoint (client .vnetVethName , client .containerVethName , mac ); err != nil {
315332return errors .Wrap (err , "failed to create veth pair" )
@@ -349,7 +366,7 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
349366return errors .Wrap (err , "failed to disable RA on container veth, deleting" )
350367}
351368
352- if err = client .setLinkNetNSAndConfirm (client .vnetVethName , uintptr (client .vnetNSFileDescriptor )); err != nil {
369+ if err = client .setLinkNetNSAndConfirm (client .vnetVethName , uintptr (client .vnetNSFileDescriptor ), client . vnetNSName ); err != nil {
353370if delErr := client .netlink .DeleteLink (client .vnetVethName ); delErr != nil {
354371logger .Error ("Deleting vnet veth failed on addendpoint failure with" , zap .Error (delErr ))
355372}
@@ -363,7 +380,7 @@ func (client *TransparentVlanEndpointClient) PopulateVM(epInfo *EndpointInfo) er
363380func (client * TransparentVlanEndpointClient ) PopulateVnet (epInfo * EndpointInfo ) error {
364381_ , err := client .netioshim .GetNetworkInterfaceByName (client .vlanIfName )
365382if err != nil {
366- return errors .Wrap (err , "vlan veth doesn't exist" )
383+ return errors .Wrap (err , "vlan interface doesn't exist" )
367384}
368385vnetVethIf , err := client .netioshim .GetNetworkInterfaceByName (client .vnetVethName )
369386if err != nil {
@@ -659,7 +676,7 @@ func (client *TransparentVlanEndpointClient) DeleteEndpointsImpl(ep *endpoint, _
659676// TODO: revist if this require in future.
660677//nolint gocritic
661678/* if routesLeft <= numDefaultRoutes {
662- // Deletes default arp, default routes, vlan veth ; there are two default routes
679+ // Deletes default arp, default routes, vlan interface ; there are two default routes
663680// so when we have <= numDefaultRoutes routes left, no containers use this namespace
664681log.Printf("[transparent vlan] Deleting namespace %s as no containers occupy it", client.vnetNSName)
665682delErr := client.netnsClient.DeleteNamed(client.vnetNSName)
0 commit comments