github.com/cilium/cilium@v1.16.2/pkg/fqdn/re/re.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 // Package re provides a simple function to access compile regex objects for 5 // the FQDN subsystem. 6 package re 7 8 import ( 9 "errors" 10 "fmt" 11 "regexp" 12 "sync/atomic" 13 14 lru "github.com/golang/groupcache/lru" 15 16 "github.com/cilium/cilium/pkg/lock" 17 "github.com/cilium/cilium/pkg/logging" 18 "github.com/cilium/cilium/pkg/logging/logfields" 19 "github.com/cilium/cilium/pkg/option" 20 ) 21 22 var ( 23 log = logging.DefaultLogger.WithField(logfields.LogSubsys, "fqdn/re") 24 ) 25 26 // CompileRegex compiles a pattern p into a regex and returns the regex object. 27 // The regex object will be cached by an LRU. If p has already been compiled 28 // and cached, this function will return the cached regex object. If not 29 // already cached, it will compile p into a regex object and cache it in the 30 // LRU. This function will return an error if the LRU has not already been 31 // initialized. 32 func CompileRegex(p string) (*regexp.Regexp, error) { 33 lru := regexCompileLRU.Load() 34 if lru == nil { 35 return nil, errors.New("FQDN regex compilation LRU not yet initialized") 36 } 37 lru.Lock() 38 r, ok := lru.Get(p) 39 lru.Unlock() 40 if ok { 41 return r.(*regexp.Regexp), nil 42 } 43 n, err := regexp.Compile(p) 44 if err != nil { 45 return nil, fmt.Errorf("failed to compile regex: %w", err) 46 } 47 lru.Lock() 48 lru.Add(p, n) 49 lru.Unlock() 50 return n, nil 51 } 52 53 // InitRegexCompileLRU creates a new instance of the regex compilation LRU. 54 func InitRegexCompileLRU(size int) error { 55 if size < 0 { 56 return fmt.Errorf("failed to initialize FQDN regex compilation LRU due to invalid size %d", size) 57 } else if size == 0 { 58 log.Warnf( 59 "FQDN regex compilation LRU size is unlimited, which can grow unbounded potentially consuming too much memory. Consider passing a maximum size via --%s.", 60 option.FQDNRegexCompileLRUSize) 61 } 62 regexCompileLRU.Store(&RegexCompileLRU{ 63 Mutex: &lock.Mutex{}, 64 Cache: lru.New(size), 65 }) 66 return nil 67 } 68 69 // regexCompileLRU is the singleton instance of the LRU that's shared 70 // throughout Cilium. 71 var regexCompileLRU atomic.Pointer[RegexCompileLRU] 72 73 // RegexCompileLRU is an LRU cache for storing compiled regex objects of FQDN 74 // names or patterns, used in CiliumNetworkPolicy or 75 // ClusterwideCiliumNetworkPolicy. 76 type RegexCompileLRU struct { 77 // The lru package doesn't provide any concurrency guarantees so we must 78 // provide our own locking. 79 *lock.Mutex 80 *lru.Cache 81 }