github.com/cilium/cilium@v1.16.2/pkg/proxy/logger/endpoint/epinfo.go (about) 1 // SPDX-License-Identifier: Apache-2.0 2 // Copyright Authors of Cilium 3 4 package endpoint 5 6 import ( 7 "context" 8 "net/netip" 9 10 "github.com/cilium/cilium/pkg/endpoint" 11 "github.com/cilium/cilium/pkg/endpointmanager" 12 "github.com/cilium/cilium/pkg/identity" 13 "github.com/cilium/cilium/pkg/identity/cache" 14 "github.com/cilium/cilium/pkg/ipcache" 15 "github.com/cilium/cilium/pkg/proxy/accesslog" 16 "github.com/cilium/cilium/pkg/proxy/logger" 17 ) 18 19 // EndpointLookup is any type which maps from IP to the endpoint owning that IP. 20 type EndpointLookup interface { 21 LookupIP(ip netip.Addr) (ep *endpoint.Endpoint) 22 } 23 24 // endpointInfoRegistry provides a default implementation of the logger.EndpointInfoRegistry interface. 25 type endpointInfoRegistry struct { 26 ipcache *ipcache.IPCache 27 endpointManager EndpointLookup 28 identityAllocator cache.IdentityAllocator 29 } 30 31 func NewEndpointInfoRegistry(ipc *ipcache.IPCache, endpointManager endpointmanager.EndpointsLookup, identityAllocator cache.IdentityAllocator) logger.EndpointInfoRegistry { 32 // **NOTE** The global identity allocator is not yet initialized here; 33 // that happens in the daemon init via InitIdentityAllocator(). 34 // Only the local identity allocator is initialized here. 35 36 return &endpointInfoRegistry{ 37 ipcache: ipc, 38 endpointManager: endpointManager, 39 identityAllocator: identityAllocator, 40 } 41 } 42 43 // FillEndpointInfo fills in as much information as possible from the provided information. 44 // It will populate empty fields on a best-effort basis. 45 // Resolving security labels may require accessing the kvstore; labelLookupTimeout sets 46 // the timeout. 47 func (r *endpointInfoRegistry) FillEndpointInfo(ctx context.Context, info *accesslog.EndpointInfo, addr netip.Addr) { 48 if addr.IsValid() { 49 if addr.Is4() { 50 info.IPv4 = addr.String() 51 } else { 52 info.IPv6 = addr.String() 53 } 54 } 55 56 // Resolve endpoint, if needed and possible. 57 // This will fail if the IP does not correspond to an endpoint on this node. 58 var ep *endpoint.Endpoint 59 if info.ID == 0 { 60 ep = r.endpointManager.LookupIP(addr) 61 if ep != nil { 62 info.ID = ep.GetID() 63 } 64 } 65 66 // Only resolve the security identity if not passed in, as it may have changed since 67 // reported by the proxy. This way we log the security identity and labels used for 68 // policy enforcement, if any. 69 if info.Identity == 0 { 70 // Try and look up identity by endpoint 71 if ep != nil { 72 secid, err := ep.GetSecurityIdentity() 73 // safe to ignore error; just means endpoint is going away. 74 // this is best-effort anyways. 75 if err == nil && secid != nil { 76 info.Identity = uint64(secid.ID) 77 info.Labels = secid.LabelArray 78 } 79 } 80 81 // Fall back to ipcache 82 if info.Identity == 0 && addr.IsValid() { 83 ID, exists := r.ipcache.LookupByIP(addr.String()) 84 if exists { 85 info.Identity = uint64(ID.ID) 86 } 87 } 88 89 // Default to WORLD if still unknown 90 if info.Identity == 0 { 91 info.Identity = uint64(identity.GetWorldIdentityFromIP(addr)) 92 } 93 } 94 95 // Look up security labels if not provided 96 if info.Labels == nil { 97 // The allocator should already have this in cache, but it may fall back to a 98 // remote read if missing. So, provide the context. 99 identity := r.identityAllocator.LookupIdentityByID(ctx, identity.NumericIdentity(info.Identity)) 100 if identity != nil { 101 info.Labels = identity.LabelArray 102 } 103 } 104 }