From: Joe Williams Date: Wed, 10 Aug 2016 14:06:44 +0000 (-0700) Subject: MINOR: tcp: add further tcp info fetchers X-Git-Tag: v1.7-dev4~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=30fcd39f35a4fe0146b3b60948cf130073b991f9;p=thirdparty%2Fhaproxy.git MINOR: tcp: add further tcp info fetchers Adding on to Thierry's work (http://git.haproxy.org/?p=haproxy.git;h=6310bef5) I have added a few more fetchers for counters based on the tcp_info struct maintained by the kernel : fc_unacked, fc_sacked, fc_retrans, fc_fackets, fc_lost, fc_reordering Two fields were not added because they're version-dependant : fc_rcv_rtt, fc_total_retrans The fields name depend on the operating system. FreeBSD and NetBSD prefix all the field names with "__" so we have to rely on a few #ifdef for portability. --- diff --git a/doc/configuration.txt b/doc/configuration.txt index 430b0ca880..9809360d34 100644 --- a/doc/configuration.txt +++ b/doc/configuration.txt @@ -12767,6 +12767,42 @@ fc_rttvar() : integer operating system does not support TCP_INFO, for example Linux kernels before 2.4, the sample fetch fails. +fc_unacked() : integer + Returns the unacked counter measured by the kernel for the client connection. + If the server connection is not established, if the connection is not TCP or + if the operating system does not support TCP_INFO, for example Linux kernels + before 2.4, the sample fetch fails. + +fc_sacked() : integer + Returns the sacked counter measured by the kernel for the client connection. + If the server connection is not established, if the connection is not TCP or + if the operating system does not support TCP_INFO, for example Linux kernels + before 2.4, the sample fetch fails. + +fc_retrans() : integer + Returns the retransmits counter measured by the kernel for the client + connection. If the server connection is not established, if the connection is + not TCP or if the operating system does not support TCP_INFO, for example + Linux kernels before 2.4, the sample fetch fails. + +fc_fackets() : integer + Returns the fack counter measured by the kernel for the client + connection. If the server connection is not established, if the connection is + not TCP or if the operating system does not support TCP_INFO, for example + Linux kernels before 2.4, the sample fetch fails. + +fc_lost() : integer + Returns the lost counter measured by the kernel for the client + connection. If the server connection is not established, if the connection is + not TCP or if the operating system does not support TCP_INFO, for example + Linux kernels before 2.4, the sample fetch fails. + +fc_reordering() : integer + Returns the reordering counter measured by the kernel for the client + connection. If the server connection is not established, if the connection is + not TCP or if the operating system does not support TCP_INFO, for example + Linux kernels before 2.4, the sample fetch fails. + fe_id : integer Returns an integer containing the current frontend's id. It can be used in backends to check from which backend it was called, or to stick all users diff --git a/src/proto_tcp.c b/src/proto_tcp.c index 797ddcbb40..9c5ea98b71 100644 --- a/src/proto_tcp.c +++ b/src/proto_tcp.c @@ -2395,8 +2395,25 @@ static inline int get_tcp_info(const struct arg *args, struct sample *smp, /* extract the value. */ smp->data.type = SMP_T_SINT; switch (val) { - case 0: smp->data.u.sint = info.tcpi_rtt; break; - case 1: smp->data.u.sint = info.tcpi_rttvar; break; + case 0: smp->data.u.sint = info.tcpi_rtt; break; + case 1: smp->data.u.sint = info.tcpi_rttvar; break; +#if defined(__linux__) + /* these ones are common to all Linux versions */ + case 2: smp->data.u.sint = info.tcpi_unacked; break; + case 3: smp->data.u.sint = info.tcpi_sacked; break; + case 4: smp->data.u.sint = info.tcpi_lost; break; + case 5: smp->data.u.sint = info.tcpi_retrans; break; + case 6: smp->data.u.sint = info.tcpi_fackets; break; + case 7: smp->data.u.sint = info.tcpi_reordering; break; +#elif defined(__FreeBSD__) || defined(__NetBSD__) + /* the ones are found on FreeBSD and NetBSD featuring TCP_INFO */ + case 2: smp->data.u.sint = info.__tcpi_unacked; break; + case 3: smp->data.u.sint = info.__tcpi_sacked; break; + case 4: smp->data.u.sint = info.__tcpi_lost; break; + case 5: smp->data.u.sint = info.__tcpi_retrans; break; + case 6: smp->data.u.sint = info.__tcpi_fackets; break; + case 7: smp->data.u.sint = info.__tcpi_reordering; break; +#endif default: return 0; } @@ -2435,7 +2452,64 @@ smp_fetch_fc_rttvar(const struct arg *args, struct sample *smp, const char *kw, return 0; return 1; } -#endif + +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) + +/* get the unacked counter on a client connexion */ +static int +smp_fetch_fc_unacked(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + if (!get_tcp_info(args, smp, 0, 2)) + return 0; + return 1; +} + +/* get the sacked counter on a client connexion */ +static int +smp_fetch_fc_sacked(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + if (!get_tcp_info(args, smp, 0, 3)) + return 0; + return 1; +} + +/* get the lost counter on a client connexion */ +static int +smp_fetch_fc_lost(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + if (!get_tcp_info(args, smp, 0, 4)) + return 0; + return 1; +} + +/* get the retrans counter on a client connexion */ +static int +smp_fetch_fc_retrans(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + if (!get_tcp_info(args, smp, 0, 5)) + return 0; + return 1; +} + +/* get the fackets counter on a client connexion */ +static int +smp_fetch_fc_fackets(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + if (!get_tcp_info(args, smp, 0, 6)) + return 0; + return 1; +} + +/* get the reordering counter on a client connexion */ +static int +smp_fetch_fc_reordering(const struct arg *args, struct sample *smp, const char *kw, void *private) +{ + if (!get_tcp_info(args, smp, 0, 7)) + return 0; + return 1; +} +#endif // linux || freebsd || netbsd +#endif // TCP_INFO #ifdef IPV6_V6ONLY /* parse the "v4v6" bind keyword */ @@ -2667,9 +2741,17 @@ static struct sample_fetch_kw_list sample_fetch_keywords = {ILH, { { "src_is_local", smp_fetch_src_is_local, 0, NULL, SMP_T_BOOL, SMP_USE_L4CLI }, { "src_port", smp_fetch_sport, 0, NULL, SMP_T_SINT, SMP_USE_L4CLI }, #ifdef TCP_INFO - { "fc_rtt", smp_fetch_fc_rtt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, - { "fc_rttvar", smp_fetch_fc_rttvar, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, -#endif + { "fc_rtt", smp_fetch_fc_rtt, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "fc_rttvar", smp_fetch_fc_rttvar, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, +#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) + { "fc_unacked", smp_fetch_fc_unacked, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "fc_sacked", smp_fetch_fc_sacked, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "fc_retrans", smp_fetch_fc_retrans, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "fc_fackets", smp_fetch_fc_fackets, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "fc_lost", smp_fetch_fc_lost, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, + { "fc_reordering", smp_fetch_fc_reordering, ARG1(0,STR), NULL, SMP_T_SINT, SMP_USE_L4CLI }, +#endif // linux || freebsd || netbsd +#endif // TCP_INFO { /* END */ }, }};