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  }