* [PATCH net-next 1/3] net: tcp_probe: also include rcv_wnd next to snd_wnd
2013-08-21 17:47 [PATCH net-next 0/3] Various tcp_probe module improvements Daniel Borkmann
@ 2013-08-21 17:47 ` Daniel Borkmann
2013-08-21 17:47 ` [PATCH net-next 2/3] net: tcp_probe: kprobes: adapt jtcp_rcv_established signature Daniel Borkmann
2013-08-21 17:48 ` [PATCH net-next 3/3] net: tcp_probe: add IPv6 support Daniel Borkmann
2 siblings, 0 replies; 7+ messages in thread
From: Daniel Borkmann @ 2013-08-21 17:47 UTC (permalink / raw)
To: davem; +Cc: netdev
It is helpful to sometimes know the TCP window sizes of an established
socket e.g. to confirm that window scaling is working or to tweak the
window size to improve high-latency connections, etc etc. Currently the
TCP snooper only exports the send window size, but not the receive window
size. Therefore, also add the receive window size to the end of the
output line.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
net/ipv4/tcp_probe.c | 6 ++++--
1 files changed, 4 insertions(+), 2 deletions(-)
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index d4943f6..fae788b 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -60,6 +60,7 @@ struct tcp_log {
u32 snd_nxt;
u32 snd_una;
u32 snd_wnd;
+ u32 rcv_wnd;
u32 snd_cwnd;
u32 ssthresh;
u32 srtt;
@@ -116,6 +117,7 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
p->snd_una = tp->snd_una;
p->snd_cwnd = tp->snd_cwnd;
p->snd_wnd = tp->snd_wnd;
+ p->rcv_wnd = tp->rcv_wnd;
p->ssthresh = tcp_current_ssthresh(sk);
p->srtt = tp->srtt >> 3;
@@ -157,13 +159,13 @@ static int tcpprobe_sprint(char *tbuf, int n)
= ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
return scnprintf(tbuf, n,
- "%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u\n",
+ "%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u %u\n",
(unsigned long) tv.tv_sec,
(unsigned long) tv.tv_nsec,
&p->saddr, ntohs(p->sport),
&p->daddr, ntohs(p->dport),
p->length, p->snd_nxt, p->snd_una,
- p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt);
+ p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt, p->rcv_wnd);
}
static ssize_t tcpprobe_read(struct file *file, char __user *buf,
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 2/3] net: tcp_probe: kprobes: adapt jtcp_rcv_established signature
2013-08-21 17:47 [PATCH net-next 0/3] Various tcp_probe module improvements Daniel Borkmann
2013-08-21 17:47 ` [PATCH net-next 1/3] net: tcp_probe: also include rcv_wnd next to snd_wnd Daniel Borkmann
@ 2013-08-21 17:47 ` Daniel Borkmann
2013-08-21 17:48 ` [PATCH net-next 3/3] net: tcp_probe: add IPv6 support Daniel Borkmann
2 siblings, 0 replies; 7+ messages in thread
From: Daniel Borkmann @ 2013-08-21 17:47 UTC (permalink / raw)
To: davem; +Cc: netdev
This patches fixes a rather unproblematic function signature mismatch
as the const specifier was missing for the th variable; and next to
that it adds a build-time assertion so that future function signature
mismatches for kprobes will not end badly, similarly as commit 22222997
("net: sctp: add build check for sctp_sf_eat_sack_6_2/jsctp_sf_eat_sack")
did it for SCTP.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
net/ipv4/tcp_probe.c | 9 ++++++++-
1 files changed, 8 insertions(+), 1 deletions(-)
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index fae788b..a2392f4 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -92,7 +92,7 @@ static inline int tcp_probe_avail(void)
* Note: arguments must match tcp_rcv_established()!
*/
static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
- struct tcphdr *th, unsigned int len)
+ const struct tcphdr *th, unsigned int len)
{
const struct tcp_sock *tp = tcp_sk(sk);
const struct inet_sock *inet = inet_sk(sk);
@@ -225,6 +225,13 @@ static __init int tcpprobe_init(void)
{
int ret = -ENOMEM;
+ /* Warning: if the function signature of tcp_rcv_established,
+ * has been changed, you also have to change the signature of
+ * jtcp_rcv_established, otherwise you end up right here!
+ */
+ BUILD_BUG_ON(__same_type(tcp_rcv_established,
+ jtcp_rcv_established) == 0);
+
init_waitqueue_head(&tcp_probe.wait);
spin_lock_init(&tcp_probe.lock);
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH net-next 3/3] net: tcp_probe: add IPv6 support
2013-08-21 17:47 [PATCH net-next 0/3] Various tcp_probe module improvements Daniel Borkmann
2013-08-21 17:47 ` [PATCH net-next 1/3] net: tcp_probe: also include rcv_wnd next to snd_wnd Daniel Borkmann
2013-08-21 17:47 ` [PATCH net-next 2/3] net: tcp_probe: kprobes: adapt jtcp_rcv_established signature Daniel Borkmann
@ 2013-08-21 17:48 ` Daniel Borkmann
2013-08-22 20:43 ` David Miller
2 siblings, 1 reply; 7+ messages in thread
From: Daniel Borkmann @ 2013-08-21 17:48 UTC (permalink / raw)
To: davem; +Cc: netdev
The tcp_probe currently only supports analysis of IPv4 connections.
Therefore, it would be nice to have IPv6 supported as well. Since we
have the recently added %pISpc specifier that is IPv4/IPv6 generic,
build related sockaddress structures from the flow information and
pass this to our format string. Tested with SSH and HTTP sessions
on IPv4 and IPv6.
Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
---
net/ipv4/tcp_probe.c | 54 ++++++++++++++++++++++++++++++++++++++++---------
1 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/net/ipv4/tcp_probe.c b/net/ipv4/tcp_probe.c
index a2392f4..301a3ef 100644
--- a/net/ipv4/tcp_probe.c
+++ b/net/ipv4/tcp_probe.c
@@ -54,8 +54,11 @@ static const char procname[] = "tcpprobe";
struct tcp_log {
ktime_t tstamp;
- __be32 saddr, daddr;
- __be16 sport, dport;
+ union {
+ struct sockaddr raw;
+ struct sockaddr_in v4;
+ struct sockaddr_in6 v6;
+ } src, dst;
u16 length;
u32 snd_nxt;
u32 snd_una;
@@ -87,6 +90,30 @@ static inline int tcp_probe_avail(void)
return bufsize - tcp_probe_used() - 1;
}
+#define tcp_probe_copy_fl_to_si4(inet, si4, mem) \
+ do { \
+ si4.sin_family = AF_INET; \
+ si4.sin_port = inet->inet_##mem##port; \
+ si4.sin_addr.s_addr = inet->inet_##mem##addr; \
+ } while (0) \
+
+#if IS_ENABLED(CONFIG_IPV6)
+#define tcp_probe_copy_fl_to_si6(inet, si6, mem) \
+ do { \
+ struct ipv6_pinfo *pi6 = inet->pinet6; \
+ si6.sin6_family = AF_INET6; \
+ si6.sin6_port = inet->inet_##mem##port; \
+ si6.sin6_addr = pi6->mem##addr; \
+ si6.sin6_flowinfo = 0; /* No need here. */ \
+ si6.sin6_scope_id = 0; /* No need here. */ \
+ } while (0)
+#else
+#define tcp_probe_copy_fl_to_si6(fl, si6, mem) \
+ do { \
+ memset(&si6, 0, sizeof(si6)); \
+ } while (0)
+#endif
+
/*
* Hook inserted to be called before each receive packet.
* Note: arguments must match tcp_rcv_established()!
@@ -108,10 +135,19 @@ static int jtcp_rcv_established(struct sock *sk, struct sk_buff *skb,
struct tcp_log *p = tcp_probe.log + tcp_probe.head;
p->tstamp = ktime_get();
- p->saddr = inet->inet_saddr;
- p->sport = inet->inet_sport;
- p->daddr = inet->inet_daddr;
- p->dport = inet->inet_dport;
+ switch (sk->sk_family) {
+ case AF_INET:
+ tcp_probe_copy_fl_to_si4(inet, p->src.v4, s);
+ tcp_probe_copy_fl_to_si4(inet, p->dst.v4, d);
+ break;
+ case AF_INET6:
+ tcp_probe_copy_fl_to_si6(inet, p->src.v6, s);
+ tcp_probe_copy_fl_to_si6(inet, p->dst.v6, d);
+ break;
+ default:
+ BUG();
+ }
+
p->length = skb->len;
p->snd_nxt = tp->snd_nxt;
p->snd_una = tp->snd_una;
@@ -159,12 +195,10 @@ static int tcpprobe_sprint(char *tbuf, int n)
= ktime_to_timespec(ktime_sub(p->tstamp, tcp_probe.start));
return scnprintf(tbuf, n,
- "%lu.%09lu %pI4:%u %pI4:%u %d %#x %#x %u %u %u %u %u\n",
+ "%lu.%09lu %pISpc %pISpc %d %#x %#x %u %u %u %u %u\n",
(unsigned long) tv.tv_sec,
(unsigned long) tv.tv_nsec,
- &p->saddr, ntohs(p->sport),
- &p->daddr, ntohs(p->dport),
- p->length, p->snd_nxt, p->snd_una,
+ &p->src, &p->dst, p->length, p->snd_nxt, p->snd_una,
p->snd_cwnd, p->ssthresh, p->snd_wnd, p->srtt, p->rcv_wnd);
}
--
1.7.1
^ permalink raw reply related [flat|nested] 7+ messages in thread