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  }