go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/descriptor/ip_scan_neighbor.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 "go.ligato.io/vpp-agent/v3/pkg/models" 23 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/descriptor/adapter" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls" 26 l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" 27 ) 28 29 const ( 30 // IPScanNeighborDescriptorName is the name of the descriptor. 31 IPScanNeighborDescriptorName = "vpp-ip-scan-neighbor" 32 ) 33 34 // IPScanNeighborDescriptor teaches KVScheduler how to configure VPP proxy ARPs. 35 type IPScanNeighborDescriptor struct { 36 log logging.Logger 37 ipNeigh vppcalls.IPNeighVppAPI 38 scheduler kvs.KVScheduler 39 defaultIPScanNeighbor *l3.IPScanNeighbor 40 } 41 42 // NewIPScanNeighborDescriptor creates a new instance of the IPScanNeighborDescriptor. 43 func NewIPScanNeighborDescriptor( 44 scheduler kvs.KVScheduler, 45 ipNeighHandler vppcalls.IPNeighVppAPI, 46 log logging.PluginLogger, 47 ) *kvs.KVDescriptor { 48 49 ctx := &IPScanNeighborDescriptor{ 50 scheduler: scheduler, 51 ipNeigh: ipNeighHandler, 52 log: log.NewLogger("ip-scan-neigh-descriptor"), 53 defaultIPScanNeighbor: ipNeighHandler.DefaultIPScanNeighbor(), 54 } 55 56 typedDescr := &adapter.IPScanNeighborDescriptor{ 57 Name: IPScanNeighborDescriptorName, 58 NBKeyPrefix: l3.ModelIPScanNeighbor.KeyPrefix(), 59 ValueTypeName: l3.ModelIPScanNeighbor.ProtoName(), 60 KeySelector: l3.ModelIPScanNeighbor.IsKeyValid, 61 ValueComparator: ctx.EquivalentIPScanNeighbors, 62 Create: ctx.Create, 63 Update: ctx.Update, 64 Delete: ctx.Delete, 65 Retrieve: ctx.Retrieve, 66 // TODO: define validation method 67 } 68 return adapter.NewIPScanNeighborDescriptor(typedDescr) 69 } 70 71 // EquivalentIPScanNeighbors compares the IP Scan Neighbor values. 72 func (d *IPScanNeighborDescriptor) EquivalentIPScanNeighbors(key string, oldValue, newValue *l3.IPScanNeighbor) bool { 73 return proto.Equal(d.withDefaults(oldValue), d.withDefaults(newValue)) 74 } 75 76 // Create adds VPP IP Scan Neighbor. 77 func (d *IPScanNeighborDescriptor) Create(key string, value *l3.IPScanNeighbor) (metadata interface{}, err error) { 78 return d.Update(key, d.defaultIPScanNeighbor, value, nil) 79 } 80 81 // Delete deletes VPP IP Scan Neighbor. 82 func (d *IPScanNeighborDescriptor) Delete(key string, value *l3.IPScanNeighbor, metadata interface{}) error { 83 _, err := d.Update(key, value, d.defaultIPScanNeighbor, metadata) 84 if errors.Is(err, vppcalls.ErrIPNeighborNotImplemented) { 85 d.log.Debug("SetIPScanNeighbor failed:", err) 86 return nil 87 } 88 return err 89 } 90 91 // Update modifies VPP IP Scan Neighbor. 92 func (d *IPScanNeighborDescriptor) Update(key string, oldValue, newValue *l3.IPScanNeighbor, oldMetadata interface{}) (newMetadata interface{}, err error) { 93 if err := d.ipNeigh.SetIPScanNeighbor(newValue); err != nil { 94 return nil, err 95 } 96 return nil, nil 97 } 98 99 // Retrieve returns current VPP IP Scan Neighbor configuration. 100 func (d *IPScanNeighborDescriptor) Retrieve(correlate []adapter.IPScanNeighborKVWithMetadata) ( 101 retrieved []adapter.IPScanNeighborKVWithMetadata, err error, 102 ) { 103 // Retrieve VPP configuration 104 ipNeigh, err := d.ipNeigh.GetIPScanNeighbor() 105 if errors.Is(err, vppcalls.ErrIPNeighborNotImplemented) { 106 d.log.Debug("GetIPScanNeighbor failed:", err) 107 return nil, nil 108 } else if err != nil { 109 return nil, err 110 } 111 d.fillDefaults(ipNeigh) 112 113 var origin = kvs.FromNB 114 if proto.Equal(ipNeigh, d.defaultIPScanNeighbor) { 115 origin = kvs.FromSB 116 } 117 118 retrieved = append(retrieved, adapter.IPScanNeighborKVWithMetadata{ 119 Key: models.Key(ipNeigh), 120 Value: ipNeigh, 121 Origin: origin, 122 }) 123 124 return retrieved, nil 125 } 126 func (d *IPScanNeighborDescriptor) withDefaults(orig *l3.IPScanNeighbor) *l3.IPScanNeighbor { 127 var ( 128 def = d.defaultIPScanNeighbor 129 val = proto.Clone(orig).(*l3.IPScanNeighbor) 130 ) 131 if def == nil { 132 return val 133 } 134 if val.ScanInterval == 0 { 135 val.ScanInterval = def.GetScanInterval() 136 } 137 if val.MaxProcTime == 0 { 138 val.MaxProcTime = def.GetMaxProcTime() 139 } 140 if val.MaxUpdate == 0 { 141 val.MaxUpdate = def.GetMaxUpdate() 142 } 143 if val.ScanIntDelay == 0 { 144 val.ScanIntDelay = def.GetScanIntDelay() 145 } 146 if val.StaleThreshold == 0 { 147 val.StaleThreshold = def.GetStaleThreshold() 148 } 149 return val 150 } 151 152 func (d *IPScanNeighborDescriptor) fillDefaults(orig *l3.IPScanNeighbor) { 153 var ( 154 def = d.defaultIPScanNeighbor 155 val = orig 156 ) 157 if def == nil { 158 return 159 } 160 if val.ScanInterval == 0 { 161 val.ScanInterval = def.GetScanInterval() 162 } 163 if val.MaxProcTime == 0 { 164 val.MaxProcTime = def.GetMaxProcTime() 165 } 166 if val.MaxUpdate == 0 { 167 val.MaxUpdate = def.GetMaxUpdate() 168 } 169 if val.ScanIntDelay == 0 { 170 val.ScanIntDelay = def.GetScanIntDelay() 171 } 172 if val.StaleThreshold == 0 { 173 val.StaleThreshold = def.GetStaleThreshold() 174 } 175 }