summaryrefslogtreecommitdiff
path: root/include
diff options
context:
space:
mode:
authorAlexey Kuznetsov <kuznet@ms2.inr.ac.ru>2002-10-24 14:48:10 -0700
committerHideaki Yoshifuji <yoshfuji@linux-ipv6.org>2002-10-24 14:48:10 -0700
commit0580e4e842285df229389e028ba18336726cfaf7 (patch)
tree12a439cc7958d2d4264c48dc9a3fe11205c1ac58 /include
parent145c04ecd4447bc4edacc4995a611ea67595f449 (diff)
[NET]: Cleanup DST metrics and abstract MSS/PMTU further.
- Changed dst named metrics, to RTAX_MAX metrics array. - Add inline shorthands to access them - Add update_pmtu and get_mss to DST ops. - Add path component to DST, it is DST itself by default.
Diffstat (limited to 'include')
-rw-r--r--include/net/dst.h48
-rw-r--r--include/net/ip.h2
-rw-r--r--include/net/ip_fib.h2
-rw-r--r--include/net/route.h1
-rw-r--r--include/net/tcp.h8
5 files changed, 46 insertions, 15 deletions
diff --git a/include/net/dst.h b/include/net/dst.h
index faf5e30316be..44d7374573f2 100644
--- a/include/net/dst.h
+++ b/include/net/dst.h
@@ -9,6 +9,7 @@
#define _NET_DST_H
#include <linux/config.h>
+#include <linux/rtnetlink.h>
#include <net/neighbour.h>
/*
@@ -22,6 +23,13 @@
#define DST_GC_INC (5*HZ)
#define DST_GC_MAX (120*HZ)
+/* Each dst_entry has reference count and sits in some parent list(s).
+ * When it is removed from parent list, it is "freed" (dst_free).
+ * After this it enters dead state (dst->obsolete > 0) and if its refcnt
+ * is zero, it can be destroyed immediately, otherwise it is added
+ * to gc list and garbage collector periodically checks the refcnt.
+ */
+
struct sk_buff;
struct dst_entry
@@ -39,15 +47,8 @@ struct dst_entry
unsigned header_len; /* more space at head required */
- unsigned mxlock;
- unsigned pmtu;
- unsigned window;
- unsigned rtt;
- unsigned rttvar;
- unsigned ssthresh;
- unsigned cwnd;
- unsigned advmss;
- unsigned reordering;
+ u32 metrics[RTAX_MAX];
+ struct dst_entry *path;
unsigned long rate_last; /* rate limiting for ICMP */
unsigned long rate_tokens;
@@ -81,6 +82,8 @@ struct dst_ops
void (*destroy)(struct dst_entry *);
struct dst_entry * (*negative_advice)(struct dst_entry *);
void (*link_failure)(struct sk_buff *);
+ void (*update_pmtu)(struct dst_entry *dst, u32 mtu);
+ int (*get_mss)(struct dst_entry *dst, u32 mtu);
int entry_size;
atomic_t entries;
@@ -89,6 +92,33 @@ struct dst_ops
#ifdef __KERNEL__
+static inline u32
+dst_metric(struct dst_entry *dst, int metric)
+{
+ return dst->metrics[metric-1];
+}
+
+static inline u32
+dst_path_metric(struct dst_entry *dst, int metric)
+{
+ return dst->path->metrics[metric-1];
+}
+
+static inline u32
+dst_pmtu(struct dst_entry *dst)
+{
+ u32 mtu = dst_path_metric(dst, RTAX_MTU);
+ /* Yes, _exactly_. This is paranoia. */
+ barrier();
+ return mtu;
+}
+
+static inline int
+dst_metric_locked(struct dst_entry *dst, int metric)
+{
+ return dst_metric(dst, RTAX_LOCK) & (1<<metric);
+}
+
static inline void dst_hold(struct dst_entry * dst)
{
atomic_inc(&dst->__refcnt);
diff --git a/include/net/ip.h b/include/net/ip.h
index af74bb3f79d9..7b365788fe00 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -178,7 +178,7 @@ int ip_dont_fragment(struct sock *sk, struct dst_entry *dst)
{
return (inet_sk(sk)->pmtudisc == IP_PMTUDISC_DO ||
(inet_sk(sk)->pmtudisc == IP_PMTUDISC_WANT &&
- !(dst->mxlock&(1<<RTAX_MTU))));
+ !(dst_metric(dst, RTAX_LOCK)&(1<<RTAX_MTU))));
}
extern void __ip_select_ident(struct iphdr *iph, struct dst_entry *dst, int more);
diff --git a/include/net/ip_fib.h b/include/net/ip_fib.h
index debc59c4c240..0d847352d121 100644
--- a/include/net/ip_fib.h
+++ b/include/net/ip_fib.h
@@ -67,7 +67,7 @@ struct fib_info
int fib_protocol;
u32 fib_prefsrc;
u32 fib_priority;
- unsigned fib_metrics[RTAX_MAX];
+ u32 fib_metrics[RTAX_MAX];
#define fib_mtu fib_metrics[RTAX_MTU-1]
#define fib_window fib_metrics[RTAX_WINDOW-1]
#define fib_rtt fib_metrics[RTAX_RTT-1]
diff --git a/include/net/route.h b/include/net/route.h
index f74195ea16ea..eea5c8f0269f 100644
--- a/include/net/route.h
+++ b/include/net/route.h
@@ -115,7 +115,6 @@ extern void rt_cache_flush(int how);
extern int ip_route_output_key(struct rtable **, const struct flowi *flp);
extern int ip_route_input(struct sk_buff*, u32 dst, u32 src, u8 tos, struct net_device *devin);
extern unsigned short ip_rt_frag_needed(struct iphdr *iph, unsigned short new_mtu);
-extern void ip_rt_update_pmtu(struct dst_entry *dst, unsigned mtu);
extern void ip_rt_send_redirect(struct sk_buff *skb);
extern unsigned inet_addr_type(u32 addr);
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 6683b8379936..38cc0e90793b 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -921,9 +921,11 @@ static __inline__ unsigned int tcp_current_mss(struct sock *sk, int large)
int mss_now = large && (sk->route_caps&NETIF_F_TSO) && !tp->urg_mode ?
tp->mss_cache : tp->mss_cache_std;
- if (dst && dst->pmtu != tp->pmtu_cookie)
- mss_now = tcp_sync_mss(sk, dst->pmtu);
-
+ if (dst) {
+ u32 mtu = dst_pmtu(dst);
+ if (mtu != tp->pmtu_cookie)
+ mss_now = tcp_sync_mss(sk, mtu);
+ }
if (tp->eff_sacks)
mss_now -= (TCPOLEN_SACK_BASE_ALIGNED +
(tp->eff_sacks * TCPOLEN_SACK_PERBLOCK));