Skip to content

Commit 54493a0

Browse files
mark-blochSaeed Mahameed
authored andcommitted
net/mlx5: Lag, record inactive state of bond device
A bond device will drop duplicate packets (received on inactive ports) by default. A flag (all_slaves_active) can be set to override such behaviour. This flag is a global flag per bond device (ALB mode isn't supported by mlx5 driver so it can be ignored) When NETDEV_CHANGEUPPER / NETDEV_CHANGEINFODATA event is received check if there is an interface that is inactive. Downstream patch will use this information in order to decide if a drop rule is needed. Signed-off-by: Mark Bloch <[email protected]> Reviewed-by: Maor Gottlieb <[email protected]> Signed-off-by: Saeed Mahameed <[email protected]>
1 parent 4f45514 commit 54493a0

File tree

3 files changed

+49
-3
lines changed

3 files changed

+49
-3
lines changed

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

Lines changed: 47 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
*/
3232

3333
#include <linux/netdevice.h>
34+
#include <net/bonding.h>
3435
#include <linux/mlx5/driver.h>
3536
#include <linux/mlx5/eswitch.h>
3637
#include <linux/mlx5/vport.h>
@@ -619,6 +620,8 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
619620
struct net_device *upper = info->upper_dev, *ndev_tmp;
620621
struct netdev_lag_upper_info *lag_upper_info = NULL;
621622
bool is_bonded, is_in_lag, mode_supported;
623+
bool has_inactive = 0;
624+
struct slave *slave;
622625
int bond_status = 0;
623626
int num_slaves = 0;
624627
int changed = 0;
@@ -638,8 +641,12 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
638641
rcu_read_lock();
639642
for_each_netdev_in_bond_rcu(upper, ndev_tmp) {
640643
idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
641-
if (idx >= 0)
644+
if (idx >= 0) {
645+
slave = bond_slave_get_rcu(ndev_tmp);
646+
if (slave)
647+
has_inactive |= bond_is_slave_inactive(slave);
642648
bond_status |= (1 << idx);
649+
}
643650

644651
num_slaves++;
645652
}
@@ -654,6 +661,7 @@ static int mlx5_handle_changeupper_event(struct mlx5_lag *ldev,
654661
tracker->hash_type = lag_upper_info->hash_type;
655662
}
656663

664+
tracker->has_inactive = has_inactive;
657665
/* Determine bonding status:
658666
* A device is considered bonded if both its physical ports are slaves
659667
* of the same lag master, and only them.
@@ -710,6 +718,38 @@ static int mlx5_handle_changelowerstate_event(struct mlx5_lag *ldev,
710718
return 1;
711719
}
712720

721+
static int mlx5_handle_changeinfodata_event(struct mlx5_lag *ldev,
722+
struct lag_tracker *tracker,
723+
struct net_device *ndev)
724+
{
725+
struct net_device *ndev_tmp;
726+
struct slave *slave;
727+
bool has_inactive = 0;
728+
int idx;
729+
730+
if (!netif_is_lag_master(ndev))
731+
return 0;
732+
733+
rcu_read_lock();
734+
for_each_netdev_in_bond_rcu(ndev, ndev_tmp) {
735+
idx = mlx5_lag_dev_get_netdev_idx(ldev, ndev_tmp);
736+
if (idx < 0)
737+
continue;
738+
739+
slave = bond_slave_get_rcu(ndev_tmp);
740+
if (slave)
741+
has_inactive |= bond_is_slave_inactive(slave);
742+
}
743+
rcu_read_unlock();
744+
745+
if (tracker->has_inactive == has_inactive)
746+
return 0;
747+
748+
tracker->has_inactive = has_inactive;
749+
750+
return 1;
751+
}
752+
713753
static int mlx5_lag_netdev_event(struct notifier_block *this,
714754
unsigned long event, void *ptr)
715755
{
@@ -718,7 +758,9 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
718758
struct mlx5_lag *ldev;
719759
int changed = 0;
720760

721-
if ((event != NETDEV_CHANGEUPPER) && (event != NETDEV_CHANGELOWERSTATE))
761+
if (event != NETDEV_CHANGEUPPER &&
762+
event != NETDEV_CHANGELOWERSTATE &&
763+
event != NETDEV_CHANGEINFODATA)
722764
return NOTIFY_DONE;
723765

724766
ldev = container_of(this, struct mlx5_lag, nb);
@@ -734,6 +776,9 @@ static int mlx5_lag_netdev_event(struct notifier_block *this,
734776
changed = mlx5_handle_changelowerstate_event(ldev, &tracker,
735777
ndev, ptr);
736778
break;
779+
case NETDEV_CHANGEINFODATA:
780+
changed = mlx5_handle_changeinfodata_event(ldev, &tracker, ndev);
781+
break;
737782
}
738783

739784
ldev->tracker = tracker;

drivers/net/ethernet/mellanox/mlx5/core/lag/lag.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ struct lag_tracker {
3535
enum netdev_lag_tx_type tx_type;
3636
struct netdev_lag_lower_state_info netdev_state[MLX5_MAX_PORTS];
3737
unsigned int is_bonded:1;
38+
unsigned int has_inactive:1;
3839
enum netdev_lag_hash hash_type;
3940
};
4041

drivers/net/ethernet/mellanox/mlx5/core/lag/mp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ bool mlx5_lag_is_multipath(struct mlx5_core_dev *dev)
5050
static void mlx5_lag_set_port_affinity(struct mlx5_lag *ldev,
5151
enum mlx5_lag_port_affinity port)
5252
{
53-
struct lag_tracker tracker;
53+
struct lag_tracker tracker = {};
5454

5555
if (!__mlx5_lag_is_multipath(ldev))
5656
return;

0 commit comments

Comments
 (0)