@@ -55,6 +55,42 @@ def execute(cmd):
5555 logging .exception ('Command exited non-zero: %s' , cmd )
5656 raise
5757
58+ def iptables_chain_exists (chain ):
59+ """Check if iptables chain exists."""
60+ try :
61+ check_output ("iptables -S %s 2>/dev/null" % chain , shell = True )
62+ return True
63+ except CalledProcessError as e :
64+ if e .returncode == 1 :
65+ # Chain not found - normal for idempotent cleanup
66+ logging .debug ("iptables chain %s does not exist" , chain )
67+ return False
68+ # Other exit codes are real errors
69+ raise
70+
71+
72+ def ip6tables_chain_exists (chain ):
73+ """Check if ip6tables chain exists."""
74+ try :
75+ check_output ("ip6tables -S %s 2>/dev/null" % chain , shell = True )
76+ return True
77+ except CalledProcessError as e :
78+ if e .returncode == 1 :
79+ logging .debug ("ip6tables chain %s does not exist" , chain )
80+ return False
81+ raise
82+
83+
84+ def ipset_exists (setname ):
85+ """Check if ipset exists."""
86+ try :
87+ check_output ("ipset list %s 2>/dev/null" % setname , shell = True )
88+ return True
89+ except CalledProcessError as e :
90+ if e .returncode == 1 :
91+ logging .debug ("ipset %s does not exist" , setname )
92+ return False
93+ raise
5894
5995def can_bridge_firewall (privnic ):
6096 try :
@@ -195,7 +231,7 @@ def destroy_network_rules_for_vm(vm_name, vif=None):
195231 vmchain = iptables_chain_name (vm_name )
196232 vmchain_egress = egress_chain_name (vm_name )
197233 vmchain_default = None
198- vm_ipsetname = ipset_chain_name (vm_name )
234+ vm_ipsetname = ipset_chain_name (vm_name )
199235
200236 delete_rules_for_vm_in_bridge_firewall_chain (vm_name )
201237 if 1 in [vm_name .startswith (c ) for c in ['r-' , 's-' , 'v-' ]]:
@@ -208,42 +244,70 @@ def destroy_network_rules_for_vm(vm_name, vif=None):
208244
209245 chains = [vmchain_default , vmchain , vmchain_egress ]
210246 for chain in [_f for _f in chains if _f ]:
247+ # iptables
248+ if iptables_chain_exists (chain ):
249+ try :
250+ execute ("iptables -F " + chain )
251+ execute ("iptables -X " + chain )
252+ except Exception as e :
253+ logging .error ("Failed to flush/delete iptables chain %s: %s" , chain , str (e ))
254+ else :
255+ logging .debug ("iptables chain %s does not exist, skipping" , chain )
256+
257+ # ip6tables
211258 try :
212- execute ("iptables -F " + chain )
213- execute ('ip6tables -F ' + chain )
214- except :
215- logging .debug ("Ignoring failure to flush chain: " + chain )
259+ exists = ip6tables_chain_exists (chain )
260+ except CalledProcessError as e :
261+ if e .returncode == 127 :
262+ logging .debug ("ip6tables command not found while checking existence of %s, skipping ip6tables cleanup" , chain )
263+ continue
264+ raise
216265
217- for chain in [_f for _f in chains if _f ]:
266+ if exists :
267+ try :
268+ execute ("ip6tables -F " + chain )
269+ execute ("ip6tables -X " + chain )
270+ except Exception as e :
271+ logging .error ("Failed to flush/delete ip6tables chain %s: %s" , chain , str (e ))
272+ else :
273+ logging .debug ("ip6tables chain %s does not exist, skipping" , chain )
274+
275+ for ipset in [vm_ipsetname , vm_ipsetname + '-6' ]:
218276 try :
219- execute ("iptables -X " + chain )
220- execute ('ip6tables -X ' + chain )
221- except :
222- logging .debug ("Ignoring failure to delete chain: " + chain )
277+ exists = ipset_exists (ipset )
278+ except CalledProcessError as e :
279+ if e .returncode == 127 :
280+ logging .debug ("ipset command not found while checking existence of %s, skipping ipset cleanup" , ipset )
281+ continue
282+ raise
223283
224- try :
225- for ipset in [vm_ipsetname , vm_ipsetname + '-6' ]:
226- execute ('ipset -F ' + ipset )
227- execute ('ipset -X ' + ipset )
228- except :
229- logging .debug ("Ignoring failure to delete ipset " + vmchain )
284+ if exists :
285+ try :
286+ execute ('ipset -F ' + ipset )
287+ execute ('ipset -X ' + ipset )
288+ except Exception as e :
289+ logging .error ("Failed to flush/delete ipset %s: %s" , ipset , str (e ))
290+ else :
291+ logging .debug ("Ipset %s does not exist, skipping" , ipset )
230292
231293 if vif :
232294 try :
233- dnats = execute ("""iptables -t nat -S | awk '/%s/ { sub(/-A/, "-D", $1) ; print }'""" % vif ).split ("\n " )
295+ dnats = execute ("""iptables -t nat -S | awk '/%s/ { sub(/-A/, "-D", $1) ; print }'""" % vif ).split ("\n " )
234296 for dnat in [_f for _f in dnats if _f ]:
235297 try :
236298 execute ("iptables -t nat " + dnat )
237- except :
299+ except Exception :
238300 logging .debug ("Ignoring failure to delete dnat: " + dnat )
239- except :
301+ except Exception :
240302 pass
303+
241304 remove_rule_log_for_vm (vm_name )
242305 remove_secip_log_for_vm (vm_name )
243306
244307 return True
245308
246309
310+
247311def destroy_ebtables_rules (vm_name , vif ):
248312 eb_vm_chain = ebtables_chain_name (vm_name )
249313 delcmd = "ebtables -t nat -L PREROUTING | grep " + eb_vm_chain
0 commit comments