Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5481d73f authored by David Ahern's avatar David Ahern Committed by David S. Miller
Browse files

ipv4: Use accessors for fib_info nexthop data



Use helpers to access fib_nh and fib_nhs fields of a fib_info. Drop the
fib_dev macro which is an alias for the first nexthop. Replacements:

  fi->fib_dev    --> fib_info_nh(fi, 0)->fib_nh_dev
  fi->fib_nh     --> fib_info_nh(fi, 0)
  fi->fib_nh[i]  --> fib_info_nh(fi, i)
  fi->fib_nhs    --> fib_info_num_path(fi)

where fib_info_nh(fi, i) returns fi->fib_nh[nhsel] and fib_info_num_path
returns fi->fib_nhs.

Move the existing fib_info_nhc to nexthop.h and define the new ones
there. A later patch adds a check if a fib_info uses a nexthop object,
and defining the helpers in nexthop.h avoid circular header
dependencies.

After this all remaining open coded references to fi->fib_nhs and
fi->fib_nh are in:
- fib_create_info and helpers used to lookup an existing fib_info
  entry, and
- the netdev event functions fib_sync_down_dev and fib_sync_up.

The latter two will not be reused for nexthops, and the fib_create_info
will be updated to handle a nexthop in a fib_info.

Signed-off-by: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent 7dd73168
Loading
Loading
Loading
Loading
+19 −10
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
/* Copyright (c) 2019 Mellanox Technologies. */

#include <linux/netdevice.h>
#include <net/nexthop.h>
#include "lag.h"
#include "lag_mp.h"
#include "mlx5_core.h"
@@ -110,6 +111,8 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
				     struct fib_info *fi)
{
	struct lag_mp *mp = &ldev->lag_mp;
	struct fib_nh *fib_nh0, *fib_nh1;
	unsigned int nhs;

	/* Handle delete event */
	if (event == FIB_EVENT_ENTRY_DEL) {
@@ -120,9 +123,11 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
	}

	/* Handle add/replace event */
	if (fi->fib_nhs == 1) {
	nhs = fib_info_num_path(fi);
	if (nhs == 1) {
		if (__mlx5_lag_is_active(ldev)) {
			struct net_device *nh_dev = fi->fib_nh[0].fib_nh_dev;
			struct fib_nh *nh = fib_info_nh(fi, 0);
			struct net_device *nh_dev = nh->fib_nh_dev;
			int i = mlx5_lag_dev_get_netdev_idx(ldev, nh_dev);

			mlx5_lag_set_port_affinity(ldev, ++i);
@@ -130,14 +135,16 @@ static void mlx5_lag_fib_route_event(struct mlx5_lag *ldev,
		return;
	}

	if (fi->fib_nhs != 2)
	if (nhs != 2)
		return;

	/* Verify next hops are ports of the same hca */
	if (!(fi->fib_nh[0].fib_nh_dev == ldev->pf[0].netdev &&
	      fi->fib_nh[1].fib_nh_dev == ldev->pf[1].netdev) &&
	    !(fi->fib_nh[0].fib_nh_dev == ldev->pf[1].netdev &&
	      fi->fib_nh[1].fib_nh_dev == ldev->pf[0].netdev)) {
	fib_nh0 = fib_info_nh(fi, 0);
	fib_nh1 = fib_info_nh(fi, 1);
	if (!(fib_nh0->fib_nh_dev == ldev->pf[0].netdev &&
	      fib_nh1->fib_nh_dev == ldev->pf[1].netdev) &&
	    !(fib_nh0->fib_nh_dev == ldev->pf[1].netdev &&
	      fib_nh1->fib_nh_dev == ldev->pf[0].netdev)) {
		mlx5_core_warn(ldev->pf[0].dev, "Multipath offload require two ports of the same HCA\n");
		return;
	}
@@ -174,7 +181,7 @@ static void mlx5_lag_fib_nexthop_event(struct mlx5_lag *ldev,
			mlx5_lag_set_port_affinity(ldev, i);
		}
	} else if (event == FIB_EVENT_NH_ADD &&
		   fi->fib_nhs == 2) {
		   fib_info_num_path(fi) == 2) {
		mlx5_lag_set_port_affinity(ldev, 0);
	}
}
@@ -238,6 +245,7 @@ static int mlx5_lag_fib_event(struct notifier_block *nb,
	struct mlx5_fib_event_work *fib_work;
	struct fib_entry_notifier_info *fen_info;
	struct fib_nh_notifier_info *fnh_info;
	struct net_device *fib_dev;
	struct fib_info *fi;

	if (info->family != AF_INET)
@@ -254,8 +262,9 @@ static int mlx5_lag_fib_event(struct notifier_block *nb,
		fen_info = container_of(info, struct fib_entry_notifier_info,
					info);
		fi = fen_info->fi;
		if (fi->fib_dev != ldev->pf[0].netdev &&
		    fi->fib_dev != ldev->pf[1].netdev) {
		fib_dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev;
		if (fib_dev != ldev->pf[0].netdev &&
		    fib_dev != ldev->pf[1].netdev) {
			return NOTIFY_DONE;
		}
		fib_work = mlx5_lag_init_fib_work(ldev, event);
+11 −8
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@
#include <net/arp.h>
#include <net/ip_fib.h>
#include <net/ip6_fib.h>
#include <net/nexthop.h>
#include <net/fib_rules.h>
#include <net/ip_tunnels.h>
#include <net/l3mdev.h>
@@ -3816,23 +3817,25 @@ static void mlxsw_sp_nexthop_rif_gone_sync(struct mlxsw_sp *mlxsw_sp,
}

static bool mlxsw_sp_fi_is_gateway(const struct mlxsw_sp *mlxsw_sp,
				   const struct fib_info *fi)
				   struct fib_info *fi)
{
	return fi->fib_nh->fib_nh_scope == RT_SCOPE_LINK ||
	       mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, fi->fib_nh, NULL);
	const struct fib_nh *nh = fib_info_nh(fi, 0);

	return nh->fib_nh_scope == RT_SCOPE_LINK ||
	       mlxsw_sp_nexthop4_ipip_type(mlxsw_sp, nh, NULL);
}

static struct mlxsw_sp_nexthop_group *
mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
{
	unsigned int nhs = fib_info_num_path(fi);
	struct mlxsw_sp_nexthop_group *nh_grp;
	struct mlxsw_sp_nexthop *nh;
	struct fib_nh *fib_nh;
	int i;
	int err;

	nh_grp = kzalloc(struct_size(nh_grp, nexthops, fi->fib_nhs),
			 GFP_KERNEL);
	nh_grp = kzalloc(struct_size(nh_grp, nexthops, nhs), GFP_KERNEL);
	if (!nh_grp)
		return ERR_PTR(-ENOMEM);
	nh_grp->priv = fi;
@@ -3840,11 +3843,11 @@ mlxsw_sp_nexthop4_group_create(struct mlxsw_sp *mlxsw_sp, struct fib_info *fi)
	nh_grp->neigh_tbl = &arp_tbl;

	nh_grp->gateway = mlxsw_sp_fi_is_gateway(mlxsw_sp, fi);
	nh_grp->count = fi->fib_nhs;
	nh_grp->count = nhs;
	fib_info_hold(fi);
	for (i = 0; i < nh_grp->count; i++) {
		nh = &nh_grp->nexthops[i];
		fib_nh = &fi->fib_nh[i];
		fib_nh = fib_info_nh(fi, i);
		err = mlxsw_sp_nexthop4_init(mlxsw_sp, nh_grp, nh, fib_nh);
		if (err)
			goto err_nexthop4_init;
@@ -4282,9 +4285,9 @@ mlxsw_sp_fib4_entry_type_set(struct mlxsw_sp *mlxsw_sp,
			     const struct fib_entry_notifier_info *fen_info,
			     struct mlxsw_sp_fib_entry *fib_entry)
{
	struct net_device *dev = fib_info_nh(fen_info->fi, 0)->fib_nh_dev;
	union mlxsw_sp_l3addr dip = { .addr4 = htonl(fen_info->dst) };
	u32 tb_id = mlxsw_sp_fix_tb_id(fen_info->tb_id);
	struct net_device *dev = fen_info->fi->fib_dev;
	struct mlxsw_sp_ipip_entry *ipip_entry;
	struct fib_info *fi = fen_info->fi;

+16 −9
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@
#include <net/neighbour.h>
#include <net/switchdev.h>
#include <net/ip_fib.h>
#include <net/nexthop.h>
#include <net/arp.h>

#include "rocker.h"
@@ -2286,8 +2287,8 @@ static int ofdpa_port_fib_ipv4(struct ofdpa_port *ofdpa_port, __be32 dst,

	/* XXX support ECMP */

	nh = fi->fib_nh;
	nh_on_port = (fi->fib_dev == ofdpa_port->dev);
	nh = fib_info_nh(fi, 0);
	nh_on_port = (nh->fib_nh_dev == ofdpa_port->dev);
	has_gw = !!nh->fib_nh_gw4;

	if (has_gw && nh_on_port) {
@@ -2737,11 +2738,13 @@ static int ofdpa_fib4_add(struct rocker *rocker,
{
	struct ofdpa *ofdpa = rocker->wpriv;
	struct ofdpa_port *ofdpa_port;
	struct fib_nh *nh;
	int err;

	if (ofdpa->fib_aborted)
		return 0;
	ofdpa_port = ofdpa_port_dev_lower_find(fen_info->fi->fib_dev, rocker);
	nh = fib_info_nh(fen_info->fi, 0);
	ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker);
	if (!ofdpa_port)
		return 0;
	err = ofdpa_port_fib_ipv4(ofdpa_port, htonl(fen_info->dst),
@@ -2749,7 +2752,7 @@ static int ofdpa_fib4_add(struct rocker *rocker,
				  fen_info->tb_id, 0);
	if (err)
		return err;
	fen_info->fi->fib_nh->fib_nh_flags |= RTNH_F_OFFLOAD;
	nh->fib_nh_flags |= RTNH_F_OFFLOAD;
	return 0;
}

@@ -2758,13 +2761,15 @@ static int ofdpa_fib4_del(struct rocker *rocker,
{
	struct ofdpa *ofdpa = rocker->wpriv;
	struct ofdpa_port *ofdpa_port;
	struct fib_nh *nh;

	if (ofdpa->fib_aborted)
		return 0;
	ofdpa_port = ofdpa_port_dev_lower_find(fen_info->fi->fib_dev, rocker);
	nh = fib_info_nh(fen_info->fi, 0);
	ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker);
	if (!ofdpa_port)
		return 0;
	fen_info->fi->fib_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
	nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
	return ofdpa_port_fib_ipv4(ofdpa_port, htonl(fen_info->dst),
				   fen_info->dst_len, fen_info->fi,
				   fen_info->tb_id, OFDPA_OP_FLAG_REMOVE);
@@ -2784,14 +2789,16 @@ static void ofdpa_fib4_abort(struct rocker *rocker)

	spin_lock_irqsave(&ofdpa->flow_tbl_lock, flags);
	hash_for_each_safe(ofdpa->flow_tbl, bkt, tmp, flow_entry, entry) {
		struct fib_nh *nh;

		if (flow_entry->key.tbl_id !=
		    ROCKER_OF_DPA_TABLE_ID_UNICAST_ROUTING)
			continue;
		ofdpa_port = ofdpa_port_dev_lower_find(flow_entry->fi->fib_dev,
						       rocker);
		nh = fib_info_nh(flow_entry->fi, 0);
		ofdpa_port = ofdpa_port_dev_lower_find(nh->fib_nh_dev, rocker);
		if (!ofdpa_port)
			continue;
		flow_entry->fi->fib_nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
		nh->fib_nh_flags &= ~RTNH_F_OFFLOAD;
		ofdpa_flow_tbl_del(ofdpa_port, OFDPA_OP_FLAG_REMOVE,
				   flow_entry);
	}
+0 −6
Original line number Diff line number Diff line
@@ -153,7 +153,6 @@ struct fib_info {
	bool			nh_updated;
	struct rcu_head		rcu;
	struct fib_nh		fib_nh[0];
#define fib_dev		fib_nh[0].fib_nh_dev
};


@@ -190,11 +189,6 @@ struct fib_result_nl {
	int             err;
};

static inline struct fib_nh_common *fib_info_nhc(struct fib_info *fi, int nhsel)
{
	return &fi->fib_nh[nhsel].nh_common;
}

#ifdef CONFIG_IP_MULTIPLE_TABLES
#define FIB_TABLE_HASHSZ 256
#else
+15 −0
Original line number Diff line number Diff line
@@ -192,4 +192,19 @@ static inline bool nexthop_is_blackhole(const struct nexthop *nh)
	nhi = rcu_dereference_rtnl(nh->nh_info);
	return nhi->reject_nh;
}

static inline unsigned int fib_info_num_path(const struct fib_info *fi)
{
	return fi->fib_nhs;
}

static inline struct fib_nh_common *fib_info_nhc(struct fib_info *fi, int nhsel)
{
	return &fi->fib_nh[nhsel].nh_common;
}

static inline struct fib_nh *fib_info_nh(struct fib_info *fi, int nhsel)
{
	return &fi->fib_nh[nhsel];
}
#endif
Loading