go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/descriptor/arp_entry.go (about) 1 // Copyright (c) 2018 Cisco and/or its affiliates. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at: 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package descriptor 16 17 import ( 18 "github.com/pkg/errors" 19 "go.ligato.io/cn-infra/v2/logging" 20 "google.golang.org/protobuf/proto" 21 22 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 23 ifdescriptor "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/descriptor" 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/descriptor/adapter" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls" 26 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 27 l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" 28 ) 29 30 const ( 31 // ArpDescriptorName is the name of the descriptor. 32 ArpDescriptorName = "vpp-arp" 33 34 // dependency labels 35 arpEntryInterfaceDep = "interface-exists" 36 ) 37 38 // ArpDescriptor teaches KVScheduler how to configure VPP ARPs. 39 type ArpDescriptor struct { 40 log logging.Logger 41 arpHandler vppcalls.ArpVppAPI 42 scheduler kvs.KVScheduler 43 } 44 45 // NewArpDescriptor creates a new instance of the ArpDescriptor. 46 func NewArpDescriptor(scheduler kvs.KVScheduler, 47 arpHandler vppcalls.ArpVppAPI, log logging.PluginLogger) *kvs.KVDescriptor { 48 49 ctx := &ArpDescriptor{ 50 scheduler: scheduler, 51 arpHandler: arpHandler, 52 log: log.NewLogger("arp-descriptor"), 53 } 54 55 typedDescr := &adapter.ARPEntryDescriptor{ 56 Name: ArpDescriptorName, 57 NBKeyPrefix: l3.ModelARPEntry.KeyPrefix(), 58 ValueTypeName: l3.ModelARPEntry.ProtoName(), 59 KeySelector: l3.ModelARPEntry.IsKeyValid, 60 KeyLabel: l3.ModelARPEntry.StripKeyPrefix, 61 ValueComparator: ctx.EquivalentArps, 62 Create: ctx.Create, 63 Delete: ctx.Delete, 64 Retrieve: ctx.Retrieve, 65 Dependencies: ctx.Dependencies, 66 RetrieveDependencies: []string{ifdescriptor.InterfaceDescriptorName}, 67 } 68 return adapter.NewARPEntryDescriptor(typedDescr) 69 } 70 71 // EquivalentArps is comparison function for ARP entries. 72 func (d *ArpDescriptor) EquivalentArps(key string, oldArp, newArp *l3.ARPEntry) bool { 73 return proto.Equal(oldArp, newArp) 74 } 75 76 // Create adds VPP ARP entry. 77 func (d *ArpDescriptor) Create(key string, arp *l3.ARPEntry) (interface{}, error) { 78 if err := d.arpHandler.VppAddArp(arp); err != nil { 79 return nil, err 80 } 81 return nil, nil 82 } 83 84 // Delete removes VPP ARP entry. 85 func (d *ArpDescriptor) Delete(key string, arp *l3.ARPEntry, metadata interface{}) error { 86 if err := d.arpHandler.VppDelArp(arp); err != nil { 87 return err 88 } 89 return nil 90 } 91 92 // Retrieve returns all ARP entries associated with interfaces managed by this agent. 93 func (d *ArpDescriptor) Retrieve(correlate []adapter.ARPEntryKVWithMetadata) ( 94 retrieved []adapter.ARPEntryKVWithMetadata, err error, 95 ) { 96 // Retrieve VPP ARP entries. 97 arpEntries, err := d.arpHandler.DumpArpEntries() 98 if err != nil { 99 return nil, errors.Errorf("failed to dump VPP arps: %v", err) 100 } 101 102 for _, arp := range arpEntries { 103 retrieved = append(retrieved, adapter.ARPEntryKVWithMetadata{ 104 Key: l3.ArpEntryKey(arp.Arp.Interface, arp.Arp.IpAddress), 105 Value: arp.Arp, 106 Origin: kvs.UnknownOrigin, 107 }) 108 } 109 110 return retrieved, nil 111 } 112 113 // Dependencies lists dependencies for a VPP ARP entry. 114 func (d *ArpDescriptor) Dependencies(key string, arp *l3.ARPEntry) (deps []kvs.Dependency) { 115 // the outgoing interface must exist 116 if arp.Interface != "" { 117 deps = append(deps, kvs.Dependency{ 118 Label: arpEntryInterfaceDep, 119 Key: interfaces.InterfaceKey(arp.Interface), 120 }) 121 } 122 return deps 123 }