go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l2plugin/descriptor/xconnect.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  
    21  	kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
    22  	vpp_ifdescriptor "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/descriptor"
    23  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l2plugin/descriptor/adapter"
    24  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l2plugin/vppcalls"
    25  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    26  	l2 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l2"
    27  )
    28  
    29  const (
    30  	// XConnectDescriptorName is the name of the descriptor for VPP xConnect pairs.
    31  	XConnectDescriptorName = "vpp-xconnect"
    32  
    33  	// dependency labels
    34  	rxInterfaceDep = "rx-interface"
    35  	txInterfaceDep = "tx-interface"
    36  )
    37  
    38  // A list of non-retriable errors:
    39  var (
    40  	// ErrXConnectWithoutInterface is returned when VPP xConnect has undefined
    41  	// Rx or Tx interface.
    42  	ErrXConnectWithoutInterface = errors.New("VPP xConnect defined without Rx/Tx interface")
    43  )
    44  
    45  // XConnectDescriptor teaches KVScheduler how to configure VPP xConnect pairs.
    46  type XConnectDescriptor struct {
    47  	// dependencies
    48  	log       logging.Logger
    49  	xcHandler vppcalls.XConnectVppAPI
    50  }
    51  
    52  // NewXConnectDescriptor creates a new instance of the xConnect descriptor.
    53  func NewXConnectDescriptor(xcHandler vppcalls.XConnectVppAPI, log logging.PluginLogger) *XConnectDescriptor {
    54  
    55  	return &XConnectDescriptor{
    56  		xcHandler: xcHandler,
    57  		log:       log.NewLogger("xconnect-descriptor"),
    58  	}
    59  }
    60  
    61  // GetDescriptor returns descriptor suitable for registration (via adapter) with
    62  // the KVScheduler.
    63  func (d *XConnectDescriptor) GetDescriptor() *adapter.XConnectDescriptor {
    64  	return &adapter.XConnectDescriptor{
    65  		Name:                 XConnectDescriptorName,
    66  		NBKeyPrefix:          l2.ModelXConnectPair.KeyPrefix(),
    67  		ValueTypeName:        l2.ModelXConnectPair.ProtoName(),
    68  		KeySelector:          l2.ModelXConnectPair.IsKeyValid,
    69  		KeyLabel:             l2.ModelXConnectPair.StripKeyPrefix,
    70  		Validate:             d.Validate,
    71  		Create:               d.Create,
    72  		Delete:               d.Delete,
    73  		Retrieve:             d.Retrieve,
    74  		Dependencies:         d.Dependencies,
    75  		RetrieveDependencies: []string{vpp_ifdescriptor.InterfaceDescriptorName},
    76  	}
    77  }
    78  
    79  // Validate validates VPP xConnect pair configuration.
    80  func (d *XConnectDescriptor) Validate(key string, xc *l2.XConnectPair) error {
    81  	if xc.ReceiveInterface == "" || xc.TransmitInterface == "" {
    82  		return kvs.NewInvalidValueError(ErrXConnectWithoutInterface,
    83  			"receive_interface", "transmit_interface")
    84  	}
    85  	return nil
    86  }
    87  
    88  // Create adds new xConnect pair.
    89  func (d *XConnectDescriptor) Create(key string, xc *l2.XConnectPair) (metadata interface{}, err error) {
    90  	// add xConnect pair
    91  	err = d.xcHandler.AddL2XConnect(xc.ReceiveInterface, xc.TransmitInterface)
    92  	if err != nil {
    93  		d.log.Error(err)
    94  	}
    95  	return nil, err
    96  }
    97  
    98  // Delete removes existing xConnect pair.
    99  func (d *XConnectDescriptor) Delete(key string, xc *l2.XConnectPair, metadata interface{}) error {
   100  	err := d.xcHandler.DeleteL2XConnect(xc.ReceiveInterface, xc.TransmitInterface)
   101  	if err != nil {
   102  		d.log.Error(err)
   103  	}
   104  	return err
   105  }
   106  
   107  // Retrieve returns all configured VPP xConnect pairs.
   108  func (d *XConnectDescriptor) Retrieve(correlate []adapter.XConnectKVWithMetadata) (retrieved []adapter.XConnectKVWithMetadata, err error) {
   109  	xConnectPairs, err := d.xcHandler.DumpXConnectPairs()
   110  	if err != nil {
   111  		d.log.Error(err)
   112  		return retrieved, err
   113  	}
   114  
   115  	for _, xc := range xConnectPairs {
   116  		retrieved = append(retrieved, adapter.XConnectKVWithMetadata{
   117  			Key:    l2.XConnectKey(xc.Xc.ReceiveInterface),
   118  			Value:  xc.Xc,
   119  			Origin: kvs.FromNB,
   120  		})
   121  	}
   122  	return retrieved, nil
   123  }
   124  
   125  // Dependencies lists both Rx and Tx interface as dependencies.
   126  func (d *XConnectDescriptor) Dependencies(key string, xc *l2.XConnectPair) []kvs.Dependency {
   127  	return []kvs.Dependency{
   128  		{
   129  			Label: rxInterfaceDep,
   130  			Key:   interfaces.InterfaceKey(xc.ReceiveInterface),
   131  		},
   132  		{
   133  			Label: txInterfaceDep,
   134  			Key:   interfaces.InterfaceKey(xc.TransmitInterface),
   135  		},
   136  	}
   137  }