mirror of
https://github.com/edk2-porting/linux-next.git
synced 2024-12-17 17:53:56 +08:00
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: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
parent
d26d4b194e
commit
767a221753
@ -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)
|
|||||||
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,
|
|||||||
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))) {
|
||||||
|
err = PTR_ERR(fi->fib_metrics);
|
||||||
kfree(fi);
|
kfree(fi);
|
||||||
return ERR_PTR(err);
|
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,
|
|||||||
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 @@
|
|||||||
#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,
|
|||||||
|
|
||||||
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)
|
|||||||
}
|
}
|
||||||
|
|
||||||
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 @@ out:
|
|||||||
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,
|
|||||||
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,
|
|||||||
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;
|
||||||
|
Loading…
Reference in New Issue
Block a user