go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/natplugin/descriptor/nat44_global_address.go (about)

     1  // Copyright (c) 2019 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  	"net"
    20  
    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/natplugin/descriptor/adapter"
    26  	"go.ligato.io/vpp-agent/v3/plugins/vpp/natplugin/vppcalls"
    27  	l3 "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3"
    28  	nat "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/nat"
    29  )
    30  
    31  const (
    32  	// NAT44GlobalAddressDescriptorName is the name of the descriptor for IP addresses
    33  	// from the VPP NAT44 address pool.
    34  	NAT44GlobalAddressDescriptorName = "vpp-nat44-global-address"
    35  
    36  	// dependency labels
    37  	addressVrfDep    = "vrf-table-exists"
    38  	addressEpModeDep = "nat44-is-in-endpoint-dependent-mode"
    39  )
    40  
    41  // A list of non-retriable errors:
    42  var (
    43  	// ErrInvalidNATAddress is returned when IP address from VPP NAT address pool
    44  	// cannot be parsed.
    45  	ErrInvalidNATAddress = errors.New("Invalid VPP NAT address")
    46  )
    47  
    48  // NAT44GlobalAddressDescriptor teaches KVScheduler how to add/remove IP addresses
    49  // to/from the VPP NAT44 address pool.
    50  // Deprecated. Functionality moved to NAT44AddressPoolDescriptor. Kept for backward compatibility.
    51  type NAT44GlobalAddressDescriptor struct {
    52  	log        logging.Logger
    53  	natHandler vppcalls.NatVppAPI
    54  }
    55  
    56  // NewNAT44GlobalAddressDescriptor creates a new instance of the NAT44Address descriptor.
    57  // Deprecated. Functionality moved to NAT44AddressPoolDescriptor. Kept for backward compatibility.
    58  func NewNAT44GlobalAddressDescriptor(natHandler vppcalls.NatVppAPI, log logging.PluginLogger) *kvs.KVDescriptor {
    59  	ctx := &NAT44GlobalAddressDescriptor{
    60  		natHandler: natHandler,
    61  		log:        log.NewLogger("nat44-global-address-descriptor"),
    62  	}
    63  
    64  	typedDescr := &adapter.NAT44GlobalAddressDescriptor{
    65  		Name:          NAT44GlobalAddressDescriptorName,
    66  		KeySelector:   ctx.IsNat44DerivedAddressKey,
    67  		ValueTypeName: string(proto.MessageName(&nat.Nat44Global_Address{})),
    68  		Create:        ctx.Create,
    69  		Delete:        ctx.Delete,
    70  		Dependencies:  ctx.Dependencies,
    71  	}
    72  	return adapter.NewNAT44GlobalAddressDescriptor(typedDescr)
    73  }
    74  
    75  // IsNat44DerivedAddressKey returns true if the key is identifying configuration
    76  // for a single address from the NAT44 address pool.
    77  func (d *NAT44GlobalAddressDescriptor) IsNat44DerivedAddressKey(key string) bool {
    78  	_, _, isNATAddrKey := nat.ParseDerivedAddressNAT44Key(key)
    79  	return isNATAddrKey
    80  }
    81  
    82  // Validate validates configuration for NAT44 address.
    83  func (d *NAT44GlobalAddressDescriptor) Validate(key string, natAddr *nat.Nat44Global_Address) error {
    84  	ipAddr := net.ParseIP(natAddr.Address)
    85  	if ipAddr == nil {
    86  		return kvs.NewInvalidValueError(ErrInvalidNATAddress, "address")
    87  	}
    88  	return nil
    89  }
    90  
    91  // Create adds IP address into the NAT44 address pool.
    92  func (d *NAT44GlobalAddressDescriptor) Create(key string, natAddr *nat.Nat44Global_Address) (metadata interface{}, err error) {
    93  	err = d.natHandler.AddNat44AddressPool(natAddr.VrfId, natAddr.Address, "", natAddr.TwiceNat)
    94  	if err != nil {
    95  		d.log.Error(err)
    96  		return nil, err
    97  	}
    98  	return nil, nil
    99  }
   100  
   101  // Delete removes IP address from the NAT44 address pool.
   102  func (d *NAT44GlobalAddressDescriptor) Delete(key string, natAddr *nat.Nat44Global_Address, metadata interface{}) error {
   103  	err := d.natHandler.DelNat44AddressPool(natAddr.VrfId, natAddr.Address, "", natAddr.TwiceNat)
   104  	if err != nil {
   105  		d.log.Error(err)
   106  		return err
   107  	}
   108  	return nil
   109  }
   110  
   111  // Dependencies lists endpoint-dependent mode and non-zero VRF as dependencies.
   112  func (d *NAT44GlobalAddressDescriptor) Dependencies(key string, natAddr *nat.Nat44Global_Address) (deps []kvs.Dependency) {
   113  	if natAddr.VrfId != 0 && natAddr.VrfId != ^uint32(0) {
   114  		deps = append(deps, kvs.Dependency{
   115  			Label: addressVrfDep,
   116  			Key:   l3.VrfTableKey(natAddr.VrfId, l3.VrfTable_IPV4),
   117  		})
   118  	}
   119  	if !d.natHandler.WithLegacyStartupConf() {
   120  		deps = append(deps, kvs.Dependency{
   121  			Label: addressEpModeDep,
   122  			Key:   nat.Nat44EndpointDepKey,
   123  		})
   124  	}
   125  	return deps
   126  }