Commit 767a2217 authored by David Ahern's avatar David Ahern Committed by David S. Miller

net: common metrics init helper for FIB entries

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: default avatarDavid Ahern <dsahern@gmail.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d26d4b19
...@@ -420,8 +420,8 @@ static inline unsigned int ip_skb_dst_mtu(struct sock *sk, ...@@ -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); 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, struct dst_metrics *ip_fib_metrics_init(struct net *net, struct nlattr *fc_mx,
u32 *metrics); int fc_mx_len);
u32 ip_idents_reserve(u32 hash, int segs); u32 ip_idents_reserve(u32 hash, int segs);
void __ip_select_ident(struct net *net, struct iphdr *iph, int segs); void __ip_select_ident(struct net *net, struct iphdr *iph, int segs);
......
...@@ -1020,13 +1020,6 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc) ...@@ -1020,13 +1020,6 @@ static bool fib_valid_prefsrc(struct fib_config *cfg, __be32 fib_prefsrc)
return true; 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 fib_info *fib_create_info(struct fib_config *cfg,
struct netlink_ext_ack *extack) struct netlink_ext_ack *extack)
{ {
...@@ -1084,16 +1077,14 @@ struct fib_info *fib_create_info(struct fib_config *cfg, ...@@ -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); fi = kzalloc(sizeof(*fi)+nhs*sizeof(struct fib_nh), GFP_KERNEL);
if (!fi) if (!fi)
goto failure; goto failure;
if (cfg->fc_mx) { fi->fib_metrics = ip_fib_metrics_init(fi->fib_net, cfg->fc_mx,
fi->fib_metrics = kzalloc(sizeof(*fi->fib_metrics), GFP_KERNEL); cfg->fc_mx_len);
if (unlikely(!fi->fib_metrics)) { if (unlikely(IS_ERR(fi->fib_metrics))) {
kfree(fi); err = PTR_ERR(fi->fib_metrics);
return ERR_PTR(err); kfree(fi);
} return ERR_PTR(err);
refcount_set(&fi->fib_metrics->refcnt, 1);
} else {
fi->fib_metrics = (struct dst_metrics *)&dst_default_metrics;
} }
fib_info_cnt++; fib_info_cnt++;
fi->fib_net = net; fi->fib_net = net;
fi->fib_protocol = cfg->fc_protocol; fi->fib_protocol = cfg->fc_protocol;
...@@ -1112,10 +1103,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg, ...@@ -1112,10 +1103,6 @@ struct fib_info *fib_create_info(struct fib_config *cfg,
goto failure; goto failure;
} endfor_nexthops(fi) } endfor_nexthops(fi)
err = fib_convert_metrics(fi, cfg);
if (err)
goto failure;
if (cfg->fc_mp) { if (cfg->fc_mp) {
#ifdef CONFIG_IP_ROUTE_MULTIPATH #ifdef CONFIG_IP_ROUTE_MULTIPATH
err = fib_get_nhs(fi, cfg->fc_mp, cfg->fc_mp_len, cfg, extack); err = fib_get_nhs(fi, cfg->fc_mp, cfg->fc_mp_len, cfg, extack);
......
...@@ -5,8 +5,8 @@ ...@@ -5,8 +5,8 @@
#include <net/net_namespace.h> #include <net/net_namespace.h>
#include <net/tcp.h> #include <net/tcp.h>
int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len, static int ip_metrics_convert(struct net *net, struct nlattr *fc_mx,
u32 *metrics) int fc_mx_len, u32 *metrics)
{ {
bool ecn_ca = false; bool ecn_ca = false;
struct nlattr *nla; struct nlattr *nla;
...@@ -52,4 +52,28 @@ int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len, ...@@ -52,4 +52,28 @@ int ip_metrics_convert(struct net *net, struct nlattr *fc_mx, int fc_mx_len,
return 0; 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);
...@@ -160,8 +160,6 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags) ...@@ -160,8 +160,6 @@ struct fib6_info *fib6_info_alloc(gfp_t gfp_flags)
} }
INIT_LIST_HEAD(&f6i->fib6_siblings); INIT_LIST_HEAD(&f6i->fib6_siblings);
f6i->fib6_metrics = (struct dst_metrics *)&dst_default_metrics;
atomic_inc(&f6i->fib6_ref); atomic_inc(&f6i->fib6_ref);
return f6i; return f6i;
......
...@@ -2705,24 +2705,6 @@ static int ip6_dst_gc(struct dst_ops *ops) ...@@ -2705,24 +2705,6 @@ static int ip6_dst_gc(struct dst_ops *ops)
return entries > rt_max_size; 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, static struct rt6_info *ip6_nh_lookup_table(struct net *net,
struct fib6_config *cfg, struct fib6_config *cfg,
const struct in6_addr *gw_addr, const struct in6_addr *gw_addr,
...@@ -2998,13 +2980,15 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg, ...@@ -2998,13 +2980,15 @@ static struct fib6_info *ip6_route_info_create(struct fib6_config *cfg,
if (!rt) if (!rt)
goto out; 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) if (cfg->fc_flags & RTF_ADDRCONF)
rt->dst_nocount = true; rt->dst_nocount = true;
err = ip6_convert_metrics(net, rt, cfg);
if (err < 0)
goto out;
if (cfg->fc_flags & RTF_EXPIRES) if (cfg->fc_flags & RTF_EXPIRES)
fib6_set_expires(rt, jiffies + fib6_set_expires(rt, jiffies +
clock_t_to_jiffies(cfg->fc_expires)); clock_t_to_jiffies(cfg->fc_expires));
...@@ -3727,6 +3711,7 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net, ...@@ -3727,6 +3711,7 @@ struct fib6_info *addrconf_f6i_alloc(struct net *net,
if (!f6i) if (!f6i)
return ERR_PTR(-ENOMEM); return ERR_PTR(-ENOMEM);
f6i->fib6_metrics = ip_fib_metrics_init(net, NULL, 0);
f6i->dst_nocount = true; f6i->dst_nocount = true;
f6i->dst_host = true; f6i->dst_host = true;
f6i->fib6_protocol = RTPROT_KERNEL; f6i->fib6_protocol = RTPROT_KERNEL;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment