github.com/cilium/cilium@v1.16.2/pkg/proxy/envoyproxy.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package proxy
     5  
     6  import (
     7  	"fmt"
     8  	"net"
     9  
    10  	"github.com/sirupsen/logrus"
    11  
    12  	"github.com/cilium/cilium/pkg/completion"
    13  	"github.com/cilium/cilium/pkg/datapath/iptables"
    14  	"github.com/cilium/cilium/pkg/envoy"
    15  	"github.com/cilium/cilium/pkg/policy"
    16  	"github.com/cilium/cilium/pkg/proxy/endpoint"
    17  	"github.com/cilium/cilium/pkg/proxy/types"
    18  	"github.com/cilium/cilium/pkg/revert"
    19  )
    20  
    21  // envoyRedirect implements the RedirectImplementation interface for an l7 proxy.
    22  type envoyRedirect struct {
    23  	listenerName string
    24  	xdsServer    envoy.XDSServer
    25  	adminClient  *envoy.EnvoyAdminClient
    26  }
    27  
    28  type envoyProxyIntegration struct {
    29  	adminClient     *envoy.EnvoyAdminClient
    30  	xdsServer       envoy.XDSServer
    31  	iptablesManager *iptables.Manager
    32  }
    33  
    34  // createRedirect creates a redirect with corresponding proxy configuration. This will launch a proxy instance.
    35  func (p *envoyProxyIntegration) createRedirect(r *Redirect, wg *completion.WaitGroup) (RedirectImplementation, error) {
    36  	if r.listener.ProxyType == types.ProxyTypeCRD {
    37  		// CRD Listeners already exist, create a no-op implementation
    38  		return &CRDRedirect{}, nil
    39  	}
    40  
    41  	// create an Envoy Listener for Cilium policy enforcement
    42  	return p.handleEnvoyRedirect(r, wg)
    43  }
    44  
    45  func (p *envoyProxyIntegration) changeLogLevel(level logrus.Level) error {
    46  	return p.adminClient.ChangeLogLevel(level)
    47  }
    48  
    49  func (p *envoyProxyIntegration) handleEnvoyRedirect(r *Redirect, wg *completion.WaitGroup) (RedirectImplementation, error) {
    50  	l := r.listener
    51  	redirect := &envoyRedirect{
    52  		listenerName: net.JoinHostPort(r.name, fmt.Sprintf("%d", l.ProxyPort)),
    53  		xdsServer:    p.xdsServer,
    54  		adminClient:  p.adminClient,
    55  	}
    56  
    57  	mayUseOriginalSourceAddr := p.iptablesManager.SupportsOriginalSourceAddr()
    58  	// Only use original source address for egress
    59  	if l.Ingress {
    60  		mayUseOriginalSourceAddr = false
    61  	}
    62  	p.xdsServer.AddListener(redirect.listenerName, policy.L7ParserType(l.ProxyType), l.ProxyPort, l.Ingress, mayUseOriginalSourceAddr, wg)
    63  
    64  	return redirect, nil
    65  }
    66  
    67  func (p *envoyProxyIntegration) UpdateNetworkPolicy(ep endpoint.EndpointUpdater, vis *policy.VisibilityPolicy, policy *policy.L4Policy, ingressPolicyEnforced, egressPolicyEnforced bool, wg *completion.WaitGroup) (error, func() error) {
    68  	return p.xdsServer.UpdateNetworkPolicy(ep, vis, policy, ingressPolicyEnforced, egressPolicyEnforced, wg)
    69  }
    70  
    71  func (p *envoyProxyIntegration) RemoveNetworkPolicy(ep endpoint.EndpointInfoSource) {
    72  	p.xdsServer.RemoveNetworkPolicy(ep)
    73  }
    74  
    75  // UpdateRules is a no-op for envoy, as redirect data is synchronized via the xDS cache.
    76  func (k *envoyRedirect) UpdateRules(wg *completion.WaitGroup) (revert.RevertFunc, error) {
    77  	return func() error { return nil }, nil
    78  }
    79  
    80  // Close the redirect.
    81  func (r *envoyRedirect) Close(wg *completion.WaitGroup) (revert.FinalizeFunc, revert.RevertFunc) {
    82  	revertFunc := r.xdsServer.RemoveListener(r.listenerName, wg)
    83  
    84  	return nil, func() error {
    85  		// Don't wait for an ACK for the reverted xDS updates.
    86  		// This is best-effort.
    87  		revertFunc(completion.NewCompletion(nil, nil))
    88  		return nil
    89  	}
    90  }