@@ -813,6 +813,12 @@ func (d *nicBridged) Stop() (*deviceConfig.RunConfig, error) {
813
813
814
814
// postStop is run after the device is removed from the instance.
815
815
func (d * nicBridged ) postStop () error {
816
+ // Handle the case where validation fails but the device still must be removed.
817
+ bridgeName := d .config ["parent" ]
818
+ if bridgeName == "" && d .config ["network" ] != "" {
819
+ bridgeName = d .config ["network" ]
820
+ }
821
+
816
822
defer func () {
817
823
_ = d .volatileSet (map [string ]string {
818
824
"host_name" : "" ,
@@ -825,9 +831,9 @@ func (d *nicBridged) postStop() error {
825
831
826
832
if d .config ["host_name" ] != "" && network .InterfaceExists (d .config ["host_name" ]) {
827
833
// Detach host-side end of veth pair from bridge (required for openvswitch particularly).
828
- err := network .DetachInterface (d .state , d . config [ "parent" ] , d .config ["host_name" ])
834
+ err := network .DetachInterface (d .state , bridgeName , d .config ["host_name" ])
829
835
if err != nil {
830
- return fmt .Errorf ("Failed to detach interface %q from %q: %w" , d .config ["host_name" ], d . config [ "parent" ] , err )
836
+ return fmt .Errorf ("Failed to detach interface %q from %q: %w" , d .config ["host_name" ], bridgeName , err )
831
837
}
832
838
833
839
// Removing host-side end of veth pair will delete the peer end too.
@@ -843,7 +849,7 @@ func (d *nicBridged) postStop() error {
843
849
routes = append (routes , util .SplitNTrimSpace (d .config ["ipv6.routes" ], "," , - 1 , true )... )
844
850
routes = append (routes , util .SplitNTrimSpace (d .config ["ipv4.routes.external" ], "," , - 1 , true )... )
845
851
routes = append (routes , util .SplitNTrimSpace (d .config ["ipv6.routes.external" ], "," , - 1 , true )... )
846
- networkNICRouteDelete (d . config [ "parent" ] , routes ... )
852
+ networkNICRouteDelete (bridgeName , routes ... )
847
853
848
854
if util .IsTrue (d .config ["security.mac_filtering" ]) || util .IsTrue (d .config ["security.ipv4_filtering" ]) || util .IsTrue (d .config ["security.ipv6_filtering" ]) {
849
855
d .removeFilters (d .config )
@@ -854,25 +860,31 @@ func (d *nicBridged) postStop() error {
854
860
855
861
// Remove is run when the device is removed from the instance or the instance is deleted.
856
862
func (d * nicBridged ) Remove () error {
857
- if d .config ["parent" ] != "" {
863
+ // Handle the case where validation fails but the device still must be removed.
864
+ bridgeName := d .config ["parent" ]
865
+ if bridgeName == "" && d .config ["network" ] != "" {
866
+ bridgeName = d .config ["network" ]
867
+ }
868
+
869
+ if bridgeName != "" {
858
870
dnsmasq .ConfigMutex .Lock ()
859
871
defer dnsmasq .ConfigMutex .Unlock ()
860
872
861
- if network .InterfaceExists (d . config [ "parent" ] ) {
862
- err := d .networkClearLease (d .inst .Name (), d . config [ "parent" ] , d .config ["hwaddr" ], clearLeaseAll )
873
+ if network .InterfaceExists (bridgeName ) {
874
+ err := d .networkClearLease (d .inst .Name (), bridgeName , d .config ["hwaddr" ], clearLeaseAll )
863
875
if err != nil {
864
876
return fmt .Errorf ("Failed clearing leases: %w" , err )
865
877
}
866
878
}
867
879
868
880
// Remove dnsmasq config if it exists (doesn't return error if file is missing).
869
- err := dnsmasq .RemoveStaticEntry (d . config [ "parent" ] , d .inst .Project ().Name , d .inst .Name (), d .Name ())
881
+ err := dnsmasq .RemoveStaticEntry (bridgeName , d .inst .Project ().Name , d .inst .Name (), d .Name ())
870
882
if err != nil {
871
883
return err
872
884
}
873
885
874
886
// Reload dnsmasq to apply new settings if dnsmasq is running.
875
- err = dnsmasq .Kill (d . config [ "parent" ] , true )
887
+ err = dnsmasq .Kill (bridgeName , true )
876
888
if err != nil {
877
889
return err
878
890
}
0 commit comments