1 /* SPDX-License-Identifier: GPL-2.0 OR Linux-OpenIB */
2 /* Copyright (c) 2021 Mellanox Technologies. */
3 
4 #ifndef _MLX5_ESW_BRIDGE_PRIVATE_
5 #define _MLX5_ESW_BRIDGE_PRIVATE_
6 
7 #include <linux/netdevice.h>
8 #include <linux/if_bridge.h>
9 #include <linux/if_vlan.h>
10 #include <linux/if_ether.h>
11 #include <linux/rhashtable.h>
12 #include <linux/xarray.h>
13 #include "fs_core.h"
14 
15 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_SIZE 1
16 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_SIZE 3
17 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE 131072
18 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_UNTAGGED_GRP_SIZE			\
19 	(524288 - MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_SIZE -		\
20 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_SIZE)
21 
22 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_IDX_FROM 0
23 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_IDX_TO		\
24 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_SIZE - 1)
25 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_FROM	\
26 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_IGMP_GRP_IDX_TO + 1)
27 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_TO		\
28 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_FROM +	\
29 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_SIZE - 1)
30 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_FROM			\
31 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_MLD_GRP_IDX_TO + 1)
32 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_TO			\
33 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_FROM +		\
34 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1)
35 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_FROM	\
36 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_IDX_TO + 1)
37 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_TO		\
38 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_FROM +	\
39 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1)
40 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_FROM			\
41 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_FILTER_GRP_IDX_TO + 1)
42 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_TO			\
43 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_FROM +		\
44 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1)
45 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_FROM	\
46 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_GRP_IDX_TO + 1)
47 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_TO		\
48 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_FROM +	\
49 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_VLAN_GRP_SIZE - 1)
50 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_FROM			\
51 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_QINQ_FILTER_GRP_IDX_TO + 1)
52 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_TO			\
53 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_FROM +		\
54 	 MLX5_ESW_BRIDGE_INGRESS_TABLE_UNTAGGED_GRP_SIZE - 1)
55 #define MLX5_ESW_BRIDGE_INGRESS_TABLE_SIZE			\
56 	(MLX5_ESW_BRIDGE_INGRESS_TABLE_MAC_GRP_IDX_TO + 1)
57 static_assert(MLX5_ESW_BRIDGE_INGRESS_TABLE_SIZE == 1048576);
58 
59 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_SIZE 131072
60 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_SIZE (262144 - 1)
61 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_FROM 0
62 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_TO		\
63 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_SIZE - 1)
64 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_FROM		\
65 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_IDX_TO + 1)
66 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_TO			\
67 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_FROM +		\
68 	 MLX5_ESW_BRIDGE_EGRESS_TABLE_VLAN_GRP_SIZE - 1)
69 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_FROM \
70 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_QINQ_GRP_IDX_TO + 1)
71 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO			\
72 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_FROM +		\
73 	 MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_SIZE - 1)
74 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_FROM \
75 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_MAC_GRP_IDX_TO + 1)
76 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_TO	\
77 	MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_FROM
78 #define MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE			\
79 	(MLX5_ESW_BRIDGE_EGRESS_TABLE_MISS_GRP_IDX_TO + 1)
80 static_assert(MLX5_ESW_BRIDGE_EGRESS_TABLE_SIZE == 524288);
81 
82 #define MLX5_ESW_BRIDGE_SKIP_TABLE_SIZE 0
83 
84 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_SIZE 1
85 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_SIZE 1
86 #define MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_SIZE 4095
87 #define MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_SIZE MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_SIZE
88 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_IDX_FROM 0
89 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_IDX_TO		\
90 	(MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_SIZE - 1)
91 #define MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_FROM		\
92 	(MLX5_ESW_BRIDGE_MCAST_TABLE_FILTER_GRP_IDX_TO + 1)
93 #define MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_TO			\
94 	(MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_FROM +		\
95 	 MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_SIZE - 1)
96 #define MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_FROM		\
97 	(MLX5_ESW_BRIDGE_MCAST_TABLE_VLAN_GRP_IDX_TO + 1)
98 #define MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_TO			\
99 	(MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_FROM +		\
100 	 MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_SIZE - 1)
101 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_FROM		\
102 	(MLX5_ESW_BRIDGE_MCAST_TABLE_QINQ_GRP_IDX_TO + 1)
103 #define MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_TO			\
104 	(MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_FROM +			\
105 	 MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_SIZE - 1)
106 
107 #define MLX5_ESW_BRIDGE_MCAST_TABLE_SIZE			\
108 	(MLX5_ESW_BRIDGE_MCAST_TABLE_FWD_GRP_IDX_TO + 1)
109 static_assert(MLX5_ESW_BRIDGE_MCAST_TABLE_SIZE == 8192);
110 
111 enum {
112 	MLX5_ESW_BRIDGE_LEVEL_INGRESS_TABLE,
113 	MLX5_ESW_BRIDGE_LEVEL_EGRESS_TABLE,
114 	MLX5_ESW_BRIDGE_LEVEL_MCAST_TABLE,
115 	MLX5_ESW_BRIDGE_LEVEL_SKIP_TABLE,
116 };
117 
118 enum {
119 	MLX5_ESW_BRIDGE_VLAN_FILTERING_FLAG = BIT(0),
120 	MLX5_ESW_BRIDGE_MCAST_FLAG = BIT(1),
121 };
122 
123 struct mlx5_esw_bridge_fdb_key {
124 	unsigned char addr[ETH_ALEN];
125 	u16 vid;
126 };
127 
128 struct mlx5_esw_bridge_mdb_key {
129 	unsigned char addr[ETH_ALEN];
130 	u16 vid;
131 };
132 
133 enum {
134 	MLX5_ESW_BRIDGE_FLAG_ADDED_BY_USER = BIT(0),
135 	MLX5_ESW_BRIDGE_FLAG_PEER = BIT(1),
136 };
137 
138 enum {
139 	MLX5_ESW_BRIDGE_PORT_FLAG_PEER = BIT(0),
140 };
141 
142 struct mlx5_esw_bridge_fdb_entry {
143 	struct mlx5_esw_bridge_fdb_key key;
144 	struct rhash_head ht_node;
145 	struct net_device *dev;
146 	struct list_head list;
147 	struct list_head vlan_list;
148 	u16 vport_num;
149 	u16 esw_owner_vhca_id;
150 	u16 flags;
151 
152 	struct mlx5_flow_handle *ingress_handle;
153 	struct mlx5_fc *ingress_counter;
154 	unsigned long lastuse;
155 	struct mlx5_flow_handle *egress_handle;
156 	struct mlx5_flow_handle *filter_handle;
157 };
158 
159 struct mlx5_esw_bridge_mdb_entry {
160 	struct mlx5_esw_bridge_mdb_key key;
161 	struct rhash_head ht_node;
162 	struct list_head list;
163 	struct xarray ports;
164 	int num_ports;
165 
166 	struct mlx5_flow_handle *egress_handle;
167 };
168 
169 struct mlx5_esw_bridge_vlan {
170 	u16 vid;
171 	u16 flags;
172 	struct list_head fdb_list;
173 	struct mlx5_pkt_reformat *pkt_reformat_push;
174 	struct mlx5_pkt_reformat *pkt_reformat_pop;
175 	struct mlx5_modify_hdr *pkt_mod_hdr_push_mark;
176 	struct mlx5_flow_handle *mcast_handle;
177 };
178 
179 struct mlx5_esw_bridge_port {
180 	u16 vport_num;
181 	u16 esw_owner_vhca_id;
182 	u16 flags;
183 	struct mlx5_esw_bridge *bridge;
184 	struct xarray vlans;
185 	struct {
186 		struct mlx5_flow_table *ft;
187 		struct mlx5_flow_group *filter_fg;
188 		struct mlx5_flow_group *vlan_fg;
189 		struct mlx5_flow_group *qinq_fg;
190 		struct mlx5_flow_group *fwd_fg;
191 
192 		struct mlx5_flow_handle *filter_handle;
193 		struct mlx5_flow_handle *fwd_handle;
194 	} mcast;
195 };
196 
197 struct mlx5_esw_bridge {
198 	int ifindex;
199 	int refcnt;
200 	struct list_head list;
201 	struct mlx5_esw_bridge_offloads *br_offloads;
202 
203 	struct list_head fdb_list;
204 	struct rhashtable fdb_ht;
205 
206 	struct list_head mdb_list;
207 	struct rhashtable mdb_ht;
208 
209 	struct mlx5_flow_table *egress_ft;
210 	struct mlx5_flow_group *egress_vlan_fg;
211 	struct mlx5_flow_group *egress_qinq_fg;
212 	struct mlx5_flow_group *egress_mac_fg;
213 	struct mlx5_flow_group *egress_miss_fg;
214 	struct mlx5_pkt_reformat *egress_miss_pkt_reformat;
215 	struct mlx5_flow_handle *egress_miss_handle;
216 	unsigned long ageing_time;
217 	u32 flags;
218 	u16 vlan_proto;
219 };
220 
221 struct mlx5_flow_table *mlx5_esw_bridge_table_create(int max_fte, u32 level,
222 						     struct mlx5_eswitch *esw);
223 unsigned long mlx5_esw_bridge_port_key(struct mlx5_esw_bridge_port *port);
224 
225 int mlx5_esw_bridge_port_mcast_init(struct mlx5_esw_bridge_port *port);
226 void mlx5_esw_bridge_port_mcast_cleanup(struct mlx5_esw_bridge_port *port);
227 int mlx5_esw_bridge_vlan_mcast_init(u16 vlan_proto, struct mlx5_esw_bridge_port *port,
228 				    struct mlx5_esw_bridge_vlan *vlan);
229 void mlx5_esw_bridge_vlan_mcast_cleanup(struct mlx5_esw_bridge_vlan *vlan);
230 
231 int mlx5_esw_bridge_mcast_enable(struct mlx5_esw_bridge *bridge);
232 void mlx5_esw_bridge_mcast_disable(struct mlx5_esw_bridge *bridge);
233 
234 int mlx5_esw_bridge_mdb_init(struct mlx5_esw_bridge *bridge);
235 void mlx5_esw_bridge_mdb_cleanup(struct mlx5_esw_bridge *bridge);
236 int mlx5_esw_bridge_port_mdb_attach(struct net_device *dev, struct mlx5_esw_bridge_port *port,
237 				    const unsigned char *addr, u16 vid);
238 void mlx5_esw_bridge_port_mdb_detach(struct net_device *dev, struct mlx5_esw_bridge_port *port,
239 				     const unsigned char *addr, u16 vid);
240 void mlx5_esw_bridge_port_mdb_vlan_flush(struct mlx5_esw_bridge_port *port,
241 					 struct mlx5_esw_bridge_vlan *vlan);
242 void mlx5_esw_bridge_mdb_flush(struct mlx5_esw_bridge *bridge);
243 
244 #endif /* _MLX5_ESW_BRIDGE_PRIVATE_ */
245