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 }