mirror of
https://github.com/ukui/kernel.git
synced 2026-03-09 10:07:04 -07:00
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
@@ -94,11 +94,6 @@ struct fib6_gc_args {
|
||||
#define FIB6_SUBTREE(fn) (rcu_dereference_protected((fn)->subtree, 1))
|
||||
#endif
|
||||
|
||||
struct mx6_config {
|
||||
const u32 *mx;
|
||||
DECLARE_BITMAP(mx_valid, RTAX_MAX);
|
||||
};
|
||||
|
||||
/*
|
||||
* routing information
|
||||
*
|
||||
@@ -176,7 +171,6 @@ struct rt6_info {
|
||||
struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
|
||||
|
||||
u32 rt6i_metric;
|
||||
u32 rt6i_pmtu;
|
||||
/* more non-fragment space at head required */
|
||||
unsigned short rt6i_nfheader_len;
|
||||
u8 rt6i_protocol;
|
||||
@@ -185,6 +179,8 @@ struct rt6_info {
|
||||
should_flush:1,
|
||||
unused:6;
|
||||
|
||||
struct dst_metrics *fib6_metrics;
|
||||
#define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1]
|
||||
struct fib6_nh fib6_nh;
|
||||
};
|
||||
|
||||
@@ -390,8 +386,7 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
|
||||
void *arg);
|
||||
|
||||
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);
|
||||
int fib6_del(struct rt6_info *rt, struct nl_info *info);
|
||||
|
||||
void inet6_rt_notify(int event, struct rt6_info *rt, struct nl_info *info,
|
||||
@@ -420,6 +415,12 @@ int fib6_tables_dump(struct net *net, struct notifier_block *nb);
|
||||
void fib6_update_sernum(struct net *net, struct rt6_info *rt);
|
||||
void fib6_update_sernum_upto_root(struct net *net, struct rt6_info *rt);
|
||||
|
||||
void fib6_metric_set(struct rt6_info *f6i, int metric, u32 val);
|
||||
static inline bool fib6_metric_locked(struct rt6_info *f6i, int metric)
|
||||
{
|
||||
return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric));
|
||||
}
|
||||
|
||||
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
|
||||
int fib6_rules_init(void);
|
||||
void fib6_rules_cleanup(void);
|
||||
|
||||
@@ -58,6 +58,7 @@ const struct dst_metrics dst_default_metrics = {
|
||||
*/
|
||||
.refcnt = REFCOUNT_INIT(1),
|
||||
};
|
||||
EXPORT_SYMBOL(dst_default_metrics);
|
||||
|
||||
void dst_init(struct dst_entry *dst, struct dst_ops *ops,
|
||||
struct net_device *dev, int initial_ref, int initial_obsolete,
|
||||
|
||||
+22
-44
@@ -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);
|
||||
|
||||
+3
-7
@@ -1323,9 +1323,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
|
||||
ra_msg->icmph.icmp6_hop_limit) {
|
||||
if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
|
||||
in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
|
||||
if (rt)
|
||||
dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
|
||||
ra_msg->icmph.icmp6_hop_limit);
|
||||
fib6_metric_set(rt, RTAX_HOPLIMIT,
|
||||
ra_msg->icmph.icmp6_hop_limit);
|
||||
} else {
|
||||
ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n");
|
||||
}
|
||||
@@ -1477,10 +1476,7 @@ skip_routeinfo:
|
||||
ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
|
||||
} else if (in6_dev->cnf.mtu6 != mtu) {
|
||||
in6_dev->cnf.mtu6 = mtu;
|
||||
|
||||
if (rt)
|
||||
dst_metric_set(&rt->dst, RTAX_MTU, mtu);
|
||||
|
||||
fib6_metric_set(rt, RTAX_MTU, mtu);
|
||||
rt6_mtu_change(skb->dev, mtu);
|
||||
}
|
||||
}
|
||||
|
||||
+98
-159
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user