Skip to content

Commit d4ead6b

Browse files
dsaherndavem330
authored andcommitted
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>
1 parent 6edb3c9 commit d4ead6b

File tree

5 files changed

+133
-218
lines changed

5 files changed

+133
-218
lines changed

include/net/ip6_fib.h

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -94,11 +94,6 @@ struct fib6_gc_args {
9494
#define FIB6_SUBTREE(fn) (rcu_dereference_protected((fn)->subtree, 1))
9595
#endif
9696

97-
struct mx6_config {
98-
const u32 *mx;
99-
DECLARE_BITMAP(mx_valid, RTAX_MAX);
100-
};
101-
10297
/*
10398
* routing information
10499
*
@@ -176,7 +171,6 @@ struct rt6_info {
176171
struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
177172

178173
u32 rt6i_metric;
179-
u32 rt6i_pmtu;
180174
/* more non-fragment space at head required */
181175
unsigned short rt6i_nfheader_len;
182176
u8 rt6i_protocol;
@@ -185,6 +179,8 @@ struct rt6_info {
185179
should_flush:1,
186180
unused:6;
187181

182+
struct dst_metrics *fib6_metrics;
183+
#define fib6_pmtu fib6_metrics->metrics[RTAX_MTU-1]
188184
struct fib6_nh fib6_nh;
189185
};
190186

@@ -390,8 +386,7 @@ void fib6_clean_all(struct net *net, int (*func)(struct rt6_info *, void *arg),
390386
void *arg);
391387

392388
int fib6_add(struct fib6_node *root, struct rt6_info *rt,
393-
struct nl_info *info, struct mx6_config *mxc,
394-
struct netlink_ext_ack *extack);
389+
struct nl_info *info, struct netlink_ext_ack *extack);
395390
int fib6_del(struct rt6_info *rt, struct nl_info *info);
396391

397392
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);
420415
void fib6_update_sernum(struct net *net, struct rt6_info *rt);
421416
void fib6_update_sernum_upto_root(struct net *net, struct rt6_info *rt);
422417

418+
void fib6_metric_set(struct rt6_info *f6i, int metric, u32 val);
419+
static inline bool fib6_metric_locked(struct rt6_info *f6i, int metric)
420+
{
421+
return !!(f6i->fib6_metrics->metrics[RTAX_LOCK - 1] & (1 << metric));
422+
}
423+
423424
#ifdef CONFIG_IPV6_MULTIPLE_TABLES
424425
int fib6_rules_init(void);
425426
void fib6_rules_cleanup(void);

net/core/dst.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ const struct dst_metrics dst_default_metrics = {
5858
*/
5959
.refcnt = REFCOUNT_INIT(1),
6060
};
61+
EXPORT_SYMBOL(dst_default_metrics);
6162

6263
void dst_init(struct dst_entry *dst, struct dst_ops *ops,
6364
struct net_device *dev, int initial_ref, int initial_obsolete,

net/ipv6/ip6_fib.c

Lines changed: 22 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -578,6 +578,24 @@ static int inet6_dump_fib(struct sk_buff *skb, struct netlink_callback *cb)
578578
return res;
579579
}
580580

581+
void fib6_metric_set(struct rt6_info *f6i, int metric, u32 val)
582+
{
583+
if (!f6i)
584+
return;
585+
586+
if (f6i->fib6_metrics == &dst_default_metrics) {
587+
struct dst_metrics *p = kzalloc(sizeof(*p), GFP_ATOMIC);
588+
589+
if (!p)
590+
return;
591+
592+
refcount_set(&p->refcnt, 1);
593+
f6i->fib6_metrics = p;
594+
}
595+
596+
f6i->fib6_metrics->metrics[metric - 1] = val;
597+
}
598+
581599
/*
582600
* Routing Table
583601
*
@@ -801,38 +819,6 @@ static struct fib6_node *fib6_add_1(struct net *net,
801819
return ln;
802820
}
803821

804-
static void fib6_copy_metrics(u32 *mp, const struct mx6_config *mxc)
805-
{
806-
int i;
807-
808-
for (i = 0; i < RTAX_MAX; i++) {
809-
if (test_bit(i, mxc->mx_valid))
810-
mp[i] = mxc->mx[i];
811-
}
812-
}
813-
814-
static int fib6_commit_metrics(struct dst_entry *dst, struct mx6_config *mxc)
815-
{
816-
if (!mxc->mx)
817-
return 0;
818-
819-
if (dst->flags & DST_HOST) {
820-
u32 *mp = dst_metrics_write_ptr(dst);
821-
822-
if (unlikely(!mp))
823-
return -ENOMEM;
824-
825-
fib6_copy_metrics(mp, mxc);
826-
} else {
827-
dst_init_metrics(dst, mxc->mx, false);
828-
829-
/* We've stolen mx now. */
830-
mxc->mx = NULL;
831-
}
832-
833-
return 0;
834-
}
835-
836822
static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn,
837823
struct net *net)
838824
{
@@ -866,7 +852,7 @@ static void fib6_purge_rt(struct rt6_info *rt, struct fib6_node *fn,
866852
*/
867853

868854
static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
869-
struct nl_info *info, struct mx6_config *mxc,
855+
struct nl_info *info,
870856
struct netlink_ext_ack *extack)
871857
{
872858
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,
923909
rt6_clean_expires(iter);
924910
else
925911
rt6_set_expires(iter, rt->dst.expires);
926-
iter->rt6i_pmtu = rt->rt6i_pmtu;
912+
fib6_metric_set(iter, RTAX_MTU, rt->fib6_pmtu);
927913
return -EEXIST;
928914
}
929915
/* If we have the same destination and the same metric,
@@ -1002,9 +988,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
1002988

1003989
add:
1004990
nlflags |= NLM_F_CREATE;
1005-
err = fib6_commit_metrics(&rt->dst, mxc);
1006-
if (err)
1007-
return err;
1008991

1009992
err = call_fib6_entry_notifiers(info->nl_net,
1010993
FIB_EVENT_ENTRY_ADD,
@@ -1035,10 +1018,6 @@ static int fib6_add_rt2node(struct fib6_node *fn, struct rt6_info *rt,
10351018
return -ENOENT;
10361019
}
10371020

1038-
err = fib6_commit_metrics(&rt->dst, mxc);
1039-
if (err)
1040-
return err;
1041-
10421021
err = call_fib6_entry_notifiers(info->nl_net,
10431022
FIB_EVENT_ENTRY_REPLACE,
10441023
rt, extack);
@@ -1135,8 +1114,7 @@ void fib6_update_sernum_upto_root(struct net *net, struct rt6_info *rt)
11351114
*/
11361115

11371116
int fib6_add(struct fib6_node *root, struct rt6_info *rt,
1138-
struct nl_info *info, struct mx6_config *mxc,
1139-
struct netlink_ext_ack *extack)
1117+
struct nl_info *info, struct netlink_ext_ack *extack)
11401118
{
11411119
struct fib6_table *table = rt->rt6i_table;
11421120
struct fib6_node *fn, *pn = NULL;
@@ -1244,7 +1222,7 @@ int fib6_add(struct fib6_node *root, struct rt6_info *rt,
12441222
}
12451223
#endif
12461224

1247-
err = fib6_add_rt2node(fn, rt, info, mxc, extack);
1225+
err = fib6_add_rt2node(fn, rt, info, extack);
12481226
if (!err) {
12491227
__fib6_update_sernum_upto_root(rt, sernum);
12501228
fib6_start_gc(info->nl_net, rt);

net/ipv6/ndisc.c

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1323,9 +1323,8 @@ static void ndisc_router_discovery(struct sk_buff *skb)
13231323
ra_msg->icmph.icmp6_hop_limit) {
13241324
if (in6_dev->cnf.accept_ra_min_hop_limit <= ra_msg->icmph.icmp6_hop_limit) {
13251325
in6_dev->cnf.hop_limit = ra_msg->icmph.icmp6_hop_limit;
1326-
if (rt)
1327-
dst_metric_set(&rt->dst, RTAX_HOPLIMIT,
1328-
ra_msg->icmph.icmp6_hop_limit);
1326+
fib6_metric_set(rt, RTAX_HOPLIMIT,
1327+
ra_msg->icmph.icmp6_hop_limit);
13291328
} else {
13301329
ND_PRINTK(2, warn, "RA: Got route advertisement with lower hop_limit than minimum\n");
13311330
}
@@ -1477,10 +1476,7 @@ static void ndisc_router_discovery(struct sk_buff *skb)
14771476
ND_PRINTK(2, warn, "RA: invalid mtu: %d\n", mtu);
14781477
} else if (in6_dev->cnf.mtu6 != mtu) {
14791478
in6_dev->cnf.mtu6 = mtu;
1480-
1481-
if (rt)
1482-
dst_metric_set(&rt->dst, RTAX_MTU, mtu);
1483-
1479+
fib6_metric_set(rt, RTAX_MTU, mtu);
14841480
rt6_mtu_change(skb->dev, mtu);
14851481
}
14861482
}

0 commit comments

Comments
 (0)