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 }