aboutsummaryrefslogtreecommitdiffstats
path: root/include/net/inetpeer.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/net/inetpeer.h')
-rw-r--r--include/net/inetpeer.h66
1 files changed, 56 insertions, 10 deletions
diff --git a/include/net/inetpeer.h b/include/net/inetpeer.h
index 417d0c894f29..8a159cc3d68b 100644
--- a/include/net/inetpeer.h
+++ b/include/net/inetpeer.h
@@ -11,12 +11,26 @@
11#include <linux/init.h> 11#include <linux/init.h>
12#include <linux/jiffies.h> 12#include <linux/jiffies.h>
13#include <linux/spinlock.h> 13#include <linux/spinlock.h>
14#include <linux/rtnetlink.h>
15#include <net/ipv6.h>
14#include <asm/atomic.h> 16#include <asm/atomic.h>
15 17
18struct inetpeer_addr_base {
19 union {
20 __be32 a4;
21 __be32 a6[4];
22 };
23};
24
25struct inetpeer_addr {
26 struct inetpeer_addr_base addr;
27 __u16 family;
28};
29
16struct inet_peer { 30struct inet_peer {
17 /* group together avl_left,avl_right,v4daddr to speedup lookups */ 31 /* group together avl_left,avl_right,v4daddr to speedup lookups */
18 struct inet_peer *avl_left, *avl_right; 32 struct inet_peer __rcu *avl_left, *avl_right;
19 __be32 v4daddr; /* peer's address */ 33 struct inetpeer_addr daddr;
20 __u32 avl_height; 34 __u32 avl_height;
21 struct list_head unused; 35 struct list_head unused;
22 __u32 dtime; /* the time of last use of not 36 __u32 dtime; /* the time of last use of not
@@ -24,16 +38,22 @@ struct inet_peer {
24 atomic_t refcnt; 38 atomic_t refcnt;
25 /* 39 /*
26 * Once inet_peer is queued for deletion (refcnt == -1), following fields 40 * Once inet_peer is queued for deletion (refcnt == -1), following fields
27 * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp 41 * are not available: rid, ip_id_count, tcp_ts, tcp_ts_stamp, metrics
28 * We can share memory with rcu_head to keep inet_peer small 42 * We can share memory with rcu_head to help keep inet_peer small.
29 * (less then 64 bytes)
30 */ 43 */
31 union { 44 union {
32 struct { 45 struct {
33 atomic_t rid; /* Frag reception counter */ 46 atomic_t rid; /* Frag reception counter */
34 atomic_t ip_id_count; /* IP ID for the next packet */ 47 atomic_t ip_id_count; /* IP ID for the next packet */
35 __u32 tcp_ts; 48 __u32 tcp_ts;
36 __u32 tcp_ts_stamp; 49 __u32 tcp_ts_stamp;
50 u32 metrics[RTAX_MAX];
51 u32 rate_tokens; /* rate limiting for ICMP */
52 unsigned long rate_last;
53 unsigned long pmtu_expires;
54 u32 pmtu_orig;
55 u32 pmtu_learned;
56 struct inetpeer_addr_base redirect_learned;
37 }; 57 };
38 struct rcu_head rcu; 58 struct rcu_head rcu;
39 }; 59 };
@@ -41,11 +61,37 @@ struct inet_peer {
41 61
42void inet_initpeers(void) __init; 62void inet_initpeers(void) __init;
43 63
64#define INETPEER_METRICS_NEW (~(u32) 0)
65
66static inline bool inet_metrics_new(const struct inet_peer *p)
67{
68 return p->metrics[RTAX_LOCK-1] == INETPEER_METRICS_NEW;
69}
70
44/* can be called with or without local BH being disabled */ 71/* can be called with or without local BH being disabled */
45struct inet_peer *inet_getpeer(__be32 daddr, int create); 72struct inet_peer *inet_getpeer(struct inetpeer_addr *daddr, int create);
73
74static inline struct inet_peer *inet_getpeer_v4(__be32 v4daddr, int create)
75{
76 struct inetpeer_addr daddr;
77
78 daddr.addr.a4 = v4daddr;
79 daddr.family = AF_INET;
80 return inet_getpeer(&daddr, create);
81}
82
83static inline struct inet_peer *inet_getpeer_v6(const struct in6_addr *v6daddr, int create)
84{
85 struct inetpeer_addr daddr;
86
87 ipv6_addr_copy((struct in6_addr *)daddr.addr.a6, v6daddr);
88 daddr.family = AF_INET6;
89 return inet_getpeer(&daddr, create);
90}
46 91
47/* can be called from BH context or outside */ 92/* can be called from BH context or outside */
48extern void inet_putpeer(struct inet_peer *p); 93extern void inet_putpeer(struct inet_peer *p);
94extern bool inet_peer_xrlim_allow(struct inet_peer *peer, int timeout);
49 95
50/* 96/*
51 * temporary check to make sure we dont access rid, ip_id_count, tcp_ts, 97 * temporary check to make sure we dont access rid, ip_id_count, tcp_ts,