0001
0002
0003
0004 #include <linux/netdevice.h>
0005 #include <linux/netlink.h>
0006 #include <linux/random.h>
0007 #include <net/vxlan.h>
0008
0009 #include "reg.h"
0010 #include "spectrum.h"
0011 #include "spectrum_nve.h"
0012
0013 #define MLXSW_SP_NVE_VXLAN_IPV4_SUPPORTED_FLAGS (VXLAN_F_UDP_ZERO_CSUM_TX | \
0014 VXLAN_F_LEARN)
0015 #define MLXSW_SP_NVE_VXLAN_IPV6_SUPPORTED_FLAGS (VXLAN_F_IPV6 | \
0016 VXLAN_F_UDP_ZERO_CSUM6_TX | \
0017 VXLAN_F_UDP_ZERO_CSUM6_RX)
0018
0019 static bool mlxsw_sp_nve_vxlan_ipv4_flags_check(const struct vxlan_config *cfg,
0020 struct netlink_ext_ack *extack)
0021 {
0022 if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM_TX)) {
0023 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Zero UDP checksum must be allowed for TX");
0024 return false;
0025 }
0026
0027 if (cfg->flags & ~MLXSW_SP_NVE_VXLAN_IPV4_SUPPORTED_FLAGS) {
0028 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Unsupported flag");
0029 return false;
0030 }
0031
0032 return true;
0033 }
0034
0035 static bool mlxsw_sp_nve_vxlan_ipv6_flags_check(const struct vxlan_config *cfg,
0036 struct netlink_ext_ack *extack)
0037 {
0038 if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM6_TX)) {
0039 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Zero UDP checksum must be allowed for TX");
0040 return false;
0041 }
0042
0043 if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM6_RX)) {
0044 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Zero UDP checksum must be allowed for RX");
0045 return false;
0046 }
0047
0048 if (cfg->flags & ~MLXSW_SP_NVE_VXLAN_IPV6_SUPPORTED_FLAGS) {
0049 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Unsupported flag");
0050 return false;
0051 }
0052
0053 return true;
0054 }
0055
0056 static bool mlxsw_sp_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
0057 const struct mlxsw_sp_nve_params *params,
0058 struct netlink_ext_ack *extack)
0059 {
0060 struct vxlan_dev *vxlan = netdev_priv(params->dev);
0061 struct vxlan_config *cfg = &vxlan->cfg;
0062
0063 if (vxlan_addr_multicast(&cfg->remote_ip)) {
0064 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Multicast destination IP is not supported");
0065 return false;
0066 }
0067
0068 if (vxlan_addr_any(&cfg->saddr)) {
0069 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Source address must be specified");
0070 return false;
0071 }
0072
0073 if (cfg->remote_ifindex) {
0074 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Local interface is not supported");
0075 return false;
0076 }
0077
0078 if (cfg->port_min || cfg->port_max) {
0079 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Only default UDP source port range is supported");
0080 return false;
0081 }
0082
0083 if (cfg->tos != 1) {
0084 NL_SET_ERR_MSG_MOD(extack, "VxLAN: TOS must be configured to inherit");
0085 return false;
0086 }
0087
0088 if (cfg->flags & VXLAN_F_TTL_INHERIT) {
0089 NL_SET_ERR_MSG_MOD(extack, "VxLAN: TTL must not be configured to inherit");
0090 return false;
0091 }
0092
0093 switch (cfg->saddr.sa.sa_family) {
0094 case AF_INET:
0095 if (!mlxsw_sp_nve_vxlan_ipv4_flags_check(cfg, extack))
0096 return false;
0097 break;
0098 case AF_INET6:
0099 if (!mlxsw_sp_nve_vxlan_ipv6_flags_check(cfg, extack))
0100 return false;
0101 break;
0102 }
0103
0104 if (cfg->ttl == 0) {
0105 NL_SET_ERR_MSG_MOD(extack, "VxLAN: TTL must not be configured to 0");
0106 return false;
0107 }
0108
0109 if (cfg->label != 0) {
0110 NL_SET_ERR_MSG_MOD(extack, "VxLAN: Flow label must be configured to 0");
0111 return false;
0112 }
0113
0114 return true;
0115 }
0116
0117 static bool mlxsw_sp1_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
0118 const struct mlxsw_sp_nve_params *params,
0119 struct netlink_ext_ack *extack)
0120 {
0121 if (params->ethertype == ETH_P_8021AD) {
0122 NL_SET_ERR_MSG_MOD(extack, "VxLAN: 802.1ad bridge is not supported with VxLAN");
0123 return false;
0124 }
0125
0126 return mlxsw_sp_nve_vxlan_can_offload(nve, params, extack);
0127 }
0128
0129 static void
0130 mlxsw_sp_nve_vxlan_ul_proto_sip_config(const struct vxlan_config *cfg,
0131 struct mlxsw_sp_nve_config *config)
0132 {
0133 switch (cfg->saddr.sa.sa_family) {
0134 case AF_INET:
0135 config->ul_proto = MLXSW_SP_L3_PROTO_IPV4;
0136 config->ul_sip.addr4 = cfg->saddr.sin.sin_addr.s_addr;
0137 break;
0138 case AF_INET6:
0139 config->ul_proto = MLXSW_SP_L3_PROTO_IPV6;
0140 config->ul_sip.addr6 = cfg->saddr.sin6.sin6_addr;
0141 break;
0142 }
0143 }
0144
0145 static void mlxsw_sp_nve_vxlan_config(const struct mlxsw_sp_nve *nve,
0146 const struct mlxsw_sp_nve_params *params,
0147 struct mlxsw_sp_nve_config *config)
0148 {
0149 struct vxlan_dev *vxlan = netdev_priv(params->dev);
0150 struct vxlan_config *cfg = &vxlan->cfg;
0151
0152 config->type = MLXSW_SP_NVE_TYPE_VXLAN;
0153 config->ttl = cfg->ttl;
0154 config->flowlabel = cfg->label;
0155 config->learning_en = cfg->flags & VXLAN_F_LEARN ? 1 : 0;
0156 config->ul_tb_id = RT_TABLE_MAIN;
0157 mlxsw_sp_nve_vxlan_ul_proto_sip_config(cfg, config);
0158 config->udp_dport = cfg->dst_port;
0159 }
0160
0161 static void
0162 mlxsw_sp_nve_vxlan_config_prepare(char *tngcr_pl,
0163 const struct mlxsw_sp_nve_config *config)
0164 {
0165 struct in6_addr addr6;
0166 u8 udp_sport;
0167
0168 mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, true,
0169 config->ttl);
0170
0171
0172
0173
0174 get_random_bytes(&udp_sport, sizeof(udp_sport));
0175 udp_sport = (udp_sport % (0xee - 0x80 + 1)) + 0x80;
0176 mlxsw_reg_tngcr_nve_udp_sport_prefix_set(tngcr_pl, udp_sport);
0177
0178 switch (config->ul_proto) {
0179 case MLXSW_SP_L3_PROTO_IPV4:
0180 mlxsw_reg_tngcr_usipv4_set(tngcr_pl,
0181 be32_to_cpu(config->ul_sip.addr4));
0182 break;
0183 case MLXSW_SP_L3_PROTO_IPV6:
0184 addr6 = config->ul_sip.addr6;
0185 mlxsw_reg_tngcr_usipv6_memcpy_to(tngcr_pl,
0186 (const char *)&addr6);
0187 break;
0188 }
0189 }
0190
0191 static int
0192 mlxsw_sp1_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
0193 const struct mlxsw_sp_nve_config *config)
0194 {
0195 char tngcr_pl[MLXSW_REG_TNGCR_LEN];
0196 u16 ul_vr_id;
0197 int err;
0198
0199 err = mlxsw_sp_router_tb_id_vr_id(mlxsw_sp, config->ul_tb_id,
0200 &ul_vr_id);
0201 if (err)
0202 return err;
0203
0204 mlxsw_sp_nve_vxlan_config_prepare(tngcr_pl, config);
0205 mlxsw_reg_tngcr_learn_enable_set(tngcr_pl, config->learning_en);
0206 mlxsw_reg_tngcr_underlay_virtual_router_set(tngcr_pl, ul_vr_id);
0207
0208 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
0209 }
0210
0211 static void mlxsw_sp1_nve_vxlan_config_clear(struct mlxsw_sp *mlxsw_sp)
0212 {
0213 char tngcr_pl[MLXSW_REG_TNGCR_LEN];
0214
0215 mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
0216
0217 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
0218 }
0219
0220 static int mlxsw_sp1_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp,
0221 unsigned int tunnel_index)
0222 {
0223 char rtdp_pl[MLXSW_REG_RTDP_LEN];
0224
0225 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_NVE, tunnel_index);
0226
0227 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
0228 }
0229
0230 static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve,
0231 const struct mlxsw_sp_nve_config *config)
0232 {
0233 struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
0234 int err;
0235
0236 err = mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, config->udp_dport);
0237 if (err)
0238 return err;
0239
0240 err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
0241 if (err)
0242 goto err_parsing_depth_inc;
0243
0244 err = mlxsw_sp1_nve_vxlan_config_set(mlxsw_sp, config);
0245 if (err)
0246 goto err_config_set;
0247
0248 err = mlxsw_sp1_nve_vxlan_rtdp_set(mlxsw_sp, nve->tunnel_index);
0249 if (err)
0250 goto err_rtdp_set;
0251
0252 err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id,
0253 config->ul_proto,
0254 &config->ul_sip,
0255 nve->tunnel_index);
0256 if (err)
0257 goto err_promote_decap;
0258
0259 return 0;
0260
0261 err_promote_decap:
0262 err_rtdp_set:
0263 mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
0264 err_config_set:
0265 mlxsw_sp_parsing_depth_dec(mlxsw_sp);
0266 err_parsing_depth_inc:
0267 mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
0268 return err;
0269 }
0270
0271 static void mlxsw_sp1_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
0272 {
0273 struct mlxsw_sp_nve_config *config = &nve->config;
0274 struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
0275
0276 mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
0277 config->ul_proto, &config->ul_sip);
0278 mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
0279 mlxsw_sp_parsing_depth_dec(mlxsw_sp);
0280 mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
0281 }
0282
0283 static int
0284 mlxsw_sp_nve_vxlan_fdb_replay(const struct net_device *nve_dev, __be32 vni,
0285 struct netlink_ext_ack *extack)
0286 {
0287 if (WARN_ON(!netif_is_vxlan(nve_dev)))
0288 return -EINVAL;
0289 return vxlan_fdb_replay(nve_dev, vni, &mlxsw_sp_switchdev_notifier,
0290 extack);
0291 }
0292
0293 static void
0294 mlxsw_sp_nve_vxlan_clear_offload(const struct net_device *nve_dev, __be32 vni)
0295 {
0296 if (WARN_ON(!netif_is_vxlan(nve_dev)))
0297 return;
0298 vxlan_fdb_clear_offload(nve_dev, vni);
0299 }
0300
0301 const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops = {
0302 .type = MLXSW_SP_NVE_TYPE_VXLAN,
0303 .can_offload = mlxsw_sp1_nve_vxlan_can_offload,
0304 .nve_config = mlxsw_sp_nve_vxlan_config,
0305 .init = mlxsw_sp1_nve_vxlan_init,
0306 .fini = mlxsw_sp1_nve_vxlan_fini,
0307 .fdb_replay = mlxsw_sp_nve_vxlan_fdb_replay,
0308 .fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
0309 };
0310
0311 static bool mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp,
0312 bool learning_en)
0313 {
0314 char tnpc_pl[MLXSW_REG_TNPC_LEN];
0315
0316 mlxsw_reg_tnpc_pack(tnpc_pl, MLXSW_REG_TUNNEL_PORT_NVE,
0317 learning_en);
0318 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tnpc), tnpc_pl);
0319 }
0320
0321 static int
0322 mlxsw_sp2_nve_decap_ethertype_set(struct mlxsw_sp *mlxsw_sp)
0323 {
0324 char spvid_pl[MLXSW_REG_SPVID_LEN] = {};
0325
0326 mlxsw_reg_spvid_tport_set(spvid_pl, true);
0327 mlxsw_reg_spvid_local_port_set(spvid_pl,
0328 MLXSW_REG_TUNNEL_PORT_NVE);
0329 mlxsw_reg_spvid_egr_et_set_set(spvid_pl, true);
0330 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
0331 }
0332
0333 static int
0334 mlxsw_sp2_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
0335 const struct mlxsw_sp_nve_config *config)
0336 {
0337 char tngcr_pl[MLXSW_REG_TNGCR_LEN];
0338 char spvtr_pl[MLXSW_REG_SPVTR_LEN];
0339 u16 ul_rif_index;
0340 int err;
0341
0342 err = mlxsw_sp_router_ul_rif_get(mlxsw_sp, config->ul_tb_id,
0343 &ul_rif_index);
0344 if (err)
0345 return err;
0346 mlxsw_sp->nve->ul_rif_index = ul_rif_index;
0347
0348 err = mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, config->learning_en);
0349 if (err)
0350 goto err_vxlan_learning_set;
0351
0352 mlxsw_sp_nve_vxlan_config_prepare(tngcr_pl, config);
0353 mlxsw_reg_tngcr_underlay_rif_set(tngcr_pl, ul_rif_index);
0354
0355 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
0356 if (err)
0357 goto err_tngcr_write;
0358
0359 mlxsw_reg_spvtr_pack(spvtr_pl, true, MLXSW_REG_TUNNEL_PORT_NVE,
0360 MLXSW_REG_SPVTR_IPVID_MODE_ALWAYS_PUSH_VLAN);
0361 err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvtr), spvtr_pl);
0362 if (err)
0363 goto err_spvtr_write;
0364
0365 err = mlxsw_sp2_nve_decap_ethertype_set(mlxsw_sp);
0366 if (err)
0367 goto err_decap_ethertype_set;
0368
0369 return 0;
0370
0371 err_decap_ethertype_set:
0372 mlxsw_reg_spvtr_pack(spvtr_pl, true, MLXSW_REG_TUNNEL_PORT_NVE,
0373 MLXSW_REG_SPVTR_IPVID_MODE_IEEE_COMPLIANT_PVID);
0374 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvtr), spvtr_pl);
0375 err_spvtr_write:
0376 mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
0377 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
0378 err_tngcr_write:
0379 mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, false);
0380 err_vxlan_learning_set:
0381 mlxsw_sp_router_ul_rif_put(mlxsw_sp, ul_rif_index);
0382 return err;
0383 }
0384
0385 static void mlxsw_sp2_nve_vxlan_config_clear(struct mlxsw_sp *mlxsw_sp)
0386 {
0387 char spvtr_pl[MLXSW_REG_SPVTR_LEN];
0388 char tngcr_pl[MLXSW_REG_TNGCR_LEN];
0389
0390 mlxsw_reg_spvtr_pack(spvtr_pl, true, MLXSW_REG_TUNNEL_PORT_NVE,
0391 MLXSW_REG_SPVTR_IPVID_MODE_IEEE_COMPLIANT_PVID);
0392 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvtr), spvtr_pl);
0393 mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
0394 mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
0395 mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, false);
0396 mlxsw_sp_router_ul_rif_put(mlxsw_sp, mlxsw_sp->nve->ul_rif_index);
0397 }
0398
0399 static int mlxsw_sp2_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp,
0400 unsigned int tunnel_index,
0401 u16 ul_rif_index)
0402 {
0403 char rtdp_pl[MLXSW_REG_RTDP_LEN];
0404
0405 mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_NVE, tunnel_index);
0406 mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_index);
0407
0408 return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
0409 }
0410
0411 static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve,
0412 const struct mlxsw_sp_nve_config *config)
0413 {
0414 struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
0415 int err;
0416
0417 err = mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, config->udp_dport);
0418 if (err)
0419 return err;
0420
0421 err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
0422 if (err)
0423 goto err_parsing_depth_inc;
0424
0425 err = mlxsw_sp2_nve_vxlan_config_set(mlxsw_sp, config);
0426 if (err)
0427 goto err_config_set;
0428
0429 err = mlxsw_sp2_nve_vxlan_rtdp_set(mlxsw_sp, nve->tunnel_index,
0430 nve->ul_rif_index);
0431 if (err)
0432 goto err_rtdp_set;
0433
0434 err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id,
0435 config->ul_proto,
0436 &config->ul_sip,
0437 nve->tunnel_index);
0438 if (err)
0439 goto err_promote_decap;
0440
0441 return 0;
0442
0443 err_promote_decap:
0444 err_rtdp_set:
0445 mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
0446 err_config_set:
0447 mlxsw_sp_parsing_depth_dec(mlxsw_sp);
0448 err_parsing_depth_inc:
0449 mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
0450 return err;
0451 }
0452
0453 static void mlxsw_sp2_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
0454 {
0455 struct mlxsw_sp_nve_config *config = &nve->config;
0456 struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
0457
0458 mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
0459 config->ul_proto, &config->ul_sip);
0460 mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
0461 mlxsw_sp_parsing_depth_dec(mlxsw_sp);
0462 mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
0463 }
0464
0465 const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = {
0466 .type = MLXSW_SP_NVE_TYPE_VXLAN,
0467 .can_offload = mlxsw_sp_nve_vxlan_can_offload,
0468 .nve_config = mlxsw_sp_nve_vxlan_config,
0469 .init = mlxsw_sp2_nve_vxlan_init,
0470 .fini = mlxsw_sp2_nve_vxlan_fini,
0471 .fdb_replay = mlxsw_sp_nve_vxlan_fdb_replay,
0472 .fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
0473 };