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  }