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 }