github.com/docker/engine@v22.0.0-20211208180946-d456264580cf+incompatible/libnetwork/iptables/conntrack.go (about) 1 //go:build linux 2 // +build linux 3 4 package iptables 5 6 import ( 7 "errors" 8 "net" 9 "syscall" 10 11 "github.com/sirupsen/logrus" 12 "github.com/vishvananda/netlink" 13 ) 14 15 var ( 16 // ErrConntrackNotConfigurable means that conntrack module is not loaded or does not have the netlink module loaded 17 ErrConntrackNotConfigurable = errors.New("conntrack is not available") 18 ) 19 20 // IsConntrackProgrammable returns true if the handle supports the NETLINK_NETFILTER and the base modules are loaded 21 func IsConntrackProgrammable(nlh *netlink.Handle) bool { 22 return nlh.SupportsNetlinkFamily(syscall.NETLINK_NETFILTER) 23 } 24 25 // DeleteConntrackEntries deletes all the conntrack connections on the host for the specified IP 26 // Returns the number of flows deleted for IPv4, IPv6 else error 27 func DeleteConntrackEntries(nlh *netlink.Handle, ipv4List []net.IP, ipv6List []net.IP) (uint, uint, error) { 28 if !IsConntrackProgrammable(nlh) { 29 return 0, 0, ErrConntrackNotConfigurable 30 } 31 32 var totalIPv4FlowPurged uint 33 for _, ipAddress := range ipv4List { 34 flowPurged, err := purgeConntrackState(nlh, syscall.AF_INET, ipAddress) 35 if err != nil { 36 logrus.Warnf("Failed to delete conntrack state for %s: %v", ipAddress, err) 37 continue 38 } 39 totalIPv4FlowPurged += flowPurged 40 } 41 42 var totalIPv6FlowPurged uint 43 for _, ipAddress := range ipv6List { 44 flowPurged, err := purgeConntrackState(nlh, syscall.AF_INET6, ipAddress) 45 if err != nil { 46 logrus.Warnf("Failed to delete conntrack state for %s: %v", ipAddress, err) 47 continue 48 } 49 totalIPv6FlowPurged += flowPurged 50 } 51 52 logrus.Debugf("DeleteConntrackEntries purged ipv4:%d, ipv6:%d", totalIPv4FlowPurged, totalIPv6FlowPurged) 53 return totalIPv4FlowPurged, totalIPv6FlowPurged, nil 54 } 55 56 func purgeConntrackState(nlh *netlink.Handle, family netlink.InetFamily, ipAddress net.IP) (uint, error) { 57 filter := &netlink.ConntrackFilter{} 58 // NOTE: doing the flush using the ipAddress is safe because today there cannot be multiple networks with the same subnet 59 // so it will not be possible to flush flows that are of other containers 60 if err := filter.AddIP(netlink.ConntrackNatAnyIP, ipAddress); err != nil { 61 return 0, err 62 } 63 return nlh.ConntrackDeleteFilter(netlink.ConntrackTable, family, filter) 64 }