aboutsummaryrefslogtreecommitdiffstats
path: root/net/ipv4/tcp_probe.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/ipv4/tcp_probe.c')
-rw-r--r--net/ipv4/tcp_probe.c33
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;
39MODULE_PARM_DESC(port, "Port to match (0=all)"); 40MODULE_PARM_DESC(port, "Port to match (0=all)");
40module_param(port, int, 0); 41module_param(port, int, 0);
41 42
42static int bufsize __read_mostly = 4096; 43static unsigned int bufsize __read_mostly = 4096;
43MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)"); 44MODULE_PARM_DESC(bufsize, "Log buffer size in packets (4096)");
44module_param(bufsize, int, 0); 45module_param(bufsize, uint, 0);
45 46
46static int full __read_mostly; 47static int full __read_mostly;
47MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)"); 48MODULE_PARM_DESC(full, "Full log (1=every ack packet received, 0=only cwnd changes)");
@@ -75,12 +76,12 @@ static struct {
75 76
76static inline int tcp_probe_used(void) 77static 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
81static inline int tcp_probe_avail(void) 82static 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)
148static int tcpprobe_sprint(char *tbuf, int n) 150static 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);