Skip to content

Commit b29c61d

Browse files
author
Saeed Mahameed
committed
net/mlx5e: Ethtool steering flow validation refactoring
Have a ethtool rx flow spec validation helper function per flow type. Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 42c625a commit b29c61d

File tree

1 file changed

+100
-64
lines changed

1 file changed

+100
-64
lines changed

drivers/net/ethernet/mellanox/mlx5/core/en_fs_ethtool.c

Lines changed: 100 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -379,90 +379,125 @@ static struct mlx5e_ethtool_rule *get_ethtool_rule(struct mlx5e_priv *priv,
379379
#define all_zeros_or_all_ones(field) \
380380
((field) == 0 || (field) == (__force typeof(field))-1)
381381

382+
static int validate_ethter(struct ethtool_rx_flow_spec *fs)
383+
{
384+
struct ethhdr *eth_mask = &fs->m_u.ether_spec;
385+
int ntuples = 0;
386+
387+
if (!is_zero_ether_addr(eth_mask->h_dest))
388+
ntuples++;
389+
if (!is_zero_ether_addr(eth_mask->h_source))
390+
ntuples++;
391+
if (eth_mask->h_proto)
392+
ntuples++;
393+
return ntuples;
394+
}
395+
396+
static int validate_tcpudp4(struct ethtool_rx_flow_spec *fs)
397+
{
398+
struct ethtool_tcpip4_spec *l4_mask = &fs->m_u.tcp_ip4_spec;
399+
int ntuples = 0;
400+
401+
if (l4_mask->tos)
402+
return -EINVAL;
403+
404+
if (l4_mask->ip4src) {
405+
if (!all_ones(l4_mask->ip4src))
406+
return -EINVAL;
407+
ntuples++;
408+
}
409+
if (l4_mask->ip4dst) {
410+
if (!all_ones(l4_mask->ip4dst))
411+
return -EINVAL;
412+
ntuples++;
413+
}
414+
if (l4_mask->psrc) {
415+
if (!all_ones(l4_mask->psrc))
416+
return -EINVAL;
417+
ntuples++;
418+
}
419+
if (l4_mask->pdst) {
420+
if (!all_ones(l4_mask->pdst))
421+
return -EINVAL;
422+
ntuples++;
423+
}
424+
/* Flow is TCP/UDP */
425+
return ++ntuples;
426+
}
427+
428+
static int validate_ip4(struct ethtool_rx_flow_spec *fs)
429+
{
430+
struct ethtool_usrip4_spec *l3_mask = &fs->m_u.usr_ip4_spec;
431+
int ntuples = 0;
432+
433+
if (l3_mask->l4_4_bytes || l3_mask->tos || l3_mask->proto ||
434+
fs->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4)
435+
return -EINVAL;
436+
if (l3_mask->ip4src) {
437+
if (!all_ones(l3_mask->ip4src))
438+
return -EINVAL;
439+
ntuples++;
440+
}
441+
if (l3_mask->ip4dst) {
442+
if (!all_ones(l3_mask->ip4dst))
443+
return -EINVAL;
444+
ntuples++;
445+
}
446+
/* Flow is IPv4 */
447+
return ++ntuples;
448+
}
449+
450+
static int validate_vlan(struct ethtool_rx_flow_spec *fs)
451+
{
452+
if (fs->m_ext.vlan_etype ||
453+
fs->m_ext.vlan_tci != cpu_to_be16(VLAN_VID_MASK))
454+
return -EINVAL;
455+
456+
if (fs->m_ext.vlan_tci &&
457+
(be16_to_cpu(fs->h_ext.vlan_tci) >= VLAN_N_VID))
458+
return -EINVAL;
459+
460+
return 1;
461+
}
462+
382463
static int validate_flow(struct mlx5e_priv *priv,
383464
struct ethtool_rx_flow_spec *fs)
384465
{
385-
struct ethtool_tcpip4_spec *l4_mask;
386-
struct ethtool_usrip4_spec *l3_mask;
387-
struct ethhdr *eth_mask;
388466
int num_tuples = 0;
467+
int ret = 0;
389468

390469
if (fs->location >= MAX_NUM_OF_ETHTOOL_RULES)
391-
return -EINVAL;
470+
return -ENOSPC;
392471

393472
if (fs->ring_cookie >= priv->channels.params.num_channels &&
394473
fs->ring_cookie != RX_CLS_FLOW_DISC)
395474
return -EINVAL;
396475

397476
switch (fs->flow_type & ~(FLOW_EXT | FLOW_MAC_EXT)) {
398477
case ETHER_FLOW:
399-
eth_mask = &fs->m_u.ether_spec;
400-
if (!is_zero_ether_addr(eth_mask->h_dest))
401-
num_tuples++;
402-
if (!is_zero_ether_addr(eth_mask->h_source))
403-
num_tuples++;
404-
if (eth_mask->h_proto)
405-
num_tuples++;
478+
num_tuples += validate_ethter(fs);
406479
break;
407480
case TCP_V4_FLOW:
408481
case UDP_V4_FLOW:
409-
if (fs->m_u.tcp_ip4_spec.tos)
410-
return -EINVAL;
411-
l4_mask = &fs->m_u.tcp_ip4_spec;
412-
if (l4_mask->ip4src) {
413-
if (!all_ones(l4_mask->ip4src))
414-
return -EINVAL;
415-
num_tuples++;
416-
}
417-
if (l4_mask->ip4dst) {
418-
if (!all_ones(l4_mask->ip4dst))
419-
return -EINVAL;
420-
num_tuples++;
421-
}
422-
if (l4_mask->psrc) {
423-
if (!all_ones(l4_mask->psrc))
424-
return -EINVAL;
425-
num_tuples++;
426-
}
427-
if (l4_mask->pdst) {
428-
if (!all_ones(l4_mask->pdst))
429-
return -EINVAL;
430-
num_tuples++;
431-
}
432-
/* Flow is TCP/UDP */
433-
num_tuples++;
482+
ret = validate_tcpudp4(fs);
483+
if (ret < 0)
484+
return ret;
485+
num_tuples += ret;
434486
break;
435487
case IP_USER_FLOW:
436-
l3_mask = &fs->m_u.usr_ip4_spec;
437-
if (l3_mask->l4_4_bytes || l3_mask->tos || l3_mask->proto ||
438-
fs->h_u.usr_ip4_spec.ip_ver != ETH_RX_NFC_IP4)
439-
return -EINVAL;
440-
if (l3_mask->ip4src) {
441-
if (!all_ones(l3_mask->ip4src))
442-
return -EINVAL;
443-
num_tuples++;
444-
}
445-
if (l3_mask->ip4dst) {
446-
if (!all_ones(l3_mask->ip4dst))
447-
return -EINVAL;
448-
num_tuples++;
449-
}
450-
/* Flow is IPv4 */
451-
num_tuples++;
488+
ret = validate_ip4(fs);
489+
if (ret < 0)
490+
return ret;
491+
num_tuples += ret;
452492
break;
453493
default:
454-
return -EINVAL;
494+
return -ENOTSUPP;
455495
}
456496
if ((fs->flow_type & FLOW_EXT)) {
457-
if (fs->m_ext.vlan_etype ||
458-
(fs->m_ext.vlan_tci != cpu_to_be16(VLAN_VID_MASK)))
459-
return -EINVAL;
460-
461-
if (fs->m_ext.vlan_tci) {
462-
if (be16_to_cpu(fs->h_ext.vlan_tci) >= VLAN_N_VID)
463-
return -EINVAL;
464-
}
465-
num_tuples++;
497+
ret = validate_vlan(fs);
498+
if (ret < 0)
499+
return ret;
500+
num_tuples += ret;
466501
}
467502

468503
if (fs->flow_type & FLOW_MAC_EXT &&
@@ -483,8 +518,9 @@ int mlx5e_ethtool_flow_replace(struct mlx5e_priv *priv,
483518

484519
num_tuples = validate_flow(priv, fs);
485520
if (num_tuples <= 0) {
486-
netdev_warn(priv->netdev, "%s: flow is not valid\n", __func__);
487-
return -EINVAL;
521+
netdev_warn(priv->netdev, "%s: flow is not valid %d\n",
522+
__func__, num_tuples);
523+
return num_tuples;
488524
}
489525

490526
eth_ft = get_flow_table(priv, fs, num_tuples);

0 commit comments

Comments
 (0)