go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ipsecplugin/descriptor/spd.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 "errors" 19 20 "go.ligato.io/cn-infra/v2/logging" 21 22 kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api" 23 vppIfDescriptor "go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/descriptor" 24 "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/descriptor/adapter" 25 "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls" 26 ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" 27 ) 28 29 const ( 30 // IPSecSPDDescriptorName is the name of the descriptor for VPP IPSec SPD 31 // configurations. 32 IPSecSPDDescriptorName = "vpp-ipsec-spd" 33 ) 34 35 // A list of non-retriable errors: 36 var ( 37 // ErrDeprecatedSPDPolicies is returned when the deprecated SecurityPolicyDatabase.PolicyEntries is used. 38 ErrDeprecatedSPDPolicies = errors.New( 39 "it is deprecated and no longer supported to define SPs inside SPD model (use SecurityPolicy model instead)") 40 ) 41 42 // IPSecSPDDescriptor teaches KVScheduler how to configure IPSec SPD in VPP. 43 type IPSecSPDDescriptor struct { 44 // dependencies 45 log logging.Logger 46 ipSecHandler vppcalls.IPSecVppAPI 47 } 48 49 // NewIPSecSPDDescriptor creates a new instance of the IPSec SPD descriptor. 50 func NewIPSecSPDDescriptor(ipSecHandler vppcalls.IPSecVppAPI, log logging.PluginLogger) *IPSecSPDDescriptor { 51 return &IPSecSPDDescriptor{ 52 ipSecHandler: ipSecHandler, 53 log: log.NewLogger("ipsec-spd-descriptor"), 54 } 55 } 56 57 // GetDescriptor returns descriptor suitable for registration (via adapter) with 58 // the KVScheduler. 59 func (d *IPSecSPDDescriptor) GetDescriptor() *adapter.SPDDescriptor { 60 return &adapter.SPDDescriptor{ 61 Name: IPSecSPDDescriptorName, 62 NBKeyPrefix: ipsec.ModelSecurityPolicyDatabase.KeyPrefix(), 63 ValueTypeName: ipsec.ModelSecurityPolicyDatabase.ProtoName(), 64 KeySelector: ipsec.ModelSecurityPolicyDatabase.IsKeyValid, 65 KeyLabel: ipsec.ModelSecurityPolicyDatabase.StripKeyPrefix, 66 ValueComparator: d.EquivalentIPSecSPDs, 67 Validate: d.Validate, 68 Create: d.Create, 69 Delete: d.Delete, 70 Retrieve: d.Retrieve, 71 DerivedValues: d.DerivedValues, 72 RetrieveDependencies: []string{vppIfDescriptor.InterfaceDescriptorName}, 73 } 74 } 75 76 // EquivalentIPSecSPDs always returns true because all non-key attributes are derived out. 77 func (d *IPSecSPDDescriptor) EquivalentIPSecSPDs(key string, oldSPD, newSPD *ipsec.SecurityPolicyDatabase) bool { 78 return true 79 } 80 81 // Validate validates IPSec SPD configuration. 82 func (d *IPSecSPDDescriptor) Validate(key string, spd *ipsec.SecurityPolicyDatabase) (err error) { 83 if len(spd.GetPolicyEntries()) != 0 { 84 return ErrDeprecatedSPDPolicies 85 } 86 return nil 87 } 88 89 // Create adds a new IPSec security policy database. 90 func (d *IPSecSPDDescriptor) Create(key string, spd *ipsec.SecurityPolicyDatabase) (metadata interface{}, err error) { 91 // create a new SPD with index 92 err = d.ipSecHandler.AddSPD(spd.GetIndex()) 93 if err != nil { 94 d.log.Error(err) 95 return nil, err 96 } 97 return nil, nil 98 } 99 100 // Delete removes VPP IPSec security policy database. 101 func (d *IPSecSPDDescriptor) Delete(key string, spd *ipsec.SecurityPolicyDatabase, metadata interface{}) error { 102 err := d.ipSecHandler.DeleteSPD(spd.GetIndex()) 103 if err != nil { 104 d.log.Error(err) 105 } 106 return err 107 } 108 109 // Retrieve returns all configured VPP security policy databases. 110 func (d *IPSecSPDDescriptor) Retrieve(correlate []adapter.SPDKVWithMetadata) (dump []adapter.SPDKVWithMetadata, err error) { 111 nbCfg := map[uint32]*ipsec.SecurityPolicyDatabase{} 112 for _, spd := range correlate { 113 nbCfg[spd.Value.GetIndex()] = spd.Value 114 } 115 116 // dump security policy associations 117 spds, err := d.ipSecHandler.DumpIPSecSPD() 118 if err != nil { 119 d.log.Error(err) 120 return dump, err 121 } 122 for _, spd := range spds { 123 // Correlate interface assignments which are not properly dumped (bug in ipsec_spd_interface_dump) 124 spd.Interfaces = nbCfg[spd.GetIndex()].GetInterfaces() 125 dump = append(dump, adapter.SPDKVWithMetadata{ 126 Key: ipsec.SPDKey(spd.Index), 127 Value: spd, 128 Origin: kvs.FromNB, 129 }) 130 } 131 return dump, nil 132 } 133 134 // DerivedValues derives ipsec.SecurityPolicyDatabase_Interface for every interface assigned to the SPD. 135 func (d *IPSecSPDDescriptor) DerivedValues(key string, spd *ipsec.SecurityPolicyDatabase) (derValues []kvs.KeyValuePair) { 136 // SPD interfaces 137 for _, spdIface := range spd.Interfaces { 138 derValues = append(derValues, kvs.KeyValuePair{ 139 Key: ipsec.SPDInterfaceKey(spd.Index, spdIface.Name), 140 Value: spdIface, 141 }) 142 } 143 144 return derValues 145 }