go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ipsecplugin/descriptor/spd_interface.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 "strconv" 19 20 "github.com/go-errors/errors" 21 "go.ligato.io/cn-infra/v2/logging" 22 "google.golang.org/protobuf/proto" 23 24 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/descriptor/adapter" 26 "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls" 27 interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces" 28 ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" 29 ) 30 31 const ( 32 // SPDInterfaceDescriptorName is the name of the descriptor for bindings between 33 // VPP IPSec security policy database and interfaces. 34 SPDInterfaceDescriptorName = "vpp-spd-interface" 35 36 // dependency labels 37 interfaceDep = "interface-exists" 38 ) 39 40 // SPDInterfaceDescriptor teaches KVScheduler how to put interface into VPP 41 // security policy database 42 type SPDInterfaceDescriptor struct { 43 // dependencies 44 log logging.Logger 45 ipSecHandler vppcalls.IPSecVppAPI 46 } 47 48 // NewSPDInterfaceDescriptor creates a new instance of the SPDInterface descriptor. 49 func NewSPDInterfaceDescriptor(ipSecHandler vppcalls.IPSecVppAPI, log logging.PluginLogger) *SPDInterfaceDescriptor { 50 return &SPDInterfaceDescriptor{ 51 log: log.NewLogger("spd-interface-descriptor"), 52 ipSecHandler: ipSecHandler, 53 } 54 } 55 56 // GetDescriptor returns descriptor suitable for registration (via adapter) with 57 // the KVScheduler. 58 func (d *SPDInterfaceDescriptor) GetDescriptor() *adapter.SPDInterfaceDescriptor { 59 return &adapter.SPDInterfaceDescriptor{ 60 Name: SPDInterfaceDescriptorName, 61 KeySelector: d.IsSPDInterfaceKey, 62 ValueTypeName: string(proto.MessageName(&ipsec.SecurityPolicyDatabase{})), 63 Create: d.Create, 64 Delete: d.Delete, 65 Dependencies: d.Dependencies, 66 } 67 } 68 69 // IsSPDInterfaceKey returns true if the key is identifying binding between 70 // VPP security policy database and interface. 71 func (d *SPDInterfaceDescriptor) IsSPDInterfaceKey(key string) bool { 72 _, _, isSPDIfaceKey := ipsec.ParseSPDInterfaceKey(key) 73 return isSPDIfaceKey 74 } 75 76 // Create puts interface into security policy database. 77 func (d *SPDInterfaceDescriptor) Create(key string, spdIf *ipsec.SecurityPolicyDatabase_Interface) (metadata interface{}, err error) { 78 // get security policy database index 79 spdIdx, _, isSPDIfKey := ipsec.ParseSPDInterfaceKey(key) 80 if !isSPDIfKey { 81 err = errors.Errorf("provided key is not a derived SPD <=> interface binding key %s", key) 82 d.log.Error(err) 83 return nil, err 84 } 85 86 // convert to numeric index 87 spdID, err := strconv.Atoi(spdIdx) 88 if err != nil { 89 err = errors.Errorf("provided SPD index is not a valid value %s", spdIdx) 90 d.log.Error(err) 91 return nil, err 92 } 93 94 // put interface into the security policy database 95 err = d.ipSecHandler.AddSPDInterface(uint32(spdID), spdIf) 96 if err != nil { 97 d.log.Error(err) 98 return nil, err 99 100 } 101 return nil, nil 102 } 103 104 // Delete removes interface from security policy database. 105 func (d *SPDInterfaceDescriptor) Delete(key string, spdIf *ipsec.SecurityPolicyDatabase_Interface, metadata interface{}) (err error) { 106 // get security policy database index 107 spdIdx, _, isSPDIfKey := ipsec.ParseSPDInterfaceKey(key) 108 if !isSPDIfKey { 109 err = errors.Errorf("provided key is not a derived SPD <=> interface binding key %s", key) 110 d.log.Error(err) 111 return err 112 } 113 114 // convert to numeric index 115 spdID, err := strconv.Atoi(spdIdx) 116 if err != nil { 117 err = errors.Errorf("provided SPD index is not a valid value %s", spdIdx) 118 d.log.Error(err) 119 return err 120 } 121 122 err = d.ipSecHandler.DeleteSPDInterface(uint32(spdID), spdIf) 123 if err != nil { 124 d.log.Error(err) 125 return err 126 127 } 128 return nil 129 } 130 131 // Dependencies lists the interface as the only dependency for the binding. 132 func (d *SPDInterfaceDescriptor) Dependencies(key string, value *ipsec.SecurityPolicyDatabase_Interface) []kvs.Dependency { 133 return []kvs.Dependency{ 134 { 135 Label: interfaceDep, 136 Key: interfaces.InterfaceKey(value.Name), 137 }, 138 } 139 }