From defb3519a64141608725e2dac5a5aa9a3c644bae Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Wed, 8 Dec 2010 21:16:57 -0800 Subject: net: Abstract away all dst_entry metrics accesses. Use helper functions to hide all direct accesses, especially writes, to dst_entry metrics values. This will allow us to: 1) More easily change how the metrics are stored. 2) Implement COW for metrics. In particular this will help us put metrics into the inetpeer cache if that is what we end up doing. We can make the _metrics member a pointer instead of an array, initially have it point at the read-only metrics in the FIB, and then on the first set grab an inetpeer entry and point the _metrics member there. Signed-off-by: David S. Miller Acked-by: Eric Dumazet --- include/net/dst.h | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) (limited to 'include/net/dst.h') diff --git a/include/net/dst.h b/include/net/dst.h index a5bd72646d6..85dee3a57b9 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -70,7 +70,7 @@ struct dst_entry { struct dst_ops *ops; - u32 metrics[RTAX_MAX]; + u32 _metrics[RTAX_MAX]; #ifdef CONFIG_NET_CLS_ROUTE __u32 tclassid; @@ -106,7 +106,27 @@ struct dst_entry { static inline u32 dst_metric(const struct dst_entry *dst, int metric) { - return dst->metrics[metric-1]; + return dst->_metrics[metric-1]; +} + +static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) +{ + dst->_metrics[metric-1] = val; +} + +static inline void dst_import_metrics(struct dst_entry *dst, const u32 *src_metrics) +{ + memcpy(dst->_metrics, src_metrics, RTAX_MAX * sizeof(u32)); +} + +static inline void dst_copy_metrics(struct dst_entry *dest, const struct dst_entry *src) +{ + dst_import_metrics(dest, src->_metrics); +} + +static inline u32 *dst_metrics_ptr(struct dst_entry *dst) +{ + return dst->_metrics; } static inline u32 @@ -134,7 +154,7 @@ static inline unsigned long dst_metric_rtt(const struct dst_entry *dst, int metr static inline void set_dst_metric_rtt(struct dst_entry *dst, int metric, unsigned long rtt) { - dst->metrics[metric-1] = jiffies_to_msecs(rtt); + dst_metric_set(dst, metric, jiffies_to_msecs(rtt)); } static inline u32 -- cgit v1.2.3-18-g5258 From 5170ae824ddf1988a63fb12cbedcff817634c444 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:35:57 -0800 Subject: net: Abstract RTAX_HOPLIMIT metric accesses behind helper. Signed-off-by: David S. Miller --- include/net/dst.h | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'include/net/dst.h') diff --git a/include/net/dst.h b/include/net/dst.h index 85dee3a57b9..9208b500aaa 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -104,11 +104,24 @@ struct dst_entry { #ifdef __KERNEL__ static inline u32 -dst_metric(const struct dst_entry *dst, int metric) +dst_metric_raw(const struct dst_entry *dst, const int metric) { return dst->_metrics[metric-1]; } +static inline u32 +dst_metric(const struct dst_entry *dst, const int metric) +{ + WARN_ON_ONCE(metric == RTAX_HOPLIMIT); + return dst_metric_raw(dst, metric); +} + +static inline u32 +dst_metric_hoplimit(const struct dst_entry *dst) +{ + return dst_metric_raw(dst, RTAX_HOPLIMIT); +} + static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { dst->_metrics[metric-1] = val; -- cgit v1.2.3-18-g5258 From 323e126f0c5995f779d7df7fd035f6e8fed8764d Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Sun, 12 Dec 2010 21:55:08 -0800 Subject: ipv4: Don't pre-seed hoplimit metric. Always go through a new ip4_dst_hoplimit() helper, just like ipv6. This allowed several simplifications: 1) The interim dst_metric_hoplimit() can go as it's no longer userd. 2) The sysctl_ip_default_ttl entry no longer needs to use ipv4_doint_and_flush, since the sysctl is not cached in routing cache metrics any longer. 3) ipv4_doint_and_flush no longer needs to be exported and therefore can be marked static. When ipv4_doint_and_flush_strategy was removed some time ago, the external declaration in ip.h was mistakenly left around so kill that off too. We have to move the sysctl_ip_default_ttl declaration into ipv4's route cache definition header net/route.h, because currently net/ip.h (where the declaration lives now) has a back dependency on net/route.h Signed-off-by: David S. Miller --- include/net/dst.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/net/dst.h') diff --git a/include/net/dst.h b/include/net/dst.h index 9208b500aaa..755ac6c1aa0 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -116,12 +116,6 @@ dst_metric(const struct dst_entry *dst, const int metric) return dst_metric_raw(dst, metric); } -static inline u32 -dst_metric_hoplimit(const struct dst_entry *dst) -{ - return dst_metric_raw(dst, RTAX_HOPLIMIT); -} - static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { dst->_metrics[metric-1] = val; -- cgit v1.2.3-18-g5258 From 0dbaee3b37e118a96bb7b8eb0d9bbaeeb46264be Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Mon, 13 Dec 2010 12:52:14 -0800 Subject: net: Abstract default ADVMSS behind an accessor. Make all RTAX_ADVMSS metric accesses go through a new helper function, dst_metric_advmss(). Leave the actual default metric as "zero" in the real metric slot, and compute the actual default value dynamically via a new dst_ops AF specific callback. For stacked IPSEC routes, we use the advmss of the path which preserves existing behavior. Unlike ipv4/ipv6, DecNET ties the advmss to the mtu and thus updates advmss on pmtu updates. This inconsistency in advmss handling results in more raw metric accesses than I wish we ended up with. Signed-off-by: David S. Miller --- include/net/dst.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'include/net/dst.h') diff --git a/include/net/dst.h b/include/net/dst.h index 755ac6c1aa0..03a1c3d52d8 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -112,10 +112,22 @@ dst_metric_raw(const struct dst_entry *dst, const int metric) static inline u32 dst_metric(const struct dst_entry *dst, const int metric) { - WARN_ON_ONCE(metric == RTAX_HOPLIMIT); + WARN_ON_ONCE(metric == RTAX_HOPLIMIT || + metric == RTAX_ADVMSS); return dst_metric_raw(dst, metric); } +static inline u32 +dst_metric_advmss(const struct dst_entry *dst) +{ + u32 advmss = dst_metric_raw(dst, RTAX_ADVMSS); + + if (!advmss) + advmss = dst->ops->default_advmss(dst); + + return advmss; +} + static inline void dst_metric_set(struct dst_entry *dst, int metric, u32 val) { dst->_metrics[metric-1] = val; -- cgit v1.2.3-18-g5258 From d33e455337ea2c71d09d7f4367d6ad6dd32b6965 Mon Sep 17 00:00:00 2001 From: "David S. Miller" Date: Tue, 14 Dec 2010 13:01:14 -0800 Subject: net: Abstract default MTU metric calculation behind an accessor. Like RTAX_ADVMSS, make the default calculation go through a dst_ops method rather than caching the computation in the routing cache entries. Now dst metrics are pretty much left as-is when new entries are created, thus optimizing metric sharing becomes a real possibility. Signed-off-by: David S. Miller --- include/net/dst.h | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'include/net/dst.h') diff --git a/include/net/dst.h b/include/net/dst.h index 03a1c3d52d8..93b0310317b 100644 --- a/include/net/dst.h +++ b/include/net/dst.h @@ -113,7 +113,8 @@ static inline u32 dst_metric(const struct dst_entry *dst, const int metric) { WARN_ON_ONCE(metric == RTAX_HOPLIMIT || - metric == RTAX_ADVMSS); + metric == RTAX_ADVMSS || + metric == RTAX_MTU); return dst_metric_raw(dst, metric); } @@ -156,11 +157,11 @@ dst_feature(const struct dst_entry *dst, u32 feature) static inline u32 dst_mtu(const struct dst_entry *dst) { - u32 mtu = dst_metric(dst, RTAX_MTU); - /* - * Alexey put it here, so ask him about it :) - */ - barrier(); + u32 mtu = dst_metric_raw(dst, RTAX_MTU); + + if (!mtu) + mtu = dst->ops->default_mtu(dst); + return mtu; } @@ -186,7 +187,7 @@ dst_allfrag(const struct dst_entry *dst) } static inline int -dst_metric_locked(struct dst_entry *dst, int metric) +dst_metric_locked(const struct dst_entry *dst, int metric) { return dst_metric(dst, RTAX_LOCK) & (1<