in pkg/ebpf/bpf_client.go [379:487]
func recoverBPFState(bpfTCClient tc.BpfTc, eBPFSDKClient goelf.BpfSDKClient, policyEndpointeBPFContext *sync.Map, globalMaps *sync.Map, updateIngressProbe,
updateEgressProbe, updateEventsProbe bool) (bool, bool, int, map[string]string, map[string]string, error) {
log := ctrl.Log.WithName("ebpf-client") //TODO reuse logger
isConntrackMapPresent, isPolicyEventsMapPresent := false, false
eventsMapFD := 0
var interfaceNametoIngressPinPath = make(map[string]string)
var interfaceNametoEgressPinPath = make(map[string]string)
// Recover global maps (Conntrack and Events) if there is no need to update
// events binary
if !updateEventsProbe {
recoveredGlobalMaps, err := eBPFSDKClient.RecoverGlobalMaps()
if err != nil {
log.Error(err, "failed to recover global maps..")
sdkAPIErr.WithLabelValues("RecoverGlobalMaps").Inc()
return isConntrackMapPresent, isPolicyEventsMapPresent, eventsMapFD, interfaceNametoIngressPinPath, interfaceNametoEgressPinPath, nil
}
log.Info("Total no.of global maps recovered...", "count: ", len(recoveredGlobalMaps))
for globalMapName, globalMap := range recoveredGlobalMaps {
log.Info("Global Map..", "Name: ", globalMapName, "updateEventsProbe: ", updateEventsProbe)
if globalMapName == CONNTRACK_MAP_PIN_PATH {
log.Info("Conntrack Map is already present on the node")
isConntrackMapPresent = true
globalMaps.Store(globalMapName, globalMap)
}
if globalMapName == POLICY_EVENTS_MAP_PIN_PATH {
isPolicyEventsMapPresent = true
eventsMapFD = int(globalMap.MapFD)
log.Info("Policy event Map is already present on the node ", "Recovered FD", eventsMapFD)
}
}
}
// If no updates required to probes, Recover BPF Programs and Maps from BPF_FS. We only aim to recover programs and maps
// created by aws-network-policy-agent (Located under /sys/fs/bpf/globals/aws)
if !updateIngressProbe || !updateEgressProbe {
bpfState, err := eBPFSDKClient.RecoverAllBpfProgramsAndMaps()
var peBPFContext BPFContext
if err != nil {
//Log it and move on. We will overwrite and recreate the maps/programs
log.Info("BPF State Recovery failed: ", "error: ", err)
sdkAPIErr.WithLabelValues("RecoverAllBpfProgramAndMaps").Inc()
}
log.Info("Number of probes/maps recovered - ", "count: ", len(bpfState))
for pinPath, bpfEntry := range bpfState {
log.Info("Recovered program Identifier: ", "Pin Path: ", pinPath)
podIdentifier, direction := utils.GetPodIdentifierFromBPFPinPath(pinPath)
log.Info("PinPath: ", "podIdentifier: ", podIdentifier, "direction: ", direction)
value, ok := policyEndpointeBPFContext.Load(podIdentifier)
if ok {
peBPFContext = value.(BPFContext)
}
if direction == "ingress" && !updateIngressProbe {
peBPFContext.ingressPgmInfo = bpfEntry
} else if direction == "egress" && !updateEgressProbe {
peBPFContext.egressPgmInfo = bpfEntry
}
policyEndpointeBPFContext.Store(podIdentifier, peBPFContext)
}
}
//If update required, cleanup probes and gather data to re attach probes with new programs
if updateIngressProbe || updateEgressProbe {
// Get all loaded programs and maps
bpfState, err := eBPFSDKClient.GetAllBpfProgramsAndMaps()
if err != nil {
log.Info("GetAllBpfProgramsAndMaps failed: ", "error: ", err)
sdkAPIErr.WithLabelValues("GetAllBpfProgramsAndMaps").Inc()
return isConntrackMapPresent, isPolicyEventsMapPresent, eventsMapFD, interfaceNametoIngressPinPath, interfaceNametoEgressPinPath, err
}
log.Info("GetAllBpfProgramsAndMaps ", "returned", len(bpfState))
progIdToPinPath := make(map[int]string)
for pinPath, bpfData := range bpfState {
progId := bpfData.Program.ProgID
if progId > 0 {
progIdToPinPath[progId] = pinPath
}
}
// Get attached progIds
interfaceToIngressProgIds, interfaceToEgressProgIds, err := bpfTCClient.GetAllAttachedProgIds()
log.Info("Got attached ", "ingressprogIds ", len(interfaceToIngressProgIds), " egressprogIds ", len(interfaceToEgressProgIds))
//cleanup all existing filters
cleanupErr := bpfTCClient.CleanupQdiscs(updateIngressProbe, updateEgressProbe)
if cleanupErr != nil {
// log the error and continue. Attaching new probes will cleanup the old ones
log.Info("Probe cleanup failed ", "error: ", cleanupErr)
sdkAPIErr.WithLabelValues("CleanupQdiscs").Inc()
}
for interfaceName, existingIngressProgId := range interfaceToIngressProgIds {
pinPath, ok := progIdToPinPath[existingIngressProgId]
if ok && updateIngressProbe {
interfaceNametoIngressPinPath[interfaceName] = pinPath
}
}
for interfaceName, existingEgressProgId := range interfaceToEgressProgIds {
pinPath, ok := progIdToPinPath[existingEgressProgId]
if ok && updateEgressProbe {
interfaceNametoEgressPinPath[interfaceName] = pinPath
}
}
log.Info("Collected all data for reattaching probes")
}
return isConntrackMapPresent, isPolicyEventsMapPresent, eventsMapFD, interfaceNametoIngressPinPath, interfaceNametoEgressPinPath, nil
}