* [MPTCP] [PATCH 1/2] mptcp: add MIB counter infrastructure
@ 2019-09-20 15:05 Florian Westphal
0 siblings, 0 replies; 4+ messages in thread
From: Florian Westphal @ 2019-09-20 15:05 UTC (permalink / raw)
To: mptcp
[-- Attachment #1: Type: text/plain, Size: 12012 bytes --]
Exported via same /proc file as the Linux TCP MIB counters.
This means tools like 'nstat' will pick them up automatically.
The MPTCP MIB counters are allocated in a distinct pcpu area in order to
avoid bloating/wasting TCP pcpu memory.
The counters are allocated once the first MPTCP socket is created in a
network namespace.
The Names are taken from the multipath-tcp.org kernel, in case we don't
need all of them the extra ones should be pruned. But for now i've
added all on the grounds that they are probably useful (i.e., make
use of them).
Signed-off-by: Florian Westphal <fw(a)strlen.de>
---
include/net/mptcp.h | 2 +
include/net/netns/mib.h | 3 ++
net/ipv4/af_inet.c | 4 ++
net/ipv4/proc.c | 2 +
net/mptcp/Makefile | 2 +-
net/mptcp/mib.c | 95 +++++++++++++++++++++++++++++++++++++++++
net/mptcp/mib.h | 67 +++++++++++++++++++++++++++++
net/mptcp/protocol.c | 8 +++-
8 files changed, 181 insertions(+), 2 deletions(-)
create mode 100644 net/mptcp/mib.c
create mode 100644 net/mptcp/mib.h
diff --git a/include/net/mptcp.h b/include/net/mptcp.h
index 50cd1b31ebdd..c4f4fdd57c74 100644
--- a/include/net/mptcp.h
+++ b/include/net/mptcp.h
@@ -82,6 +82,7 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
bool mptcp_sk_is_subflow(const struct sock *sk);
+void mptcp_seq_show(struct seq_file *seq);
#else
static inline void mptcp_init(void)
@@ -145,5 +146,6 @@ static inline bool mptcp_sk_is_subflow(const struct sock *sk)
return false;
}
+static inline void mptcp_seq_show(struct seq_file *seq) { }
#endif /* CONFIG_MPTCP */
#endif /* __NET_MPTCP_H */
diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
index 830bdf345b17..59fcaef98fb8 100644
--- a/include/net/netns/mib.h
+++ b/include/net/netns/mib.h
@@ -24,6 +24,9 @@ struct netns_mib {
#ifdef CONFIG_XFRM_STATISTICS
DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
#endif
+#ifdef CONFIG_MPTCP
+ DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics);
+#endif
};
#endif
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 70f92aaca411..3b2817267989 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1793,6 +1793,10 @@ static __net_exit void ipv4_mib_exit_net(struct net *net)
free_percpu(net->mib.net_statistics);
free_percpu(net->mib.ip_statistics);
free_percpu(net->mib.tcp_statistics);
+#ifdef CONFIG_MPTCP
+ /* allocated on demand, see mptcp_init_sock() */
+ free_percpu(net->mib.mptcp_statistics);
+#endif
}
static __net_initdata struct pernet_operations ipv4_mib_ops = {
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index cc90243ccf76..aeb9be9a9cdb 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -32,6 +32,7 @@
#include <net/icmp.h>
#include <net/protocol.h>
#include <net/tcp.h>
+#include <net/mptcp.h>
#include <net/udp.h>
#include <net/udplite.h>
#include <linux/bottom_half.h>
@@ -483,6 +484,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
offsetof(struct ipstats_mib, syncp)));
seq_putc(seq, '\n');
+ mptcp_seq_show(seq);
return 0;
}
diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
index 289fdf4339c1..77da3f45cc97 100644
--- a/net/mptcp/Makefile
+++ b/net/mptcp/Makefile
@@ -1,4 +1,4 @@
# SPDX-License-Identifier: GPL-2.0
obj-$(CONFIG_MPTCP) += mptcp.o
-mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o
+mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o mib.o
diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
new file mode 100644
index 000000000000..975a29237260
--- /dev/null
+++ b/net/mptcp/mib.c
@@ -0,0 +1,95 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+#include <linux/seq_file.h>
+#include <net/ip.h>
+#include <net/snmp.h>
+#include <net/net_namespace.h>
+
+#include "mib.h"
+
+static const struct snmp_mib mptcp_snmp_list[] = {
+ SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE),
+ SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE),
+ SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK),
+ SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK),
+ SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK),
+ SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
+ SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK),
+ SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED),
+ SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
+ SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX),
+ SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL),
+ SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX),
+ SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX),
+ SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB),
+ SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT),
+ SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB),
+ SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT),
+ SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB),
+ SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
+ SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK),
+ SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX),
+ SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX),
+ SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX),
+ SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
+ SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
+ SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
+ SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL),
+ SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO),
+ SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT),
+ SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW),
+ SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
+ SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
+ SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
+ SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD),
+ SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL),
+ SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD),
+ SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX),
+ SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX),
+ SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX),
+ SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX),
+ SNMP_MIB_SENTINEL
+};
+
+/* mptcp_mib_alloc - allocate percpu mib counters
+ *
+ * These are allocated when the first mptcp socket is created so
+ * we do not waste percpu memory if mptcp isn't in use.
+ */
+bool mptcp_mib_alloc(struct net *net)
+{
+ struct mptcp_mib *mib = alloc_percpu(struct mptcp_mib);
+
+ if (!mib)
+ return false;
+
+ if (cmpxchg(&net->mib.mptcp_statistics, NULL, mib))
+ free_percpu(mib);
+
+ return true;
+}
+
+void mptcp_seq_show(struct seq_file *seq)
+{
+ struct net *net = seq->private;
+ int i;
+
+ seq_puts(seq, "MPTcpExt:");
+ for (i = 0; mptcp_snmp_list[i].name; i++)
+ seq_printf(seq, " %s", mptcp_snmp_list[i].name);
+
+ seq_puts(seq, "\nMPTcpExt:");
+
+ if (!net->mib.mptcp_statistics) {
+ for (i = 0; mptcp_snmp_list[i].name; i++)
+ seq_printf(seq, " %lu", 0ul);
+
+ return;
+ }
+
+ for (i = 0; mptcp_snmp_list[i].name; i++)
+ seq_printf(seq, " %lu",
+ snmp_fold_field(net->mib.mptcp_statistics,
+ mptcp_snmp_list[i].entry));
+ seq_putc(seq, '\n');
+}
diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
new file mode 100644
index 000000000000..c24c41dc330c
--- /dev/null
+++ b/net/mptcp/mib.h
@@ -0,0 +1,67 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+
+enum linux_mptcp_mib_field {
+ MPTCP_MIB_NUM = 0,
+ MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */
+ MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */
+ MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */
+ MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */
+ MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */
+ MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
+ MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */
+ MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */
+ MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */
+ MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */
+ MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */
+ MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */
+ MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */
+ MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */
+ MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */
+ MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */
+ MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */
+ MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */
+ MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */
+ MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */
+ MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */
+ MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */
+ MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */
+ MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */
+ MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
+ MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
+ MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */
+ MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */
+ MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */
+ MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */
+ MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
+ MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
+ MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */
+ MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */
+ MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */
+ MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */
+ MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */
+ MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */
+ MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */
+ MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */
+ __MPTCP_MIB_MAX
+};
+
+#define LINUX_MIB_MPTCP_MAX __MPTCP_MIB_MAX
+struct mptcp_mib {
+ unsigned long mibs[LINUX_MIB_MPTCP_MAX];
+};
+
+static inline void MPTCP_INC_STATS(struct net *net,
+ enum linux_mptcp_mib_field field)
+{
+ if (likely(net->mib.mptcp_statistics))
+ SNMP_INC_STATS(net->mib.mptcp_statistics, field);
+}
+
+static inline void __MPTCP_INC_STATS(struct net *net,
+ enum linux_mptcp_mib_field field)
+{
+ if (likely(net->mib.mptcp_statistics))
+ __SNMP_INC_STATS(net->mib.mptcp_statistics, field);
+}
+
+bool mptcp_mib_alloc(struct net *net);
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 9c019e696fc7..66ac7dafe388 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -16,6 +16,7 @@
#include <net/tcp.h>
#include <net/mptcp.h>
#include "protocol.h"
+#include "mib.h"
static inline bool before64(__u64 seq1, __u64 seq2)
{
@@ -621,9 +622,14 @@ static int __mptcp_init_sock(struct sock *sk)
static int mptcp_init_sock(struct sock *sk)
{
- if (!mptcp_is_enabled(sock_net(sk)))
+ struct net *net = sock_net(sk);
+
+ if (!mptcp_is_enabled(net))
return -ENOPROTOOPT;
+ if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
+ return -ENOMEM;
+
return __mptcp_init_sock(sk);
}
--
2.21.0
^ permalink raw reply related [flat|nested] 4+ messages in thread
* Re: [MPTCP] [PATCH 1/2] mptcp: add MIB counter infrastructure
@ 2019-09-21 0:00 Mat Martineau
0 siblings, 0 replies; 4+ messages in thread
From: Mat Martineau @ 2019-09-21 0:00 UTC (permalink / raw)
To: mptcp
[-- Attachment #1: Type: text/plain, Size: 13125 bytes --]
On Fri, 20 Sep 2019, Florian Westphal wrote:
> Exported via same /proc file as the Linux TCP MIB counters.
> This means tools like 'nstat' will pick them up automatically.
>
> The MPTCP MIB counters are allocated in a distinct pcpu area in order to
> avoid bloating/wasting TCP pcpu memory.
>
> The counters are allocated once the first MPTCP socket is created in a
> network namespace.
>
> The Names are taken from the multipath-tcp.org kernel, in case we don't
> need all of them the extra ones should be pruned. But for now i've
> added all on the grounds that they are probably useful (i.e., make
> use of them).
>
Hi Florian -
I went through all the code and don't have any changes to suggest.
Regarding the extra entries, there are some that have to do with features
we aren't planning to support right away (checksum-related, mostly), but
may be relevant later. Is it better to prune them and add back later, or
just leave them there?
Mat
> Signed-off-by: Florian Westphal <fw(a)strlen.de>
> ---
> include/net/mptcp.h | 2 +
> include/net/netns/mib.h | 3 ++
> net/ipv4/af_inet.c | 4 ++
> net/ipv4/proc.c | 2 +
> net/mptcp/Makefile | 2 +-
> net/mptcp/mib.c | 95 +++++++++++++++++++++++++++++++++++++++++
> net/mptcp/mib.h | 67 +++++++++++++++++++++++++++++
> net/mptcp/protocol.c | 8 +++-
> 8 files changed, 181 insertions(+), 2 deletions(-)
> create mode 100644 net/mptcp/mib.c
> create mode 100644 net/mptcp/mib.h
>
> diff --git a/include/net/mptcp.h b/include/net/mptcp.h
> index 50cd1b31ebdd..c4f4fdd57c74 100644
> --- a/include/net/mptcp.h
> +++ b/include/net/mptcp.h
> @@ -82,6 +82,7 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
>
> bool mptcp_sk_is_subflow(const struct sock *sk);
>
> +void mptcp_seq_show(struct seq_file *seq);
> #else
>
> static inline void mptcp_init(void)
> @@ -145,5 +146,6 @@ static inline bool mptcp_sk_is_subflow(const struct sock *sk)
> return false;
> }
>
> +static inline void mptcp_seq_show(struct seq_file *seq) { }
> #endif /* CONFIG_MPTCP */
> #endif /* __NET_MPTCP_H */
> diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
> index 830bdf345b17..59fcaef98fb8 100644
> --- a/include/net/netns/mib.h
> +++ b/include/net/netns/mib.h
> @@ -24,6 +24,9 @@ struct netns_mib {
> #ifdef CONFIG_XFRM_STATISTICS
> DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
> #endif
> +#ifdef CONFIG_MPTCP
> + DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics);
> +#endif
> };
>
> #endif
> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index 70f92aaca411..3b2817267989 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -1793,6 +1793,10 @@ static __net_exit void ipv4_mib_exit_net(struct net *net)
> free_percpu(net->mib.net_statistics);
> free_percpu(net->mib.ip_statistics);
> free_percpu(net->mib.tcp_statistics);
> +#ifdef CONFIG_MPTCP
> + /* allocated on demand, see mptcp_init_sock() */
> + free_percpu(net->mib.mptcp_statistics);
> +#endif
> }
>
> static __net_initdata struct pernet_operations ipv4_mib_ops = {
> diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
> index cc90243ccf76..aeb9be9a9cdb 100644
> --- a/net/ipv4/proc.c
> +++ b/net/ipv4/proc.c
> @@ -32,6 +32,7 @@
> #include <net/icmp.h>
> #include <net/protocol.h>
> #include <net/tcp.h>
> +#include <net/mptcp.h>
> #include <net/udp.h>
> #include <net/udplite.h>
> #include <linux/bottom_half.h>
> @@ -483,6 +484,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
> offsetof(struct ipstats_mib, syncp)));
>
> seq_putc(seq, '\n');
> + mptcp_seq_show(seq);
> return 0;
> }
>
> diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
> index 289fdf4339c1..77da3f45cc97 100644
> --- a/net/mptcp/Makefile
> +++ b/net/mptcp/Makefile
> @@ -1,4 +1,4 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_MPTCP) += mptcp.o
>
> -mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o
> +mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o mib.o
> diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
> new file mode 100644
> index 000000000000..975a29237260
> --- /dev/null
> +++ b/net/mptcp/mib.c
> @@ -0,0 +1,95 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#include <linux/seq_file.h>
> +#include <net/ip.h>
> +#include <net/snmp.h>
> +#include <net/net_namespace.h>
> +
> +#include "mib.h"
> +
> +static const struct snmp_mib mptcp_snmp_list[] = {
> + SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE),
> + SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE),
> + SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK),
> + SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK),
> + SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK),
> + SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
> + SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK),
> + SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED),
> + SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
> + SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX),
> + SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL),
> + SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX),
> + SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX),
> + SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB),
> + SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT),
> + SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB),
> + SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT),
> + SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB),
> + SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
> + SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK),
> + SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX),
> + SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX),
> + SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX),
> + SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
> + SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
> + SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
> + SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL),
> + SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO),
> + SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT),
> + SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW),
> + SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
> + SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
> + SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
> + SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD),
> + SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL),
> + SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD),
> + SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX),
> + SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX),
> + SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX),
> + SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX),
> + SNMP_MIB_SENTINEL
> +};
> +
> +/* mptcp_mib_alloc - allocate percpu mib counters
> + *
> + * These are allocated when the first mptcp socket is created so
> + * we do not waste percpu memory if mptcp isn't in use.
> + */
> +bool mptcp_mib_alloc(struct net *net)
> +{
> + struct mptcp_mib *mib = alloc_percpu(struct mptcp_mib);
> +
> + if (!mib)
> + return false;
> +
> + if (cmpxchg(&net->mib.mptcp_statistics, NULL, mib))
> + free_percpu(mib);
> +
> + return true;
> +}
> +
> +void mptcp_seq_show(struct seq_file *seq)
> +{
> + struct net *net = seq->private;
> + int i;
> +
> + seq_puts(seq, "MPTcpExt:");
> + for (i = 0; mptcp_snmp_list[i].name; i++)
> + seq_printf(seq, " %s", mptcp_snmp_list[i].name);
> +
> + seq_puts(seq, "\nMPTcpExt:");
> +
> + if (!net->mib.mptcp_statistics) {
> + for (i = 0; mptcp_snmp_list[i].name; i++)
> + seq_printf(seq, " %lu", 0ul);
> +
> + return;
> + }
> +
> + for (i = 0; mptcp_snmp_list[i].name; i++)
> + seq_printf(seq, " %lu",
> + snmp_fold_field(net->mib.mptcp_statistics,
> + mptcp_snmp_list[i].entry));
> + seq_putc(seq, '\n');
> +}
> diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
> new file mode 100644
> index 000000000000..c24c41dc330c
> --- /dev/null
> +++ b/net/mptcp/mib.h
> @@ -0,0 +1,67 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +enum linux_mptcp_mib_field {
> + MPTCP_MIB_NUM = 0,
> + MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */
> + MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
> + MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */
> + MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */
> + MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */
> + MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */
> + MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */
> + MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */
> + MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */
> + MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */
> + MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */
> + MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */
> + MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */
> + MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */
> + MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */
> + MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */
> + MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */
> + MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */
> + MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */
> + MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */
> + MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
> + MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
> + MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */
> + MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */
> + MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */
> + MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */
> + MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
> + MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
> + MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */
> + MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */
> + MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */
> + MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */
> + MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */
> + MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */
> + MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */
> + MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */
> + __MPTCP_MIB_MAX
> +};
> +
> +#define LINUX_MIB_MPTCP_MAX __MPTCP_MIB_MAX
> +struct mptcp_mib {
> + unsigned long mibs[LINUX_MIB_MPTCP_MAX];
> +};
> +
> +static inline void MPTCP_INC_STATS(struct net *net,
> + enum linux_mptcp_mib_field field)
> +{
> + if (likely(net->mib.mptcp_statistics))
> + SNMP_INC_STATS(net->mib.mptcp_statistics, field);
> +}
> +
> +static inline void __MPTCP_INC_STATS(struct net *net,
> + enum linux_mptcp_mib_field field)
> +{
> + if (likely(net->mib.mptcp_statistics))
> + __SNMP_INC_STATS(net->mib.mptcp_statistics, field);
> +}
> +
> +bool mptcp_mib_alloc(struct net *net);
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 9c019e696fc7..66ac7dafe388 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -16,6 +16,7 @@
> #include <net/tcp.h>
> #include <net/mptcp.h>
> #include "protocol.h"
> +#include "mib.h"
>
> static inline bool before64(__u64 seq1, __u64 seq2)
> {
> @@ -621,9 +622,14 @@ static int __mptcp_init_sock(struct sock *sk)
>
> static int mptcp_init_sock(struct sock *sk)
> {
> - if (!mptcp_is_enabled(sock_net(sk)))
> + struct net *net = sock_net(sk);
> +
> + if (!mptcp_is_enabled(net))
> return -ENOPROTOOPT;
>
> + if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
> + return -ENOMEM;
> +
> return __mptcp_init_sock(sk);
> }
>
> --
> 2.21.0
>
> _______________________________________________
> mptcp mailing list
> mptcp(a)lists.01.org
> https://lists.01.org/mailman/listinfo/mptcp
>
--
Mat Martineau
Intel
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [MPTCP] [PATCH 1/2] mptcp: add MIB counter infrastructure
@ 2019-09-21 7:28 Florian Westphal
0 siblings, 0 replies; 4+ messages in thread
From: Florian Westphal @ 2019-09-21 7:28 UTC (permalink / raw)
To: mptcp
[-- Attachment #1: Type: text/plain, Size: 613 bytes --]
Mat Martineau <mathew.j.martineau(a)linux.intel.com> wrote:
> I went through all the code and don't have any changes to suggest. Regarding
> the extra entries, there are some that have to do with features we aren't
> planning to support right away (checksum-related, mostly), but may be
> relevant later. Is it better to prune them and add back later, or just leave
> them there?
Prune. I can resubmit a v2 with only those counters left that are
likely going to be useful.
I can also start with adding the appropriate mib increments "for real"
rather than the toy patch i made.
Thanks,
Florian
^ permalink raw reply [flat|nested] 4+ messages in thread
* Re: [MPTCP] [PATCH 1/2] mptcp: add MIB counter infrastructure
@ 2019-09-23 16:55 Christoph Paasch
0 siblings, 0 replies; 4+ messages in thread
From: Christoph Paasch @ 2019-09-23 16:55 UTC (permalink / raw)
To: mptcp
[-- Attachment #1: Type: text/plain, Size: 13766 bytes --]
Hello,
some comments inline on the counters:
> On Sep 20, 2019, at 8:05 AM, Florian Westphal <fw(a)strlen.de> wrote:
>
> Exported via same /proc file as the Linux TCP MIB counters.
> This means tools like 'nstat' will pick them up automatically.
>
> The MPTCP MIB counters are allocated in a distinct pcpu area in order to
> avoid bloating/wasting TCP pcpu memory.
>
> The counters are allocated once the first MPTCP socket is created in a
> network namespace.
>
> The Names are taken from the multipath-tcp.org kernel, in case we don't
> need all of them the extra ones should be pruned. But for now i've
> added all on the grounds that they are probably useful (i.e., make
> use of them).
>
> Signed-off-by: Florian Westphal <fw(a)strlen.de>
> ---
> include/net/mptcp.h | 2 +
> include/net/netns/mib.h | 3 ++
> net/ipv4/af_inet.c | 4 ++
> net/ipv4/proc.c | 2 +
> net/mptcp/Makefile | 2 +-
> net/mptcp/mib.c | 95 +++++++++++++++++++++++++++++++++++++++++
> net/mptcp/mib.h | 67 +++++++++++++++++++++++++++++
> net/mptcp/protocol.c | 8 +++-
> 8 files changed, 181 insertions(+), 2 deletions(-)
> create mode 100644 net/mptcp/mib.c
> create mode 100644 net/mptcp/mib.h
>
> diff --git a/include/net/mptcp.h b/include/net/mptcp.h
> index 50cd1b31ebdd..c4f4fdd57c74 100644
> --- a/include/net/mptcp.h
> +++ b/include/net/mptcp.h
> @@ -82,6 +82,7 @@ void mptcp_write_options(__be32 *ptr, struct mptcp_out_options *opts);
>
> bool mptcp_sk_is_subflow(const struct sock *sk);
>
> +void mptcp_seq_show(struct seq_file *seq);
> #else
>
> static inline void mptcp_init(void)
> @@ -145,5 +146,6 @@ static inline bool mptcp_sk_is_subflow(const struct sock *sk)
> return false;
> }
>
> +static inline void mptcp_seq_show(struct seq_file *seq) { }
> #endif /* CONFIG_MPTCP */
> #endif /* __NET_MPTCP_H */
> diff --git a/include/net/netns/mib.h b/include/net/netns/mib.h
> index 830bdf345b17..59fcaef98fb8 100644
> --- a/include/net/netns/mib.h
> +++ b/include/net/netns/mib.h
> @@ -24,6 +24,9 @@ struct netns_mib {
> #ifdef CONFIG_XFRM_STATISTICS
> DEFINE_SNMP_STAT(struct linux_xfrm_mib, xfrm_statistics);
> #endif
> +#ifdef CONFIG_MPTCP
> + DEFINE_SNMP_STAT(struct mptcp_mib, mptcp_statistics);
> +#endif
> };
>
> #endif
> diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
> index 70f92aaca411..3b2817267989 100644
> --- a/net/ipv4/af_inet.c
> +++ b/net/ipv4/af_inet.c
> @@ -1793,6 +1793,10 @@ static __net_exit void ipv4_mib_exit_net(struct net *net)
> free_percpu(net->mib.net_statistics);
> free_percpu(net->mib.ip_statistics);
> free_percpu(net->mib.tcp_statistics);
> +#ifdef CONFIG_MPTCP
> + /* allocated on demand, see mptcp_init_sock() */
> + free_percpu(net->mib.mptcp_statistics);
> +#endif
> }
>
> static __net_initdata struct pernet_operations ipv4_mib_ops = {
> diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
> index cc90243ccf76..aeb9be9a9cdb 100644
> --- a/net/ipv4/proc.c
> +++ b/net/ipv4/proc.c
> @@ -32,6 +32,7 @@
> #include <net/icmp.h>
> #include <net/protocol.h>
> #include <net/tcp.h>
> +#include <net/mptcp.h>
> #include <net/udp.h>
> #include <net/udplite.h>
> #include <linux/bottom_half.h>
> @@ -483,6 +484,7 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
> offsetof(struct ipstats_mib, syncp)));
>
> seq_putc(seq, '\n');
> + mptcp_seq_show(seq);
> return 0;
> }
>
> diff --git a/net/mptcp/Makefile b/net/mptcp/Makefile
> index 289fdf4339c1..77da3f45cc97 100644
> --- a/net/mptcp/Makefile
> +++ b/net/mptcp/Makefile
> @@ -1,4 +1,4 @@
> # SPDX-License-Identifier: GPL-2.0
> obj-$(CONFIG_MPTCP) += mptcp.o
>
> -mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o
> +mptcp-y := protocol.o subflow.o options.o token.o crypto.o pm.o ctrl.o mib.o
> diff --git a/net/mptcp/mib.c b/net/mptcp/mib.c
> new file mode 100644
> index 000000000000..975a29237260
> --- /dev/null
> +++ b/net/mptcp/mib.c
> @@ -0,0 +1,95 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +#include <linux/seq_file.h>
> +#include <net/ip.h>
> +#include <net/snmp.h>
> +#include <net/net_namespace.h>
> +
> +#include "mib.h"
> +
> +static const struct snmp_mib mptcp_snmp_list[] = {
> + SNMP_MIB_ITEM("MPCapableSYNRX", MPTCP_MIB_MPCAPABLEPASSIVE),
> + SNMP_MIB_ITEM("MPCapableSYNTX", MPTCP_MIB_MPCAPABLEACTIVE),
> + SNMP_MIB_ITEM("MPCapableSYNACKRX", MPTCP_MIB_MPCAPABLEACTIVEACK),
> + SNMP_MIB_ITEM("MPCapableACKRX", MPTCP_MIB_MPCAPABLEPASSIVEACK),
> + SNMP_MIB_ITEM("MPCapableFallbackACK", MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK),
> + SNMP_MIB_ITEM("MPCapableFallbackSYNACK", MPTCP_MIB_MPCAPABLEACTIVEFALLBACK),
> + SNMP_MIB_ITEM("MPCapableRetransFallback", MPTCP_MIB_MPCAPABLERETRANSFALLBACK),
> + SNMP_MIB_ITEM("MPTCPCsumEnabled", MPTCP_MIB_CSUMENABLED),
> + SNMP_MIB_ITEM("MPTCPRetrans", MPTCP_MIB_RETRANSSEGS),
> + SNMP_MIB_ITEM("MPFailRX", MPTCP_MIB_MPFAILRX),
> + SNMP_MIB_ITEM("MPCsumFail", MPTCP_MIB_CSUMFAIL),
> + SNMP_MIB_ITEM("MPFastcloseRX", MPTCP_MIB_FASTCLOSERX),
> + SNMP_MIB_ITEM("MPFastcloseTX", MPTCP_MIB_FASTCLOSETX),
> + SNMP_MIB_ITEM("MPFallbackAckSub", MPTCP_MIB_FBACKSUB),
> + SNMP_MIB_ITEM("MPFallbackAckInit", MPTCP_MIB_FBACKINIT),
> + SNMP_MIB_ITEM("MPFallbackDataSub", MPTCP_MIB_FBDATASUB),
> + SNMP_MIB_ITEM("MPFallbackDataInit", MPTCP_MIB_FBDATAINIT),
> + SNMP_MIB_ITEM("MPRemoveAddrSubDelete", MPTCP_MIB_REMADDRSUB),
> + SNMP_MIB_ITEM("MPJoinNoTokenFound", MPTCP_MIB_JOINNOTOKEN),
> + SNMP_MIB_ITEM("MPJoinAlreadyFallenback", MPTCP_MIB_JOINFALLBACK),
> + SNMP_MIB_ITEM("MPJoinSynTx", MPTCP_MIB_JOINSYNTX),
> + SNMP_MIB_ITEM("MPJoinSynRx", MPTCP_MIB_JOINSYNRX),
> + SNMP_MIB_ITEM("MPJoinSynAckRx", MPTCP_MIB_JOINSYNACKRX),
> + SNMP_MIB_ITEM("MPJoinSynAckHMacFailure", MPTCP_MIB_JOINSYNACKMAC),
> + SNMP_MIB_ITEM("MPJoinAckRx", MPTCP_MIB_JOINACKRX),
> + SNMP_MIB_ITEM("MPJoinAckHMacFailure", MPTCP_MIB_JOINACKMAC),
> + SNMP_MIB_ITEM("MPJoinAckMissing", MPTCP_MIB_JOINACKFAIL),
> + SNMP_MIB_ITEM("MPJoinAckRTO", MPTCP_MIB_JOINACKRTO),
> + SNMP_MIB_ITEM("MPJoinAckRexmit", MPTCP_MIB_JOINACKRXMIT),
> + SNMP_MIB_ITEM("NoDSSInWindow", MPTCP_MIB_NODSSWINDOW),
> + SNMP_MIB_ITEM("DSSNotMatching", MPTCP_MIB_DSSNOMATCH),
> + SNMP_MIB_ITEM("InfiniteMapRx", MPTCP_MIB_INFINITEMAPRX),
> + SNMP_MIB_ITEM("DSSNoMatchTCP", MPTCP_MIB_DSSTCPMISMATCH),
> + SNMP_MIB_ITEM("DSSTrimHead", MPTCP_MIB_DSSTRIMHEAD),
> + SNMP_MIB_ITEM("DSSSplitTail", MPTCP_MIB_DSSSPLITTAIL),
> + SNMP_MIB_ITEM("DSSPurgeOldSubSegs", MPTCP_MIB_PURGEOLD),
> + SNMP_MIB_ITEM("AddAddrRx", MPTCP_MIB_ADDADDRRX),
> + SNMP_MIB_ITEM("AddAddrTx", MPTCP_MIB_ADDADDRTX),
> + SNMP_MIB_ITEM("RemAddrRx", MPTCP_MIB_REMADDRRX),
> + SNMP_MIB_ITEM("RemAddrTx", MPTCP_MIB_REMADDRTX),
I think these are roughly what we have in multipath-tcp.org <http://multipath-tcp.org/>.
And I think they are a bit too extensive (I just added whatever I could think of in multipath-tcp.org <http://multipath-tcp.org/> ;-) ). Like, ADDADDRTX/RX,... JoinSynTX (will be steered by the user-space path-manager),...
We are not really looking at them that much. It's more about the error-conditions that are interesting in ratio with the number of established connections. For example, MPTCP_MIB_JOINNOTOKEN is very useful because it is an indicator that the subflow-steering behind the loadbalancer is not working correctly.
Maybe we start with the most minimal set of counters and can add later on as more ops-experience is being gathered?
> + SNMP_MIB_SENTINEL
> +};
A very useful MIB is a counter for the currently established MPTCP-connections, and MPTCP-subflows (similar to what TCP offers with TCP_MIB_CURRESTAB).
Christoph
> +
> +/* mptcp_mib_alloc - allocate percpu mib counters
> + *
> + * These are allocated when the first mptcp socket is created so
> + * we do not waste percpu memory if mptcp isn't in use.
> + */
> +bool mptcp_mib_alloc(struct net *net)
> +{
> + struct mptcp_mib *mib = alloc_percpu(struct mptcp_mib);
> +
> + if (!mib)
> + return false;
> +
> + if (cmpxchg(&net->mib.mptcp_statistics, NULL, mib))
> + free_percpu(mib);
> +
> + return true;
> +}
> +
> +void mptcp_seq_show(struct seq_file *seq)
> +{
> + struct net *net = seq->private;
> + int i;
> +
> + seq_puts(seq, "MPTcpExt:");
> + for (i = 0; mptcp_snmp_list[i].name; i++)
> + seq_printf(seq, " %s", mptcp_snmp_list[i].name);
> +
> + seq_puts(seq, "\nMPTcpExt:");
> +
> + if (!net->mib.mptcp_statistics) {
> + for (i = 0; mptcp_snmp_list[i].name; i++)
> + seq_printf(seq, " %lu", 0ul);
> +
> + return;
> + }
> +
> + for (i = 0; mptcp_snmp_list[i].name; i++)
> + seq_printf(seq, " %lu",
> + snmp_fold_field(net->mib.mptcp_statistics,
> + mptcp_snmp_list[i].entry));
> + seq_putc(seq, '\n');
> +}
> diff --git a/net/mptcp/mib.h b/net/mptcp/mib.h
> new file mode 100644
> index 000000000000..c24c41dc330c
> --- /dev/null
> +++ b/net/mptcp/mib.h
> @@ -0,0 +1,67 @@
> +/* SPDX-License-Identifier: GPL-2.0-or-later */
> +
> +enum linux_mptcp_mib_field {
> + MPTCP_MIB_NUM = 0,
> + MPTCP_MIB_MPCAPABLEPASSIVE, /* Received SYN with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEACTIVE, /* Sent SYN with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEACTIVEACK, /* Received SYN/ACK with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEPASSIVEACK, /* Received third ACK with MP_CAPABLE */
> + MPTCP_MIB_MPCAPABLEPASSIVEFALLBACK,/* Server-side fallback during 3-way handshake */
> + MPTCP_MIB_MPCAPABLEACTIVEFALLBACK, /* Client-side fallback during 3-way handshake */
> + MPTCP_MIB_MPCAPABLERETRANSFALLBACK,/* Client-side stopped sending MP_CAPABLE after too many SYN-retransmissions */
> + MPTCP_MIB_CSUMENABLED, /* Created MPTCP-connection with DSS-checksum enabled */
> + MPTCP_MIB_RETRANSSEGS, /* Segments retransmitted at the MPTCP-level */
> + MPTCP_MIB_MPFAILRX, /* Received an MP_FAIL */
> + MPTCP_MIB_CSUMFAIL, /* Received segment with invalid checksum */
> + MPTCP_MIB_FASTCLOSERX, /* Recevied a FAST_CLOSE */
> + MPTCP_MIB_FASTCLOSETX, /* Sent a FAST_CLOSE */
> + MPTCP_MIB_FBACKSUB, /* Fallback upon ack without data-ack on new subflow */
> + MPTCP_MIB_FBACKINIT, /* Fallback upon ack without data-ack on initial subflow */
> + MPTCP_MIB_FBDATASUB, /* Fallback upon data without DSS at the beginning on new subflow */
> + MPTCP_MIB_FBDATAINIT, /* Fallback upon data without DSS at the beginning on initial subflow */
> + MPTCP_MIB_REMADDRSUB, /* Remove subflow due to REMOVE_ADDR */
> + MPTCP_MIB_JOINNOTOKEN, /* Received MP_JOIN but the token was not found */
> + MPTCP_MIB_JOINFALLBACK, /* Received MP_JOIN on session that has fallen back to reg. TCP */
> + MPTCP_MIB_JOINSYNTX, /* Sent a SYN + MP_JOIN */
> + MPTCP_MIB_JOINSYNRX, /* Received a SYN + MP_JOIN */
> + MPTCP_MIB_JOINSYNACKRX, /* Received a SYN/ACK + MP_JOIN */
> + MPTCP_MIB_JOINSYNACKMAC, /* HMAC was wrong on SYN/ACK + MP_JOIN */
> + MPTCP_MIB_JOINACKRX, /* Received an ACK + MP_JOIN */
> + MPTCP_MIB_JOINACKMAC, /* HMAC was wrong on ACK + MP_JOIN */
> + MPTCP_MIB_JOINACKFAIL, /* Third ACK on new subflow did not contain an MP_JOIN */
> + MPTCP_MIB_JOINACKRTO, /* Retransmission timer for third ACK + MP_JOIN timed out */
> + MPTCP_MIB_JOINACKRXMIT, /* Retransmitted an ACK + MP_JOIN */
> + MPTCP_MIB_NODSSWINDOW, /* Received too many packets without a DSS-option */
> + MPTCP_MIB_DSSNOMATCH, /* Received a new mapping that did not match the previous one */
> + MPTCP_MIB_INFINITEMAPRX, /* Received an infinite mapping */
> + MPTCP_MIB_DSSTCPMISMATCH, /* DSS-mapping did not map with TCP's sequence numbers */
> + MPTCP_MIB_DSSTRIMHEAD, /* Trimmed segment at the head (coalescing middlebox) */
> + MPTCP_MIB_DSSSPLITTAIL, /* Trimmed segment at the tail (coalescing middlebox) */
> + MPTCP_MIB_PURGEOLD, /* Removed old skb from the rcv-queue due to missing DSS-mapping */
> + MPTCP_MIB_ADDADDRRX, /* Received an ADD_ADDR */
> + MPTCP_MIB_ADDADDRTX, /* Sent an ADD_ADDR */
> + MPTCP_MIB_REMADDRRX, /* Received a REMOVE_ADDR */
> + MPTCP_MIB_REMADDRTX, /* Sent a REMOVE_ADDR */
> + __MPTCP_MIB_MAX
> +};
> +
> +#define LINUX_MIB_MPTCP_MAX __MPTCP_MIB_MAX
> +struct mptcp_mib {
> + unsigned long mibs[LINUX_MIB_MPTCP_MAX];
> +};
> +
> +static inline void MPTCP_INC_STATS(struct net *net,
> + enum linux_mptcp_mib_field field)
> +{
> + if (likely(net->mib.mptcp_statistics))
> + SNMP_INC_STATS(net->mib.mptcp_statistics, field);
> +}
> +
> +static inline void __MPTCP_INC_STATS(struct net *net,
> + enum linux_mptcp_mib_field field)
> +{
> + if (likely(net->mib.mptcp_statistics))
> + __SNMP_INC_STATS(net->mib.mptcp_statistics, field);
> +}
> +
> +bool mptcp_mib_alloc(struct net *net);
> diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
> index 9c019e696fc7..66ac7dafe388 100644
> --- a/net/mptcp/protocol.c
> +++ b/net/mptcp/protocol.c
> @@ -16,6 +16,7 @@
> #include <net/tcp.h>
> #include <net/mptcp.h>
> #include "protocol.h"
> +#include "mib.h"
>
> static inline bool before64(__u64 seq1, __u64 seq2)
> {
> @@ -621,9 +622,14 @@ static int __mptcp_init_sock(struct sock *sk)
>
> static int mptcp_init_sock(struct sock *sk)
> {
> - if (!mptcp_is_enabled(sock_net(sk)))
> + struct net *net = sock_net(sk);
> +
> + if (!mptcp_is_enabled(net))
> return -ENOPROTOOPT;
>
> + if (unlikely(!net->mib.mptcp_statistics) && !mptcp_mib_alloc(net))
> + return -ENOMEM;
> +
> return __mptcp_init_sock(sk);
> }
>
> --
> 2.21.0
>
> _______________________________________________
> mptcp mailing list
> mptcp(a)lists.01.org
> https://lists.01.org/mailman/listinfo/mptcp
[-- Attachment #2: attachment.html --]
[-- Type: text/html, Size: 31746 bytes --]
^ permalink raw reply [flat|nested] 4+ messages in thread
end of thread, other threads:[~2019-09-23 16:55 UTC | newest]
Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-09-21 7:28 [MPTCP] [PATCH 1/2] mptcp: add MIB counter infrastructure Florian Westphal
-- strict thread matches above, loose matches on Subject: below --
2019-09-23 16:55 Christoph Paasch
2019-09-21 0:00 Mat Martineau
2019-09-20 15:05 Florian Westphal
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.