From: Steffen Klassert <steffen.klassert@secunet.com>
To: David Miller <davem@davemloft.net>
Cc: timo.teras@iki.fi, netdev@vger.kernel.org
Subject: [PATCH 2/4] net: Unlink the inetpeer metrics from dst_entry
Date: Thu, 2 Feb 2012 11:12:56 +0100 [thread overview]
Message-ID: <20120202101255.GE23142@secunet.com> (raw)
In-Reply-To: <20120202101141.GC23142@secunet.com>
In order to be able to exchange the inetpeer metrics,
we remove the direct reference from the dst_entry. We
access them via a new dst_ops method 'metrics' and the
inet_peer pointer of the routes.
Signed-off-by: Steffen Klassert <steffen.klassert@secunet.com>
---
include/net/dst.h | 20 +++++++++++++-------
include/net/dst_ops.h | 1 +
net/bridge/br_netfilter.c | 6 ++++++
net/decnet/dn_route.c | 1 +
net/ipv4/route.c | 32 +++++++++++++++++---------------
net/ipv4/xfrm4_policy.c | 1 +
net/ipv6/route.c | 27 +++++++++++++++++----------
net/ipv6/xfrm6_policy.c | 1 +
8 files changed, 57 insertions(+), 32 deletions(-)
diff --git a/include/net/dst.h b/include/net/dst.h
index 344c8dd..be1ffc8 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -124,6 +124,17 @@ static inline void dst_destroy_metrics_generic(struct dst_entry *dst)
__dst_destroy_metrics_generic(dst, val);
}
+static inline u32 *dst_metrics_ptr(const struct dst_entry *dst)
+{
+ return dst->ops->metrics(dst);
+}
+
+static inline u32 *dst_metrics_ptr_default(const struct dst_entry *dst)
+{
+ return DST_METRICS_PTR(dst);
+
+}
+
static inline u32 *dst_metrics_write_ptr(struct dst_entry *dst)
{
unsigned long p = dst->_metrics;
@@ -151,21 +162,16 @@ static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_ent
u32 *dst_metrics = dst_metrics_write_ptr(dest);
if (dst_metrics) {
- u32 *src_metrics = DST_METRICS_PTR(src);
+ u32 *src_metrics = dst_metrics_ptr(src);
memcpy(dst_metrics, src_metrics, RTAX_MAX * sizeof(u32));
}
}
-static inline u32 *dst_metrics_ptr(struct dst_entry *dst)
-{
- return DST_METRICS_PTR(dst);
-}
-
static inline u32
dst_metric_raw(const struct dst_entry *dst, const int metric)
{
- u32 *p = DST_METRICS_PTR(dst);
+ u32 *p = dst_metrics_ptr(dst);
return p[metric-1];
}
diff --git a/include/net/dst_ops.h b/include/net/dst_ops.h
index e1c2ee0..2c7849b 100644
--- a/include/net/dst_ops.h
+++ b/include/net/dst_ops.h
@@ -19,6 +19,7 @@ struct dst_ops {
unsigned int (*default_advmss)(const struct dst_entry *);
unsigned int (*mtu)(const struct dst_entry *);
u32 * (*cow_metrics)(struct dst_entry *, unsigned long);
+ u32 * (*metrics)(const struct dst_entry *);
void (*destroy)(struct dst_entry *);
void (*ifdown)(struct dst_entry *,
struct net_device *dev, int how);
diff --git a/net/bridge/br_netfilter.c b/net/bridge/br_netfilter.c
index 8412247..74ba4bc 100644
--- a/net/bridge/br_netfilter.c
+++ b/net/bridge/br_netfilter.c
@@ -109,6 +109,11 @@ static u32 *fake_cow_metrics(struct dst_entry *dst, unsigned long old)
return NULL;
}
+static u32 *fake_metrics(const struct dst_entry *dst)
+{
+ return NULL;
+}
+
static struct neighbour *fake_neigh_lookup(const struct dst_entry *dst, const void *daddr)
{
return NULL;
@@ -124,6 +129,7 @@ static struct dst_ops fake_dst_ops = {
.protocol = cpu_to_be16(ETH_P_IP),
.update_pmtu = fake_update_pmtu,
.cow_metrics = fake_cow_metrics,
+ .metrics = fake_metrics,
.neigh_lookup = fake_neigh_lookup,
.mtu = fake_mtu,
};
diff --git a/net/decnet/dn_route.c b/net/decnet/dn_route.c
index f31ce72..d2e56b0 100644
--- a/net/decnet/dn_route.c
+++ b/net/decnet/dn_route.c
@@ -137,6 +137,7 @@ static struct dst_ops dn_dst_ops = {
.default_advmss = dn_dst_default_advmss,
.mtu = dn_dst_mtu,
.cow_metrics = dst_cow_metrics_generic,
+ .metrics = dst_metrics_ptr_default,
.destroy = dn_dst_destroy,
.negative_advice = dn_dst_negative_advice,
.link_failure = dn_dst_link_failure,
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 5099d35..dc22d6f 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -155,6 +155,16 @@ static void ipv4_dst_ifdown(struct dst_entry *dst, struct net_device *dev,
{
}
+static u32 *ipv4_metrics(const struct dst_entry *dst)
+{
+ const struct rtable *rt = (const struct rtable *) dst;
+
+ if (rt->peer && !inet_metrics_new(rt->peer))
+ return inetpeer_metrics(rt->peer);
+
+ return DST_METRICS_PTR(dst);
+}
+
static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
{
struct rtable *rt = (struct rtable *) dst;
@@ -167,25 +177,10 @@ static u32 *ipv4_cow_metrics(struct dst_entry *dst, unsigned long old)
peer = rt->peer;
if (peer) {
u32 *old_p = __DST_METRICS_PTR(old);
- unsigned long prev, new;
p = inetpeer_metrics(peer);
if (inet_metrics_new(peer))
memcpy(p, old_p, sizeof(u32) * RTAX_MAX);
-
- new = (unsigned long) p;
- prev = cmpxchg(&dst->_metrics, old, new);
-
- if (prev != old) {
- p = __DST_METRICS_PTR(prev);
- if (prev & DST_METRICS_READ_ONLY)
- p = NULL;
- } else {
- if (rt->fi) {
- fib_info_put(rt->fi);
- rt->fi = NULL;
- }
- }
}
return p;
}
@@ -200,6 +195,7 @@ static struct dst_ops ipv4_dst_ops = {
.default_advmss = ipv4_default_advmss,
.mtu = ipv4_mtu,
.cow_metrics = ipv4_cow_metrics,
+ .metrics = ipv4_metrics,
.destroy = ipv4_dst_destroy,
.ifdown = ipv4_dst_ifdown,
.negative_advice = ipv4_negative_advice,
@@ -2883,6 +2879,11 @@ static u32 *ipv4_rt_blackhole_cow_metrics(struct dst_entry *dst,
return NULL;
}
+static u32 *ipv4_rt_blackhole_metrics(const struct dst_entry *dst)
+{
+ return NULL;
+}
+
static struct dst_ops ipv4_dst_blackhole_ops = {
.family = AF_INET,
.protocol = cpu_to_be16(ETH_P_IP),
@@ -2892,6 +2893,7 @@ static struct dst_ops ipv4_dst_blackhole_ops = {
.default_advmss = ipv4_default_advmss,
.update_pmtu = ipv4_rt_blackhole_update_pmtu,
.cow_metrics = ipv4_rt_blackhole_cow_metrics,
+ .metrics = ipv4_rt_blackhole_metrics,
.neigh_lookup = ipv4_neigh_lookup,
};
diff --git a/net/ipv4/xfrm4_policy.c b/net/ipv4/xfrm4_policy.c
index a0b4c5d..7a6ebfe 100644
--- a/net/ipv4/xfrm4_policy.c
+++ b/net/ipv4/xfrm4_policy.c
@@ -233,6 +233,7 @@ static struct dst_ops xfrm4_dst_ops = {
.gc = xfrm4_garbage_collect,
.update_pmtu = xfrm4_update_pmtu,
.cow_metrics = dst_cow_metrics_generic,
+ .metrics = dst_metrics_ptr_default,
.destroy = xfrm4_dst_destroy,
.ifdown = xfrm4_dst_ifdown,
.local_out = __ip_local_out,
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index ea13565..d8b01c0 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -88,6 +88,16 @@ static struct rt6_info *rt6_get_route_info(struct net *net,
const struct in6_addr *gwaddr, int ifindex);
#endif
+static u32 *ipv6_metrics(const struct dst_entry *dst)
+{
+ const struct rt6_info *rt = (const struct rt6_info *) dst;
+
+ if (rt->rt6i_peer && !inet_metrics_new(rt->rt6i_peer))
+ return inetpeer_metrics(rt->rt6i_peer);
+
+ return DST_METRICS_PTR(dst);
+}
+
static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
{
struct rt6_info *rt = (struct rt6_info *) dst;
@@ -103,20 +113,10 @@ static u32 *ipv6_cow_metrics(struct dst_entry *dst, unsigned long old)
peer = rt->rt6i_peer;
if (peer) {
u32 *old_p = __DST_METRICS_PTR(old);
- unsigned long prev, new;
p = inetpeer_metrics(peer);
if (inet_metrics_new(peer))
memcpy(p, old_p, sizeof(u32) * RTAX_MAX);
-
- new = (unsigned long) p;
- prev = cmpxchg(&dst->_metrics, old, new);
-
- if (prev != old) {
- p = __DST_METRICS_PTR(prev);
- if (prev & DST_METRICS_READ_ONLY)
- p = NULL;
- }
}
return p;
}
@@ -151,6 +151,7 @@ static struct dst_ops ip6_dst_ops_template = {
.default_advmss = ip6_default_advmss,
.mtu = ip6_mtu,
.cow_metrics = ipv6_cow_metrics,
+ .metrics = ipv6_metrics,
.destroy = ip6_dst_destroy,
.ifdown = ip6_dst_ifdown,
.negative_advice = ip6_negative_advice,
@@ -177,6 +178,11 @@ static u32 *ip6_rt_blackhole_cow_metrics(struct dst_entry *dst,
return NULL;
}
+static u32 *ip6_rt_blackhole_metrics(const struct dst_entry *dst)
+{
+ return NULL;
+}
+
static struct dst_ops ip6_dst_blackhole_ops = {
.family = AF_INET6,
.protocol = cpu_to_be16(ETH_P_IPV6),
@@ -186,6 +192,7 @@ static struct dst_ops ip6_dst_blackhole_ops = {
.default_advmss = ip6_default_advmss,
.update_pmtu = ip6_rt_blackhole_update_pmtu,
.cow_metrics = ip6_rt_blackhole_cow_metrics,
+ .metrics = ip6_rt_blackhole_metrics,
.neigh_lookup = ip6_neigh_lookup,
};
diff --git a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
index 8ea65e0..af4854c 100644
--- a/net/ipv6/xfrm6_policy.c
+++ b/net/ipv6/xfrm6_policy.c
@@ -261,6 +261,7 @@ static struct dst_ops xfrm6_dst_ops = {
.gc = xfrm6_garbage_collect,
.update_pmtu = xfrm6_update_pmtu,
.cow_metrics = dst_cow_metrics_generic,
+ .metrics = dst_metrics_ptr_default,
.destroy = xfrm6_dst_destroy,
.ifdown = xfrm6_dst_ifdown,
.local_out = __ip6_local_out,
--
1.7.0.4
next prev parent reply other threads:[~2012-02-02 10:13 UTC|newest]
Thread overview: 22+ messages / expand[flat|nested] mbox.gz Atom feed top
2012-02-02 10:11 [PATCH 0/4] Fix routing metrics Steffen Klassert
2012-02-02 10:12 ` [PATCH 1/4] inetpeer: Allocate the peer metrics dynamically Steffen Klassert
2012-02-02 10:12 ` Steffen Klassert [this message]
2012-02-02 10:13 ` [PATCH 3/4] inetpeer: protect the inetpeerpeer metrics with rcu Steffen Klassert
2012-02-02 10:14 ` [PATCH 4/4] route: Invalidate the peer metrics along with the routing cache Steffen Klassert
2012-02-06 20:29 ` [PATCH 0/4] Fix routing metrics David Miller
2012-02-08 7:30 ` Steffen Klassert
2012-02-08 20:18 ` David Miller
2012-02-09 12:44 ` Steffen Klassert
2012-02-09 18:40 ` David Miller
2012-02-10 6:50 ` Steffen Klassert
2012-02-10 7:38 ` David Miller
2012-02-10 7:51 ` Steffen Klassert
2012-02-10 8:12 ` David Miller
2012-02-10 8:44 ` Steffen Klassert
2012-02-10 18:25 ` David Miller
2012-02-21 6:19 ` Steffen Klassert
2012-02-21 6:36 ` David Miller
2012-02-21 8:18 ` Steffen Klassert
2012-02-21 19:24 ` David Miller
2012-02-24 9:08 ` Steffen Klassert
2012-02-24 9:13 ` David Miller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20120202101255.GE23142@secunet.com \
--to=steffen.klassert@secunet.com \
--cc=davem@davemloft.net \
--cc=netdev@vger.kernel.org \
--cc=timo.teras@iki.fi \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).