pkg/ip: Fix ipmasq teardown on v6-only interfaces
This commit is contained in:
parent
556e509097
commit
7a62515407
@ -75,7 +75,16 @@ func SetupIPMasq(ipn *net.IPNet, chain string, comment string) error {
|
|||||||
|
|
||||||
// TeardownIPMasq undoes the effects of SetupIPMasq
|
// TeardownIPMasq undoes the effects of SetupIPMasq
|
||||||
func TeardownIPMasq(ipn *net.IPNet, chain string, comment string) error {
|
func TeardownIPMasq(ipn *net.IPNet, chain string, comment string) error {
|
||||||
ipt, err := iptables.New()
|
isV6 := ipn.IP.To4() == nil
|
||||||
|
|
||||||
|
var ipt *iptables.IPTables
|
||||||
|
var err error
|
||||||
|
|
||||||
|
if isV6 {
|
||||||
|
ipt, err = iptables.NewWithProtocol(iptables.ProtocolIPv6)
|
||||||
|
} else {
|
||||||
|
ipt, err = iptables.NewWithProtocol(iptables.ProtocolIPv4)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to locate iptables: %v", err)
|
return fmt.Errorf("failed to locate iptables: %v", err)
|
||||||
}
|
}
|
||||||
|
@ -158,6 +158,9 @@ func SetupVeth(contVethName string, mtu int, hostNS ns.NetNS) (net.Interface, ne
|
|||||||
func DelLinkByName(ifName string) error {
|
func DelLinkByName(ifName string) error {
|
||||||
iface, err := netlink.LinkByName(ifName)
|
iface, err := netlink.LinkByName(ifName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
if err.Error() == "Link not found" {
|
||||||
|
return ErrLinkNotFound
|
||||||
|
}
|
||||||
return fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
return fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,9 +171,8 @@ func DelLinkByName(ifName string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// DelLinkByNameAddr remove an interface returns its IP address
|
// DelLinkByNameAddr remove an interface and returns its addresses
|
||||||
// of the specified family
|
func DelLinkByNameAddr(ifName string) ([]*net.IPNet, error) {
|
||||||
func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) {
|
|
||||||
iface, err := netlink.LinkByName(ifName)
|
iface, err := netlink.LinkByName(ifName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err != nil && err.Error() == "Link not found" {
|
if err != nil && err.Error() == "Link not found" {
|
||||||
@ -179,7 +181,7 @@ func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) {
|
|||||||
return nil, fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
return nil, fmt.Errorf("failed to lookup %q: %v", ifName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addrs, err := netlink.AddrList(iface, family)
|
addrs, err := netlink.AddrList(iface, netlink.FAMILY_ALL)
|
||||||
if err != nil || len(addrs) == 0 {
|
if err != nil || len(addrs) == 0 {
|
||||||
return nil, fmt.Errorf("failed to get IP addresses for %q: %v", ifName, err)
|
return nil, fmt.Errorf("failed to get IP addresses for %q: %v", ifName, err)
|
||||||
}
|
}
|
||||||
@ -188,7 +190,14 @@ func DelLinkByNameAddr(ifName string, family int) (*net.IPNet, error) {
|
|||||||
return nil, fmt.Errorf("failed to delete %q: %v", ifName, err)
|
return nil, fmt.Errorf("failed to delete %q: %v", ifName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return addrs[0].IPNet, nil
|
out := []*net.IPNet{}
|
||||||
|
for _, addr := range addrs {
|
||||||
|
if addr.IP.IsGlobalUnicast() {
|
||||||
|
out = append(out, addr.IPNet)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func SetHWAddrByIP(ifName string, ip4 net.IP, ip6 net.IP) error {
|
func SetHWAddrByIP(ifName string, ip4 net.IP, ip6 net.IP) error {
|
||||||
|
@ -27,7 +27,6 @@ import (
|
|||||||
"github.com/containernetworking/plugins/pkg/ns"
|
"github.com/containernetworking/plugins/pkg/ns"
|
||||||
|
|
||||||
"github.com/vishvananda/netlink"
|
"github.com/vishvananda/netlink"
|
||||||
"github.com/vishvananda/netlink/nl"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func getHwAddr(linkname string) string {
|
func getHwAddr(linkname string) string {
|
||||||
@ -133,7 +132,7 @@ var _ = Describe("Link", func() {
|
|||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
|
||||||
// This string should match the expected error codes in the cmdDel functions of some of the plugins
|
// This string should match the expected error codes in the cmdDel functions of some of the plugins
|
||||||
_, err := ip.DelLinkByNameAddr("THIS_DONT_EXIST", netlink.FAMILY_V4)
|
_, err := ip.DelLinkByNameAddr("THIS_DONT_EXIST")
|
||||||
Expect(err).To(Equal(ip.ErrLinkNotFound))
|
Expect(err).To(Equal(ip.ErrLinkNotFound))
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
@ -220,16 +219,14 @@ var _ = Describe("Link", func() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
It("DelLinkByNameAddr must throw an error for configured interfaces", func() {
|
It("DelLinkByNameAddr should return no IPs when no IPs are configured", func() {
|
||||||
_ = containerNetNS.Do(func(ns.NetNS) error {
|
_ = containerNetNS.Do(func(ns.NetNS) error {
|
||||||
defer GinkgoRecover()
|
defer GinkgoRecover()
|
||||||
|
|
||||||
// this will delete the host endpoint too
|
// this will delete the host endpoint too
|
||||||
addr, err := ip.DelLinkByNameAddr(containerVethName, nl.FAMILY_V4)
|
addr, err := ip.DelLinkByNameAddr(containerVethName)
|
||||||
Expect(err).To(HaveOccurred())
|
Expect(err).NotTo(HaveOccurred())
|
||||||
|
Expect(addr).To(HaveLen(0))
|
||||||
var ipNetNil *net.IPNet
|
|
||||||
Expect(addr).To(Equal(ipNetNil))
|
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
@ -474,10 +474,10 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
// There is a netns so try to clean up. Delete can be called multiple times
|
// There is a netns so try to clean up. Delete can be called multiple times
|
||||||
// so don't return an error if the device is already removed.
|
// so don't return an error if the device is already removed.
|
||||||
// If the device isn't there then don't try to clean up IP masq either.
|
// If the device isn't there then don't try to clean up IP masq either.
|
||||||
var ipn *net.IPNet
|
var ipnets []*net.IPNet
|
||||||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||||
var err error
|
var err error
|
||||||
ipn, err = ip.DelLinkByNameAddr(args.IfName, netlink.FAMILY_ALL)
|
ipnets, err = ip.DelLinkByNameAddr(args.IfName)
|
||||||
if err != nil && err == ip.ErrLinkNotFound {
|
if err != nil && err == ip.ErrLinkNotFound {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -488,10 +488,14 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ipn != nil && n.IPMasq {
|
if n.IPMasq {
|
||||||
chain := utils.FormatChainName(n.Name, args.ContainerID)
|
chain := utils.FormatChainName(n.Name, args.ContainerID)
|
||||||
comment := utils.FormatComment(n.Name, args.ContainerID)
|
comment := utils.FormatComment(n.Name, args.ContainerID)
|
||||||
err = ip.TeardownIPMasq(ipn, chain, comment)
|
for _, ipn := range ipnets {
|
||||||
|
if err := ip.TeardownIPMasq(ipn, chain, comment); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
|
@ -194,7 +194,7 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
// There is a netns so try to clean up. Delete can be called multiple times
|
// There is a netns so try to clean up. Delete can be called multiple times
|
||||||
// so don't return an error if the device is already removed.
|
// so don't return an error if the device is already removed.
|
||||||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||||
if _, err := ip.DelLinkByNameAddr(args.IfName, netlink.FAMILY_V4); err != nil {
|
if err := ip.DelLinkByName(args.IfName); err != nil {
|
||||||
if err != ip.ErrLinkNotFound {
|
if err != ip.ErrLinkNotFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -226,7 +226,7 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
// There is a netns so try to clean up. Delete can be called multiple times
|
// There is a netns so try to clean up. Delete can be called multiple times
|
||||||
// so don't return an error if the device is already removed.
|
// so don't return an error if the device is already removed.
|
||||||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||||
if _, err := ip.DelLinkByNameAddr(args.IfName, netlink.FAMILY_V4); err != nil {
|
if err := ip.DelLinkByName(args.IfName); err != nil {
|
||||||
if err != ip.ErrLinkNotFound {
|
if err != ip.ErrLinkNotFound {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -259,10 +259,10 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
// There is a netns so try to clean up. Delete can be called multiple times
|
// There is a netns so try to clean up. Delete can be called multiple times
|
||||||
// so don't return an error if the device is already removed.
|
// so don't return an error if the device is already removed.
|
||||||
// If the device isn't there then don't try to clean up IP masq either.
|
// If the device isn't there then don't try to clean up IP masq either.
|
||||||
var ipn *net.IPNet
|
var ipnets []*net.IPNet
|
||||||
err := ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
err := ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||||
var err error
|
var err error
|
||||||
ipn, err = ip.DelLinkByNameAddr(args.IfName, netlink.FAMILY_V4)
|
ipnets, err = ip.DelLinkByNameAddr(args.IfName)
|
||||||
if err != nil && err == ip.ErrLinkNotFound {
|
if err != nil && err == ip.ErrLinkNotFound {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@ -273,11 +273,13 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if ipn != nil && conf.IPMasq {
|
if len(ipnets) != 0 && conf.IPMasq {
|
||||||
chain := utils.FormatChainName(conf.Name, args.ContainerID)
|
chain := utils.FormatChainName(conf.Name, args.ContainerID)
|
||||||
comment := utils.FormatComment(conf.Name, args.ContainerID)
|
comment := utils.FormatComment(conf.Name, args.ContainerID)
|
||||||
|
for _, ipn := range ipnets {
|
||||||
err = ip.TeardownIPMasq(ipn, chain, comment)
|
err = ip.TeardownIPMasq(ipn, chain, comment)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -181,9 +181,8 @@ func cmdDel(args *skel.CmdArgs) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
err = ns.WithNetNSPath(args.Netns, func(_ ns.NetNS) error {
|
||||||
_, err = ip.DelLinkByNameAddr(args.IfName, netlink.FAMILY_V4)
|
err = ip.DelLinkByName(args.IfName)
|
||||||
// FIXME: use ip.ErrLinkNotFound when cni is revendored
|
if err != nil && err != ip.ErrLinkNotFound {
|
||||||
if err != nil && err.Error() == "Link not found" {
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
|
Loading…
x
Reference in New Issue
Block a user