Mrp.ned
NED File src/inet/linklayer/mrp/Mrp.ned
| Name | Type | Description |
|---|---|---|
| Mrp | simple module |
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. |
Source code
// // Copyright (C) 2024 Daniel Zeitler // // SPDX-License-Identifier: LGPL-3.0-or-later // package inet.linklayer.mrp; import inet.common.SimpleModule; import inet.linklayer.contract.IMrp; // // 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; }