go.ligato.io/vpp-agent/v3@v3.5.0/pkg/idxvpp/README.md (about)

     1  # NameToIndex
     2  
     3  Note: idxvpp package will completely replace idxvpp once all plugins are based on
     4  `KVScheduler`.
     5  
     6  The NameToIndex mapping is an extension of the NamedMapping mapping. It is
     7  used by VPP Agent plugins that interact with VPP/Linux to map between items
     8  with integer handles and the string-based object identifiers used by northbound
     9  clients of the Agent.
    10  
    11  The mappings are primarily used to match VPP dumps with the northbound
    12  configuration. This is essential for the re-configuration and state
    13  re-synchronization after failures.
    14  Furthermore, a mapping registry may be shared between plugins.
    15  For example, `ifplugin` exposes a `sw_if_index->iface_meta` mapping (extended
    16  `NameToIndex`) so that other plugins may reference interfaces from objects
    17  that depend on them, such as bridge domains or IP routes.
    18  
    19  **API**
    20  
    21  Every plugin is allowed to allocate a new mapping using the function
    22  `NewNameToIndex(logger, title, indexfunction)`, giving in-memory-only
    23  storage capabilities. Specifying `indexFunction` allows to add user-defined
    24  secondary indices.
    25  
    26  The `NameToIndexRW` interface supports read and write operations. While the
    27  registry owner is allowed to do both reads and writes, only the read
    28  interface `NameToIndex` is typically exposed to other plugins.
    29  
    30  The read-only interface provides item-by-name and item-by-index look-ups using
    31  the `LookupByName` and `LookupByIndex` functions, respectively. Additionally,
    32  a client can use the `WatchItems` function to watch for changes in the registry
    33  related to items with integer handles. The registry owner can change the mapping
    34  content using the `Put/Delete/Update` functions from the underlying NamedMapping.
    35  
    36  **KVScheduler-owned mapping**
    37  
    38  Plugins configuring VPP items via `KVScheduler` (`ligato/cn-infra/kvscheduler`),
    39  are able to let the scheduler to keep the mapping of item metadata up-to-date.
    40  `WithMetadata()` function of `KVDescriptor` is used to enable/disable
    41  the scheduler-managed mapping for item metadata. Normally, the scheduler uses
    42  the basic `NamedMapping` to keep the association between item name and item
    43  metadata. Descriptor, however, may provide a mapping factory, building mapping
    44  with customized secondary indexes - like `NameToIndex` or its extensions.
    45  The mapping is then available for reading to everyone via scheduler's method
    46  `GetMetadataMap(descriptor)`. For mappings customized using the factory,
    47  the returned `NamedMapping` can be then further casted to interface exposing
    48  the extra look-ups, but keeping the access read-only.
    49  
    50  *Example*
    51  
    52  Here are some simplified code snippets from `ifplugin` showing how descriptor
    53  can define mapping factory for the scheduler, and how the plugin then propagates
    54  a read-only access to the mapping, including the extra secondary indexes:
    55  
    56  ```
    57  // ifaceidx extends NameToIndex with IP lookups (for full code see plugins/vpp/ifplugin/ifaceidx2):
    58  
    59  type IfaceMetadataIndex interface {
    60  	LookupByName(name string) (metadata *IfaceMetadata, exists bool)
    61  	LookupBySwIfIndex(swIfIndex uint32) (name string, metadata *IfaceMetadata, exists bool)
    62  	LookupByIP(ip string) []string /* name */
    63  	WatchInterfaces(subscriber string, channel chan<- IfaceMetadataDto)
    64  }
    65  
    66  type IfaceMetadata struct {
    67  	SwIfIndex   uint32
    68  	IpAddresses []string
    69  }
    70  
    71  // In descriptor:
    72  
    73  func (intfd *IntfDescriptorImpl) WithMetadata() (withMeta bool, customMapFactory kvscheduler.MetadataMapFactory) {
    74  	return true, func() idxmap.NamedMappingRW {
    75  		return ifaceidx.NewIfaceIndex(logrus.DefaultLogger(), "interface-index")
    76  		}
    77  }
    78  
    79  // In ifplugin API:
    80  
    81  type IfPlugin struct {
    82  	Deps
    83  
    84  	intfIndex ifaceidx.IfaceMetadataIndex
    85  }
    86  
    87  func (p *IfPlugin) Init() error {
    88  	descriptor := adapter.NewIntfDescriptor(&descriptor.IntfDescriptorImpl{})
    89  	p.Deps.Scheduler.RegisterKVDescriptor(descriptor)
    90  
    91  	var withIndex bool
    92  	metadataMap := p.Deps.Scheduler.GetMetadataMap(descriptor.GetName())
    93  	p.intfIndex, withIndex = metadataMap.(ifaceidx.IfaceMetadataIndex)
    94  	if !withIndex {
    95  		return errors.New("missing index with interface metadata")
    96  	}
    97  	return nil
    98  }
    99  
   100  func (p *IfPlugin) GetInterfaceIndex() ifaceidx.IfaceMetadataIndex {
   101  	return p.intfIndex
   102  }
   103  ```