Back to home page

OSCL-LXR

 
 

    


0001 // SPDX-License-Identifier: BSD-3-Clause OR GPL-2.0
0002 /* Copyright (c) 2018 Mellanox Technologies. All rights reserved */
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     /* VxLAN driver's default UDP source port range is 32768 (0x8000)
0171      * to 60999 (0xee47). Set the upper 8 bits of the UDP source port
0172      * to a random number between 0x80 and 0xee
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 };