1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
3 #ifndef _BR_PRIVATE_CFM_H_
4 #define _BR_PRIVATE_CFM_H_
5 
6 #include "br_private.h"
7 #include <uapi/linux/cfm_bridge.h>
8 
9 struct br_cfm_mep_create {
10 	enum br_cfm_domain domain; /* Domain for this MEP */
11 	enum br_cfm_mep_direction direction; /* Up or Down MEP direction */
12 	u32 ifindex; /* Residence port */
13 };
14 
15 int br_cfm_mep_create(struct net_bridge *br,
16 		      const u32 instance,
17 		      struct br_cfm_mep_create *const create,
18 		      struct netlink_ext_ack *extack);
19 
20 int br_cfm_mep_delete(struct net_bridge *br,
21 		      const u32 instance,
22 		      struct netlink_ext_ack *extack);
23 
24 struct br_cfm_mep_config {
25 	u32 mdlevel;
26 	u32 mepid; /* MEPID for this MEP */
27 	struct mac_addr unicast_mac; /* The MEP unicast MAC */
28 };
29 
30 int br_cfm_mep_config_set(struct net_bridge *br,
31 			  const u32 instance,
32 			  const struct br_cfm_mep_config *const config,
33 			  struct netlink_ext_ack *extack);
34 
35 struct br_cfm_maid {
36 	u8 data[CFM_MAID_LENGTH];
37 };
38 
39 struct br_cfm_cc_config {
40 	/* Expected received CCM PDU MAID. */
41 	struct br_cfm_maid exp_maid;
42 
43 	/* Expected received CCM PDU interval. */
44 	/* Transmitting CCM PDU interval when CCM tx is enabled. */
45 	enum br_cfm_ccm_interval exp_interval;
46 
47 	bool enable; /* Enable/disable CCM PDU handling */
48 };
49 
50 int br_cfm_cc_config_set(struct net_bridge *br,
51 			 const u32 instance,
52 			 const struct br_cfm_cc_config *const config,
53 			 struct netlink_ext_ack *extack);
54 
55 int br_cfm_cc_peer_mep_add(struct net_bridge *br, const u32 instance,
56 			   u32 peer_mep_id,
57 			   struct netlink_ext_ack *extack);
58 int br_cfm_cc_peer_mep_remove(struct net_bridge *br, const u32 instance,
59 			      u32 peer_mep_id,
60 			      struct netlink_ext_ack *extack);
61 
62 /* Transmitted CCM Remote Defect Indication status set.
63  * This RDI is inserted in transmitted CCM PDUs if CCM transmission is enabled.
64  * See br_cfm_cc_ccm_tx() with interval != BR_CFM_CCM_INTERVAL_NONE
65  */
66 int br_cfm_cc_rdi_set(struct net_bridge *br, const u32 instance,
67 		      const bool rdi, struct netlink_ext_ack *extack);
68 
69 /* OAM PDU Tx information */
70 struct br_cfm_cc_ccm_tx_info {
71 	struct mac_addr dmac;
72 	/* The CCM will be transmitted for this period in seconds.
73 	 * Call br_cfm_cc_ccm_tx before timeout to keep transmission alive.
74 	 * When period is zero any ongoing transmission will be stopped.
75 	 */
76 	u32 period;
77 
78 	bool seq_no_update; /* Update Tx CCM sequence number */
79 	bool if_tlv; /* Insert Interface Status TLV */
80 	u8 if_tlv_value; /* Interface Status TLV value */
81 	bool port_tlv; /* Insert Port Status TLV */
82 	u8 port_tlv_value; /* Port Status TLV value */
83 	/* Sender ID TLV ??
84 	 * Organization-Specific TLV ??
85 	 */
86 };
87 
88 int br_cfm_cc_ccm_tx(struct net_bridge *br, const u32 instance,
89 		     const struct br_cfm_cc_ccm_tx_info *const tx_info,
90 		     struct netlink_ext_ack *extack);
91 
92 struct br_cfm_mep_status {
93 	/* Indications that an OAM PDU has been seen. */
94 	bool opcode_unexp_seen; /* RX of OAM PDU with unexpected opcode */
95 	bool version_unexp_seen; /* RX of OAM PDU with unexpected version */
96 	bool rx_level_low_seen; /* Rx of OAM PDU with level low */
97 };
98 
99 struct br_cfm_cc_peer_status {
100 	/* This CCM related status is based on the latest received CCM PDU. */
101 	u8 port_tlv_value; /* Port Status TLV value */
102 	u8 if_tlv_value; /* Interface Status TLV value */
103 
104 	/* CCM has not been received for 3.25 intervals */
105 	u8 ccm_defect:1;
106 
107 	/* (RDI == 1) for last received CCM PDU */
108 	u8 rdi:1;
109 
110 	/* Indications that a CCM PDU has been seen. */
111 	u8 seen:1; /* CCM PDU received */
112 	u8 tlv_seen:1; /* CCM PDU with TLV received */
113 	/* CCM PDU with unexpected sequence number received */
114 	u8 seq_unexp_seen:1;
115 };
116 
117 struct br_cfm_mep {
118 	/* list header of MEP instances */
119 	struct hlist_node		head;
120 	u32				instance;
121 	struct br_cfm_mep_create	create;
122 	struct br_cfm_mep_config	config;
123 	struct br_cfm_cc_config		cc_config;
124 	struct br_cfm_cc_ccm_tx_info	cc_ccm_tx_info;
125 	/* List of multiple peer MEPs */
126 	struct hlist_head		peer_mep_list;
127 	struct net_bridge_port __rcu	*b_port;
128 	unsigned long			ccm_tx_end;
129 	struct delayed_work		ccm_tx_dwork;
130 	u32				ccm_tx_snumber;
131 	u32				ccm_rx_snumber;
132 	struct br_cfm_mep_status	status;
133 	bool				rdi;
134 	struct rcu_head			rcu;
135 };
136 
137 struct br_cfm_peer_mep {
138 	struct hlist_node		head;
139 	struct br_cfm_mep		*mep;
140 	struct delayed_work		ccm_rx_dwork;
141 	u32				mepid;
142 	struct br_cfm_cc_peer_status	cc_status;
143 	u32				ccm_rx_count_miss;
144 	struct rcu_head			rcu;
145 };
146 
147 #endif /* _BR_PRIVATE_CFM_H_ */
148