Skip to content

Commit 3e6c62d

Browse files
author
hyphen.wang
committed
bridge: clean ip masq if netns is empty
In the Del command it didn't clean ip masq when netns is empty. Add the clean-up code if ip address can fetch from prevResult in StdinData. Fix #810 Signed-off-by: hyphen.wang <[email protected]>
1 parent 5188dc8 commit 3e6c62d

File tree

1 file changed

+90
-16
lines changed

1 file changed

+90
-16
lines changed

plugins/main/bridge/bridge.go

Lines changed: 90 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -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 {
10881104
func 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

Comments
 (0)