github.com/cilium/cilium@v1.16.2/pkg/datapath/garp/processor.go (about)

     1  // SPDX-License-Identifier: Apache-2.0
     2  // Copyright Authors of Cilium
     3  
     4  package garp
     5  
     6  import (
     7  	"net/netip"
     8  
     9  	"github.com/cilium/hive/cell"
    10  	"github.com/sirupsen/logrus"
    11  
    12  	"github.com/cilium/cilium/pkg/endpoint"
    13  	"github.com/cilium/cilium/pkg/endpointmanager"
    14  	"github.com/cilium/cilium/pkg/lock"
    15  	"github.com/cilium/cilium/pkg/logging/logfields"
    16  )
    17  
    18  type processorParams struct {
    19  	cell.In
    20  
    21  	Logger          logrus.FieldLogger
    22  	EndpointManager endpointmanager.EndpointManager
    23  	GARPSender      Sender
    24  	Config          Config
    25  }
    26  
    27  func newGARPProcessor(p processorParams) *processor {
    28  	if !p.Config.EnableL2PodAnnouncements {
    29  		return nil
    30  	}
    31  
    32  	gp := &processor{
    33  		log:         p.Logger,
    34  		garpSender:  p.GARPSender,
    35  		endpointIPs: make(map[uint16]netip.Addr),
    36  	}
    37  
    38  	if p.EndpointManager != nil {
    39  		p.EndpointManager.Subscribe(gp)
    40  	}
    41  
    42  	p.Logger.Info("initialised gratuitous arp processor")
    43  
    44  	return gp
    45  }
    46  
    47  type processor struct {
    48  	mu lock.Mutex
    49  
    50  	log        logrus.FieldLogger
    51  	garpSender Sender
    52  
    53  	endpointIPs map[uint16]netip.Addr
    54  }
    55  
    56  var _ endpointmanager.Subscriber = &processor{}
    57  
    58  // EndpointCreated implements endpointmanager.Subscriber
    59  func (gp *processor) EndpointCreated(ep *endpoint.Endpoint) {
    60  	gp.mu.Lock()
    61  	defer gp.mu.Unlock()
    62  
    63  	newIP := ep.IPv4
    64  	if newIP.IsUnspecified() {
    65  		return
    66  	}
    67  
    68  	oldIP, ok := gp.endpointIPs[ep.ID]
    69  	if ok && oldIP == newIP {
    70  		return
    71  	}
    72  
    73  	gp.endpointIPs[ep.ID] = newIP
    74  
    75  	log := gp.log.WithFields(logrus.Fields{
    76  		logfields.K8sPodName: ep.K8sPodName,
    77  		logfields.IPAddr:     newIP,
    78  	})
    79  
    80  	if err := gp.garpSender.Send(newIP); err != nil {
    81  		log.WithError(err).Warn("Failed to send gratuitous arp")
    82  	} else {
    83  		log.Debug("pod upsert gratuitous arp sent")
    84  	}
    85  }
    86  
    87  // EndpointDeleted implements endpointmanager.Subscriber
    88  func (gp *processor) EndpointDeleted(ep *endpoint.Endpoint, conf endpoint.DeleteConfig) {
    89  	gp.mu.Lock()
    90  	defer gp.mu.Unlock()
    91  
    92  	delete(gp.endpointIPs, ep.ID)
    93  }
    94  
    95  // EndpointRestored implements endpointmanager.Subscriber.
    96  func (gp *processor) EndpointRestored(ep *endpoint.Endpoint) {
    97  	// No-op
    98  }