Mrp

Package: inet.linklayer.mrp

simple module Mrp

Implements the Media Redundancy Protocol (MRP) as specified in IEC 62439-2. MRP is used for managing redundancy in ring network topologies commonly found in industrial network settings. MRP is similar in its function to STP and RSTP, in that it ensures a loop-free topology for an Ethernet local area network. This module implements the Media Redundancy Manager (MRM), Media Redundancy Client (MRC), and Media Redundancy Automanager (MRA) roles. This model also includes support for detecting link errors with the help of Continuity Check Messages (CCM) messages defined in 802.1q CFM.

Note: Support for interconnecting rings, i.e. for the Media Redundancy Interconnection Manager (MIM) and Media Redundancy Interconnection Client (MIC) roles, is implemented in the MrpInterconnection module.

The basic function of MRP is to prevent bridge loops by establishing a logical line topology based on a physical ring topology. MRP nodes must be directly connected to each other, with a maximum of 50 nodes per ring as defined in the standard. In the event of a network, link, or node error, a node in the manager role can alter the topology by activating its secondary ring port to reestablish a functioning network within a guaranteed maximum time limit.

An MRP node can be either a switch or a single device. Each node has exactly two ports that are part of the MRP ring, while all other ports function as normal switch ports.

The health of the ring is monitored by periodic test frames sent by the node in the manager role. If a test frame is not received on the opposite ring port of the node within five test intervals, a topology change is initiated. Ring failures may also be detected by clients, which can locally identify link errors with the help of 802.1q CCM messages. In such cases, a client sends a link change frame, prompting the manager to potentially initiate a topology change.

MRP makes use of per-port configuration data defining role and state. They can be set using L2NetworkConfigurator. Port state is kept in the switch’s InterfaceTable.

To configure MRP in a network, follow these steps:

  1. Identify and Configure Rings: Assign a unique ring ID to all nodes within the same ring using the uuid0 and uuid1 parameters. This ensures that each node is correctly recognized as part of the ring topology.

  2. Assign Ring Ports: Configure the ringPort1 and ringPort2 parameters. If you already set up the network topology so the ring ports are index 0 and 1, these parameters do not need to be touched as the default values will suffice.

  3. Set Node Roles: Use the mrpRole parameter to assign roles within the ring. Designate one node as the Media Redundancy Manager (MRM) and the others as Media Redundancy Clients (MRC). Alternatively, you can set all nodes to Media Redundancy Automanager (MRA).

  4. Adjust Features: Modify optional feature flags and settings as needed.

See also: MrpInterconnection, MrpRelay, MrpMacForwardingTable, L2NetworkConfigurator, InterfaceTable

inet.linklayer.mrp.MrpMrpsimple

Usage diagram

Inheritance diagram

Used in compound modules

Name

Type

Description

EthernetSwitch

compound module

EthernetSwitch models a Layer 2 Ethernet switch with support for various IEEE 802.1 protocols and features. It provides frame forwarding based on MAC addresses and implements multiple switching technologies.

Known subclasses

Name

Type

Description

MrpInterconnection

simple module

Implements ring interconnection support for the Media Redundancy Protocol (MRP) as specified in IEC 62439-2. This is an extension of the Mrp module with the Media Redundancy Interconnection Manager (MIM) and Media Redundancy Interconnection Client (MIC) roles. This module should be used instead of Mrp in MRP nodes that are also ring interconnection nodes.

Extends

Name

Type

Description

SimpleModule

simple module

Base module for all INET simple modules.

Parameters

Name

Type

Default value

Description

displayStringTextFormat

string

“role: %r\nnode: %n\nring: %g”

Determines the text that is written on top of the submodule, supports displaying pars, watches, and module-specific information

linkDetectionDelay

double

truncnormal(385ms,325ms)

Switches do not detect a link change immediately. This parameter sets the simulated delay of a “link down” event. Note: the delay for “link up” is hardcoded to 1us in the code.

processingDelay

double

truncnormal(100us,80us)

Switches require a certain amount of time to process each received packet. This parameter sets the processing delay; it is applied in handleMessageWhenUp().

timingProfile

int

500ms

MRP defines four Maximum Recovery Time settings for rings: 500 ms, 200 ms, 30 ms, or 10 ms. This parameter sets a hard upper time limit guaranteed by the protocol, and the interval for test frames, topology changes, and link change times are adapted accordingly. It should be set to the same value on all nodes within a ring.

mrpRole

string

“disabled”

Each MRP node can either be disabled (value 0, no MRP function), be a MediaRedundancyClient (MRC, value 1), a MediaRedundancyManager (MRM, value 2), or a MediaRedundancyAutoManager (MRA, value 4). The model does not support the backward-compatible MRA (value 3) as it would be redundant. Each network may have only one MRM; all other nodes must assume the MRC role. MRAs can vote on which node should take the MRM role based on priority and MAC address value; other nodes dynamically switch to the MRC role. Mixing MRM and MRA is possible but not recommended.

ringPort1

int

0

Each MRP node has exactly two ring interfaces, which must be configured by the network administrator. The ringPort1 and ringPort2 parameters define the port index of the first and second ring port, respectively.

ringPort2

int

1

uuid0

int

An MRP ring has a UUID, split into two 64-bit parts. Every node in a ring must be configured with the same UUID.

uuid1

int

enableLinkCheckOnRing

bool

false

It is possible to enable active link checks on Layer 2 for each ring port, using CCM (Connectivity Check Message) messages defined in 802.1q Continuity Fault Management (CFM). Consider the additional load on the node and network when enabling this feature.

ccmInterval

double

10ms

CCM (Connectivity Check Message) link checks can be performed every 3.3 ms or every 10 ms.

interconnectionRingCheckAware

bool

true

MRP rings can be redundantly connected by interconnection nodes. To manage necessary communication, normal MRP nodes should be aware of the check methods used. Checks can be performed either by ring check (similar to the ring test mechanism) or by link check on Layer 2 (CCM messages).

interconnectionLinkCheckAware

bool

true

visualize

bool

true

Visualizes the ring by coloring connections in the network graphics. Labels the Ethernet interface with port role and status.

interfaceTableModule

string

The path to the InterfaceTable module.

macTableModule

string

The path to the MacForwardingTable module.

mrpRelayModule

string

The path to the MrpRelay module.

mrpPriority

int

0xA000

A MRM or MRA can have a priority ranging from the highest (0x0000) to the lowest (0xFFFF). MRMs should be assigned one of the following values: HIGHEST = 0x0000, HIGH = 0x4000, DEFAULT = 0x8000. If the node is an MRA, assign one of these: MRAHIGHEST = 0x9000, MRADEFAULT = 0xA000, MRALOWEST = 0xFFFF. MRAs determine the acting manager based on priority and MAC address.

nonblockingMrcSupported

bool

true

In MRM role: Specifies whether non-blocking MRCs are supported by the MRM, i.e. those that are not capable of setting a ring port to BLOCKED state.

reactOnLinkChange

bool

true

In MRM role: Determines if the manager reacts to link change frames sent by clients or if it solely relies on ring tests for status updates.

Properties

Name

Value

Description

class

Mrp

display

i=block/network2

Gates

Name

Direction

Size

Description

relayIn

input

relayOut

output

Signals

Name

Type

Unit

Description

fdbCleared

long

value = constant 1

linkChangeDetected

long

emitted by the node that detected the link change; value = constant 0 or 1 (for down/up)

nodeStateChanged

long

ringPort1StateChanged

unsigned long

ringPort2StateChanged

unsigned long

ringStateChanged

long

testFrameLatency

simtime_t

emitted by the MRM only, upon receiving a Test frame

topologyChangeAnnounced

long

emitted by MRM only with value = constant 1

Statistics

Name

Title

Source

Record

Unit

Interpolation Mode

Description

fdbClearedEvents

FDB Cleared Events

fdbCleared

vector

none

linkChangeDetections

Link Up/Down Detection Events

linkChangeDetected

vector

none

nodeState

Node state

nodeStateChanged

vector

sample-hold

ringPort1State

State of Primary Ring Port

ringPort1StateChanged

vector

sample-hold

ringPort2State

State of Secondary Ring Port

ringPort2StateChanged

vector

sample-hold

ringState

Ring state

ringStateChanged

vector

sample-hold

testFrameLatency

Latency of Received Test Frames

testFrameLatency

vector

none

topologyChangeAnnouncements

Topology Change Announcements by MRM

topologyChangeAnnounced

vector

none

Source code

//
// Implements the Media Redundancy Protocol (MRP) as specified in IEC 62439-2.
// MRP is used for managing redundancy in ring network topologies commonly found
// in industrial network settings. MRP is similar in its function to STP and
// RSTP, in that it ensures a loop-free topology for an Ethernet local area
// network. This module implements the Media Redundancy Manager (MRM), Media
// Redundancy Client (MRC), and Media Redundancy Automanager (MRA) roles. This
// model also includes support for detecting link errors with the help of
// Continuity Check Messages (CCM) messages defined in 802.1q CFM.
//
// Note: Support for interconnecting rings, i.e. for the Media Redundancy
// Interconnection Manager (MIM) and Media Redundancy Interconnection Client
// (MIC) roles, is implemented in the ~MrpInterconnection module.
//
// The basic function of MRP is to prevent bridge loops by establishing a
// logical line topology based on a physical ring topology. MRP nodes must be
// directly connected to each other, with a maximum of 50 nodes per ring as
// defined in the standard. In the event of a network, link, or node error, a
// node in the manager role can alter the topology by activating its secondary
// ring port to reestablish a functioning network within a guaranteed maximum
// time limit.
//
// An MRP node can be either a switch or a single device. Each node has exactly
// two ports that are part of the MRP ring, while all other ports function as
// normal switch ports.
//
// The health of the ring is monitored by periodic test frames sent by the node
// in the manager role. If a test frame is not received on the opposite ring
// port of the node within five test intervals, a topology change is initiated.
// Ring failures may also be detected by clients, which can locally identify
// link errors with the help of 802.1q CCM messages. In such cases, a client
// sends a link change frame, prompting the manager to potentially initiate a
// topology change.
//
// MRP makes use of per-port configuration data defining role and state. They
// can be set using ~L2NetworkConfigurator. Port state is kept in the switch's
// ~InterfaceTable.
//
// To configure MRP in a network, follow these steps:
//
// 1. Identify and Configure Rings: Assign a unique ring ID to all nodes within the
//    same ring using the `uuid0` and `uuid1` parameters. This ensures that each node
//    is correctly recognized as part of the ring topology.
//
// 2. Assign Ring Ports: Configure the `ringPort1` and `ringPort2` parameters.
//    If you already set up the network topology so the ring ports are index 0
//    and 1, these parameters do not need to be touched as the default values will suffice.
//
// 3. Set Node Roles: Use the `mrpRole` parameter to assign roles within the ring.
//    Designate one node as the Media Redundancy Manager (MRM) and the others as
//    Media Redundancy Clients (MRC). Alternatively, you can set all nodes to Media
//    Redundancy Automanager (MRA).
//
// 4. Adjust Features: Modify optional feature flags and settings as needed.
//
// @see ~MrpInterconnection, ~MrpRelay, ~MrpMacForwardingTable, ~L2NetworkConfigurator, ~InterfaceTable
//
simple Mrp extends SimpleModule like IMrp
{
    parameters:
        @class(Mrp);
        @class(Mrp);

        // Switches do not detect a link change immediately. This parameter sets
        // the simulated delay of a "link down" event. Note: the delay for "link
        // up" is hardcoded to 1us in the code.
        volatile double linkDetectionDelay @unit(s) = default(truncnormal(385ms,325ms));

        // Switches require a certain amount of time to process each received packet.
        // This parameter sets the processing delay; it is applied in handleMessageWhenUp().
        volatile double processingDelay @unit(s) = default(truncnormal(100us,80us));

        // MRP defines four Maximum Recovery Time settings for rings: 500 ms, 200 ms, 30 ms, or 10 ms.
        // This parameter sets a hard upper time limit guaranteed by the protocol,
        // and the interval for test frames, topology changes, and link change times are adapted accordingly.
        // It should be set to the same value on all nodes within a ring.
        int timingProfile @unit(ms) = default(500ms);

        // Each MRP node can either be disabled (value 0, no MRP function), be a MediaRedundancyClient (MRC, value 1),
        // a MediaRedundancyManager (MRM, value 2), or a MediaRedundancyAutoManager (MRA, value 4).
        // The model does not support the backward-compatible MRA (value 3) as it would be redundant.
        // Each network may have only one MRM; all other nodes must assume the MRC role.
        // MRAs can vote on which node should take the MRM role based on priority and MAC address value; other nodes
        // dynamically switch to the MRC role. Mixing MRM and MRA is possible but not recommended.
        string mrpRole @enum("disabled", "MRC", "MRM", "MRA") = default("disabled");

        // Each MRP node has exactly two ring interfaces, which must be configured by
        // the network administrator. The ringPort1 and ringPort2 parameters define
        // the port index of the first and second ring port, respectively.
        int ringPort1 = default(0);
        int ringPort2 = default(1);

        // An MRP ring has a UUID, split into two 64-bit parts.
        // Every node in a ring must be configured with the same UUID.
        int uuid0;
        int uuid1;

        // It is possible to enable active link checks on Layer 2 for each ring port,
        // using CCM (Connectivity Check Message) messages defined in 802.1q Continuity
        // Fault Management (CFM). Consider the additional load on the node and network
        // when enabling this feature.
        bool enableLinkCheckOnRing = default(false);

        // CCM (Connectivity Check Message) link checks can be performed every 3.3 ms or every 10 ms.
        double ccmInterval @unit(s) = default(10ms);

        // MRP rings can be redundantly connected by interconnection nodes.
        // To manage necessary communication, normal MRP nodes should be aware of the
        // check methods used. Checks can be performed either by ring check (similar to the
        // ring test mechanism) or by link check on Layer 2 (CCM messages).
        bool interconnectionRingCheckAware = default(true);
        bool interconnectionLinkCheckAware = default(true);

        // Visualizes the ring by coloring connections in the network graphics.
        // Labels the Ethernet interface with port role and status.
        bool visualize = default(true);

        // The path to the InterfaceTable module.
        string interfaceTableModule;

        // The path to the MacForwardingTable module.
        string macTableModule;

        // The path to the MrpRelay module.
        string mrpRelayModule;

        // A MRM or MRA can have a priority ranging from the highest (0x0000) to the lowest (0xFFFF).
        // MRMs should be assigned one of the following values: HIGHEST = 0x0000, HIGH = 0x4000, DEFAULT = 0x8000.
        // If the node is an MRA, assign one of these: MRAHIGHEST = 0x9000, MRADEFAULT = 0xA000, MRALOWEST = 0xFFFF.
        // MRAs determine the acting manager based on priority and MAC address.
        int mrpPriority = default(0xA000);

        // In MRM role: Specifies whether non-blocking MRCs are supported by the MRM,
        // i.e. those that are not capable of setting a ring port to BLOCKED state.
        bool nonblockingMrcSupported = default(true);

        // In MRM role: Determines if the manager reacts to link change frames sent
        // by clients or if it solely relies on ring tests for status updates.
        bool reactOnLinkChange = default(true);

        // Format for the text displayed above the module icon.
        // Directives: `%r`: MRP role, `%n`: node state, `%g`: ring state
        displayStringTextFormat = default("role: %r\nnode: %n\nring: %g");

        @display("i=block/network2");
        @signal[ringStateChanged](type=long);
        @signal[nodeStateChanged](type=long);
        @signal[ringPort1StateChanged](type=unsigned long);
        @signal[ringPort2StateChanged](type=unsigned long);
        @signal[topologyChangeAnnounced](type=long); // emitted by MRM only with value = constant 1
        @signal[fdbCleared](type=long);  // value = constant 1
        @signal[linkChangeDetected](type=long);  // emitted by the node that detected the link change; value = constant 0 or 1 (for down/up)
        @signal[testFrameLatency](type=simtime_t); // emitted by the MRM only, upon receiving a Test frame
        @statistic[ringState](title="Ring state"; source=ringStateChanged; record=vector; interpolationmode=sample-hold; enumname=inet::Mrp::RingState);
        @statistic[nodeState](title="Node state"; source=nodeStateChanged; record=vector; interpolationmode=sample-hold; enumname=inet::Mrp::NodeState);
        @statistic[ringPort1State](title="State of Primary Ring Port"; source=ringPort1StateChanged; record=vector; interpolationmode=sample-hold; enumname=inet::MrpInterfaceData::PortState);
        @statistic[ringPort2State](title="State of Secondary Ring Port"; source=ringPort2StateChanged; record=vector; interpolationmode=sample-hold; enumname=inet::MrpInterfaceData::PortState);
        @statistic[topologyChangeAnnouncements](title="Topology Change Announcements by MRM"; source=topologyChangeAnnounced; record=vector; interpolationmode=none);
        @statistic[fdbClearedEvents](title="FDB Cleared Events"; source=fdbCleared; record=vector; interpolationmode=none);
        @statistic[linkChangeDetections](title="Link Up/Down Detection Events"; source=linkChangeDetected; record=vector; interpolationmode=none);
        @statistic[testFrameLatency](title="Latency of Received Test Frames"; source=testFrameLatency; record=vector; interpolationmode=none);

    gates:
        input relayIn;
        output relayOut;
}

File: src/inet/linklayer/mrp/Mrp.ned