Implemented By
typedef struct {
        int  (*connect_device)(conf_object_t *_obj, conf_object_t *dev,
                               int *new_connection);
        void (*disconnect_device)(conf_object_t *_obj,
                                  conf_object_t *dev);
        void (*send_frame)(conf_object_t *_obj, int id,
                           dbuffer_t *frame,
                           int crc_calculated, nano_secs_t delay);
        void (*auto_negotiate)(conf_object_t *_obj, int id,
                               phy_speed_t speed);
        void (*add_mac)(conf_object_t *_obj, int id,
                        byte_string_t addr);
        void (*add_mac_mask)(conf_object_t *_obj, int id,
                             byte_string_t addr, byte_string_t mask);
        void (*delete_mac)(conf_object_t *_obj, int id,
                           byte_string_t addr);
        void (*delete_mac_mask)(conf_object_t *_obj, int id,
                                byte_string_t addr, byte_string_t mask);
        void (*clear_macs)(conf_object_t *_obj, int id);
        void (*promiscuous_mode)(conf_object_t *_obj, int id, int enable);
} ethernet_link_interface_t;
#define ETHERNET_LINK_INTERFACE "ethernet_link"

This interface is implemented by Ethernet link objects that provide a data link layer interface for Ethernet frame delivery.

An Ethernet device calls the connect_device device function to attach itself to the link, and disconnect_device to detach itself. The device must implement the ethernet_device interface.

The connect_device function attaches an Ethernet device to the link. The device must implement the ethernet_device interface. The return value is an identification number that should be used in subsequent calls to the link to identify the device.

The disconnect_device function detaches an Ethernet device from the link. It will not receive any more frames from the link and may not call any functions in the interface, except connect_device.

The send_frame function is used by a device to send an Ethernet frame onto the link to be delivered to the other devices connected to the same link. The frame should be a dbuffer_t containing a complete Ethernet frame, excluding the preamble and SFD, but including the CRC. The crc_calculated flag indicates whether the CRC is actually calculated. In many cases, the CRC will not be checked by the receiver, which makes it more efficient to skip the CRC calculation an set this flag to 0. If needed, Simics will calculate a valid CRC for the frame. The delay makes it possible to add a small delay to the frame. This can be used when a device wants to send multiple frames at once, but want them to be delivered in a specific sequence. Instead of using an event handler to send each frame, they can be sent at once, with an increasing delay for each frame. The delay is given in nanoseconds.

The auto_negotiate is used to do auto-negotiation of speed. An Ethernet device should call this function with the speed argument set to a value where all the bits that corresponds to speeds that the device can handle set. The device should call this function after it connects to the link the very first time (i.e. not after restarting from a checkpoint), or whenever the auto_neg_request function in its ethernet_device is called.

The add_mac function registers a MAC address that the device will accept frames for. By default, the device will receive no frames at all, but by calling this function, the device can inform the link that it will receive frames that match any of the MAC addresses it has registered. The device is not guaranteed to receive any frames not addressed to one of the registered addresses. The address is given as a string of six bytes in a byte_string_t structure.

The add_mac_mask is similar to add_mac, but in addition to the MAC address, a six byte bit mask is also be provided. This mask will be used to mask addresses when checking if they should be delivered to the device. Only bits in the address that has the corresponding bit in the mask set to 1 will be considered a match. If the bit mask is zero bytes, it will be handled as if it had been all ones, only an exact match will be accepted.

Most network cards listen to the broadcast address (ff:ff:ff:ff:ff:ff) or multicast addresses (01:00:00:00:00:00/01:00:00:00:00:00) in addition to the configured MAC address. Such models need to call add_mac_mask with appropriate arguments after being connected to a link.

The delete_mac and delete_mac_mask functions unregisters a MAC address previously registered with add_mac or add_mac_mask.

The clear_macs unregisters all previously registered MAC addresses.

The promiscuous_mode function sets the promiscuous flag that indicates that the device is listening to all MAC addresses. Setting this to true (non-zero) has a similar effect as clear_macs in that the link will start sending all frames to the device, but when the flag is set to false (zero) the MAC addresses filtering will resume with the previously registered MAC addresses.

The functions auto_negotiate, add_mac, add_mac_mask, delete_mac, clear_macs, and promiscuous behave slightly differently when called during initialization and during simulation. When loading a configuration, the devices may call these functions to set the initial configuration, but after the configuration has been set, the effect of these calls will be delayed by at least the latency of the link, since it is a change in the simulated state that needs to be propagated in a deterministic way.