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