go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ipsecplugin/descriptor/sa.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 "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/descriptor/adapter" 23 "go.ligato.io/vpp-agent/v3/plugins/vpp/ipsecplugin/vppcalls" 24 ipsec "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/ipsec" 25 ) 26 27 const ( 28 // SADescriptorName is the name of the descriptor for VPP security associations. 29 SADescriptorName = "vpp-ipsec-sa" 30 ) 31 32 // A list of non-retriable errors: 33 var ( 34 // ErrSAWithoutIndex is returned when VPP security association was defined 35 // without index. 36 ErrSAWithoutIndex = errors.New("VPP security association defined without index") 37 38 // ErrSAInvalidIndex is returned when VPP security association was defined 39 // with non-numerical index. 40 ErrSAInvalidIndex = errors.New("VPP security association defined with invalid index") 41 ) 42 43 // IPSecSADescriptor teaches KVScheduler how to configure VPP IPSec security associations. 44 type IPSecSADescriptor struct { 45 // dependencies 46 log logging.Logger 47 ipSecHandler vppcalls.IPSecVppAPI 48 } 49 50 // NewIPSecSADescriptor creates a new instance of the IPSec SA descriptor. 51 func NewIPSecSADescriptor(ipSecHandler vppcalls.IPSecVppAPI, log logging.PluginLogger) *IPSecSADescriptor { 52 return &IPSecSADescriptor{ 53 ipSecHandler: ipSecHandler, 54 log: log.NewLogger("ipsec-sa-descriptor"), 55 } 56 } 57 58 // GetDescriptor returns descriptor suitable for registration (via adapter) with 59 // the KVScheduler. 60 func (d *IPSecSADescriptor) GetDescriptor() *adapter.SADescriptor { 61 return &adapter.SADescriptor{ 62 Name: SADescriptorName, 63 NBKeyPrefix: ipsec.ModelSecurityAssociation.KeyPrefix(), 64 ValueTypeName: ipsec.ModelSecurityAssociation.ProtoName(), 65 KeySelector: ipsec.ModelSecurityAssociation.IsKeyValid, 66 KeyLabel: ipsec.ModelSecurityAssociation.StripKeyPrefix, 67 ValueComparator: d.EquivalentIPSecSAs, 68 Create: d.Create, 69 Delete: d.Delete, 70 Retrieve: d.Retrieve, 71 } 72 } 73 74 // EquivalentIPSecSAs is case-insensitive comparison function for 75 // ipsec.SecurityAssociation 76 func (d *IPSecSADescriptor) EquivalentIPSecSAs(key string, oldSA, newSA *ipsec.SecurityAssociation) bool { 77 // compare base fields 78 return oldSA.Spi == newSA.Spi && 79 oldSA.Protocol == newSA.Protocol && 80 oldSA.CryptoAlg == newSA.CryptoAlg && 81 oldSA.CryptoKey == newSA.CryptoKey && 82 oldSA.IntegAlg == newSA.IntegAlg && 83 oldSA.IntegKey == newSA.IntegKey && 84 oldSA.UseEsn == newSA.UseEsn && 85 oldSA.UseAntiReplay == newSA.UseAntiReplay && 86 oldSA.TunnelSrcAddr == newSA.TunnelSrcAddr && 87 oldSA.TunnelDstAddr == newSA.TunnelDstAddr && 88 oldSA.EnableUdpEncap == newSA.EnableUdpEncap 89 } 90 91 // Create adds a new security association pair. 92 func (d *IPSecSADescriptor) Create(key string, sa *ipsec.SecurityAssociation) (metadata interface{}, err error) { 93 // add security association 94 err = d.ipSecHandler.AddSA(sa) 95 if err != nil { 96 d.log.Error(err) 97 } 98 99 return nil, err 100 } 101 102 // Delete removes VPP security association. 103 func (d *IPSecSADescriptor) Delete(key string, sa *ipsec.SecurityAssociation, metadata interface{}) error { 104 err := d.ipSecHandler.DeleteSA(sa) 105 if err != nil { 106 d.log.Error(err) 107 } 108 return err 109 } 110 111 // Retrieve returns all configured VPP security associations. 112 func (d *IPSecSADescriptor) Retrieve(correlate []adapter.SAKVWithMetadata) (dump []adapter.SAKVWithMetadata, err error) { 113 // dump security associations 114 sas, err := d.ipSecHandler.DumpIPSecSA() 115 if err != nil { 116 d.log.Error(err) 117 return dump, err 118 } 119 for _, sa := range sas { 120 dump = append(dump, adapter.SAKVWithMetadata{ 121 Key: ipsec.SAKey(sa.Sa.Index), 122 Value: sa.Sa, 123 Metadata: sa.Meta, 124 Origin: kvs.FromNB, 125 }) 126 } 127 128 return dump, nil 129 }