net/ipv6: move metrics from dst to rt6_info
Similar to IPv4, add fib metrics to the fib struct, which at the moment is rt6_info. Will be moved to fib6_info in a later patch. Copy metrics into dst by reference using refcount. To make the transition: - add dst_metrics to rt6_info. Default to dst_default_metrics if no metrics are passed during route add. No need for a separate pmtu entry; it can reference the MTU slot in fib6_metrics - ip6_convert_metrics allocates memory in the FIB entry and uses ip_metrics_convert to copy from netlink attribute to metrics entry - the convert metrics call is done in ip6_route_info_create simplifying the route add path + fib6_commit_metrics and fib6_copy_metrics and the temporary mx6_config are no longer needed - add fib6_metric_set helper to change the value of a metric in the fib entry since dst_metric_set can no longer be used - cow_metrics for IPv6 can drop to dst_cow_metrics_generic - rt6_dst_from_metrics_check is no longer needed - rt6_fill_node needs the FIB entry and dst as separate arguments to keep compatibility with existing output. Current dst address is renamed to dest. (to be consistent with IPv4 rt6_fill_node really should be split into 2 functions similar to fib_dump_info and rt_fill_info) - rt6_fill_node no longer needs the temporary metrics variable Signed-off-by: David Ahern <dsahern@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:

committed by
David S. Miller

parent
6edb3c96a5
commit
d4ead6b34b
@@ -578,6 +578,24 @@ out:
|
||||
return res;
|
||||
}
|
||||
|
||||
void fib6_metric_set(struct rt6_info *f6i, int metric, u32 val)
|
||||
{
|
||||
if (!f6i)
|
||||
return;
|
||||
|
||||
if (f6i->fib6_metrics == &dst_default_metrics) {
|
||||
struct dst_metrics *p = kzalloc(sizeof(*p), GFP_ATOMIC);
|
||||
|
||||
if (!p)
|
||||
return;
|
||||
|
||||
refcount_set(&p->refcnt, 1);
|
||||
f6i->fib6_metrics = p;
|
||||
}
|
||||
|
||||
f6i->fib6_metrics->metrics[metric - 1] = val;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routing Table
|
||||
*
|
||||
@@ -801,38 +819,6 @@ insert_above:
|
||||
return ln;
|
||||
}
|
||||
|
||||
static void fib6_copy_metrics(u32 *mp, const struct mx6_config *mxc)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < RTAX_MAX; i++) {
|
||||
if (test_bit(i, mxc->mx_valid))
|
||||
mp[i] = mxc->mx[i];
|
||||
}
|
||||
}
|
||||
|
||||
static int fib6_commit_metrics(struct dst_entry *dst, struct mx6_config *mxc)
|
||||
{
|
||||
if (!mxc->mx)
|
||||
return 0;
|
||||
|
||||
if (dst->flags & DST_HOST) {
|
||||
u32 *mp = dst_metrics_write_ptr(dst);
|
||||
|
||||
if (unlikely(!mp))
|
||||
return -ENOMEM;
|
||||
|
||||
fib6_copy_metrics(mp, mxc);
|
||||
} else {
|
||||
dst_init_metrics(dst, mxc->mx, false);
|
||||
|
||||
/* We've stolen mx now. */
|
||||
mxc->mx = NULL;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn,
|
||||
struct net *net)
|
||||
{
|
||||
@@ -866,7 +852,7 @@ static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn,
|
||||
*/
|
||||
|
||||
static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||
struct nl_info *info, struct mx6_config *mxc,
|
||||
struct nl_info *info,
|
||||
struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct rt6_info *leaf = rcu_dereference_protected(fn->leaf,
|
||||
@@ -923,7 +909,7 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
|
||||
rt6_clean_expires(iter);
|
||||
else
|
||||
rt6_set_expires(iter, rt->dst.expires);
|
||||
iter->rt6i_pmtu = rt->rt6i_pmtu;
|
||||
fib6_metric_set(iter, RTAX_MTU, rt->fib6_pmtu);
|
||||
return -EEXIST;
|
||||
}
|
||||
/* If we have the same destination and the same metric,
|
||||
@@ -1002,9 +988,6 @@ next_iter:
|
||||
|
||||
add:
|
||||
nlflags |= NLM_F_CREATE;
|
||||
err = fib6_commit_metrics(&rt->dst, mxc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = call_fib6_entry_notifiers(info->nl_net,
|
||||
FIB_EVENT_ENTRY_ADD,
|
||||
@@ -1035,10 +1018,6 @@ add:
|
||||
return -ENOENT;
|
||||
}
|
||||
|
||||
err = fib6_commit_metrics(&rt->dst, mxc);
|
||||
if (err)
|
||||
return err;
|
||||
|
||||
err = call_fib6_entry_notifiers(info->nl_net,
|
||||
FIB_EVENT_ENTRY_REPLACE,
|
||||
rt, extack);
|
||||
@@ -1135,8 +1114,7 @@ void fib6_update_sernum_upto_root(struct net *net, struct rt6_info *rt)
|
||||
*/
|
||||
|
||||
int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
struct nl_info *info, struct mx6_config *mxc,
|
||||
struct netlink_ext_ack *extack)
|
||||
struct nl_info *info, struct netlink_ext_ack *extack)
|
||||
{
|
||||
struct fib6_table *table = rt->rt6i_table;
|
||||
struct fib6_node *fn, *pn = NULL;
|
||||
@@ -1244,7 +1222,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
|
||||
}
|
||||
#endif
|
||||
|
||||
err = fib6_add_rt2node(fn, rt, info, mxc, extack);
|
||||
err = fib6_add_rt2node(fn, rt, info, extack);
|
||||
if (!err) {
|
||||
__fib6_update_sernum_upto_root(rt, sernum);
|
||||
fib6_start_gc(info->nl_net, rt);
|
||||
|
Reference in New Issue
Block a user