linux/net/bridge/br_mrp.c

// SPDX-License-Identifier: GPL-2.0-or-later

#include <linux/mrp_bridge.h>
#include "br_private_mrp.h"

static const u8 mrp_test_dmac[ETH_ALEN] =;
static const u8 mrp_in_test_dmac[ETH_ALEN] =;

static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);

static struct br_frame_type mrp_frame_type __read_mostly =;

static bool br_mrp_is_ring_port(struct net_bridge_port *p_port,
				struct net_bridge_port *s_port,
				struct net_bridge_port *port)
{}

static bool br_mrp_is_in_port(struct net_bridge_port *i_port,
			      struct net_bridge_port *port)
{}

static struct net_bridge_port *br_mrp_get_port(struct net_bridge *br,
					       u32 ifindex)
{}

static struct br_mrp *br_mrp_find_id(struct net_bridge *br, u32 ring_id)
{}

static struct br_mrp *br_mrp_find_in_id(struct net_bridge *br, u32 in_id)
{}

static bool br_mrp_unique_ifindex(struct net_bridge *br, u32 ifindex)
{}

static struct br_mrp *br_mrp_find_port(struct net_bridge *br,
				       struct net_bridge_port *p)
{}

static int br_mrp_next_seq(struct br_mrp *mrp)
{}

static struct sk_buff *br_mrp_skb_alloc(struct net_bridge_port *p,
					const u8 *src, const u8 *dst)
{}

static void br_mrp_skb_tlv(struct sk_buff *skb,
			   enum br_mrp_tlv_header_type type,
			   u8 length)
{}

static void br_mrp_skb_common(struct sk_buff *skb, struct br_mrp *mrp)
{}

static struct sk_buff *br_mrp_alloc_test_skb(struct br_mrp *mrp,
					     struct net_bridge_port *p,
					     enum br_mrp_port_role_type port_role)
{}

static struct sk_buff *br_mrp_alloc_in_test_skb(struct br_mrp *mrp,
						struct net_bridge_port *p,
						enum br_mrp_port_role_type port_role)
{}

/* This function is continuously called in the following cases:
 * - when node role is MRM, in this case test_monitor is always set to false
 *   because it needs to notify the userspace that the ring is open and needs to
 *   send MRP_Test frames
 * - when node role is MRA, there are 2 subcases:
 *     - when MRA behaves as MRM, in this case is similar with MRM role
 *     - when MRA behaves as MRC, in this case test_monitor is set to true,
 *       because it needs to detect when it stops seeing MRP_Test frames
 *       from MRM node but it doesn't need to send MRP_Test frames.
 */
static void br_mrp_test_work_expired(struct work_struct *work)
{}

/* This function is continuously called when the node has the interconnect role
 * MIM. It would generate interconnect test frames and will send them on all 3
 * ports. But will also check if it stop receiving interconnect test frames.
 */
static void br_mrp_in_test_work_expired(struct work_struct *work)
{}

/* Deletes the MRP instance.
 * note: called under rtnl_lock
 */
static void br_mrp_del_impl(struct net_bridge *br, struct br_mrp *mrp)
{}

/* Adds a new MRP instance.
 * note: called under rtnl_lock
 */
int br_mrp_add(struct net_bridge *br, struct br_mrp_instance *instance)
{}

/* Deletes the MRP instance from which the port is part of
 * note: called under rtnl_lock
 */
void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p)
{}

/* Deletes existing MRP instance based on ring_id
 * note: called under rtnl_lock
 */
int br_mrp_del(struct net_bridge *br, struct br_mrp_instance *instance)
{}

/* Set port state, port state can be forwarding, blocked or disabled
 * note: already called with rtnl_lock
 */
int br_mrp_set_port_state(struct net_bridge_port *p,
			  enum br_mrp_port_state_type state)
{}

/* Set port role, port role can be primary or secondary
 * note: already called with rtnl_lock
 */
int br_mrp_set_port_role(struct net_bridge_port *p,
			 enum br_mrp_port_role_type role)
{}

/* Set ring state, ring state can be only Open or Closed
 * note: already called with rtnl_lock
 */
int br_mrp_set_ring_state(struct net_bridge *br,
			  struct br_mrp_ring_state *state)
{}

/* Set ring role, ring role can be only MRM(Media Redundancy Manager) or
 * MRC(Media Redundancy Client).
 * note: already called with rtnl_lock
 */
int br_mrp_set_ring_role(struct net_bridge *br,
			 struct br_mrp_ring_role *role)
{}

/* Start to generate or monitor MRP test frames, the frames are generated by
 * HW and if it fails, they are generated by the SW.
 * note: already called with rtnl_lock
 */
int br_mrp_start_test(struct net_bridge *br,
		      struct br_mrp_start_test *test)
{}

/* Set in state, int state can be only Open or Closed
 * note: already called with rtnl_lock
 */
int br_mrp_set_in_state(struct net_bridge *br, struct br_mrp_in_state *state)
{}

/* Set in role, in role can be only MIM(Media Interconnection Manager) or
 * MIC(Media Interconnection Client).
 * note: already called with rtnl_lock
 */
int br_mrp_set_in_role(struct net_bridge *br, struct br_mrp_in_role *role)
{}

/* Start to generate MRP_InTest frames, the frames are generated by
 * HW and if it fails, they are generated by the SW.
 * note: already called with rtnl_lock
 */
int br_mrp_start_in_test(struct net_bridge *br,
			 struct br_mrp_start_in_test *in_test)
{}

/* Determine if the frame type is a ring frame */
static bool br_mrp_ring_frame(struct sk_buff *skb)
{}

/* Determine if the frame type is an interconnect frame */
static bool br_mrp_in_frame(struct sk_buff *skb)
{}

/* Process only MRP Test frame. All the other MRP frames are processed by
 * userspace application
 * note: already called with rcu_read_lock
 */
static void br_mrp_mrm_process(struct br_mrp *mrp, struct net_bridge_port *port,
			       struct sk_buff *skb)
{}

/* Determine if the test hdr has a better priority than the node */
static bool br_mrp_test_better_than_own(struct br_mrp *mrp,
					struct net_bridge *br,
					const struct br_mrp_ring_test_hdr *hdr)
{}

/* Process only MRP Test frame. All the other MRP frames are processed by
 * userspace application
 * note: already called with rcu_read_lock
 */
static void br_mrp_mra_process(struct br_mrp *mrp, struct net_bridge *br,
			       struct net_bridge_port *port,
			       struct sk_buff *skb)
{}

/* Process only MRP InTest frame. All the other MRP frames are processed by
 * userspace application
 * note: already called with rcu_read_lock
 */
static bool br_mrp_mim_process(struct br_mrp *mrp, struct net_bridge_port *port,
			       struct sk_buff *skb)
{}

/* Get the MRP frame type
 * note: already called with rcu_read_lock
 */
static u8 br_mrp_get_frame_type(struct sk_buff *skb)
{}

static bool br_mrp_mrm_behaviour(struct br_mrp *mrp)
{}

static bool br_mrp_mrc_behaviour(struct br_mrp *mrp)
{}

/* This will just forward the frame to the other mrp ring ports, depending on
 * the frame type, ring role and interconnect role
 * note: already called with rcu_read_lock
 */
static int br_mrp_rcv(struct net_bridge_port *p,
		      struct sk_buff *skb, struct net_device *dev)
{}

/* Check if the frame was received on a port that is part of MRP ring
 * and if the frame has MRP eth. In that case process the frame otherwise do
 * normal forwarding.
 * note: already called with rcu_read_lock
 */
static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
{}

bool br_mrp_enabled(struct net_bridge *br)
{}