To be part of a standard, component-based configuration, new links have to provide a component that will wrap the link implementation and handle connections. An important role of the link component is to create and destroy endpoint objects as the connections are being made.
Links tend to share a lot of common functionality, and link components are no exceptions. The link library provides two interfaces to easily create link components.
The simplest way to create a link component is to use the link_components.create_simple() function. Here is the component definition for datagram_link:
from link_components import create_simple
class datagram_link(
create_simple(link_class = 'datagram_link_impl',
endpoint_class = 'datagram_link_endpoint',
connector_type = 'datagram-link',
class_desc = "datagram link",
basename = 'datagram_link')):
"""The datagram link component creates a datagram-link, which is a simple
broadcast bus forwarding messages (as sequences of bytes) from a sender
device to all other devices present of the link. The datagram-link is both
an example of how to build a link with the Simics Link Library, and a
simple broadcast link that can be reused when multi-cell communication
between devices is necessary. Refer to the <cite>Link Library Programming
Guide</cite> for more information."""
Using this simplified method assumes that the link fulfills a number of requirements:
Further information is available in the link_components.create_simple() API description, in the Link Library API reference.
If the new link type does not comply with the limitations above, a slightly more complex interface is available.
When more flexibility is required, it is possible to create a new component class inheriting from link_components.link_component.
Two functions should be overridden to control how the component handles connections:
class ethernet_switch(link_components.link_component):
"""Ethernet switch: this component represents a switched Ethernet network,
allowing any number of devices to connect and optimizing the packet routing
according to what is learned about the MAC addresses talking on the link."""
_class_desc = 'an Ethernet switch component'
_help_categories = ['Networking']
class basename(link_components.link_component.basename):
val = 'ethernet_switch'
def create_unconnected_endpoint(self, cnt):
return create_vlan_switch_endpoint(self.get_slot('link'), None,
None, True)
def register_connector_templates(self):
self.eth_tmpl = self.add_link_connector_template(
name = 'ethernet-link-connector',
type = 'ethernet-link',
growing = True,
create_unconnected_endpoint = self.create_unconnected_endpoint)
def add_objects(self):
self.add_pre_obj_with_name('link', 'eth-switch-link',
self.get_link_object_name(),
goal_latency = self.goal_latency.val,
global_id = self.global_id.val)
self.add_link_connector('device', self.eth_tmpl)
def get_free_connector_cmd(self):
c = self.get_unconnected_connector_object('device')
if not c:
raise cli.CliError('Internal error: no connectors found')
return c.name
register_connector_templates() is responsible for registering the description—called template here—of the connectors that will be allowed in the link.
Each connector template can be associated with a number of functions that will be called when a connection is attempted, is successful, or is destroyed.
Each connector template can also be defined as growing, meaning that new connectors will be added dynamically to make sure there is always one connector free.
add_objects() is responsible for creating the necessary link object and the initial connectors.
A more complete explanation of these functions is available in the component API in the Link Library API reference.