go.ligato.io/vpp-agent/v3@v3.5.0/plugins/vpp/l3plugin/l3plugin.go (about)

     1  // Copyright (c) 2021 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  //go:generate descriptor-adapter --descriptor-name Route --value-type *vpp_l3.Route --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    16  //go:generate descriptor-adapter --descriptor-name ARPEntry --value-type *vpp_l3.ARPEntry --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    17  //go:generate descriptor-adapter --descriptor-name ProxyARP --value-type *vpp_l3.ProxyARP --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    18  //go:generate descriptor-adapter --descriptor-name ProxyARPInterface --value-type *vpp_l3.ProxyARP_Interface --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    19  //go:generate descriptor-adapter --descriptor-name IPScanNeighbor --value-type *vpp_l3.IPScanNeighbor --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    20  //go:generate descriptor-adapter --descriptor-name VrfTable --value-type *vpp_l3.VrfTable --meta-type *vrfidx.VRFMetadata --import "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vrfidx" --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    21  //go:generate descriptor-adapter --descriptor-name DHCPProxy --value-type *vpp_l3.DHCPProxy --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    22  //go:generate descriptor-adapter --descriptor-name L3XC --value-type *vpp_l3.L3XConnect --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    23  //go:generate descriptor-adapter --descriptor-name TeibEntry --value-type *vpp_l3.TeibEntry --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    24  //go:generate descriptor-adapter --descriptor-name VRRPEntry --value-type *vpp_l3.VRRPEntry --import "go.ligato.io/vpp-agent/v3/proto/ligato/vpp/l3" --output-dir "descriptor"
    25  
    26  package l3plugin
    27  
    28  import (
    29  	"github.com/pkg/errors"
    30  	"go.ligato.io/cn-infra/v2/health/statuscheck"
    31  	"go.ligato.io/cn-infra/v2/infra"
    32  
    33  	"go.ligato.io/vpp-agent/v3/plugins/govppmux"
    34  	"go.ligato.io/vpp-agent/v3/plugins/kvscheduler"
    35  	kvs "go.ligato.io/vpp-agent/v3/plugins/kvscheduler/api"
    36  	"go.ligato.io/vpp-agent/v3/plugins/netalloc"
    37  	"go.ligato.io/vpp-agent/v3/plugins/vpp/ifplugin"
    38  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/descriptor"
    39  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls"
    40  	"go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vrfidx"
    41  
    42  	_ "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls/vpp2101"
    43  	_ "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls/vpp2106"
    44  	_ "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls/vpp2202"
    45  	_ "go.ligato.io/vpp-agent/v3/plugins/vpp/l3plugin/vppcalls/vpp2210"
    46  )
    47  
    48  func init() {
    49  	kvscheduler.AddNonRetryableError(
    50  		vppcalls.ErrIPNeighborNotImplemented,
    51  		vppcalls.ErrTeibUnsupported,
    52  		vppcalls.ErrVRRPUnsupported,
    53  	)
    54  }
    55  
    56  // L3Plugin configures Linux routes and ARP entries using Netlink API.
    57  type L3Plugin struct {
    58  	Deps
    59  
    60  	// VPP handler
    61  	l3Handler vppcalls.L3VppAPI
    62  
    63  	// index maps
    64  	vrfIndex vrfidx.VRFMetadataIndex
    65  }
    66  
    67  type Deps struct {
    68  	infra.PluginDeps
    69  	KVScheduler kvs.KVScheduler
    70  	VPP         govppmux.API
    71  	IfPlugin    ifplugin.API
    72  	AddrAlloc   netalloc.AddressAllocator
    73  	StatusCheck statuscheck.PluginStatusWriter // optional
    74  }
    75  
    76  // Init initializes and registers descriptors for Linux ARPs and Routes.
    77  func (p *L3Plugin) Init() (err error) {
    78  	// init handlers
    79  	p.l3Handler = vppcalls.CompatibleL3VppHandler(p.VPP, p.IfPlugin.GetInterfaceIndex(),
    80  		p.vrfIndex, p.AddrAlloc, p.Log)
    81  	if p.l3Handler == nil {
    82  		return errors.Errorf("could not find compatible L3VppHandler")
    83  	}
    84  
    85  	// init and register VRF descriptor
    86  	vrfTableDescriptor := descriptor.NewVrfTableDescriptor(p.l3Handler, p.Log)
    87  	if err = p.Deps.KVScheduler.RegisterKVDescriptor(vrfTableDescriptor); err != nil {
    88  		return err
    89  	}
    90  	metadataMap := p.KVScheduler.GetMetadataMap(vrfTableDescriptor.Name)
    91  	var withIndex bool
    92  	p.vrfIndex, withIndex = metadataMap.(vrfidx.VRFMetadataIndex)
    93  	if !withIndex {
    94  		return errors.New("missing index with VRF metadata")
    95  	}
    96  
    97  	// set l3 handler again since VRF index was nil before
    98  	p.l3Handler = vppcalls.CompatibleL3VppHandler(p.VPP, p.IfPlugin.GetInterfaceIndex(),
    99  		p.vrfIndex, p.AddrAlloc, p.Log)
   100  
   101  	// init & register descriptors
   102  	routeDescriptor := descriptor.NewRouteDescriptor(p.l3Handler, p.AddrAlloc, p.Log)
   103  	arpDescriptor := descriptor.NewArpDescriptor(p.KVScheduler, p.l3Handler, p.Log)
   104  	proxyArpDescriptor := descriptor.NewProxyArpDescriptor(p.KVScheduler, p.l3Handler, p.Log)
   105  	proxyArpIfaceDescriptor := descriptor.NewProxyArpInterfaceDescriptor(p.KVScheduler, p.l3Handler, p.Log)
   106  	ipScanNeighborDescriptor := descriptor.NewIPScanNeighborDescriptor(p.KVScheduler, p.l3Handler, p.Log)
   107  	dhcpProxyDescriptor := descriptor.NewDHCPProxyDescriptor(p.KVScheduler, p.l3Handler, p.Log)
   108  	l3xcDescriptor := descriptor.NewL3XCDescriptor(p.l3Handler, p.IfPlugin.GetInterfaceIndex(), p.Log)
   109  	teibDescriptor := descriptor.NewTeibDescriptor(p.KVScheduler, p.l3Handler, p.Log)
   110  	vrrpDescriptor := descriptor.NewVrrpDescriptor(p.l3Handler, p.Log)
   111  
   112  	err = p.Deps.KVScheduler.RegisterKVDescriptor(
   113  		routeDescriptor,
   114  		arpDescriptor,
   115  		proxyArpDescriptor,
   116  		proxyArpIfaceDescriptor,
   117  		ipScanNeighborDescriptor,
   118  		dhcpProxyDescriptor,
   119  		l3xcDescriptor,
   120  		teibDescriptor,
   121  		vrrpDescriptor,
   122  	)
   123  	if err != nil {
   124  		return err
   125  	}
   126  
   127  	return nil
   128  }
   129  
   130  // AfterInit registers plugin with StatusCheck.
   131  func (p *L3Plugin) AfterInit() error {
   132  	if p.StatusCheck != nil {
   133  		p.StatusCheck.Register(p.PluginName, nil)
   134  	}
   135  	return nil
   136  }
   137  
   138  // GetVRFIndex gives read-only access to map with metadata of all configured VPP VRFs.
   139  func (p *L3Plugin) GetVRFIndex() vrfidx.VRFMetadataIndex {
   140  	return p.vrfIndex
   141  }