Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

bridge: mrp: Implement LC mode for MRP

Extend MRP to support LC mode(link check) for the interconnect port.
This applies only to the interconnect ring.

Opposite to RC mode(ring check) the LC mode is using CFM frames to
detect when the link goes up or down and based on that the userspace
will need to react.
One advantage of the LC mode over RC mode is that there will be fewer
frames in the normal rings. Because RC mode generates InTest on all
ports while LC mode sends CFM frame only on the interconnect port.

All 4 nodes part of the interconnect ring needs to have the same mode.
And it is not possible to have running LC and RC mode at the same time
on a node.

Whenever the MIM starts it needs to detect the status of the other 3
nodes in the interconnect ring so it would send a frame called
InLinkStatus, on which the clients needs to reply with their link
status.

This patch adds InLinkStatus frame type and extends existing rules on
how to forward this frame.

Acked-by: Nikolay Aleksandrov <nikolay@nvidia.com>
Signed-off-by: Horatiu Vultur <horatiu.vultur@microchip.com>
Link: https://lore.kernel.org/r/20201124082525.273820-1-horatiu.vultur@microchip.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>

authored by

Horatiu Vultur and committed by
Jakub Kicinski
bfd04232 f460019b

+16 -3
+1
include/uapi/linux/mrp_bridge.h
··· 61 61 BR_MRP_TLV_HEADER_IN_TOPO = 0x7, 62 62 BR_MRP_TLV_HEADER_IN_LINK_DOWN = 0x8, 63 63 BR_MRP_TLV_HEADER_IN_LINK_UP = 0x9, 64 + BR_MRP_TLV_HEADER_IN_LINK_STATUS = 0xa, 64 65 BR_MRP_TLV_HEADER_OPTION = 0x7f, 65 66 }; 66 67
+15 -3
net/bridge/br_mrp.c
··· 858 858 if (hdr->type == BR_MRP_TLV_HEADER_IN_TEST || 859 859 hdr->type == BR_MRP_TLV_HEADER_IN_TOPO || 860 860 hdr->type == BR_MRP_TLV_HEADER_IN_LINK_DOWN || 861 - hdr->type == BR_MRP_TLV_HEADER_IN_LINK_UP) 861 + hdr->type == BR_MRP_TLV_HEADER_IN_LINK_UP || 862 + hdr->type == BR_MRP_TLV_HEADER_IN_LINK_STATUS) 862 863 return true; 863 864 864 865 return false; ··· 1127 1126 goto no_forward; 1128 1127 } 1129 1128 } else { 1130 - /* MIM should forward IntLinkChange and 1129 + /* MIM should forward IntLinkChange/Status and 1131 1130 * IntTopoChange between ring ports but MIM 1132 - * should not forward IntLinkChange and 1131 + * should not forward IntLinkChange/Status and 1133 1132 * IntTopoChange if the frame was received at 1134 1133 * the interconnect port 1135 1134 */ ··· 1155 1154 (in_type == BR_MRP_TLV_HEADER_IN_LINK_UP || 1156 1155 in_type == BR_MRP_TLV_HEADER_IN_LINK_DOWN)) 1157 1156 goto forward; 1157 + 1158 + /* MIC should forward IntLinkStatus frames only to 1159 + * interconnect port if it was received on a ring port. 1160 + * If it is received on interconnect port then, it 1161 + * should be forward on both ring ports 1162 + */ 1163 + if (br_mrp_is_ring_port(p_port, s_port, p) && 1164 + in_type == BR_MRP_TLV_HEADER_IN_LINK_STATUS) { 1165 + p_dst = NULL; 1166 + s_dst = NULL; 1167 + } 1158 1168 1159 1169 /* Should forward the InTopo frames only between the 1160 1170 * ring ports