cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

spectrum_nve_vxlan.c (13513B)


      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.h"
     11#include "spectrum_nve.h"
     12
     13#define MLXSW_SP_NVE_VXLAN_IPV4_SUPPORTED_FLAGS (VXLAN_F_UDP_ZERO_CSUM_TX | \
     14						 VXLAN_F_LEARN)
     15#define MLXSW_SP_NVE_VXLAN_IPV6_SUPPORTED_FLAGS (VXLAN_F_IPV6 | \
     16						 VXLAN_F_UDP_ZERO_CSUM6_TX | \
     17						 VXLAN_F_UDP_ZERO_CSUM6_RX)
     18
     19static bool mlxsw_sp_nve_vxlan_ipv4_flags_check(const struct vxlan_config *cfg,
     20						struct netlink_ext_ack *extack)
     21{
     22	if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM_TX)) {
     23		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Zero UDP checksum must be allowed for TX");
     24		return false;
     25	}
     26
     27	if (cfg->flags & ~MLXSW_SP_NVE_VXLAN_IPV4_SUPPORTED_FLAGS) {
     28		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Unsupported flag");
     29		return false;
     30	}
     31
     32	return true;
     33}
     34
     35static bool mlxsw_sp_nve_vxlan_ipv6_flags_check(const struct vxlan_config *cfg,
     36						struct netlink_ext_ack *extack)
     37{
     38	if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM6_TX)) {
     39		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Zero UDP checksum must be allowed for TX");
     40		return false;
     41	}
     42
     43	if (!(cfg->flags & VXLAN_F_UDP_ZERO_CSUM6_RX)) {
     44		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Zero UDP checksum must be allowed for RX");
     45		return false;
     46	}
     47
     48	if (cfg->flags & ~MLXSW_SP_NVE_VXLAN_IPV6_SUPPORTED_FLAGS) {
     49		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Unsupported flag");
     50		return false;
     51	}
     52
     53	return true;
     54}
     55
     56static bool mlxsw_sp_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
     57					   const struct mlxsw_sp_nve_params *params,
     58					   struct netlink_ext_ack *extack)
     59{
     60	struct vxlan_dev *vxlan = netdev_priv(params->dev);
     61	struct vxlan_config *cfg = &vxlan->cfg;
     62
     63	if (vxlan_addr_multicast(&cfg->remote_ip)) {
     64		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Multicast destination IP is not supported");
     65		return false;
     66	}
     67
     68	if (vxlan_addr_any(&cfg->saddr)) {
     69		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Source address must be specified");
     70		return false;
     71	}
     72
     73	if (cfg->remote_ifindex) {
     74		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Local interface is not supported");
     75		return false;
     76	}
     77
     78	if (cfg->port_min || cfg->port_max) {
     79		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Only default UDP source port range is supported");
     80		return false;
     81	}
     82
     83	if (cfg->tos != 1) {
     84		NL_SET_ERR_MSG_MOD(extack, "VxLAN: TOS must be configured to inherit");
     85		return false;
     86	}
     87
     88	if (cfg->flags & VXLAN_F_TTL_INHERIT) {
     89		NL_SET_ERR_MSG_MOD(extack, "VxLAN: TTL must not be configured to inherit");
     90		return false;
     91	}
     92
     93	switch (cfg->saddr.sa.sa_family) {
     94	case AF_INET:
     95		if (!mlxsw_sp_nve_vxlan_ipv4_flags_check(cfg, extack))
     96			return false;
     97		break;
     98	case AF_INET6:
     99		if (!mlxsw_sp_nve_vxlan_ipv6_flags_check(cfg, extack))
    100			return false;
    101		break;
    102	}
    103
    104	if (cfg->ttl == 0) {
    105		NL_SET_ERR_MSG_MOD(extack, "VxLAN: TTL must not be configured to 0");
    106		return false;
    107	}
    108
    109	if (cfg->label != 0) {
    110		NL_SET_ERR_MSG_MOD(extack, "VxLAN: Flow label must be configured to 0");
    111		return false;
    112	}
    113
    114	return true;
    115}
    116
    117static bool mlxsw_sp1_nve_vxlan_can_offload(const struct mlxsw_sp_nve *nve,
    118					    const struct mlxsw_sp_nve_params *params,
    119					    struct netlink_ext_ack *extack)
    120{
    121	if (params->ethertype == ETH_P_8021AD) {
    122		NL_SET_ERR_MSG_MOD(extack, "VxLAN: 802.1ad bridge is not supported with VxLAN");
    123		return false;
    124	}
    125
    126	return mlxsw_sp_nve_vxlan_can_offload(nve, params, extack);
    127}
    128
    129static void
    130mlxsw_sp_nve_vxlan_ul_proto_sip_config(const struct vxlan_config *cfg,
    131				       struct mlxsw_sp_nve_config *config)
    132{
    133	switch (cfg->saddr.sa.sa_family) {
    134	case AF_INET:
    135		config->ul_proto = MLXSW_SP_L3_PROTO_IPV4;
    136		config->ul_sip.addr4 = cfg->saddr.sin.sin_addr.s_addr;
    137		break;
    138	case AF_INET6:
    139		config->ul_proto = MLXSW_SP_L3_PROTO_IPV6;
    140		config->ul_sip.addr6 = cfg->saddr.sin6.sin6_addr;
    141		break;
    142	}
    143}
    144
    145static void mlxsw_sp_nve_vxlan_config(const struct mlxsw_sp_nve *nve,
    146				      const struct mlxsw_sp_nve_params *params,
    147				      struct mlxsw_sp_nve_config *config)
    148{
    149	struct vxlan_dev *vxlan = netdev_priv(params->dev);
    150	struct vxlan_config *cfg = &vxlan->cfg;
    151
    152	config->type = MLXSW_SP_NVE_TYPE_VXLAN;
    153	config->ttl = cfg->ttl;
    154	config->flowlabel = cfg->label;
    155	config->learning_en = cfg->flags & VXLAN_F_LEARN ? 1 : 0;
    156	config->ul_tb_id = RT_TABLE_MAIN;
    157	mlxsw_sp_nve_vxlan_ul_proto_sip_config(cfg, config);
    158	config->udp_dport = cfg->dst_port;
    159}
    160
    161static void
    162mlxsw_sp_nve_vxlan_config_prepare(char *tngcr_pl,
    163				  const struct mlxsw_sp_nve_config *config)
    164{
    165	struct in6_addr addr6;
    166	u8 udp_sport;
    167
    168	mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, true,
    169			     config->ttl);
    170	/* VxLAN driver's default UDP source port range is 32768 (0x8000)
    171	 * to 60999 (0xee47). Set the upper 8 bits of the UDP source port
    172	 * to a random number between 0x80 and 0xee
    173	 */
    174	get_random_bytes(&udp_sport, sizeof(udp_sport));
    175	udp_sport = (udp_sport % (0xee - 0x80 + 1)) + 0x80;
    176	mlxsw_reg_tngcr_nve_udp_sport_prefix_set(tngcr_pl, udp_sport);
    177
    178	switch (config->ul_proto) {
    179	case MLXSW_SP_L3_PROTO_IPV4:
    180		mlxsw_reg_tngcr_usipv4_set(tngcr_pl,
    181					   be32_to_cpu(config->ul_sip.addr4));
    182		break;
    183	case MLXSW_SP_L3_PROTO_IPV6:
    184		addr6 = config->ul_sip.addr6;
    185		mlxsw_reg_tngcr_usipv6_memcpy_to(tngcr_pl,
    186						 (const char *)&addr6);
    187		break;
    188	}
    189}
    190
    191static int
    192mlxsw_sp1_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
    193			       const struct mlxsw_sp_nve_config *config)
    194{
    195	char tngcr_pl[MLXSW_REG_TNGCR_LEN];
    196	u16 ul_vr_id;
    197	int err;
    198
    199	err = mlxsw_sp_router_tb_id_vr_id(mlxsw_sp, config->ul_tb_id,
    200					  &ul_vr_id);
    201	if (err)
    202		return err;
    203
    204	mlxsw_sp_nve_vxlan_config_prepare(tngcr_pl, config);
    205	mlxsw_reg_tngcr_learn_enable_set(tngcr_pl, config->learning_en);
    206	mlxsw_reg_tngcr_underlay_virtual_router_set(tngcr_pl, ul_vr_id);
    207
    208	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
    209}
    210
    211static void mlxsw_sp1_nve_vxlan_config_clear(struct mlxsw_sp *mlxsw_sp)
    212{
    213	char tngcr_pl[MLXSW_REG_TNGCR_LEN];
    214
    215	mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
    216
    217	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
    218}
    219
    220static int mlxsw_sp1_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp,
    221					unsigned int tunnel_index)
    222{
    223	char rtdp_pl[MLXSW_REG_RTDP_LEN];
    224
    225	mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_NVE, tunnel_index);
    226
    227	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
    228}
    229
    230static int mlxsw_sp1_nve_vxlan_init(struct mlxsw_sp_nve *nve,
    231				    const struct mlxsw_sp_nve_config *config)
    232{
    233	struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
    234	int err;
    235
    236	err = mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, config->udp_dport);
    237	if (err)
    238		return err;
    239
    240	err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
    241	if (err)
    242		goto err_parsing_depth_inc;
    243
    244	err = mlxsw_sp1_nve_vxlan_config_set(mlxsw_sp, config);
    245	if (err)
    246		goto err_config_set;
    247
    248	err = mlxsw_sp1_nve_vxlan_rtdp_set(mlxsw_sp, nve->tunnel_index);
    249	if (err)
    250		goto err_rtdp_set;
    251
    252	err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id,
    253						config->ul_proto,
    254						&config->ul_sip,
    255						nve->tunnel_index);
    256	if (err)
    257		goto err_promote_decap;
    258
    259	return 0;
    260
    261err_promote_decap:
    262err_rtdp_set:
    263	mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
    264err_config_set:
    265	mlxsw_sp_parsing_depth_dec(mlxsw_sp);
    266err_parsing_depth_inc:
    267	mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
    268	return err;
    269}
    270
    271static void mlxsw_sp1_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
    272{
    273	struct mlxsw_sp_nve_config *config = &nve->config;
    274	struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
    275
    276	mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
    277					 config->ul_proto, &config->ul_sip);
    278	mlxsw_sp1_nve_vxlan_config_clear(mlxsw_sp);
    279	mlxsw_sp_parsing_depth_dec(mlxsw_sp);
    280	mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
    281}
    282
    283static int
    284mlxsw_sp_nve_vxlan_fdb_replay(const struct net_device *nve_dev, __be32 vni,
    285			      struct netlink_ext_ack *extack)
    286{
    287	if (WARN_ON(!netif_is_vxlan(nve_dev)))
    288		return -EINVAL;
    289	return vxlan_fdb_replay(nve_dev, vni, &mlxsw_sp_switchdev_notifier,
    290				extack);
    291}
    292
    293static void
    294mlxsw_sp_nve_vxlan_clear_offload(const struct net_device *nve_dev, __be32 vni)
    295{
    296	if (WARN_ON(!netif_is_vxlan(nve_dev)))
    297		return;
    298	vxlan_fdb_clear_offload(nve_dev, vni);
    299}
    300
    301const struct mlxsw_sp_nve_ops mlxsw_sp1_nve_vxlan_ops = {
    302	.type		= MLXSW_SP_NVE_TYPE_VXLAN,
    303	.can_offload	= mlxsw_sp1_nve_vxlan_can_offload,
    304	.nve_config	= mlxsw_sp_nve_vxlan_config,
    305	.init		= mlxsw_sp1_nve_vxlan_init,
    306	.fini		= mlxsw_sp1_nve_vxlan_fini,
    307	.fdb_replay	= mlxsw_sp_nve_vxlan_fdb_replay,
    308	.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
    309};
    310
    311static bool mlxsw_sp2_nve_vxlan_learning_set(struct mlxsw_sp *mlxsw_sp,
    312					     bool learning_en)
    313{
    314	char tnpc_pl[MLXSW_REG_TNPC_LEN];
    315
    316	mlxsw_reg_tnpc_pack(tnpc_pl, MLXSW_REG_TUNNEL_PORT_NVE,
    317			    learning_en);
    318	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tnpc), tnpc_pl);
    319}
    320
    321static int
    322mlxsw_sp2_nve_decap_ethertype_set(struct mlxsw_sp *mlxsw_sp)
    323{
    324	char spvid_pl[MLXSW_REG_SPVID_LEN] = {};
    325
    326	mlxsw_reg_spvid_tport_set(spvid_pl, true);
    327	mlxsw_reg_spvid_local_port_set(spvid_pl,
    328				       MLXSW_REG_TUNNEL_PORT_NVE);
    329	mlxsw_reg_spvid_egr_et_set_set(spvid_pl, true);
    330	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvid), spvid_pl);
    331}
    332
    333static int
    334mlxsw_sp2_nve_vxlan_config_set(struct mlxsw_sp *mlxsw_sp,
    335			       const struct mlxsw_sp_nve_config *config)
    336{
    337	char tngcr_pl[MLXSW_REG_TNGCR_LEN];
    338	char spvtr_pl[MLXSW_REG_SPVTR_LEN];
    339	u16 ul_rif_index;
    340	int err;
    341
    342	err = mlxsw_sp_router_ul_rif_get(mlxsw_sp, config->ul_tb_id,
    343					 &ul_rif_index);
    344	if (err)
    345		return err;
    346	mlxsw_sp->nve->ul_rif_index = ul_rif_index;
    347
    348	err = mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, config->learning_en);
    349	if (err)
    350		goto err_vxlan_learning_set;
    351
    352	mlxsw_sp_nve_vxlan_config_prepare(tngcr_pl, config);
    353	mlxsw_reg_tngcr_underlay_rif_set(tngcr_pl, ul_rif_index);
    354
    355	err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
    356	if (err)
    357		goto err_tngcr_write;
    358
    359	mlxsw_reg_spvtr_pack(spvtr_pl, true, MLXSW_REG_TUNNEL_PORT_NVE,
    360			     MLXSW_REG_SPVTR_IPVID_MODE_ALWAYS_PUSH_VLAN);
    361	err = mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvtr), spvtr_pl);
    362	if (err)
    363		goto err_spvtr_write;
    364
    365	err = mlxsw_sp2_nve_decap_ethertype_set(mlxsw_sp);
    366	if (err)
    367		goto err_decap_ethertype_set;
    368
    369	return 0;
    370
    371err_decap_ethertype_set:
    372	mlxsw_reg_spvtr_pack(spvtr_pl, true, MLXSW_REG_TUNNEL_PORT_NVE,
    373			     MLXSW_REG_SPVTR_IPVID_MODE_IEEE_COMPLIANT_PVID);
    374	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvtr), spvtr_pl);
    375err_spvtr_write:
    376	mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
    377	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
    378err_tngcr_write:
    379	mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, false);
    380err_vxlan_learning_set:
    381	mlxsw_sp_router_ul_rif_put(mlxsw_sp, ul_rif_index);
    382	return err;
    383}
    384
    385static void mlxsw_sp2_nve_vxlan_config_clear(struct mlxsw_sp *mlxsw_sp)
    386{
    387	char spvtr_pl[MLXSW_REG_SPVTR_LEN];
    388	char tngcr_pl[MLXSW_REG_TNGCR_LEN];
    389
    390	mlxsw_reg_spvtr_pack(spvtr_pl, true, MLXSW_REG_TUNNEL_PORT_NVE,
    391			     MLXSW_REG_SPVTR_IPVID_MODE_IEEE_COMPLIANT_PVID);
    392	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(spvtr), spvtr_pl);
    393	mlxsw_reg_tngcr_pack(tngcr_pl, MLXSW_REG_TNGCR_TYPE_VXLAN, false, 0);
    394	mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(tngcr), tngcr_pl);
    395	mlxsw_sp2_nve_vxlan_learning_set(mlxsw_sp, false);
    396	mlxsw_sp_router_ul_rif_put(mlxsw_sp, mlxsw_sp->nve->ul_rif_index);
    397}
    398
    399static int mlxsw_sp2_nve_vxlan_rtdp_set(struct mlxsw_sp *mlxsw_sp,
    400					unsigned int tunnel_index,
    401					u16 ul_rif_index)
    402{
    403	char rtdp_pl[MLXSW_REG_RTDP_LEN];
    404
    405	mlxsw_reg_rtdp_pack(rtdp_pl, MLXSW_REG_RTDP_TYPE_NVE, tunnel_index);
    406	mlxsw_reg_rtdp_egress_router_interface_set(rtdp_pl, ul_rif_index);
    407
    408	return mlxsw_reg_write(mlxsw_sp->core, MLXSW_REG(rtdp), rtdp_pl);
    409}
    410
    411static int mlxsw_sp2_nve_vxlan_init(struct mlxsw_sp_nve *nve,
    412				    const struct mlxsw_sp_nve_config *config)
    413{
    414	struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
    415	int err;
    416
    417	err = mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, config->udp_dport);
    418	if (err)
    419		return err;
    420
    421	err = mlxsw_sp_parsing_depth_inc(mlxsw_sp);
    422	if (err)
    423		goto err_parsing_depth_inc;
    424
    425	err = mlxsw_sp2_nve_vxlan_config_set(mlxsw_sp, config);
    426	if (err)
    427		goto err_config_set;
    428
    429	err = mlxsw_sp2_nve_vxlan_rtdp_set(mlxsw_sp, nve->tunnel_index,
    430					   nve->ul_rif_index);
    431	if (err)
    432		goto err_rtdp_set;
    433
    434	err = mlxsw_sp_router_nve_promote_decap(mlxsw_sp, config->ul_tb_id,
    435						config->ul_proto,
    436						&config->ul_sip,
    437						nve->tunnel_index);
    438	if (err)
    439		goto err_promote_decap;
    440
    441	return 0;
    442
    443err_promote_decap:
    444err_rtdp_set:
    445	mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
    446err_config_set:
    447	mlxsw_sp_parsing_depth_dec(mlxsw_sp);
    448err_parsing_depth_inc:
    449	mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
    450	return err;
    451}
    452
    453static void mlxsw_sp2_nve_vxlan_fini(struct mlxsw_sp_nve *nve)
    454{
    455	struct mlxsw_sp_nve_config *config = &nve->config;
    456	struct mlxsw_sp *mlxsw_sp = nve->mlxsw_sp;
    457
    458	mlxsw_sp_router_nve_demote_decap(mlxsw_sp, config->ul_tb_id,
    459					 config->ul_proto, &config->ul_sip);
    460	mlxsw_sp2_nve_vxlan_config_clear(mlxsw_sp);
    461	mlxsw_sp_parsing_depth_dec(mlxsw_sp);
    462	mlxsw_sp_parsing_vxlan_udp_dport_set(mlxsw_sp, 0);
    463}
    464
    465const struct mlxsw_sp_nve_ops mlxsw_sp2_nve_vxlan_ops = {
    466	.type		= MLXSW_SP_NVE_TYPE_VXLAN,
    467	.can_offload	= mlxsw_sp_nve_vxlan_can_offload,
    468	.nve_config	= mlxsw_sp_nve_vxlan_config,
    469	.init		= mlxsw_sp2_nve_vxlan_init,
    470	.fini		= mlxsw_sp2_nve_vxlan_fini,
    471	.fdb_replay	= mlxsw_sp_nve_vxlan_fdb_replay,
    472	.fdb_clear_offload = mlxsw_sp_nve_vxlan_clear_offload,
    473};