Skip to content

Commit

Permalink
net: common metrics init helper for FIB entries
Browse files Browse the repository at this point in the history
Consolidate initialization of ipv4 and ipv6 metrics when fib entries
are created into a single helper, ip_fib_metrics_init, that handles
the call to ip_metrics_convert.

If no metrics are defined for the fib entry, then the metrics is set
to dst_default_metrics.

Signed-off-by: David Ahern <dsahern@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
  • Loading branch information
David Ahern authored and David S. Miller committed Oct 5, 2018
1 parent d26d4b1 commit 767a221
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 49 deletions.
4 changes: 2 additions & 2 deletions include/net/ip.h
Original file line number Diff line number Diff line change
Expand Up @@ -420,8 +420,8 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk,
return min(READ_ONCE(skb_dst(skb)->dev->mtu), IP_MAX_MTU);
}

int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,
u32 *metrics);
struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx,
int fc_mx_len);

u32 ip_idents_reserve(u32 hash, int segs);
void __ip_select_ident(struct net *net, struct iphdr *iph, int segs);
Expand Down
27 changes: 7 additions & 20 deletions net/ipv4/fib_semantics.c
Original file line number Diff line number Diff line change
Expand Up @@ -1020,13 +1020,6 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
return true;
}

static int
fib_convert_metrics(struct fib_info *fi, const struct fib_config *cfg)
{
return ip_metrics_convert(fi->fib_net, cfg->fc_mx, cfg->fc_mx_len,
fi->fib_metrics->metrics);
}

struct fib_info *fib_create_info(struct fib_config *cfg,
struct netlink_ext_ack *extack)
{
Expand Down Expand Up @@ -1084,16 +1077,14 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
if (!fi)
goto failure;
if (cfg->fc_mx) {
fi->fib_metrics = kzalloc(sizeof(*fi->fib_metrics), GFP_KERNEL);
if (unlikely(!fi->fib_metrics)) {
kfree(fi);
return ERR_PTR(err);
}
refcount_set(&fi->fib_metrics->refcnt, 1);
} else {
fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics;
fi->fib_metrics = ip_fib_metrics_init(fi->fib_net, cfg->fc_mx,
cfg->fc_mx_len);
if (unlikely(IS_ERR(fi->fib_metrics))) {
err = PTR_ERR(fi->fib_metrics);
kfree(fi);
return ERR_PTR(err);
}

fib_info_cnt++;
fi->fib_net = net;
fi->fib_protocol = cfg->fc_protocol;
Expand All @@ -1112,10 +1103,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
goto failure;
} endfor_nexthops(fi)

err = fib_convert_metrics(fi, cfg);
if (err)
goto failure;

if (cfg->fc_mp) {
#ifdef CONFIG_IP_ROUTE_MULTIPATH
err = fib_get_nhs(fi, cfg->fc_mp, cfg->fc_mp_len, cfg, extack);
Expand Down
30 changes: 27 additions & 3 deletions net/ipv4/metrics.c
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
#include <net/net_namespace.h>
#include <net/tcp.h>

int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,
u32 *metrics)
static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx,
int fc_mx_len, u32 *metrics)
{
bool ecn_ca = false;
struct nlattr *nla;
Expand Down Expand Up @@ -52,4 +52,28 @@ int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,

return 0;
}
EXPORT_SYMBOL_GPL(ip_metrics_convert);

struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx,
int fc_mx_len)
{
struct dst_metrics *fib_metrics;
int err;

if (!fc_mx)
return (struct dst_metrics *)&dst_default_metrics;

fib_metrics = kzalloc(sizeof(*fib_metrics), GFP_KERNEL);
if (unlikely(!fib_metrics))
return ERR_PTR(-ENOMEM);

err = ip_metrics_convert(net, fc_mx, fc_mx_len, fib_metrics->metrics);
if (!err) {
refcount_set(&fib_metrics->refcnt, 1);
} else {
kfree(fib_metrics);
fib_metrics = ERR_PTR(err);
}

return fib_metrics;
}
EXPORT_SYMBOL_GPL(ip_fib_metrics_init);
2 changes: 0 additions & 2 deletions net/ipv6/ip6_fib.c
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,6 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags)
}

INIT_LIST_HEAD(&f6i->fib6_siblings);
f6i->fib6_metrics = (struct dst_metrics *)&dst_default_metrics;

atomic_inc(&f6i->fib6_ref);

return f6i;
Expand Down
29 changes: 7 additions & 22 deletions net/ipv6/route.c
Original file line number Diff line number Diff line change
Expand Up @@ -2705,24 +2705,6 @@ static int ip6_dst_gc(struct dst_ops *ops)
return entries > rt_max_size;
}

static int ip6_convert_metrics(struct net *net, struct fib6_info *rt,
struct fib6_config *cfg)
{
struct dst_metrics *p;

if (!cfg->fc_mx)
return 0;

p = kzalloc(sizeof(*rt->fib6_metrics), GFP_KERNEL);
if (unlikely(!p))
return -ENOMEM;

refcount_set(&p->refcnt, 1);
rt->fib6_metrics = p;

return ip_metrics_convert(net, cfg->fc_mx, cfg->fc_mx_len, p->metrics);
}

static struct rt6_info *ip6_nh_lookup_table(struct net *net,
struct fib6_config *cfg,
const struct in6_addr *gw_addr,
Expand Down Expand Up @@ -2998,13 +2980,15 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
if (!rt)
goto out;

rt->fib6_metrics = ip_fib_metrics_init(net, cfg->fc_mx, cfg->fc_mx_len);
if (IS_ERR(rt->fib6_metrics)) {
err = PTR_ERR(rt->fib6_metrics);
goto out;
}

if (cfg->fc_flags & RTF_ADDRCONF)
rt->dst_nocount = true;

err = ip6_convert_metrics(net, rt, cfg);
if (err < 0)
goto out;

if (cfg->fc_flags & RTF_EXPIRES)
fib6_set_expires(rt, jiffies +
clock_t_to_jiffies(cfg->fc_expires));
Expand Down Expand Up @@ -3727,6 +3711,7 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net,
if (!f6i)
return ERR_PTR(-ENOMEM);

f6i->fib6_metrics = ip_fib_metrics_init(net, NULL, 0);
f6i->dst_nocount = true;
f6i->dst_host = true;
f6i->fib6_protocol = RTPROT_KERNEL;
Expand Down

0 comments on commit 767a221

Please sign in to comment.