diff options
Diffstat (limited to 'net/ipv4/tcp_probe.c')
-rw-r--r-- | net/ipv4/tcp_probe.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c index 59f5b5e7c566..f8efada580e8 100644 --- a/net/ipv4/tcp_probe.c +++ b/net/ipv4/tcp_probe.c | |||
@@ -22,6 +22,7 @@ | |||
22 | #include <linux/kprobes.h> | 22 | #include <linux/kprobes.h> |
23 | #include <linux/socket.h> | 23 | #include <linux/socket.h> |
24 | #include <linux/tcp.h> | 24 | #include <linux/tcp.h> |
25 | #include <linux/slab.h> | ||
25 | #include <linux/proc_fs.h> | 26 | #include <linux/proc_fs.h> |
26 | #include <linux/module.h> | 27 | #include <linux/module.h> |
27 | #include <linux/ktime.h> | 28 | #include <linux/ktime.h> |
@@ -39,9 +40,9 @@ static int port __read_mostly = 0; | |||
39 | MODULE_PARM_DESC(port, "Port to match (0=all)"); | 40 | MODULE_PARM_DESC(port, "Port to match (0=all)"); |
40 | module_param(port, int, 0); | 41 | module_param(port, int, 0); |
41 | 42 | ||
42 | static int bufsize __read_mostly = 4096; | 43 | static unsigned int bufsize __read_mostly = 4096; |
43 | MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)"); | 44 | MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)"); |
44 | module_param(bufsize, int, 0); | 45 | module_param(bufsize, uint, 0); |
45 | 46 | ||
46 | static int full __read_mostly; | 47 | static int full __read_mostly; |
47 | MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); | 48 | MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); |
@@ -75,12 +76,12 @@ static struct { | |||
75 | 76 | ||
76 | static inline int tcp_probe_used(void) | 77 | static inline int tcp_probe_used(void) |
77 | { | 78 | { |
78 | return (tcp_probe.head - tcp_probe.tail) % bufsize; | 79 | return (tcp_probe.head - tcp_probe.tail) & (bufsize - 1); |
79 | } | 80 | } |
80 | 81 | ||
81 | static inline int tcp_probe_avail(void) | 82 | static inline int tcp_probe_avail(void) |
82 | { | 83 | { |
83 | return bufsize - tcp_probe_used(); | 84 | return bufsize - tcp_probe_used() - 1; |
84 | } | 85 | } |
85 | 86 | ||
86 | /* | 87 | /* |
@@ -94,8 +95,9 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
94 | const struct inet_sock *inet = inet_sk(sk); | 95 | const struct inet_sock *inet = inet_sk(sk); |
95 | 96 | ||
96 | /* Only update if port matches */ | 97 | /* Only update if port matches */ |
97 | if ((port == 0 || ntohs(inet->dport) == port || ntohs(inet->sport) == port) | 98 | if ((port == 0 || ntohs(inet->inet_dport) == port || |
98 | && (full || tp->snd_cwnd != tcp_probe.lastcwnd)) { | 99 | ntohs(inet->inet_sport) == port) && |
100 | (full || tp->snd_cwnd != tcp_probe.lastcwnd)) { | ||
99 | 101 | ||
100 | spin_lock(&tcp_probe.lock); | 102 | spin_lock(&tcp_probe.lock); |
101 | /* If log fills, just silently drop */ | 103 | /* If log fills, just silently drop */ |
@@ -103,10 +105,10 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
103 | struct tcp_log *p = tcp_probe.log + tcp_probe.head; | 105 | struct tcp_log *p = tcp_probe.log + tcp_probe.head; |
104 | 106 | ||
105 | p->tstamp = ktime_get(); | 107 | p->tstamp = ktime_get(); |
106 | p->saddr = inet->saddr; | 108 | p->saddr = inet->inet_saddr; |
107 | p->sport = inet->sport; | 109 | p->sport = inet->inet_sport; |
108 | p->daddr = inet->daddr; | 110 | p->daddr = inet->inet_daddr; |
109 | p->dport = inet->dport; | 111 | p->dport = inet->inet_dport; |
110 | p->length = skb->len; | 112 | p->length = skb->len; |
111 | p->snd_nxt = tp->snd_nxt; | 113 | p->snd_nxt = tp->snd_nxt; |
112 | p->snd_una = tp->snd_una; | 114 | p->snd_una = tp->snd_una; |
@@ -115,7 +117,7 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb, | |||
115 | p->ssthresh = tcp_current_ssthresh(sk); | 117 | p->ssthresh = tcp_current_ssthresh(sk); |
116 | p->srtt = tp->srtt >> 3; | 118 | p->srtt = tp->srtt >> 3; |
117 | 119 | ||
118 | tcp_probe.head = (tcp_probe.head + 1) % bufsize; | 120 | tcp_probe.head = (tcp_probe.head + 1) & (bufsize - 1); |
119 | } | 121 | } |
120 | tcp_probe.lastcwnd = tp->snd_cwnd; | 122 | tcp_probe.lastcwnd = tp->snd_cwnd; |
121 | spin_unlock(&tcp_probe.lock); | 123 | spin_unlock(&tcp_probe.lock); |
@@ -148,7 +150,7 @@ static int tcpprobe_open(struct inode * inode, struct file * file) | |||
148 | static int tcpprobe_sprint(char *tbuf, int n) | 150 | static int tcpprobe_sprint(char *tbuf, int n) |
149 | { | 151 | { |
150 | const struct tcp_log *p | 152 | const struct tcp_log *p |
151 | = tcp_probe.log + tcp_probe.tail % bufsize; | 153 | = tcp_probe.log + tcp_probe.tail; |
152 | struct timespec tv | 154 | struct timespec tv |
153 | = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start)); | 155 | = ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start)); |
154 | 156 | ||
@@ -191,7 +193,7 @@ static ssize_t tcpprobe_read(struct file *file, char __user *buf, | |||
191 | width = tcpprobe_sprint(tbuf, sizeof(tbuf)); | 193 | width = tcpprobe_sprint(tbuf, sizeof(tbuf)); |
192 | 194 | ||
193 | if (cnt + width < len) | 195 | if (cnt + width < len) |
194 | tcp_probe.tail = (tcp_probe.tail + 1) % bufsize; | 196 | tcp_probe.tail = (tcp_probe.tail + 1) & (bufsize - 1); |
195 | 197 | ||
196 | spin_unlock_bh(&tcp_probe.lock); | 198 | spin_unlock_bh(&tcp_probe.lock); |
197 | 199 | ||
@@ -221,9 +223,10 @@ static __init int tcpprobe_init(void) | |||
221 | init_waitqueue_head(&tcp_probe.wait); | 223 | init_waitqueue_head(&tcp_probe.wait); |
222 | spin_lock_init(&tcp_probe.lock); | 224 | spin_lock_init(&tcp_probe.lock); |
223 | 225 | ||
224 | if (bufsize < 0) | 226 | if (bufsize == 0) |
225 | return -EINVAL; | 227 | return -EINVAL; |
226 | 228 | ||
229 | bufsize = roundup_pow_of_two(bufsize); | ||
227 | tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL); | 230 | tcp_probe.log = kcalloc(bufsize, sizeof(struct tcp_log), GFP_KERNEL); |
228 | if (!tcp_probe.log) | 231 | if (!tcp_probe.log) |
229 | goto err0; | 232 | goto err0; |
@@ -235,7 +238,7 @@ static __init int tcpprobe_init(void) | |||
235 | if (ret) | 238 | if (ret) |
236 | goto err1; | 239 | goto err1; |
237 | 240 | ||
238 | pr_info("TCP probe registered (port=%d)\n", port); | 241 | pr_info("TCP probe registered (port=%d) bufsize=%u\n", port, bufsize); |
239 | return 0; | 242 | return 0; |
240 | err1: | 243 | err1: |
241 | proc_net_remove(&init_net, procname); | 244 | proc_net_remove(&init_net, procname); |