From: Kevin Darbyshire-Bryant <kevin@darbyshire-bryant.me.uk>
To: <cake@lists.bufferbloat.net>
Subject: Re: [Cake] de-natting & host fairness
Date: Tue, 27 Sep 2016 16:28:50 +0100 [thread overview]
Message-ID: <e4c3e32e-68bd-7cba-da13-3a68e17a5dac@darbyshire-bryant.me.uk> (raw)
In-Reply-To: <d8c6114d-146f-6c21-b018-3661652512ff@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 3642 bytes --]
LEDE already has a patch included in the basefiles 'iproute2' package to
make tc cake aware. If you replace
package/network/utils/iproute2/patches/950-add-cake-to-tc.patch (which
is unaware of the nat options) with the attached nat option aware
version then recompile, you should find you've a 'natted cake' capable
version of the iproute utilities without adding extra packages, feeds etc.
I've not yet got around to adding a 'de-nat ipv6' option, so assuming
you've built my latest version of cake, it can be configured to de-nat
ipv4 but not ipv6.
Similarly I've not updated the LEDE stuff as I'd rather like some code
review/testing done before it gets pushed out....and I get shouted at
lots :-)
Kevin
On 27/09/16 15:52, Noah Causin wrote:
> Thank you for helping me get cake to compile on LEDE.
>
> The issue I have now is getting tc-adv to compile.
>
> I use this MakeFile:
> https://github.com/antoinedeschenes/openwrt-sqm/tree/master/net/tc-adv
>
> I use these commands to compile it:
>
> make package/feeds/sqm/tc-adv/clean -j 1 V=s
> make package/feeds/sqm/tc-adv/prepare
> USE_SOURCE_DIR=/home/n0man/Desktop/denat/ -j 1 V=s
> make package/feeds/sqm/tc-adv/compile -j 1 V=s
>
> These are the errors I get:
>
> *namespace.c: In function 'bind_etc':**
> **namespace.c:18:22: error: 'MAXPATHLEN' undeclared (first use in this
> function)**
> ** char etc_netns_path[MAXPATHLEN];**
> ** ^**
> **namespace.c:18:22: note: each undeclared identifier is reported only
> once for each function it appears in**
> **namespace.c:20:7: warning: unused variable 'etc_name'
> [-Wunused-variable]**
> ** char etc_name[MAXPATHLEN];**
> ** ^**
> **namespace.c:19:7: warning: unused variable 'netns_name'
> [-Wunused-variable]**
> ** char netns_name[MAXPATHLEN];**
> ** ^**
> **namespace.c:18:7: warning: unused variable 'etc_netns_path'
> [-Wunused-variable]**
> ** char etc_netns_path[MAXPATHLEN];**
> ** ^**
> **namespace.c: In function 'netns_switch':**
> **namespace.c:46:16: error: 'MAXPATHLEN' undeclared (first use in this
> function)**
> ** char net_path[MAXPATHLEN];**
> ** ^**
> **namespace.c:46:7: warning: unused variable 'net_path'
> [-Wunused-variable]**
> ** char net_path[MAXPATHLEN];**
> ** ^**
> **namespace.c: In function 'netns_get_fd':**
> **namespace.c:90:15: error: 'MAXPATHLEN' undeclared (first use in this
> function)**
> ** char pathbuf[MAXPATHLEN];**
> ** ^**
> **namespace.c:90:7: warning: unused variable 'pathbuf' [-Wunused-variable]**
> ** char pathbuf[MAXPATHLEN];**
> ** ^**
> **<builtin>: recipe for target 'namespace.o' failed**
> **make[4]: *** [namespace.o] Error 1**
> **make[4]: Leaving directory '/home/n0man/Desktop/denat/lib'*
>
> Any help would be appreciated.
>
> Thank you,
>
> Noah Causin
>
> On 9/26/2016 10:32 PM, Kevin Darbyshire-Bryant wrote:
>> Easy fix. See the added DEPENDS line in the attached patch for the
>> package Makefile :-)
>>
>> I'm guessing you've updated the git checkout hash to point at a
>> suitable place.
>>
>> Cheers,
>>
>> Kevin
>>
>>
>>
>> On 27/09/16 02:52, Noah Causin wrote:
>>> I've been trying to compile this on LEDE, but I get this error:
>>>
>>> Package kmod-sched-cake is missing dependencies for the following
>>> libraries:
>>> nf_conntrack.ko
>>>
>>>
>>
>>
>> _______________________________________________
>> Cake mailing list
>> Cake@lists.bufferbloat.net
>> https://lists.bufferbloat.net/listinfo/cake
>
>
>
> _______________________________________________
> Cake mailing list
> Cake@lists.bufferbloat.net
> https://lists.bufferbloat.net/listinfo/cake
>
[-- Attachment #2: 950-add-cake-to-tc.patch --]
[-- Type: text/x-patch, Size: 21004 bytes --]
--- a/include/linux/pkt_sched.h
+++ b/include/linux/pkt_sched.h
@@ -850,4 +850,57 @@ struct tc_pie_xstats {
__u32 maxq; /* maximum queue size */
__u32 ecn_mark; /* packets marked with ecn*/
};
+
+/* CAKE */
+enum {
+ TCA_CAKE_UNSPEC,
+ TCA_CAKE_BASE_RATE,
+ TCA_CAKE_DIFFSERV_MODE,
+ TCA_CAKE_ATM,
+ TCA_CAKE_FLOW_MODE,
+ TCA_CAKE_OVERHEAD,
+ TCA_CAKE_RTT,
+ TCA_CAKE_TARGET,
+ TCA_CAKE_AUTORATE,
+ TCA_CAKE_MEMORY,
+ TCA_CAKE_NAT_MODE,
+ __TCA_CAKE_MAX
+};
+#define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1)
+
+struct tc_cake_traffic_stats {
+ __u32 packets;
+ __u32 link_ms;
+ __u64 bytes;
+};
+
+#define TC_CAKE_MAX_TINS (8)
+struct tc_cake_xstats {
+ __u16 version; /* == 4, increments when struct extended */
+ __u8 max_tins; /* == TC_CAKE_MAX_TINS */
+ __u8 tin_cnt; /* <= TC_CAKE_MAX_TINS */
+
+ __u32 threshold_rate [TC_CAKE_MAX_TINS];
+ __u32 target_us [TC_CAKE_MAX_TINS];
+ struct tc_cake_traffic_stats sent [TC_CAKE_MAX_TINS];
+ struct tc_cake_traffic_stats dropped [TC_CAKE_MAX_TINS];
+ struct tc_cake_traffic_stats ecn_marked[TC_CAKE_MAX_TINS];
+ struct tc_cake_traffic_stats backlog [TC_CAKE_MAX_TINS];
+ __u32 interval_us [TC_CAKE_MAX_TINS];
+ __u32 way_indirect_hits[TC_CAKE_MAX_TINS];
+ __u32 way_misses [TC_CAKE_MAX_TINS];
+ __u32 way_collisions [TC_CAKE_MAX_TINS];
+ __u32 peak_delay_us [TC_CAKE_MAX_TINS]; /* ~= delay to bulk flows */
+ __u32 avge_delay_us [TC_CAKE_MAX_TINS];
+ __u32 base_delay_us [TC_CAKE_MAX_TINS]; /* ~= delay to sparse flows */
+ __u16 sparse_flows [TC_CAKE_MAX_TINS];
+ __u16 bulk_flows [TC_CAKE_MAX_TINS];
+ __u16 unresponse_flows [TC_CAKE_MAX_TINS]; /* v4 - was u32 last_len */
+ __u16 spare [TC_CAKE_MAX_TINS]; /* v4 - split last_len */
+ __u32 max_skblen [TC_CAKE_MAX_TINS];
+ __u32 capacity_estimate; /* version 2 */
+ __u32 memory_limit; /* version 3 */
+ __u32 memory_used; /* version 3 */
+};
+
#endif
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -63,6 +63,7 @@ TCMODULES += q_codel.o
TCMODULES += q_fq_codel.o
TCMODULES += q_fq.o
TCMODULES += q_pie.o
+TCMODULES += q_cake.o
TCMODULES += q_hhf.o
TCMODULES += e_bpf.o
--- /dev/null
+++ b/tc/q_cake.c
@@ -0,0 +1,637 @@
+/*
+ * Common Applications Kept Enhanced -- CAKE
+ *
+ * Copyright (C) 2014-2015 Jonathan Morton <chromatix99@gmail.com>
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions, and the following disclaimer,
+ * without modification.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. The names of the authors may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * Alternatively, provided that this notice is retained in full, this
+ * software may be distributed under the terms of the GNU General
+ * Public License ("GPL") version 2, in which case the provisions of the
+ * GPL apply INSTEAD OF those given above.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+
+#include "utils.h"
+#include "tc_util.h"
+
+static void explain(void)
+{
+ fprintf(stderr, "Usage: ... cake [ bandwidth RATE | unlimited* | autorate_ingress ]\n"
+ " [ rtt TIME | datacentre | lan | metro | regional | internet* | oceanic | satellite | interplanetary ]\n"
+ " [ besteffort | precedence | diffserv8 | diffserv4* ]\n"
+ " [ flowblind | srchost | dsthost | hosts | flows* | dual-srchost | dual-dsthost | triple-isolate ]\n"
+ " [ nonat* | srcnat | dstnat | nat ]\n"
+ " [ atm | noatm* ] [ overhead N | conservative | raw* ]\n"
+ " [ memlimit LIMIT ]\n"
+ " (* marks defaults)\n");
+}
+
+static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv,
+ struct nlmsghdr *n)
+{
+ int unlimited = 0;
+ unsigned bandwidth = 0;
+ unsigned interval = 0;
+ unsigned target = 0;
+ unsigned diffserv = 0;
+ unsigned memlimit = 0;
+ int overhead = 0;
+ bool overhead_set = false;
+ int flowmode = -1;
+ int natmode = -1;
+ int atm = -1;
+ int autorate = -1;
+ struct rtattr *tail;
+
+ while (argc > 0) {
+ if (strcmp(*argv, "bandwidth") == 0) {
+ NEXT_ARG();
+ if (get_rate(&bandwidth, *argv)) {
+ fprintf(stderr, "Illegal \"bandwidth\"\n");
+ return -1;
+ }
+ unlimited = 0;
+ autorate = 0;
+ } else if (strcmp(*argv, "unlimited") == 0) {
+ bandwidth = 0;
+ unlimited = 1;
+ autorate = 0;
+ } else if (strcmp(*argv, "autorate_ingress") == 0) {
+ autorate = 1;
+
+ } else if (strcmp(*argv, "rtt") == 0) {
+ NEXT_ARG();
+ if (get_time(&interval, *argv)) {
+ fprintf(stderr, "Illegal \"rtt\"\n");
+ return -1;
+ }
+ target = interval / 20;
+ if(!target)
+ target = 1;
+ } else if (strcmp(*argv, "datacentre") == 0) {
+ interval = 100;
+ target = 5;
+ } else if (strcmp(*argv, "lan") == 0) {
+ interval = 1000;
+ target = 50;
+ } else if (strcmp(*argv, "metro") == 0) {
+ interval = 10000;
+ target = 500;
+ } else if (strcmp(*argv, "regional") == 0) {
+ interval = 30000;
+ target = 1500;
+ } else if (strcmp(*argv, "internet") == 0) {
+ interval = 100000;
+ target = 5000;
+ } else if (strcmp(*argv, "oceanic") == 0) {
+ interval = 300000;
+ target = 15000;
+ } else if (strcmp(*argv, "satellite") == 0) {
+ interval = 1000000;
+ target = 50000;
+ } else if (strcmp(*argv, "interplanetary") == 0) {
+ interval = 3600000000U;
+ target = 5000;
+
+ } else if (strcmp(*argv, "besteffort") == 0) {
+ diffserv = 1;
+ } else if (strcmp(*argv, "precedence") == 0) {
+ diffserv = 2;
+ } else if (strcmp(*argv, "diffserv8") == 0) {
+ diffserv = 3;
+ } else if (strcmp(*argv, "diffserv4") == 0) {
+ diffserv = 4;
+ } else if (strcmp(*argv, "diffserv") == 0) {
+ diffserv = 4;
+ } else if (strcmp(*argv, "diffserv-llt") == 0) {
+ diffserv = 5;
+
+ } else if (strcmp(*argv, "flowblind") == 0) {
+ flowmode = 0;
+ } else if (strcmp(*argv, "srchost") == 0) {
+ flowmode = 1;
+ } else if (strcmp(*argv, "dsthost") == 0) {
+ flowmode = 2;
+ } else if (strcmp(*argv, "hosts") == 0) {
+ flowmode = 3;
+ } else if (strcmp(*argv, "flows") == 0) {
+ flowmode = 4;
+ } else if (strcmp(*argv, "dual-srchost") == 0) {
+ flowmode = 5;
+ } else if (strcmp(*argv, "dual-dsthost") == 0) {
+ flowmode = 6;
+ } else if (strcmp(*argv, "triple-isolate") == 0) {
+ flowmode = 7;
+
+ } else if (strcmp(*argv, "nonat") == 0) {
+ natmode = 0;
+ } else if (strcmp(*argv, "srcnat") == 0) {
+ natmode = 1;
+ } else if (strcmp(*argv, "dstnat") == 0) {
+ natmode = 2;
+ } else if (strcmp(*argv, "nat") == 0) {
+ natmode = 3;
+
+ } else if (strcmp(*argv, "atm") == 0) {
+ atm = 1;
+ } else if (strcmp(*argv, "noatm") == 0) {
+ atm = 0;
+
+ } else if (strcmp(*argv, "raw") == 0) {
+ atm = 0;
+ overhead = 0;
+ overhead_set = true;
+ } else if (strcmp(*argv, "conservative") == 0) {
+ /*
+ * Deliberately over-estimate overhead:
+ * one whole ATM cell plus ATM framing.
+ * A safe choice if the actual overhead is unknown.
+ */
+ atm = 1;
+ overhead = 48;
+ overhead_set = true;
+
+ /* Various ADSL framing schemes */
+ } else if (strcmp(*argv, "ipoa-vcmux") == 0) {
+ atm = 1;
+ overhead += 8;
+ overhead_set = true;
+ } else if (strcmp(*argv, "ipoa-llcsnap") == 0) {
+ atm = 1;
+ overhead += 16;
+ overhead_set = true;
+ } else if (strcmp(*argv, "bridged-vcmux") == 0) {
+ atm = 1;
+ overhead += 24;
+ overhead_set = true;
+ } else if (strcmp(*argv, "bridged-llcsnap") == 0) {
+ atm = 1;
+ overhead += 32;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoa-vcmux") == 0) {
+ atm = 1;
+ overhead += 10;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoa-llc") == 0) {
+ atm = 1;
+ overhead += 14;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoe-vcmux") == 0) {
+ atm = 1;
+ overhead += 32;
+ overhead_set = true;
+ } else if (strcmp(*argv, "pppoe-llcsnap") == 0) {
+ atm = 1;
+ overhead += 40;
+ overhead_set = true;
+
+ /* Typical VDSL2 framing schemes */
+ /* NB: PTM includes HDLC's 0x7D/7E expansion, adds extra 1/128 */
+ } else if (strcmp(*argv, "pppoe-ptm") == 0) {
+ atm = 0;
+ overhead += 27;
+ } else if (strcmp(*argv, "bridged-ptm") == 0) {
+ atm = 0;
+ overhead += 19;
+
+ } else if (strcmp(*argv, "via-ethernet") == 0) {
+ /*
+ * The above overheads are relative to an IP packet,
+ * but if the physical interface is Ethernet, Linux
+ * includes Ethernet framing overhead already.
+ */
+ overhead -= 14;
+ overhead_set = true;
+
+ /* Additional Ethernet-related overheads used by some ISPs */
+ } else if (strcmp(*argv, "ether-phy") == 0) {
+ /* ethernet pre-amble & interframe gap 20 bytes
+ * Linux will have already accounted for MACs & frame type 14 bytes
+ * you probably want to add an FCS as well*/
+ overhead += 20;
+ overhead_set = true;
+ } else if (strcmp(*argv, "ether-all") == 0) {
+ /* ethernet pre-amble & interframe gap & FCS
+ * Linux will have already accounted for MACs & frame type 14 bytes
+ * you may need to add vlan tag*/
+ overhead += 24;
+ overhead_set = true;
+
+ } else if (strcmp(*argv, "ether-fcs") == 0) {
+ /* Frame Check Sequence */
+ /* we ignore the minimum frame size, because IP packets usually meet it */
+ overhead += 4;
+ overhead_set = true;
+ } else if (strcmp(*argv, "ether-vlan") == 0) {
+ /* 802.1q VLAN tag - may be repeated */
+ overhead += 4;
+ overhead_set = true;
+
+ } else if (strcmp(*argv, "overhead") == 0) {
+ char* p = NULL;
+ NEXT_ARG();
+ overhead = strtol(*argv, &p, 10);
+ if(!p || *p || !*argv || overhead < -64 || overhead > 256) {
+ fprintf(stderr, "Illegal \"overhead\", valid range is -64 to 256\\n");
+ return -1;
+ }
+ overhead_set = true;
+
+ } else if (strcmp(*argv, "memlimit") == 0) {
+ NEXT_ARG();
+ if(get_size(&memlimit, *argv)) {
+ fprintf(stderr, "Illegal value for \"memlimit\": \"%s\"\n", *argv);
+ return -1;
+ }
+
+ } else if (strcmp(*argv, "help") == 0) {
+ explain();
+ return -1;
+ } else {
+ fprintf(stderr, "What is \"%s\"?\n", *argv);
+ explain();
+ return -1;
+ }
+ argc--; argv++;
+ }
+
+ tail = NLMSG_TAIL(n);
+ addattr_l(n, 1024, TCA_OPTIONS, NULL, 0);
+ if (bandwidth || unlimited)
+ addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwidth));
+ if (diffserv)
+ addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(diffserv));
+ if (atm != -1)
+ addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm));
+ if (flowmode != -1)
+ addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmode));
+ if (natmode != -1)
+ addattr_l(n, 1024, TCA_CAKE_NAT_MODE, &natmode, sizeof(natmode));
+ if (overhead_set)
+ addattr_l(n, 1024, TCA_CAKE_OVERHEAD, &overhead, sizeof(overhead));
+ if (interval)
+ addattr_l(n, 1024, TCA_CAKE_RTT, &interval, sizeof(interval));
+ if (target)
+ addattr_l(n, 1024, TCA_CAKE_TARGET, &target, sizeof(target));
+ if (autorate != -1)
+ addattr_l(n, 1024, TCA_CAKE_AUTORATE, &autorate, sizeof(autorate));
+ if (memlimit)
+ addattr_l(n, 1024, TCA_CAKE_MEMORY, &memlimit, sizeof(memlimit));
+
+ tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail;
+ return 0;
+}
+
+
+static int cake_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt)
+{
+ struct rtattr *tb[TCA_CAKE_MAX + 1];
+ unsigned bandwidth = 0;
+ unsigned diffserv = 0;
+ unsigned flowmode = 0;
+ unsigned natmode = 0;
+ unsigned interval = 0;
+ unsigned memlimit = 0;
+ int overhead = 0;
+ int atm = 0;
+ int autorate = 0;
+ SPRINT_BUF(b1);
+ SPRINT_BUF(b2);
+
+ if (opt == NULL)
+ return 0;
+
+ parse_rtattr_nested(tb, TCA_CAKE_MAX, opt);
+
+ if (tb[TCA_CAKE_BASE_RATE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >= sizeof(__u32)) {
+ bandwidth = rta_getattr_u32(tb[TCA_CAKE_BASE_RATE]);
+ if(bandwidth)
+ fprintf(f, "bandwidth %s ", sprint_rate(bandwidth, b1));
+ else
+ fprintf(f, "unlimited ");
+ }
+ if (tb[TCA_CAKE_AUTORATE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_AUTORATE]) >= sizeof(__u32)) {
+ autorate = rta_getattr_u32(tb[TCA_CAKE_AUTORATE]);
+ if(autorate == 1)
+ fprintf(f, "autorate_ingress ");
+ else if(autorate)
+ fprintf(f, "(?autorate?) ");
+ }
+ if (tb[TCA_CAKE_DIFFSERV_MODE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >= sizeof(__u32)) {
+ diffserv = rta_getattr_u32(tb[TCA_CAKE_DIFFSERV_MODE]);
+ switch(diffserv) {
+ case 1:
+ fprintf(f, "besteffort ");
+ break;
+ case 2:
+ fprintf(f, "precedence ");
+ break;
+ case 3:
+ fprintf(f, "diffserv8 ");
+ break;
+ case 4:
+ fprintf(f, "diffserv4 ");
+ break;
+ case 5:
+ fprintf(f, "diffserv-llt ");
+ break;
+ default:
+ fprintf(f, "(?diffserv?) ");
+ break;
+ };
+ }
+ if (tb[TCA_CAKE_FLOW_MODE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >= sizeof(__u32)) {
+ flowmode = rta_getattr_u32(tb[TCA_CAKE_FLOW_MODE]);
+ switch(flowmode) {
+ case 0:
+ fprintf(f, "flowblind ");
+ break;
+ case 1:
+ fprintf(f, "srchost ");
+ break;
+ case 2:
+ fprintf(f, "dsthost ");
+ break;
+ case 3:
+ fprintf(f, "hosts ");
+ break;
+ case 4:
+ fprintf(f, "flows ");
+ break;
+ case 5:
+ fprintf(f, "dual-srchost ");
+ break;
+ case 6:
+ fprintf(f, "dual-dsthost ");
+ break;
+ case 7:
+ fprintf(f, "triple-isolate ");
+ break;
+ default:
+ fprintf(f, "(?flowmode?) ");
+ break;
+ };
+ }
+
+ if (tb[TCA_CAKE_NAT_MODE] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_NAT_MODE]) >= sizeof(__u32)) {
+ natmode = rta_getattr_u32(tb[TCA_CAKE_NAT_MODE]);
+ switch(natmode) {
+ case 0:
+ fprintf(f, "nonat ");
+ break;
+ case 1:
+ fprintf(f, "srcnat ");
+ break;
+ case 2:
+ fprintf(f, "dstnat ");
+ break;
+ case 3:
+ fprintf(f, "nat ");
+ break;
+ default:
+ fprintf(f, "(?natmode?) ");
+ break;
+ };
+ }
+
+ if (tb[TCA_CAKE_ATM] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >= sizeof(__u32)) {
+ atm = rta_getattr_u32(tb[TCA_CAKE_ATM]);
+ }
+ if (tb[TCA_CAKE_OVERHEAD] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_OVERHEAD]) >= sizeof(__u32)) {
+ overhead = rta_getattr_u32(tb[TCA_CAKE_OVERHEAD]);
+ }
+ if (tb[TCA_CAKE_RTT] &&
+ RTA_PAYLOAD(tb[TCA_CAKE_RTT]) >= sizeof(__u32)) {
+ interval = rta_getattr_u32(tb[TCA_CAKE_RTT]);
+ }
+
+ if (interval)
+ fprintf(f, "rtt %s ", sprint_time(interval, b2));
+
+ if (atm)
+ fprintf(f, "atm ");
+ else if (overhead)
+ fprintf(f, "noatm ");
+
+ if (overhead || atm)
+ fprintf(f, "overhead %d ", overhead);
+
+ if (!atm && !overhead)
+ fprintf(f, "raw ");
+
+ if (memlimit)
+ fprintf(f, "memlimit %s", sprint_size(memlimit, b1));
+
+ return 0;
+}
+
+static int cake_print_xstats(struct qdisc_util *qu, FILE *f,
+ struct rtattr *xstats)
+{
+ /* fq_codel stats format borrowed */
+ struct tc_fq_codel_xstats *st;
+ struct tc_cake_xstats *stnc;
+ SPRINT_BUF(b1);
+ SPRINT_BUF(b2);
+
+ if (xstats == NULL)
+ return 0;
+
+ if (RTA_PAYLOAD(xstats) < sizeof(st->type))
+ return -1;
+
+ st = RTA_DATA(xstats);
+ stnc = RTA_DATA(xstats);
+
+ if (st->type == TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats) >= sizeof(*st)) {
+ fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u ecn_mark %u",
+ st->qdisc_stats.maxpacket,
+ st->qdisc_stats.drop_overlimit,
+ st->qdisc_stats.new_flow_count,
+ st->qdisc_stats.ecn_mark);
+ fprintf(f, "\n new_flows_len %u old_flows_len %u",
+ st->qdisc_stats.new_flows_len,
+ st->qdisc_stats.old_flows_len);
+ } else if (st->type == TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(xstats) >= sizeof(*st)) {
+ fprintf(f, " deficit %d count %u lastcount %u ldelay %s",
+ st->class_stats.deficit,
+ st->class_stats.count,
+ st->class_stats.lastcount,
+ sprint_time(st->class_stats.ldelay, b1));
+ if (st->class_stats.dropping) {
+ fprintf(f, " dropping");
+ if (st->class_stats.drop_next < 0)
+ fprintf(f, " drop_next -%s",
+ sprint_time(-st->class_stats.drop_next, b1));
+ else
+ fprintf(f, " drop_next %s",
+ sprint_time(st->class_stats.drop_next, b1));
+ }
+ } else if (stnc->version >= 1 && stnc->version < 0xFF
+ && stnc->max_tins == TC_CAKE_MAX_TINS
+ && RTA_PAYLOAD(xstats) >= offsetof(struct tc_cake_xstats, capacity_estimate))
+ {
+ int i;
+
+ if(stnc->version >= 3)
+ fprintf(f, " memory used: %s of %s\n", sprint_size(stnc->memory_used, b1), sprint_size(stnc->memory_limit, b2));
+
+ if(stnc->version >= 2)
+ fprintf(f, " capacity estimate: %s\n", sprint_rate(stnc->capacity_estimate, b1));
+
+ switch(stnc->tin_cnt) {
+ case 4:
+ fprintf(f, " Bulk Best Effort Video Voice\n");
+ break;
+
+ case 5:
+ fprintf(f, " Low Loss Best Effort Low Delay Bulk Net Control\n");
+ break;
+
+ default:
+ fprintf(f, " ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, " Tin %u", i);
+ fprintf(f, "\n");
+ };
+
+ fprintf(f, " thresh ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12s", sprint_rate(stnc->threshold_rate[i], b1));
+ fprintf(f, "\n");
+
+ fprintf(f, " target ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12s", sprint_time(stnc->target_us[i], b1));
+ fprintf(f, "\n");
+
+ fprintf(f, " interval");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12s", sprint_time(stnc->interval_us[i], b1));
+ fprintf(f, "\n");
+
+ fprintf(f, " pk_delay");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12s", sprint_time(stnc->peak_delay_us[i], b1));
+ fprintf(f, "\n");
+
+ fprintf(f, " av_delay");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12s", sprint_time(stnc->avge_delay_us[i], b1));
+ fprintf(f, "\n");
+
+ fprintf(f, " sp_delay");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12s", sprint_time(stnc->base_delay_us[i], b1));
+ fprintf(f, "\n");
+
+ fprintf(f, " pkts ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->sent[i].packets);
+ fprintf(f, "\n");
+
+ fprintf(f, " bytes ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12llu", stnc->sent[i].bytes);
+ fprintf(f, "\n");
+
+ fprintf(f, " way_inds");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->way_indirect_hits[i]);
+ fprintf(f, "\n");
+
+ fprintf(f, " way_miss");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->way_misses[i]);
+ fprintf(f, "\n");
+
+ fprintf(f, " way_cols");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->way_collisions[i]);
+ fprintf(f, "\n");
+
+ fprintf(f, " drops ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->dropped[i].packets);
+ fprintf(f, "\n");
+
+ fprintf(f, " marks ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->ecn_marked[i].packets);
+ fprintf(f, "\n");
+
+ fprintf(f, " sp_flows");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->sparse_flows[i]);
+ fprintf(f, "\n");
+
+ fprintf(f, " bk_flows");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->bulk_flows[i]);
+ fprintf(f, "\n");
+
+ if(stnc->version >= 4) {
+ fprintf(f, " un_flows");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->unresponse_flows[i]);
+ fprintf(f, "\n");
+ }
+
+ fprintf(f, " max_len ");
+ for(i=0; i < stnc->tin_cnt; i++)
+ fprintf(f, "%12u", stnc->max_skblen[i]);
+ fprintf(f, "\n");
+ } else {
+ return -1;
+ }
+ return 0;
+}
+
+struct qdisc_util cake_qdisc_util = {
+ .id = "cake",
+ .parse_qopt = cake_parse_opt,
+ .print_qopt = cake_print_opt,
+ .print_xstats = cake_print_xstats,
+};
next prev parent reply other threads:[~2016-09-27 15:28 UTC|newest]
Thread overview: 29+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-09-26 3:20 Kevin Darbyshire-Bryant
2016-09-26 3:54 ` Dave Taht
2016-09-26 5:11 ` Dave Taht
2016-09-26 8:54 ` moeller0
2016-09-26 13:02 ` Kevin Darbyshire-Bryant
2016-09-26 13:28 ` moeller0
2016-09-26 14:06 ` Kevin Darbyshire-Bryant
2016-09-26 14:30 ` Jonathan Morton
2016-09-26 15:23 ` moeller0
2016-09-27 1:52 ` Noah Causin
2016-09-27 2:32 ` Kevin Darbyshire-Bryant
2016-09-27 4:20 ` Noah Causin
2016-09-27 14:52 ` Noah Causin
2016-09-27 15:28 ` Kevin Darbyshire-Bryant [this message]
2016-09-27 20:40 ` Noah Causin
2016-09-27 20:44 ` Jonathan Morton
[not found] ` <CAA93jw6rPE8aAGEiqf7jp3hc1J0ThrVer8PFmFLPBqANdtEixg@mail.gmail.com>
2016-09-27 20:58 ` Noah Causin
2016-09-28 4:38 ` Kevin Darbyshire-Bryant
2016-09-28 5:08 ` Noah Causin
2016-09-27 23:08 ` Jonathan Morton
2016-09-28 2:56 ` Kevin Darbyshire-Bryant
2016-09-28 3:06 ` Jonathan Morton
2016-09-28 3:33 ` Kevin Darbyshire-Bryant
2016-09-28 3:49 ` Jonathan Morton
2016-09-28 6:07 ` Kevin Darbyshire-Bryant
2016-09-28 11:08 ` Kevin Darbyshire-Bryant
2016-09-28 11:49 ` Dave Taht
2016-09-28 14:11 ` Kevin Darbyshire-Bryant
2016-09-28 5:56 ` Sebastian Moeller
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://lists.bufferbloat.net/postorius/lists/cake.lists.bufferbloat.net/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=e4c3e32e-68bd-7cba-da13-3a68e17a5dac@darbyshire-bryant.me.uk \
--to=kevin@darbyshire-bryant.me.uk \
--cc=cake@lists.bufferbloat.net \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox