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  }