|
|
|
|
@@ -32,27 +32,25 @@ import (
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
// CleanStaleEntries takes care of flushing stale conntrack entries for services and endpoints.
|
|
|
|
|
func CleanStaleEntries(ct Interface, svcPortMap proxy.ServicePortMap,
|
|
|
|
|
func CleanStaleEntries(ct Interface, ipFamily v1.IPFamily, svcPortMap proxy.ServicePortMap,
|
|
|
|
|
serviceUpdateResult proxy.UpdateServiceMapResult, endpointsUpdateResult proxy.UpdateEndpointsMapResult) {
|
|
|
|
|
deleteStaleServiceConntrackEntries(ct, svcPortMap, serviceUpdateResult, endpointsUpdateResult)
|
|
|
|
|
deleteStaleEndpointConntrackEntries(ct, svcPortMap, endpointsUpdateResult)
|
|
|
|
|
deleteStaleServiceConntrackEntries(ct, ipFamily, svcPortMap, serviceUpdateResult, endpointsUpdateResult)
|
|
|
|
|
deleteStaleEndpointConntrackEntries(ct, ipFamily, svcPortMap, endpointsUpdateResult)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// deleteStaleServiceConntrackEntries takes care of flushing stale conntrack entries related
|
|
|
|
|
// to UDP Service IPs. When a service has no endpoints and we drop traffic to it, conntrack
|
|
|
|
|
// may create "black hole" entries for that IP+port. When the service gets endpoints we
|
|
|
|
|
// need to delete those entries so further traffic doesn't get dropped.
|
|
|
|
|
func deleteStaleServiceConntrackEntries(ct Interface, svcPortMap proxy.ServicePortMap, serviceUpdateResult proxy.UpdateServiceMapResult, endpointsUpdateResult proxy.UpdateEndpointsMapResult) {
|
|
|
|
|
func deleteStaleServiceConntrackEntries(ct Interface, ipFamily v1.IPFamily, svcPortMap proxy.ServicePortMap, serviceUpdateResult proxy.UpdateServiceMapResult, endpointsUpdateResult proxy.UpdateEndpointsMapResult) {
|
|
|
|
|
var filters []netlink.CustomConntrackFilter
|
|
|
|
|
conntrackCleanupServiceIPs := serviceUpdateResult.DeletedUDPClusterIPs
|
|
|
|
|
conntrackCleanupServiceNodePorts := sets.New[int]()
|
|
|
|
|
isIPv6 := false
|
|
|
|
|
|
|
|
|
|
// merge newly active services gathered from endpointsUpdateResult
|
|
|
|
|
// a UDP service that changes from 0 to non-0 endpoints is newly active.
|
|
|
|
|
for _, svcPortName := range endpointsUpdateResult.NewlyActiveUDPServices {
|
|
|
|
|
if svcInfo, ok := svcPortMap[svcPortName]; ok {
|
|
|
|
|
isIPv6 = netutils.IsIPv6(svcInfo.ClusterIP())
|
|
|
|
|
klog.V(4).InfoS("Newly-active UDP service may have stale conntrack entries", "servicePortName", svcPortName)
|
|
|
|
|
conntrackCleanupServiceIPs.Insert(svcInfo.ClusterIP().String())
|
|
|
|
|
for _, extIP := range svcInfo.ExternalIPs() {
|
|
|
|
|
@@ -77,7 +75,7 @@ func deleteStaleServiceConntrackEntries(ct Interface, svcPortMap proxy.ServicePo
|
|
|
|
|
filters = append(filters, filterForPort(nodePort, v1.ProtocolUDP))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := ct.ClearEntries(getUnixIPFamily(isIPv6), filters...); err != nil {
|
|
|
|
|
if err := ct.ClearEntries(ipFamilyMap[ipFamily], filters...); err != nil {
|
|
|
|
|
klog.ErrorS(err, "Failed to delete stale service connections")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
@@ -85,12 +83,10 @@ func deleteStaleServiceConntrackEntries(ct Interface, svcPortMap proxy.ServicePo
|
|
|
|
|
// deleteStaleEndpointConntrackEntries takes care of flushing stale conntrack entries related
|
|
|
|
|
// to UDP endpoints. After a UDP endpoint is removed we must flush any conntrack entries
|
|
|
|
|
// for it so that if the same client keeps sending, the packets will get routed to a new endpoint.
|
|
|
|
|
func deleteStaleEndpointConntrackEntries(ct Interface, svcPortMap proxy.ServicePortMap, endpointsUpdateResult proxy.UpdateEndpointsMapResult) {
|
|
|
|
|
func deleteStaleEndpointConntrackEntries(ct Interface, ipFamily v1.IPFamily, svcPortMap proxy.ServicePortMap, endpointsUpdateResult proxy.UpdateEndpointsMapResult) {
|
|
|
|
|
var filters []netlink.CustomConntrackFilter
|
|
|
|
|
isIPv6 := false
|
|
|
|
|
for _, epSvcPair := range endpointsUpdateResult.DeletedUDPEndpoints {
|
|
|
|
|
if svcInfo, ok := svcPortMap[epSvcPair.ServicePortName]; ok {
|
|
|
|
|
isIPv6 = netutils.IsIPv6(svcInfo.ClusterIP())
|
|
|
|
|
endpointIP := proxyutil.IPPart(epSvcPair.Endpoint)
|
|
|
|
|
nodePort := svcInfo.NodePort()
|
|
|
|
|
if nodePort != 0 {
|
|
|
|
|
@@ -107,17 +103,15 @@ func deleteStaleEndpointConntrackEntries(ct Interface, svcPortMap proxy.ServiceP
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if err := ct.ClearEntries(getUnixIPFamily(isIPv6), filters...); err != nil {
|
|
|
|
|
if err := ct.ClearEntries(ipFamilyMap[ipFamily], filters...); err != nil {
|
|
|
|
|
klog.ErrorS(err, "Failed to delete stale endpoint connections")
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// getUnixIPFamily returns the unix IPFamily constant.
|
|
|
|
|
func getUnixIPFamily(isIPv6 bool) uint8 {
|
|
|
|
|
if isIPv6 {
|
|
|
|
|
return unix.AF_INET6
|
|
|
|
|
}
|
|
|
|
|
return unix.AF_INET
|
|
|
|
|
// ipFamilyMap maps v1.IPFamily to the corresponding unix constant.
|
|
|
|
|
var ipFamilyMap = map[v1.IPFamily]uint8{
|
|
|
|
|
v1.IPv4Protocol: unix.AF_INET,
|
|
|
|
|
v1.IPv6Protocol: unix.AF_INET6,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// protocolMap maps v1.Protocol to the Assigned Internet Protocol Number.
|
|
|
|
|
|