// Copyright 2016-2019 Authors of Cilium // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package bpf import ( "regexp" "time" "github.com/cilium/cilium/pkg/controller" "github.com/cilium/cilium/pkg/datapath/linux/probes" ) // MapType is an enumeration for valid BPF map types type MapType int // This enumeration must be in sync with enum bpf_prog_type in const ( MapTypeUnspec MapType = iota MapTypeHash MapTypeArray MapTypeProgArray MapTypePerfEventArray MapTypePerCPUHash MapTypePerCPUArray MapTypeStackTrace MapTypeCgroupArray MapTypeLRUHash MapTypeLRUPerCPUHash MapTypeLPMTrie MapTypeArrayOfMaps MapTypeHashOfMaps MapTypeDevMap MapTypeSockMap MapTypeCPUMap MapTypeXSKMap MapTypeSockHash // MapTypeMaximum is the maximum supported known map type. MapTypeMaximum // maxSyncErrors is the maximum consecutive errors syncing before the // controller bails out maxSyncErrors = 512 // errorResolverSchedulerMinInterval is the minimum interval for the // error resolver to be scheduled. This minimum interval ensures not to // overschedule if a large number of updates fail in a row. errorResolverSchedulerMinInterval = 5 * time.Second // errorResolverSchedulerDelay is the delay to update the controller // after determination that a run is needed. The delay allows to // schedule the resolver after series of updates have failed. errorResolverSchedulerDelay = 200 * time.Millisecond ) var ( mapControllers = controller.NewManager() ) func (t MapType) String() string { switch t { case MapTypeHash: return "Hash" case MapTypeArray: return "Array" case MapTypeProgArray: return "Program array" case MapTypePerfEventArray: return "Event array" case MapTypePerCPUHash: return "Per-CPU hash" case MapTypePerCPUArray: return "Per-CPU array" case MapTypeStackTrace: return "Stack trace" case MapTypeCgroupArray: return "Cgroup array" case MapTypeLRUHash: return "LRU hash" case MapTypeLRUPerCPUHash: return "LRU per-CPU hash" case MapTypeLPMTrie: return "Longest prefix match trie" case MapTypeArrayOfMaps: return "Array of maps" case MapTypeHashOfMaps: return "Hash of maps" case MapTypeDevMap: return "Device Map" case MapTypeSockMap: return "Socket Map" case MapTypeCPUMap: return "CPU Redirect Map" case MapTypeSockHash: return "Socket Hash" } return "Unknown" } func (t MapType) allowsPreallocation() bool { return t != MapTypeLPMTrie } func (t MapType) requiresPreallocation() bool { switch t { case MapTypeHash, MapTypePerCPUHash, MapTypeLPMTrie, MapTypeHashOfMaps: return false } return true } // DesiredAction is the action to be performed on the BPF map type DesiredAction int const ( // OK indicates that to further action is required and the entry is in // sync OK DesiredAction = iota // Insert indicates that the entry needs to be created or updated Insert // Delete indicates that the entry needs to be deleted Delete ) func (d DesiredAction) String() string { switch d { case OK: return "sync" case Insert: return "to-be-inserted" case Delete: return "to-be-deleted" default: return "unknown" } } // GetMapType determines whether the specified map type is supported by the // kernel (as determined by bpftool feature checks), and if the map type is not // supported, returns a more primitive map type that may be used to implement // the map on older implementations. Otherwise, returns the specified map type. func GetMapType(t MapType) MapType { pm := probes.NewProbeManager() supportedMapTypes := pm.GetMapTypes() switch t { case MapTypeLPMTrie: fallthrough case MapTypeLRUHash: if !supportedMapTypes.HaveLruHashMapType { return MapTypeHash } } return t } var commonNameRegexps = []*regexp.Regexp{ regexp.MustCompile(`^(cilium_)(.+)_reserved_[0-9]+$`), regexp.MustCompile(`^(cilium_)(.+)_netdev_ns_[0-9]+$`), regexp.MustCompile(`^(cilium_)(.+)_overlay_[0-9]+$`), regexp.MustCompile(`^(cilium_)(.+)_[0-9]+$`), regexp.MustCompile(`^(cilium_)(.+)+$`), } func extractCommonName(name string) string { for _, r := range commonNameRegexps { if replaced := r.ReplaceAllString(name, `$2`); replaced != name { return replaced } } return name }