Skip to content

Latest commit

 

History

History
 
 

idxvpp

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 

NameToIndex

Note: idxvpp package will completely replace idxvpp once all plugins are based on KVScheduler.

The NameToIndex mapping is an extension of the NamedMapping mapping. It is used by VPP Agent plugins that interact with VPP/Linux to map between items with integer handles and the string-based object identifiers used by northbound clients of the Agent.

The mappings are primarily used to match VPP dumps with the northbound configuration. This is essential for the re-configuration and state re-synchronization after failures. Furthermore, a mapping registry may be shared between plugins. For example, ifplugin exposes a sw_if_index->iface_meta mapping (extended NameToIndex) so that other plugins may reference interfaces from objects that depend on them, such as bridge domains or IP routes.

API

Every plugin is allowed to allocate a new mapping using the function NewNameToIndex(logger, title, indexfunction), giving in-memory-only storage capabilities. Specifying indexFunction allows to add user-defined secondary indices.

The NameToIndexRW interface supports read and write operations. While the registry owner is allowed to do both reads and writes, only the read interface NameToIndex is typically exposed to other plugins.

The read-only interface provides item-by-name and item-by-index look-ups using the LookupByName and LookupByIndex functions, respectively. Additionally, a client can use the WatchItems function to watch for changes in the registry related to items with integer handles. The registry owner can change the mapping content using the Put/Delete/Update functions from the underlying NamedMapping.

KVScheduler-owned mapping

Plugins configuring VPP items via KVScheduler (ligato/cn-infra/kvscheduler), are able to let the scheduler to keep the mapping of item metadata up-to-date. WithMetadata() function of KVDescriptor is used to enable/disable the scheduler-managed mapping for item metadata. Normally, the scheduler uses the basic NamedMapping to keep the association between item name and item metadata. Descriptor, however, may provide a mapping factory, building mapping with customized secondary indexes - like NameToIndex or its extensions. The mapping is then available for reading to everyone via scheduler's method GetMetadataMap(descriptor). For mappings customized using the factory, the returned NamedMapping can be then further casted to interface exposing the extra look-ups, but keeping the access read-only.

Example

Here are some simplified code snippets from ifplugin showing how descriptor can define mapping factory for the scheduler, and how the plugin then propagates a read-only access to the mapping, including the extra secondary indexes:

// ifaceidx extends NameToIndex with IP lookups (for full code see plugins/vpp/ifplugin/ifaceidx2):

type IfaceMetadataIndex interface {
	LookupByName(name string) (metadata *IfaceMetadata, exists bool)
	LookupBySwIfIndex(swIfIndex uint32) (name string, metadata *IfaceMetadata, exists bool)
	LookupByIP(ip string) []string /* name */
	WatchInterfaces(subscriber string, channel chan<- IfaceMetadataDto)
}

type IfaceMetadata struct {
	SwIfIndex   uint32
	IpAddresses []string
}

// In descriptor:

func (intfd *IntfDescriptorImpl) WithMetadata() (withMeta bool, customMapFactory kvscheduler.MetadataMapFactory) {
	return true, func() idxmap.NamedMappingRW {
		return ifaceidx.NewIfaceIndex(logrus.DefaultLogger(), "interface-index")
		}
}

// In ifplugin API:

type IfPlugin struct {
	Deps

	intfIndex ifaceidx.IfaceMetadataIndex
}

func (p *IfPlugin) Init() error {
	descriptor := adapter.NewIntfDescriptor(&descriptor.IntfDescriptorImpl{})
	p.Deps.Scheduler.RegisterKVDescriptor(descriptor)

	var withIndex bool
	metadataMap := p.Deps.Scheduler.GetMetadataMap(descriptor.GetName())
	p.intfIndex, withIndex = metadataMap.(ifaceidx.IfaceMetadataIndex)
	if !withIndex {
		return errors.New("missing index with interface metadata")
	}
	return nil
}

func (p *IfPlugin) GetInterfaceIndex() ifaceidx.IfaceMetadataIndex {
	return p.intfIndex
}