Skip to content

Commit

Permalink
ipv4: Use accessors for fib_info nexthop data
Browse files Browse the repository at this point in the history
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: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
dsahern authored and davem330 committed Jun 5, 2019
1 parent 7dd7316 commit 5481d73
Show file tree
Hide file tree
Showing 12 changed files with 132 additions and 80 deletions.
29 changes: 19 additions & 10 deletions drivers/net/ethernet/mellanox/mlx5/core/lag_mp.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand All @@ -120,24 +123,28 @@ 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);
}
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;
}
Expand Down Expand Up @@ -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);
}
}
Expand Down Expand Up @@ -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)
Expand All @@ -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);
Expand Down
19 changes: 11 additions & 8 deletions drivers/net/ethernet/mellanox/mlxsw/spectrum_router.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down Expand Up @@ -3816,35 +3817,37 @@ 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;
INIT_LIST_HEAD(&nh_grp->fib_list);
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;
Expand Down Expand Up @@ -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;

Expand Down
25 changes: 16 additions & 9 deletions drivers/net/ethernet/rocker/rocker_ofdpa.c
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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) {
Expand Down Expand Up @@ -2737,19 +2738,21 @@ 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),
fen_info->dst_len, fen_info->fi,
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;
}

Expand All @@ -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);
Expand All @@ -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);
}
Expand Down
6 changes: 0 additions & 6 deletions include/net/ip_fib.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
};


Expand Down Expand Up @@ -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
Expand Down
15 changes: 15 additions & 0 deletions include/net/nexthop.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
3 changes: 2 additions & 1 deletion net/core/filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
#include <net/inet_hashtables.h>
#include <net/inet6_hashtables.h>
#include <net/ip_fib.h>
#include <net/nexthop.h>
#include <net/flow.h>
#include <net/arp.h>
#include <net/ipv6.h>
Expand Down Expand Up @@ -4674,7 +4675,7 @@ static int bpf_ipv4_fib_lookup(struct net *net, struct bpf_fib_lookup *params,
if (res.type != RTN_UNICAST)
return BPF_FIB_LKUP_RET_NOT_FWDED;

if (res.fi->fib_nhs > 1)
if (fib_info_num_path(res.fi) > 1)
fib_select_path(net, &res, &fl4, NULL);

if (check_mtu) {
Expand Down
11 changes: 7 additions & 4 deletions net/ipv4/fib_frontend.c
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@
#include <net/sock.h>
#include <net/arp.h>
#include <net/ip_fib.h>
#include <net/nexthop.h>
#include <net/rtnetlink.h>
#include <net/xfrm.h>
#include <net/l3mdev.h>
Expand Down Expand Up @@ -234,7 +235,9 @@ static inline unsigned int __inet_dev_addr_type(struct net *net,
if (table) {
ret = RTN_UNICAST;
if (!fib_table_lookup(table, &fl4, &res, FIB_LOOKUP_NOREF)) {
if (!dev || dev == res.fi->fib_dev)
struct fib_nh *nh = fib_info_nh(res.fi, 0);

if (!dev || dev == nh->fib_nh_dev)
ret = res.type;
}
}
Expand Down Expand Up @@ -321,8 +324,8 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
#ifdef CONFIG_IP_ROUTE_MULTIPATH
int ret;

for (ret = 0; ret < fi->fib_nhs; ret++) {
struct fib_nh *nh = &fi->fib_nh[ret];
for (ret = 0; ret < fib_info_num_path(fi); ret++) {
const struct fib_nh *nh = fib_info_nh(fi, ret);

if (nh->fib_nh_dev == dev) {
dev_match = true;
Expand All @@ -333,7 +336,7 @@ bool fib_info_nh_uses_dev(struct fib_info *fi, const struct net_device *dev)
}
}
#else
if (fi->fib_nh[0].fib_nh_dev == dev)
if (fib_info_nh(fi, 0)->fib_nh_dev == dev)
dev_match = true;
#endif

Expand Down
1 change: 1 addition & 0 deletions net/ipv4/fib_lookup.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <linux/types.h>
#include <linux/list.h>
#include <net/ip_fib.h>
#include <net/nexthop.h>

struct fib_alias {
struct hlist_node fa_list;
Expand Down
8 changes: 6 additions & 2 deletions net/ipv4/fib_rules.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include <net/route.h>
#include <net/tcp.h>
#include <net/ip_fib.h>
#include <net/nexthop.h>
#include <net/fib_rules.h>

struct fib4_rule {
Expand Down Expand Up @@ -145,8 +146,11 @@ static bool fib4_rule_suppress(struct fib_rule *rule, struct fib_lookup_arg *arg
struct fib_result *result = (struct fib_result *) arg->result;
struct net_device *dev = NULL;

if (result->fi)
dev = result->fi->fib_dev;
if (result->fi) {
struct fib_nh *nh = fib_info_nh(result->fi, 0);

dev = nh->fib_nh_dev;
}

/* do not accept result if the route does
* not meet the required prefix length
Expand Down
Loading

0 comments on commit 5481d73

Please sign in to comment.