go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/ifplugin/descriptor/unnumbered.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  	"context"
    19  
    20  	"github.com/pkg/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/ifplugin/descriptor/adapter"
    26  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/ifaceidx"
    27  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin/vppcalls"
    28  	interfaces "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/interfaces"
    29  )
    30  
    31  const (
    32  	// UnnumberedIfDescriptorName is the name of the descriptor for the unnumbered
    33  	// config-subsection of VPP interfaces.
    34  	UnnumberedIfDescriptorName = "vpp-unnumbered-interface"
    35  
    36  	// dependency labels
    37  	unnumberedInterfaceHasIPDep = "unnumbered-interface-has-IP"
    38  )
    39  
    40  // UnnumberedIfDescriptor sets/unsets VPP interfaces as unnumbered.
    41  // Values = Interface_Unnumbered{} derived from interfaces where IsUnnumbered==true
    42  type UnnumberedIfDescriptor struct {
    43  	log       logging.Logger
    44  	ifHandler vppcalls.InterfaceVppAPI
    45  	ifIndex   ifaceidx.IfaceMetadataIndex
    46  }
    47  
    48  // NewUnnumberedIfDescriptor creates a new instance of UnnumberedIfDescriptor.
    49  func NewUnnumberedIfDescriptor(ifHandler vppcalls.InterfaceVppAPI, ifIndex ifaceidx.IfaceMetadataIndex,
    50  	log logging.PluginLogger) *kvs.KVDescriptor {
    51  
    52  	ctx := &UnnumberedIfDescriptor{
    53  		ifHandler: ifHandler,
    54  		ifIndex:   ifIndex,
    55  		log:       log.NewLogger("unif-descriptor"),
    56  	}
    57  
    58  	typedDescr := &adapter.UnnumberedDescriptor{
    59  		Name:          UnnumberedIfDescriptorName,
    60  		KeySelector:   ctx.IsUnnumberedInterfaceKey,
    61  		ValueTypeName: string(proto.MessageName(&interfaces.Interface_Unnumbered{})),
    62  		Create:        ctx.Create,
    63  		Delete:        ctx.Delete,
    64  		Dependencies:  ctx.Dependencies,
    65  	}
    66  
    67  	return adapter.NewUnnumberedDescriptor(typedDescr)
    68  }
    69  
    70  // IsUnnumberedInterfaceKey returns true if the key is identifying unnumbered
    71  // VPP interface.
    72  func (d *UnnumberedIfDescriptor) IsUnnumberedInterfaceKey(key string) bool {
    73  	_, isValid := interfaces.ParseNameFromUnnumberedKey(key)
    74  	return isValid
    75  }
    76  
    77  // Create sets interface as unnumbered.
    78  func (d *UnnumberedIfDescriptor) Create(key string, unIntf *interfaces.Interface_Unnumbered) (metadata interface{}, err error) {
    79  	ifName, _ := interfaces.ParseNameFromUnnumberedKey(key)
    80  
    81  	ifMeta, found := d.ifIndex.LookupByName(ifName)
    82  	if !found {
    83  		err = errors.Errorf("failed to find unnumbered interface %s", ifName)
    84  		d.log.Error(err)
    85  		return nil, err
    86  	}
    87  
    88  	ifWithIPMeta, found := d.ifIndex.LookupByName(unIntf.InterfaceWithIp)
    89  	if !found {
    90  		err = errors.Errorf("failed to find interface %s referenced by unnumbered interface %s",
    91  			unIntf.InterfaceWithIp, ifName)
    92  		d.log.Error(err)
    93  		return nil, err
    94  	}
    95  
    96  	err = d.ifHandler.SetUnnumberedIP(context.TODO(), ifMeta.SwIfIndex, ifWithIPMeta.SwIfIndex)
    97  	if err != nil {
    98  		d.log.Error(err)
    99  	}
   100  	return nil, err
   101  }
   102  
   103  // Delete un-sets interface as unnumbered.
   104  func (d *UnnumberedIfDescriptor) Delete(key string, unIntf *interfaces.Interface_Unnumbered, metadata interface{}) error {
   105  	ifName, _ := interfaces.ParseNameFromUnnumberedKey(key)
   106  
   107  	ifMeta, found := d.ifIndex.LookupByName(ifName)
   108  	if !found {
   109  		err := errors.Errorf("failed to find unnumbered interface %s", ifName)
   110  		d.log.Error(err)
   111  		return err
   112  	}
   113  
   114  	err := d.ifHandler.UnsetUnnumberedIP(context.TODO(), ifMeta.SwIfIndex)
   115  	if err != nil {
   116  		d.log.Error(err)
   117  	}
   118  
   119  	return err
   120  }
   121  
   122  // Dependencies lists dependencies for an unnumbered VPP interface.
   123  func (d *UnnumberedIfDescriptor) Dependencies(key string, unIntf *interfaces.Interface_Unnumbered) (deps []kvs.Dependency) {
   124  	// link between unnumbered interface and the referenced interface with IP address
   125  	// - satisfied as along as the referenced interface is configured and has at least
   126  	//   one IP address assigned
   127  	deps = []kvs.Dependency{
   128  		{
   129  			Label: unnumberedInterfaceHasIPDep,
   130  			Key:   interfaces.InterfaceWithIPKey(unIntf.InterfaceWithIp),
   131  		},
   132  	}
   133  
   134  	// interface has to be assigned to VRF before setting as unnumbered
   135  	iface, _ := interfaces.ParseNameFromUnnumberedKey(key)
   136  	deps = append(deps, kvs.Dependency{
   137  		Label: interfaceInVrfDep,
   138  		AnyOf: kvs.AnyOfDependency{
   139  			KeyPrefixes: []string{interfaces.InterfaceVrfKeyPrefix(iface)},
   140  		},
   141  	})
   142  	return
   143  }