@@ -18,6 +18,7 @@ import (
1818 "encoding/json"
1919 "errors"
2020 "fmt"
21+ "log"
2122 "net"
2223 "os"
2324 "runtime"
@@ -774,10 +775,6 @@ func cmdDel(args *skel.CmdArgs) error {
774775 return nil
775776 }
776777
777- if args .Netns == "" {
778- return ipamDel ()
779- }
780-
781778 // There is a netns so try to clean up. Delete can be called multiple times
782779 // so don't return an error if the device is already removed.
783780 // If the device isn't there then don't try to clean up IP masq either.
@@ -791,28 +788,35 @@ func cmdDel(args *skel.CmdArgs) error {
791788 return err
792789 })
793790 if err != nil {
794- // if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
791+ // if NetNs is passed down by the Cloud Orchestration Engine, or if it called multiple times
795792 // so don't return an error if the device is already removed.
796793 // https://github.com/kubernetes/kubernetes/issues/43014#issuecomment-287164444
797794 _ , ok := err .(ns.NSPathNotExistErr )
798- if ok {
799- return ipamDel ()
795+ if ! ok {
796+ return err
800797 }
801- return err
802798 }
803799
804- // call ipam.ExecDel after clean up device in netns
805- if err := ipamDel (); err != nil {
806- return err
807- }
800+ if len (ipnets ) == 0 {
801+ // could not get ip address within netns, so try to get it from prevResult
802+ prevResult , err := parsePrevResult (n )
803+ if err != nil {
804+ return err
805+ }
808806
809- if n .MacSpoofChk {
810- sc := link .NewSpoofChecker ("" , "" , uniqueID (args .ContainerID , args .IfName ))
811- if err := sc .Teardown (); err != nil {
812- fmt .Fprintf (os .Stderr , "%v" , err )
807+ if prevResult != nil {
808+ ipCfgs , err := getIPCfgs (args .IfName , prevResult )
809+ if err != nil {
810+ return err
811+ }
812+
813+ for _ , ip := range ipCfgs {
814+ ipnets = append (ipnets , & ip .Address )
815+ }
813816 }
814817 }
815818
819+ // clean up IP masq first
816820 if isLayer3 && n .IPMasq {
817821 chain := utils .FormatChainName (n .Name , args .ContainerID )
818822 comment := utils .FormatComment (n .Name , args .ContainerID )
@@ -823,6 +827,18 @@ func cmdDel(args *skel.CmdArgs) error {
823827 }
824828 }
825829
830+ // call ipam.ExecDel after clean up device in netns
831+ if err := ipamDel (); err != nil {
832+ return err
833+ }
834+
835+ if n .MacSpoofChk {
836+ sc := link .NewSpoofChecker ("" , "" , uniqueID (args .ContainerID , args .IfName ))
837+ if err := sc .Teardown (); err != nil {
838+ fmt .Fprintf (os .Stderr , "%v" , err )
839+ }
840+ }
841+
826842 return err
827843}
828844
@@ -1088,3 +1104,61 @@ func cmdCheck(args *skel.CmdArgs) error {
10881104func uniqueID (containerID , cniIface string ) string {
10891105 return containerID + "-" + cniIface
10901106}
1107+
1108+ // parsePrevResult parse previous result
1109+ func parsePrevResult (conf * NetConf ) (* current.Result , error ) {
1110+ var prevResult * current.Result
1111+ if conf .RawPrevResult != nil {
1112+ resultBytes , err := json .Marshal (conf .RawPrevResult )
1113+ if err != nil {
1114+ return nil , fmt .Errorf ("could not serialize prevResult: %#v" , err )
1115+ }
1116+ res , err := version .NewResult (conf .CNIVersion , resultBytes )
1117+ if err != nil {
1118+ return nil , fmt .Errorf ("could not parse prevResult: %v" , err )
1119+ }
1120+ conf .RawPrevResult = nil
1121+ prevResult , err = current .NewResultFromResult (res )
1122+ if err != nil {
1123+ return nil , fmt .Errorf ("could not convert result to current version: %v" , err )
1124+ }
1125+ }
1126+ return prevResult , nil
1127+ }
1128+
1129+ // getIPCfgs finds the IPs on the supplied interface, returning as IPConfig structures
1130+ func getIPCfgs (iface string , prevResult * current.Result ) ([]* current.IPConfig , error ) {
1131+
1132+ if len (prevResult .IPs ) == 0 {
1133+ // No IP addresses; that makes no sense. Pack it in.
1134+ return nil , fmt .Errorf ("No IP addresses supplied on interface: %s" , iface )
1135+ }
1136+
1137+ // We do a single interface name, stored in args.IfName
1138+ log .Printf ("Checking for relevant interface: %s" , iface )
1139+
1140+ // ips contains the IPConfig structures that were passed, filtered somewhat
1141+ ipCfgs := make ([]* current.IPConfig , 0 , len (prevResult .IPs ))
1142+
1143+ for _ , ipCfg := range prevResult .IPs {
1144+ // IPs have an interface that is an index into the interfaces array.
1145+ // We assume a match if this index is missing.
1146+ if ipCfg .Interface == nil {
1147+ log .Printf ("No interface for IP address %s" , ipCfg .Address .IP )
1148+ ipCfgs = append (ipCfgs , ipCfg )
1149+ continue
1150+ }
1151+
1152+ // Skip all IPs we know belong to an interface with the wrong name.
1153+ intIdx := * ipCfg .Interface
1154+ if intIdx >= 0 && intIdx < len (prevResult .Interfaces ) && prevResult .Interfaces [intIdx ].Name != iface {
1155+ log .Printf ("Incorrect interface for IP address %s" , ipCfg .Address .IP )
1156+ continue
1157+ }
1158+
1159+ log .Printf ("Found IP address %s" , ipCfg .Address .IP .String ())
1160+ ipCfgs = append (ipCfgs , ipCfg )
1161+ }
1162+
1163+ return ipCfgs , nil
1164+ }
0 commit comments