go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ifplugin/descriptor/rx_placement.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  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/descriptor/adapter"
    24  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    25  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls"
    26  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    27  )
    28  
    29  const (
    30  	// RxPlacementDescriptorName is the name of the descriptor for the rx-placement
    31  	// config-subsection of VPP interfaces.
    32  	RxPlacementDescriptorName = "vpp-interface-rx-placement"
    33  )
    34  
    35  // RxPlacementDescriptor configures Rx placement for VPP interface queues.
    36  type RxPlacementDescriptor struct {
    37  	log       logging.Logger
    38  	ifHandler vppcalls.InterfaceVppAPI
    39  	ifIndex   ifaceidx.IfaceMetadataIndex
    40  }
    41  
    42  // NewRxPlacementDescriptor creates a new instance of RxPlacementDescriptor.
    43  func NewRxPlacementDescriptor(ifHandler vppcalls.InterfaceVppAPI, ifIndex ifaceidx.IfaceMetadataIndex,
    44  	log logging.PluginLogger) *kvs.KVDescriptor {
    45  
    46  	ctx := &RxPlacementDescriptor{
    47  		ifHandler: ifHandler,
    48  		ifIndex:   ifIndex,
    49  		log:       log.NewLogger("rx-placement-descriptor"),
    50  	}
    51  
    52  	typedDescr := &adapter.RxPlacementDescriptor{
    53  		Name:            RxPlacementDescriptorName,
    54  		KeySelector:     ctx.IsInterfaceRxPlacementKey,
    55  		ValueComparator: ctx.EquivalentRxPlacement,
    56  		ValueTypeName:   string(proto.MessageName(&interfaces.Interface{})),
    57  		Create:          ctx.Create,
    58  		Delete:          ctx.Delete,
    59  		Dependencies:    ctx.Dependencies,
    60  	}
    61  
    62  	return adapter.NewRxPlacementDescriptor(typedDescr)
    63  }
    64  
    65  // IsInterfaceRxPlacementKey returns true if the key is identifying RxPlacement
    66  // configuration.
    67  func (d *RxPlacementDescriptor) IsInterfaceRxPlacementKey(key string) bool {
    68  	_, _, isValid := interfaces.ParseRxPlacementKey(key)
    69  	return isValid
    70  }
    71  
    72  // EquivalentRxMode compares Rx placements for equivalency.
    73  func (d *RxPlacementDescriptor) EquivalentRxPlacement(key string, oldRxPl, newRxPl *interfaces.Interface_RxPlacement) bool {
    74  
    75  	if (oldRxPl.MainThread != newRxPl.MainThread) ||
    76  		(!oldRxPl.MainThread && oldRxPl.Worker != newRxPl.Worker) {
    77  		return false
    78  	}
    79  	return true
    80  }
    81  
    82  // Create configures RxPlacement for a given interface queue.
    83  // Please note the proto message Interface is only used as container for RxMode.
    84  // Only interface name, type and Rx mode are set.
    85  func (d *RxPlacementDescriptor) Create(key string, rxPlacement *interfaces.Interface_RxPlacement) (md interface{}, err error) {
    86  	ifaceName, _, _ := interfaces.ParseRxPlacementKey(key)
    87  	ifMeta, found := d.ifIndex.LookupByName(ifaceName)
    88  	if !found {
    89  		err = errors.Errorf("failed to find interface %s", ifaceName)
    90  		d.log.Error(err)
    91  		return nil, err
    92  	}
    93  
    94  	if err = d.ifHandler.SetRxPlacement(ifMeta.SwIfIndex, rxPlacement); err != nil {
    95  		err = errors.Errorf("failed to set rx-placement for queue %d of the interface %s: %v",
    96  			rxPlacement.Queue, ifaceName, err)
    97  		d.log.Error(err)
    98  		return nil, err
    99  	}
   100  	return nil, err
   101  }
   102  
   103  // Delete is NOOP (Rx placement cannot be returned back to default).
   104  func (d *RxPlacementDescriptor) Delete(key string, rxPlacement *interfaces.Interface_RxPlacement, metadata interface{}) error {
   105  	return nil
   106  }
   107  
   108  // Dependencies informs scheduler that Rx placement configuration cannot be applied
   109  // until the interface link is UP.
   110  func (d *RxPlacementDescriptor) Dependencies(key string, rxPlacement *interfaces.Interface_RxPlacement) []kvs.Dependency {
   111  	ifaceName, _, _ := interfaces.ParseRxPlacementKey(key)
   112  	return []kvs.Dependency{
   113  		{
   114  			Label: linkIsUpDep,
   115  			Key:   interfaces.LinkStateKey(ifaceName, true),
   116  		},
   117  	}
   118  }