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