xref: /linux/drivers/net/ethernet/mellanox/mlxsw/spectrum_nve_vxlan.c (revision bd628c1bed7902ec1f24ba0fe70758949146abbe)
1 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
2 /* Copyright (c) 2018 Mellanox Technologies. All rights reserved */
3 
4 #include <linux/netdevice.h>
5 #include <linux/netlink.h>
6 #include <linux/random.h>
7 #include <net/vxlan.h>
8 
9 #include "reg.h"
10 #include "spectrum_nve.h"
11 
12 /* Eth (18B) | IPv6 (40B) | UDP (8B) | VxLAN (8B) | Eth (14B) | IPv6 (40B)
13  *
14  * In the worst case - where we have a VLAN tag on the outer Ethernet
15  * header and IPv6 in overlay and underlay - we need to parse 128 bytes
16  */
17 #define MLXSW_SP_NVE_VXLAN_PARSING_DEPTH 128
18 #define MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH 96
19 
20 #define MLXSW_SP_NVE_VXLAN_SUPPORTED_FLAGS	(VXLAN_F_UDP_ZERO_CSUM_TX | \
21 						 VXLAN_F_LEARN)
22 
23 static bool mlxsw_sp1_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
24 					    const struct net_device *dev,
25 					    struct netlink_ext_ack *extack)
26 {
27 	struct vxlan_dev *vxlan = netdev_priv(dev);
28 	struct vxlan_config *cfg = &vxlan->cfg;
29 
30 	if (cfg->saddr.sa.sa_family != AF_INET) {
31 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Only IPv4 underlay is supported");
32 		return false;
33 	}
34 
35 	if (vxlan_addr_multicast(&cfg->remote_ip)) {
36 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Multicast destination IP is not supported");
37 		return false;
38 	}
39 
40 	if (vxlan_addr_any(&cfg->saddr)) {
41 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Source address must be specified");
42 		return false;
43 	}
44 
45 	if (cfg->remote_ifindex) {
46 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Local interface is not supported");
47 		return false;
48 	}
49 
50 	if (cfg->port_min || cfg->port_max) {
51 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Only default UDP source port range is supported");
52 		return false;
53 	}
54 
55 	if (cfg->tos != 1) {
56 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: TOS must be configured to inherit");
57 		return false;
58 	}
59 
60 	if (cfg->flags & VXLAN_F_TTL_INHERIT) {
61 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: TTL must not be configured to inherit");
62 		return false;
63 	}
64 
65 	if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM_TX)) {
66 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: UDP checksum is not supported");
67 		return false;
68 	}
69 
70 	if (cfg->flags & ~MLXSW_SP_NVE_VXLAN_SUPPORTED_FLAGS) {
71 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Unsupported flag");
72 		return false;
73 	}
74 
75 	if (cfg->ttl == 0) {
76 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: TTL must not be configured to 0");
77 		return false;
78 	}
79 
80 	if (cfg->label != 0) {
81 		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Flow label must be configured to 0");
82 		return false;
83 	}
84 
85 	return true;
86 }
87 
88 static void mlxsw_sp_nve_vxlan_config(const struct mlxsw_sp_nve *nve,
89 				      const struct net_device *dev,
90 				      struct mlxsw_sp_nve_config *config)
91 {
92 	struct vxlan_dev *vxlan = netdev_priv(dev);
93 	struct vxlan_config *cfg = &vxlan->cfg;
94 
95 	config->type = MLXSW_SP_NVE_TYPE_VXLAN;
96 	config->ttl = cfg->ttl;
97 	config->flowlabel = cfg->label;
98 	config->learning_en = cfg->flags & VXLAN_F_LEARN ? 1 : 0;
99 	config->ul_tb_id = RT_TABLE_MAIN;
100 	config->ul_proto = MLXSW_SP_L3_PROTO_IPV4;
101 	config->ul_sip.addr4 = cfg->saddr.sin.sin_addr.s_addr;
102 	config->udp_dport = cfg->dst_port;
103 }
104 
105 static int mlxsw_sp_nve_parsing_set(struct mlxsw_sp *mlxsw_sp,
106 				    unsigned int parsing_depth,
107 				    __be16 udp_dport)
108 {
109 	char mprs_pl[MLXSW_REG_MPRS_LEN];
110 
111 	mlxsw_reg_mprs_pack(mprs_pl, parsing_depth, be16_to_cpu(udp_dport));
112 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(mprs), mprs_pl);
113 }
114 
115 static int
116 mlxsw_sp1_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
117 			       const struct mlxsw_sp_nve_config *config)
118 {
119 	char tngcr_pl[MLXSW_REG_TNGCR_LEN];
120 	u16 ul_vr_id;
121 	u8 udp_sport;
122 	int err;
123 
124 	err = mlxsw_sp_router_tb_id_vr_id(mlxsw_sp, config->ul_tb_id,
125 					  &ul_vr_id);
126 	if (err)
127 		return err;
128 
129 	mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, true,
130 			     config->ttl);
131 	/* VxLAN driver's default UDP source port range is 32768 (0x8000)
132 	 * to 60999 (0xee47). Set the upper 8 bits of the UDP source port
133 	 * to a random number between 0x80 and 0xee
134 	 */
135 	get_random_bytes(&udp_sport, sizeof(udp_sport));
136 	udp_sport = (udp_sport % (0xee - 0x80 + 1)) + 0x80;
137 	mlxsw_reg_tngcr_nve_udp_sport_prefix_set(tngcr_pl, udp_sport);
138 	mlxsw_reg_tngcr_learn_enable_set(tngcr_pl, config->learning_en);
139 	mlxsw_reg_tngcr_underlay_virtual_router_set(tngcr_pl, ul_vr_id);
140 	mlxsw_reg_tngcr_usipv4_set(tngcr_pl, be32_to_cpu(config->ul_sip.addr4));
141 
142 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
143 }
144 
145 static void mlxsw_sp1_nve_vxlan_config_clear(struct mlxsw_sp *mlxsw_sp)
146 {
147 	char tngcr_pl[MLXSW_REG_TNGCR_LEN];
148 
149 	mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
150 
151 	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
152 }
153 
154 static int mlxsw_sp1_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp,
155 					unsigned int tunnel_index)
156 {
157 	char rtdp_pl[MLXSW_REG_RTDP_LEN];
158 
159 	mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_NVE, tunnel_index);
160 
161 	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
162 }
163 
164 static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve,
165 				    const struct mlxsw_sp_nve_config *config)
166 {
167 	struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
168 	int err;
169 
170 	err = mlxsw_sp_nve_parsing_set(mlxsw_sp,
171 				       MLXSW_SP_NVE_VXLAN_PARSING_DEPTH,
172 				       config->udp_dport);
173 	if (err)
174 		return err;
175 
176 	err = mlxsw_sp1_nve_vxlan_config_set(mlxsw_sp, config);
177 	if (err)
178 		goto err_config_set;
179 
180 	err = mlxsw_sp1_nve_vxlan_rtdp_set(mlxsw_sp, nve->tunnel_index);
181 	if (err)
182 		goto err_rtdp_set;
183 
184 	err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id,
185 						config->ul_proto,
186 						&config->ul_sip,
187 						nve->tunnel_index);
188 	if (err)
189 		goto err_promote_decap;
190 
191 	return 0;
192 
193 err_promote_decap:
194 err_rtdp_set:
195 	mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
196 err_config_set:
197 	mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
198 				 config->udp_dport);
199 	return err;
200 }
201 
202 static void mlxsw_sp1_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
203 {
204 	struct mlxsw_sp_nve_config *config = &nve->config;
205 	struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
206 
207 	mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
208 					 config->ul_proto, &config->ul_sip);
209 	mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
210 	mlxsw_sp_nve_parsing_set(mlxsw_sp, MLXSW_SP_NVE_DEFAULT_PARSING_DEPTH,
211 				 config->udp_dport);
212 }
213 
214 static int
215 mlxsw_sp_nve_vxlan_fdb_replay(const struct net_device *nve_dev, __be32 vni)
216 {
217 	if (WARN_ON(!netif_is_vxlan(nve_dev)))
218 		return -EINVAL;
219 	return vxlan_fdb_replay(nve_dev, vni, &mlxsw_sp_switchdev_notifier);
220 }
221 
222 static void
223 mlxsw_sp_nve_vxlan_clear_offload(const struct net_device *nve_dev, __be32 vni)
224 {
225 	if (WARN_ON(!netif_is_vxlan(nve_dev)))
226 		return;
227 	vxlan_fdb_clear_offload(nve_dev, vni);
228 }
229 
230 const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops = {
231 	.type		= MLXSW_SP_NVE_TYPE_VXLAN,
232 	.can_offload	= mlxsw_sp1_nve_vxlan_can_offload,
233 	.nve_config	= mlxsw_sp_nve_vxlan_config,
234 	.init		= mlxsw_sp1_nve_vxlan_init,
235 	.fini		= mlxsw_sp1_nve_vxlan_fini,
236 	.fdb_replay	= mlxsw_sp_nve_vxlan_fdb_replay,
237 	.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
238 };
239 
240 static bool mlxsw_sp2_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
241 					    const struct net_device *dev,
242 					    struct netlink_ext_ack *extack)
243 {
244 	return false;
245 }
246 
247 static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve,
248 				    const struct mlxsw_sp_nve_config *config)
249 {
250 	return -EOPNOTSUPP;
251 }
252 
253 static void mlxsw_sp2_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
254 {
255 }
256 
257 const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = {
258 	.type		= MLXSW_SP_NVE_TYPE_VXLAN,
259 	.can_offload	= mlxsw_sp2_nve_vxlan_can_offload,
260 	.nve_config	= mlxsw_sp_nve_vxlan_config,
261 	.init		= mlxsw_sp2_nve_vxlan_init,
262 	.fini		= mlxsw_sp2_nve_vxlan_fini,
263 	.fdb_replay	= mlxsw_sp_nve_vxlan_fdb_replay,
264 	.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
265 };
266