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 }