diff options
Diffstat (limited to 'package/network/utils/iproute2/patches/950-add-cake-to-tc.patch')
-rw-r--r-- | package/network/utils/iproute2/patches/950-add-cake-to-tc.patch | 850 |
1 files changed, 0 insertions, 850 deletions
diff --git a/package/network/utils/iproute2/patches/950-add-cake-to-tc.patch b/package/network/utils/iproute2/patches/950-add-cake-to-tc.patch deleted file mode 100644 index 882db8af19..0000000000 --- a/package/network/utils/iproute2/patches/950-add-cake-to-tc.patch +++ /dev/null @@ -1,850 +0,0 @@ ---- a/include/linux/pkt_sched.h -+++ b/include/linux/pkt_sched.h -@@ -850,4 +850,63 @@ 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, -+ TCA_CAKE_ETHERNET, -+ TCA_CAKE_WASH, -+ TCA_CAKE_MPU, -+ TCA_CAKE_INGRESS, -+ TCA_CAKE_ACK_FILTER, -+ __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; /* == 5, 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]; /* ~= bulk flow delay */ -+ __u32 avge_delay_us [TC_CAKE_MAX_TINS]; -+ __u32 base_delay_us [TC_CAKE_MAX_TINS]; /* ~= sparse flows delay */ -+ __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 */ -+ struct tc_cake_traffic_stats ack_drops [TC_CAKE_MAX_TINS]; /* v5 */ -+}; -+ - #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,771 @@ -+/* -+ * 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 |\n" -+" internet* | oceanic | satellite | interplanetary ]\n" -+" [ besteffort | diffserv8 | diffserv4 | diffserv-llt |\n" -+" diffserv3* ]\n" -+" [ flowblind | srchost | dsthost | hosts | flows |\n" -+" dual-srchost | dual-dsthost | triple-isolate* ]\n" -+" [ nat | nonat* ]\n" -+" [ wash | nowash * ]\n" -+" [ ack-filter | ack-filter-aggressive | no-ack-filter * ]\n" -+" [ memlimit LIMIT ]\n" -+" [ ptm | atm | noatm* ] [ overhead N | conservative | raw* ]\n" -+" [ mpu N ] [ ingress | egress* ]\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; -+ bool overhead_override = false; -+ int mpu = 0; -+ int flowmode = -1; -+ int nat = -1; -+ int atm = -1; -+ int autorate = -1; -+ int wash = -1; -+ int ingress = -1; -+ int ack_filter = -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, "diffserv3") == 0) { -+ diffserv = 6; -+ -+ } else if (strcmp(*argv, "nowash") == 0) { -+ wash = 0; -+ } else if (strcmp(*argv, "wash") == 0) { -+ wash = 1; -+ -+ } 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, "nat") == 0) { -+ nat = 1; -+ } else if (strcmp(*argv, "nonat") == 0) { -+ nat = 0; -+ -+ } else if (strcmp(*argv, "ptm") == 0) { -+ atm = 2; -+ } 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; -+ overhead_override = 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, all over ATM cells */ -+ } 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, both over PTM */ -+ /* PTM has 64b/65b coding which absorbs some bandwidth */ -+ } else if (strcmp(*argv, "pppoe-ptm") == 0) { -+ /* 2B PPP + 6B PPPoE + 6B dest MAC + 6B src MAC -+ * + 2B ethertype + 4B Frame Check Sequence -+ * + 1B Start of Frame (S) + 1B End of Frame (Ck) -+ * + 2B TC-CRC (PTM-FCS) = 30B -+ */ -+ atm = 2; -+ overhead += 30; -+ overhead_set = true; -+ } else if (strcmp(*argv, "bridged-ptm") == 0) { -+ /* 6B dest MAC + 6B src MAC + 2B ethertype -+ * + 4B Frame Check Sequence -+ * + 1B Start of Frame (S) + 1B End of Frame (Ck) -+ * + 2B TC-CRC (PTM-FCS) = 22B -+ */ -+ atm = 2; -+ overhead += 22; -+ overhead_set = true; -+ -+ } else if (strcmp(*argv, "via-ethernet") == 0) { -+ /* -+ * We used to use this flag to manually compensate for -+ * Linux including the Ethernet header on Ethernet-type -+ * interfaces, but not on IP-type interfaces. -+ * -+ * It is no longer needed, because Cake now adjusts for -+ * that automatically, and is thus ignored. -+ * -+ * It would be deleted entirely, but it appears in the -+ * stats output when the automatic compensation is -+ * active. -+ */ -+ -+ } else if (strcmp(*argv, "total_overhead") == 0) { -+ /* -+ * This is the overhead cake accounts for; added here so -+ * that cake's "tc -s qdisc" output can be directly -+ * pasted into the tc command to instantate a new cake.. -+ */ -+ NEXT_ARG(); -+ -+ } else if (strcmp(*argv, "hard_header_len") == 0) { -+ /* -+ * This is the overhead the kernel automatically -+ * accounted for; added here so that cake's "tc -s -+ * qdisc" output can be directly pasted into the tc -+ * command to instantiate a new cake.. -+ */ -+ NEXT_ARG(); -+ -+ } else if (strcmp(*argv, "ethernet") == 0) { -+ /* ethernet pre-amble & interframe gap & FCS -+ * you may need to add vlan tag */ -+ overhead += 38; -+ overhead_set = true; -+ mpu = 84; -+ -+ /* Additional Ethernet-related overhead used by some ISPs */ -+ } else if (strcmp(*argv, "ether-vlan") == 0) { -+ /* 802.1q VLAN tag - may be repeated */ -+ overhead += 4; -+ overhead_set = true; -+ -+ /* -+ * DOCSIS cable shapers account for Ethernet frame with FCS, -+ * but not interframe gap or preamble. -+ */ -+ } else if (strcmp(*argv, "docsis") == 0) { -+ atm = 0; -+ overhead += 18; -+ overhead_set = true; -+ mpu = 64; -+ -+ } 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, "mpu") == 0) { -+ char* p = NULL; -+ NEXT_ARG(); -+ mpu = strtol(*argv, &p, 10); -+ if(!p || *p || !*argv || mpu < 0 || mpu > 256) { -+ fprintf(stderr, "Illegal \"mpu\", valid range is 0 to 256\\n"); -+ return -1; -+ } -+ -+ } else if (strcmp(*argv, "ingress") == 0) { -+ ingress = 1; -+ } else if (strcmp(*argv, "egress") == 0) { -+ ingress = 0; -+ -+ } else if (strcmp(*argv, "no-ack-filter") == 0) { -+ ack_filter = 0; -+ } else if (strcmp(*argv, "ack-filter") == 0) { -+ ack_filter = 0x0200; -+ } else if (strcmp(*argv, "ack-filter-aggressive") == 0) { -+ ack_filter = 0x0600; -+ -+ } 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 (overhead_set) -+ addattr_l(n, 1024, TCA_CAKE_OVERHEAD, &overhead, sizeof(overhead)); -+ if (overhead_override) { -+ unsigned zero = 0; -+ addattr_l(n, 1024, TCA_CAKE_ETHERNET, &zero, sizeof(zero)); -+ } -+ if (mpu > 0) -+ addattr_l(n, 1024, TCA_CAKE_MPU, &mpu, sizeof(mpu)); -+ 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)); -+ if (nat != -1) -+ addattr_l(n, 1024, TCA_CAKE_NAT, &nat, sizeof(nat)); -+ if (wash != -1) -+ addattr_l(n, 1024, TCA_CAKE_WASH, &wash, sizeof(wash)); -+ if (ingress != -1) -+ addattr_l(n, 1024, TCA_CAKE_INGRESS, &ingress, sizeof(ingress)); -+ if (ack_filter != -1) -+ addattr_l(n, 1024, TCA_CAKE_ACK_FILTER, &ack_filter, sizeof(ack_filter)); -+ -+ 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 interval = 0; -+ unsigned memlimit = 0; -+ int overhead = 0; -+ int ethernet = 0; -+ int mpu = 0; -+ int atm = 0; -+ int nat = 0; -+ int autorate = 0; -+ int wash = 0; -+ int ingress = 0; -+ int ack_filter = 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; -+ case 6: -+ fprintf(f, "diffserv3 "); -+ 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]); -+ nat = !!(flowmode & 64); -+ flowmode &= ~64; -+ 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(nat) -+ fprintf(f, "nat "); -+ } -+ if (tb[TCA_CAKE_WASH] && -+ RTA_PAYLOAD(tb[TCA_CAKE_WASH]) >= sizeof(__u32)) { -+ wash = rta_getattr_u32(tb[TCA_CAKE_WASH]); -+ } -+ 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_MPU] && -+ RTA_PAYLOAD(tb[TCA_CAKE_MPU]) >= sizeof(__u32)) { -+ mpu = rta_getattr_u32(tb[TCA_CAKE_MPU]); -+ } -+ if (tb[TCA_CAKE_INGRESS] && -+ RTA_PAYLOAD(tb[TCA_CAKE_INGRESS]) >= sizeof(__u32)) { -+ ingress = rta_getattr_u32(tb[TCA_CAKE_INGRESS]); -+ } -+ if (tb[TCA_CAKE_ACK_FILTER] && -+ RTA_PAYLOAD(tb[TCA_CAKE_ACK_FILTER]) >= sizeof(__u32)) { -+ ack_filter = rta_getattr_u32(tb[TCA_CAKE_ACK_FILTER]); -+ } -+ if (tb[TCA_CAKE_ETHERNET] && -+ RTA_PAYLOAD(tb[TCA_CAKE_ETHERNET]) >= sizeof(__u32)) { -+ ethernet = rta_getattr_u32(tb[TCA_CAKE_ETHERNET]); -+ } -+ if (tb[TCA_CAKE_RTT] && -+ RTA_PAYLOAD(tb[TCA_CAKE_RTT]) >= sizeof(__u32)) { -+ interval = rta_getattr_u32(tb[TCA_CAKE_RTT]); -+ } -+ -+ if (wash) -+ fprintf(f,"wash "); -+ -+ if (ingress) -+ fprintf(f,"ingress "); -+ -+ if (ack_filter == 0x0600) -+ fprintf(f,"ack-filter-aggressive "); -+ else if (ack_filter) -+ fprintf(f,"ack-filter "); -+ -+ if (interval) -+ fprintf(f, "rtt %s ", sprint_time(interval, b2)); -+ -+ if (!atm && overhead == ethernet) { -+ fprintf(f, "raw "); -+ } else { -+ if (atm == 1) -+ fprintf(f, "atm "); -+ else if (atm == 2) -+ fprintf(f, "ptm "); -+ else -+ fprintf(f, "noatm "); -+ -+ fprintf(f, "overhead %d ", overhead); -+ -+ /* This is actually the *amount* of automatic compensation, but -+ * we only report its presence as a boolean for now. -+ */ -+ if (ethernet) -+ fprintf(f, "via-ethernet "); -+ } -+ -+ /* unconditionally report the overhead and hard_header_len overhead the -+ * kernel added automatically -+ */ -+ fprintf(f, "total_overhead %d ", overhead); -+ fprintf(f, "hard_header_len %d ", ethernet); -+ -+ if (mpu) { -+ fprintf(f, "mpu %d ", mpu); -+ } -+ -+ 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 3: -+ fprintf(f, " Bulk Best Effort Voice\n"); -+ break; -+ -+ 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"); -+ -+ if(stnc->version >= 5) { -+ fprintf(f, " ack_drop"); -+ for(i=0; i < stnc->tin_cnt; i++) -+ fprintf(f, " %12u", stnc->ack_drops[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, -+}; |