From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pg0-x22c.google.com (mail-pg0-x22c.google.com [IPv6:2607:f8b0:400e:c05::22c]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.bufferbloat.net (Postfix) with ESMTPS id F14A13BA8E for ; Fri, 17 Nov 2017 16:19:52 -0500 (EST) Received: by mail-pg0-x22c.google.com with SMTP id 70so2821150pgf.6 for ; Fri, 17 Nov 2017 13:19:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=PKPZyjXKB8HWis24L4HN29hNyTpDqI/YFNYhqLA4vXw=; b=Crckf/LRrzXbBK2AwgaFnv4xfre+VVMMTtl4BcJBQtyQ432e0t6LFFNWxQim1Ic67g 1RIpIBgVFSrK+Ntmc3Jcxyg1HIQe1QW1uZXzhSkdMQrQc0RSJ6S4nA9XNaTrT93oAgfM Dtzff30rGFDLv21BVUzS/6j6XiZOKZ/BqjtjPQD1An3TTFbo1ch5tCX3ZmjAZdvxsIOi Ttvcw6QEmTX+yi3h+GNJY6pvPpS85bX4SDCxSiApMlocJwCvBOr0HOKS/dXXZ/JKgmRD RkQKOIGoA2qJ+E3D15cbOaCpc203HolEhELnM3bCYD5T+BpKNJrVJQCxN1a8hGsCOkee tjGg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=PKPZyjXKB8HWis24L4HN29hNyTpDqI/YFNYhqLA4vXw=; b=M9JFoREKYQxzwFL44DDrtC7VDOpa+vh5vt81NSwDSZ+hnDcw8ew3l2rNfEr1+PLev/ L+x+DhjGFoRfr7BiaQhnqbD1GZbtwaKUL1SkiTOUhLNxfwpydDqC8d5pjgekj3M1VnIo TJIo79PsioqQiD61B2WkcefuSc1l+SYlOuoFdj5SmCL/fPLZU3eNQSZOTHnMmWJY6RFy SqElixMPtTSmQdz54J+JgnfJv2CicvWdSxw7fOk7Qf0fvKufOobOMKCZ1V8W75fYJatQ HffO+0BaW8w9QXsk3DS8fHEhMvlqlVBA7y7BdEqlT3gRM2IHwRWiU+qwdALRfh/PIfo7 GY+g== X-Gm-Message-State: AJaThX7mEl21xh8OLimPfTMhGWJDGl+A/yVT3h3S4Yx3kMZUQ8tQzG70 9TrSeBc4PhlF1bKYeCjv3LH24g== X-Google-Smtp-Source: AGs4zMaF1McNCIrCHf0wU9jeUm9UhdcWA7cYGRpoTqNFBdyeMHocgaJZyPILu4HLgjj+kryvgXcP/A== X-Received: by 10.99.56.74 with SMTP id h10mr6301310pgn.311.1510953591935; Fri, 17 Nov 2017 13:19:51 -0800 (PST) Received: from nemesis.lab.teklibre.com (c-24-6-113-161.hsd1.ca.comcast.net. [24.6.113.161]) by smtp.gmail.com with ESMTPSA id r68sm8747869pfb.149.2017.11.17.13.19.51 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Fri, 17 Nov 2017 13:19:51 -0800 (PST) From: Dave Taht To: cake@lists.bufferbloat.net Date: Fri, 17 Nov 2017 13:19:27 -0800 Message-Id: <1510953568-11797-5-git-send-email-dave.taht@gmail.com> X-Mailer: git-send-email 2.7.4 In-Reply-To: <1510953568-11797-1-git-send-email-dave.taht@gmail.com> References: <1510953568-11797-1-git-send-email-dave.taht@gmail.com> Subject: [Cake] [RFC PATCH 4/5] q_netem: support delivering packets in delayed time slots X-BeenThere: cake@lists.bufferbloat.net X-Mailman-Version: 2.1.20 Precedence: list List-Id: Cake - FQ_codel the next generation List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 17 Nov 2017 21:19:53 -0000 Slotting is a crude approximation of the behaviors of shared media such as cable, wifi, and LTE, which gather up a bunch of packets within a varying delay window and deliver them, relative to that, nearly all at once. It works within the existing loss, duplication, jitter and delay parameters of netem. Some amount of inherent latency must be specified, regardless. The new "slot" parameter specifies a minimum and maximum delay between transmission attempts. The "bytes" and "packets" parameters can be used to limit the amount of information transferred per slot. Examples of use: tc qdisc add dev eth0 root netem delay 200us \ slot 800us 10ms bytes 64k packets 42 A more correct example, using stacked netem instances and a packet limit to emulate a tail drop wifi queue with slots and variable packet delivery, with a 200Mbit isochronous underlying rate, and 20ms path delay: tc qdisc add dev eth0 root handle 1: netem delay 20ms rate 200mbit \ limit 10000 tc qdisc add dev eth0 parent 1:1 handle 10:1 netem delay 200us \ slot 800us 10ms bytes 64k packets 42 limit 512 --- tc/q_netem.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/tc/q_netem.c b/tc/q_netem.c index 82eb46f..1524788 100644 --- a/tc/q_netem.c +++ b/tc/q_netem.c @@ -40,7 +40,10 @@ static void explain(void) " [ loss gemodel PERCENT [R [1-H [1-K]]]\n" \ " [ ecn ]\n" \ " [ reorder PRECENT [CORRELATION] [ gap DISTANCE ]]\n" \ -" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n"); +" [ rate RATE [PACKETOVERHEAD] [CELLSIZE] [CELLOVERHEAD]]\n" \ +" [ slot MIN_DELAY MAX_DELAY [packets MAX_PACKETS]" \ +" [bytes MAX_BYTES]]\n" \ + ); } static void explain1(const char *arg) @@ -178,6 +181,7 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv, struct tc_netem_gimodel gimodel; struct tc_netem_gemodel gemodel; struct tc_netem_rate rate = {}; + struct tc_netem_slot slot = {}; __s16 *dist_data = NULL; __u16 loss_type = NETEM_LOSS_UNSPEC; int present[__TCA_NETEM_MAX] = {}; @@ -421,6 +425,36 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv, return -1; } } + } else if (matches(*argv, "slot") == 0) { + NEXT_ARG(); + present[TCA_NETEM_SLOT] = 1; + if (get_time64(&slot.min_delay, *argv)) { + explain1("slot min_delay"); + return -1; + } + if (NEXT_IS_NUMBER()) { + NEXT_ARG(); + if (get_time64(&slot.max_delay, *argv)) { + explain1("slot min_delay max_delay"); + return -1; + } + } + if (slot.max_delay < slot.min_delay) + slot.max_delay = slot.min_delay; + } else if (matches(*argv, "packets") == 0) { + NEXT_ARG(); + if (get_s32(&slot.max_packets, *argv, 0)) { + explain1("slot packets"); + return -1; + } + } else if (matches(*argv, "bytes") == 0) { + unsigned int max_bytes; + NEXT_ARG(); + if (get_size(&max_bytes, *argv)) { + explain1("slot bytes"); + return -1; + } + slot.max_bytes = (int) max_bytes; } else if (strcmp(*argv, "help") == 0) { explain(); return -1; @@ -481,6 +515,10 @@ static int netem_parse_opt(struct qdisc_util *qu, int argc, char **argv, addattr_l(n, 1024, TCA_NETEM_CORRUPT, &corrupt, sizeof(corrupt)) < 0) return -1; + if (present[TCA_NETEM_SLOT] && + addattr_l(n, 1024, TCA_NETEM_SLOT, &slot, sizeof(slot)) < 0) + return -1; + if (loss_type != NETEM_LOSS_UNSPEC) { struct rtattr *start; @@ -535,6 +573,7 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) int *ecn = NULL; struct tc_netem_qopt qopt; const struct tc_netem_rate *rate = NULL; + const struct tc_netem_slot *slot = NULL; int len; __u64 rate64 = 0; @@ -595,6 +634,11 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) return -1; rate64 = rta_getattr_u64(tb[TCA_NETEM_RATE64]); } + if (tb[TCA_NETEM_SLOT]) { + if (RTA_PAYLOAD(tb[TCA_NETEM_SLOT]) < sizeof(*slot)) + return -1; + slot = RTA_DATA(tb[TCA_NETEM_SLOT]); + } } fprintf(f, "limit %d", qopt.limit); @@ -668,6 +712,15 @@ static int netem_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr *opt) fprintf(f, " celloverhead %d", rate->cell_overhead); } + if (slot) { + fprintf(f, " slot %s", sprint_time64(slot->min_delay, b1)); + fprintf(f, " %s", sprint_time64(slot->max_delay, b1)); + if(slot->max_packets) + fprintf(f, " packets %d", slot->max_packets); + if(slot->max_bytes) + fprintf(f, " bytes %d", slot->max_bytes); + } + if (ecn) fprintf(f, " ecn "); -- 2.7.4