From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from emea01-db3-obe.outbound.protection.outlook.com (mail-db3on0072.outbound.protection.outlook.com [157.55.234.72]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client CN "mail.protection.outlook.com", Issuer "MSIT Machine Auth CA 2" (verified OK)) by huchra.bufferbloat.net (Postfix) with ESMTPS id 8862821F2D3 for ; Fri, 1 May 2015 02:50:55 -0700 (PDT) Received: from HE1PR07MB0937.eurprd07.prod.outlook.com (25.162.27.143) by HE1PR07MB1049.eurprd07.prod.outlook.com (25.162.28.11) with Microsoft SMTP Server (TLS) id 15.1.148.16; Fri, 1 May 2015 09:50:49 +0000 Authentication-Results: lists.bufferbloat.net; dkim=none (message not signed) header.d=none; Received: from [IPv6:2001:470:183f:da2b::717c:e11c] (2001:470:183f:da2b::717c:e11c) by HE1PR07MB0937.eurprd07.prod.outlook.com (25.162.27.143) with Microsoft SMTP Server (TLS) id 15.1.148.16; Fri, 1 May 2015 09:50:43 +0000 Message-ID: <55434C61.4060203@darbyshire-bryant.me.uk> Date: Fri, 1 May 2015 10:50:25 +0100 From: Kevin Darbyshire-Bryant User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.6.0 MIME-Version: 1.0 To: References: In-Reply-To: Content-Type: multipart/signed; protocol="application/pkcs7-signature"; micalg=sha1; boundary="------------ms070009000207070405030806" X-Originating-IP: [2001:470:183f:da2b::717c:e11c] X-ClientProxiedBy: CO2PR06CA018.namprd06.prod.outlook.com (10.141.242.18) To HE1PR07MB0937.eurprd07.prod.outlook.com (25.162.27.143) X-Microsoft-Antispam: UriScan:; BCL:0; PCL:0; RULEID:; SRVR:HE1PR07MB0937; UriScan:; BCL:0; PCL:0; RULEID:; SRVR:HE1PR07MB1049; X-Microsoft-Antispam-PRVS: X-Exchange-Antispam-Report-Test: UriScan:; X-Exchange-Antispam-Report-CFA-Test: BCL:0; PCL:0; RULEID:(601004)(5005006)(3002001); SRVR:HE1PR07MB0937; BCL:0; PCL:0; RULEID:; SRVR:HE1PR07MB0937; X-Forefront-PRVS: 0563F2E8B7 X-Forefront-Antispam-Report: SFV:NSPM; SFS:(10009020)(6009001)(377454003)(24454002)(479174004)(19580405001)(42186005)(36756003)(19580395003)(4001350100001)(33656002)(450100001)(2950100001)(4810100001)(107886002)(110136002)(92566002)(5890100001)(83506001)(86362001)(84326002)(93886004)(87976001)(122386002)(76176999)(40100003)(65956001)(99136001)(512944002)(80316001)(74482002)(77156002)(62966003)(512874002)(87266999)(568964001)(50986999)(65816999)(54356999)(5001960100002)(46102003)(2351001)(3826002)(579004)(559001); DIR:OUT; SFP:1101; SCL:1; SRVR:HE1PR07MB0937; H:[IPv6:2001:470:183f:da2b::717c:e11c]; FPR:; SPF:None; MLV:sfv; LANG:en; X-MS-Exchange-CrossTenant-OriginalArrivalTime: 01 May 2015 09:50:43.0037 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-Transport-CrossTenantHeadersStamped: HE1PR07MB0937 X-OriginatorOrg: darbyshire-bryant.me.uk Subject: Re: [Cerowrt-devel] [Cake] documentation review request and out of tree cake builds for openwrt/etc. X-BeenThere: cerowrt-devel@lists.bufferbloat.net X-Mailman-Version: 2.1.13 Precedence: list List-Id: Development issues regarding the cerowrt test router project List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 01 May 2015 09:51:25 -0000 --------------ms070009000207070405030806 Content-Type: multipart/mixed; boundary="------------070100020904050000080609" This is a multi-part message in MIME format. --------------070100020904050000080609 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable On 30/04/2015 16:17, Dave Taht wrote: > On Thu, Apr 30, 2015 at 7:38 AM, Jonathan Morton wrote: >> It took me a while to get around to thinking about this, partly becaus= e my >> phone inexplicably refuses to believe snapon exists. > It has an old dnssec signed dns tree, using the isc dlv, which turned > out to somewhat break older versions of dnsmasq, if that helps any. OpenWrt CC trunk is now up to dnsmasq2.73rc7 - the latest fix was for a d= nssec fallback to tcp problem. Highly recommended. > So the next step for me is to get cake working in openwrt on hardware f= ast enough to run at 110Mbit and returning to the yurtlab to try it... bu= t that won't be til sunday at best. Tho I almost got it built, at least, = last night. Still sorting through patches.... I have no idea if this will help you guys. I was fiddling with getting c= ake into CC a little earlier based on the web page instructions. My totally unsubtle approach was to = basically copy over relevant cerowrt-3.10 packages into the CC build tree: ceropackages-3.10/net/sqm-scripts openwrt/package/feeds/packages/sqm-scri= pts ceropackages-3.10/net/kmod-sched-cake openwrt/feeds/packages/net/kmod-sch= ed-cake * ceropackages-3.10/luci/luci-app-sqm openwrt/package/feeds/packages/luci-a= pp-sqm iproute2 140&141 patches to openwrt/package/network/utils/iproute2/patche= s You'll need to put a symlink from openwrt/package/feeds/packages/kmod-sch= ed-cake to openwrt/feeds/packages/net/kmod-sched-cake * note different directory! Also to get iproute2 tc to understand cake I basically did a git diff on = toke's iproute-cake vs iproute 4.0.0 which is where CC currently is: Result 2 patches, 140 &= 141, 1st is to get cake in, the 2nd is to do the required tc makefile tweak. CC builds, run= s on Archer C7, nothing obviously exploded or broken...yet... your mileage may vary! VER= Y VERY UNTESTED, DRAGONS LURK, I'M AN IDIOT AND DON'T REALLY KNOW WHAT I'M DOING= =2E Is that clear enough? :-) Maybe it helps. What I will say is that a dslreports test appears less j= ittery for me. Kevin 141-cake-disable-sfq-codel.patch diff --git a/tc/Makefile b/tc/Makefile index e503c8a..3dce533 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -61,7 +61,7 @@ TCMODULES +=3D q_codel.o TCMODULES +=3D q_fq_codel.o TCMODULES +=3D q_nfq_codel.o TCMODULES +=3D q_efq_codel.o -TCMODULES +=3D q_sfq_codel.o +#TCMODULES +=3D q_sfq_codel.o TCMODULES +=3D q_pfq_codel.o TCMODULES +=3D q_ns2_codel.o TCMODULES +=3D q_ns4_codel.o 140-cake-add-support.patch diff --git a/include/linux/pkt_sched.h b/include/linux/pkt_sched.h index 534b847..a1d7b67 100644 --- a/include/linux/pkt_sched.h +++ b/include/linux/pkt_sched.h @@ -845,4 +845,38 @@ 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_MAX +}; +#define TCA_CAKE_MAX (__TCA_CAKE_MAX - 1) + +struct tc_cake_xstats { + __u16 type; /* constant magic 0xCAFE */ + __u16 class_cnt; + struct { + __u32 rate; + __u32 target_us; + __u32 packets; + __u32 interval_us; + __u64 bytes; + __u32 dropped; + __u32 ecn_marked; + __u32 way_indirect_hits; + __u32 way_misses; + __u32 way_collisions; + __u32 backlog_bytes; + __u32 peak_delay; /* delay to fat flows */ + __u32 avge_delay; + __u32 base_delay; /* delay to sparse flows */ + __u32 dummy2; + } cls[8]; +}; + #endif diff --git a/tc/Makefile b/tc/Makefile index d831a15..e503c8a 100644 --- a/tc/Makefile +++ b/tc/Makefile @@ -59,8 +59,17 @@ TCMODULES +=3D em_meta.o TCMODULES +=3D q_mqprio.o TCMODULES +=3D q_codel.o TCMODULES +=3D q_fq_codel.o +TCMODULES +=3D q_nfq_codel.o +TCMODULES +=3D q_efq_codel.o +TCMODULES +=3D q_sfq_codel.o +TCMODULES +=3D q_pfq_codel.o +TCMODULES +=3D q_ns2_codel.o +TCMODULES +=3D q_ns4_codel.o TCMODULES +=3D q_fq.o TCMODULES +=3D q_pie.o +TCMODULES +=3D q_cake.o +TCMODULES +=3D q_cake0.o +TCMODULES +=3D q_cake2.o TCMODULES +=3D q_hhf.o =20 ifeq ($(TC_CONFIG_IPSET), y) diff --git a/tc/q_cake.c b/tc/q_cake.c new file mode 100644 index 0000000..d9415d3 --- /dev/null +++ b/tc/q_cake.c @@ -0,0 +1,333 @@ +/* + * Common Applications Kept Enhanced -- CAKE + * + * Copyright (C) 2014-2015 Jonathan Morton + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... cake [ bandwidth RATE | unlimited ]\n" + " [ besteffort | precedence | diffser= v8 | diffserv4 ]\n" + " [ flowblind | srchost | dsthost | h= osts | flows ]\n" + " [ atm ]\n"); +} + +static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv, + struct nlmsghdr *n) +{ + int unlimited =3D 0; + unsigned bandwidth =3D 0; + unsigned diffserv =3D 0; + int flowmode =3D -1; + int atm =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "bandwidth") =3D=3D 0) { + NEXT_ARG(); + if (get_rate(&bandwidth, *argv)) { + fprintf(stderr, "Illegal \"bandwidth\"\n"); + return -1; + } + unlimited =3D 0; + } else if (strcmp(*argv, "unlimited") =3D=3D 0) { + bandwidth =3D 0; + unlimited =3D 1; + + } else if (strcmp(*argv, "besteffort") =3D=3D 0) { + diffserv =3D 1; + } else if (strcmp(*argv, "precedence") =3D=3D 0) { + diffserv =3D 2; + } else if (strcmp(*argv, "diffserv8") =3D=3D 0) { + diffserv =3D 3; + } else if (strcmp(*argv, "diffserv4") =3D=3D 0) { + diffserv =3D 4; + } else if (strcmp(*argv, "diffserv") =3D=3D 0) { + diffserv =3D 4; + + } else if (strcmp(*argv, "flowblind") =3D=3D 0) { + flowmode =3D 0; + } else if (strcmp(*argv, "srchost") =3D=3D 0) { + flowmode =3D 1; + } else if (strcmp(*argv, "dsthost") =3D=3D 0) { + flowmode =3D 2; + } else if (strcmp(*argv, "hosts") =3D=3D 0) { + flowmode =3D 3; + } else if (strcmp(*argv, "flows") =3D=3D 0) { + flowmode =3D 4; + + } else if (strcmp(*argv, "atm") =3D=3D 0) { + atm =3D 1; + } else if (strcmp(*argv, "noatm") =3D=3D 0) { + atm =3D 0; + + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (bandwidth || unlimited) + addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwi= dth)); + if (diffserv) + addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(dif= fserv)); + if (atm !=3D -1) + addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm)); + if (flowmode !=3D -1) + addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmod= e)); + tail->rta_len =3D (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 =3D 0; + unsigned diffserv =3D 0; + unsigned flowmode =3D 0; + int atm =3D -1; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_CAKE_MAX, opt); + + if (tb[TCA_CAKE_BASE_RATE] && + RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >=3D sizeof(__u32)) { + bandwidth =3D 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_DIFFSERV_MODE] && + RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >=3D sizeof(__u32)) { + diffserv =3D 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; + default: + fprintf(f, "(?diffserv?) "); + break; + }; + } + if (tb[TCA_CAKE_FLOW_MODE] && + RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >=3D sizeof(__u32)) { + flowmode =3D 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; + default: + fprintf(f, "(?flowmode?) "); + break; + }; + } + if (tb[TCA_CAKE_ATM] && + RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >=3D sizeof(__u32)) { + atm =3D rta_getattr_u32(tb[TCA_CAKE_ATM]); + if (atm) + fprintf(f, "atm "); + } + + 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 *stc; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(st->type)) + return -1; + + st =3D RTA_DATA(xstats); + stc =3D RTA_DATA(xstats); + + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats)= >=3D sizeof(*st)) { + fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u e= cn_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 =3D=3D TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(= xstats) >=3D 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 (stc->type =3D=3D 0xCAFE && RTA_PAYLOAD(xstats) >=3D sizeo= f(*stc)) { + int i; + + fprintf(f, " "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, " Class %u ", i); + fprintf(f, "\n"); + + fprintf(f, " rate "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12s", sprint_rate(stc->cls[i].rate, b1)); + fprintf(f, "\n"); + + fprintf(f, " target"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12s", sprint_time(stc->cls[i].target_us, b1)); + fprintf(f, "\n"); + + fprintf(f, "interval"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12s", sprint_time(stc->cls[i].interval_us, b1))= ; + fprintf(f, "\n"); + + fprintf(f, "Pk delay"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12s", sprint_time(stc->cls[i].peak_delay, b1));= + fprintf(f, "\n"); + + fprintf(f, "Av delay"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12s", sprint_time(stc->cls[i].avge_delay, b1));= + fprintf(f, "\n"); + + fprintf(f, "Sp delay"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12s", sprint_time(stc->cls[i].base_delay, b1));= + fprintf(f, "\n"); + + fprintf(f, " pkts "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12u", stc->cls[i].packets); + fprintf(f, "\n"); + + fprintf(f, "way inds"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12u", stc->cls[i].way_indirect_hits); + fprintf(f, "\n"); + + fprintf(f, "way miss"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12u", stc->cls[i].way_misses); + fprintf(f, "\n"); + + fprintf(f, "way cols"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12u", stc->cls[i].way_collisions); + fprintf(f, "\n"); + + fprintf(f, " bytes "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12llu", stc->cls[i].bytes); + fprintf(f, "\n"); + + fprintf(f, " drops "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12u", stc->cls[i].dropped); + fprintf(f, "\n"); + + fprintf(f, " marks "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%12u", stc->cls[i].ecn_marked); + } else { + return -1; + } + return 0; +} + +struct qdisc_util cake_qdisc_util =3D { + .id =3D "cake", + .parse_qopt =3D cake_parse_opt, + .print_qopt =3D cake_print_opt, + .print_xstats =3D cake_print_xstats, +}; diff --git a/tc/q_cake0.c b/tc/q_cake0.c new file mode 100644 index 0000000..9fb63ed --- /dev/null +++ b/tc/q_cake0.c @@ -0,0 +1,301 @@ +/* + * Common Applications Kept Enhanced -- CAKE + * + * Copyright (C) 2014 Jonathan Morton + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... cake0 [ bandwidth RATE | unlimited ]\n" + " [ besteffort | precedence | diffse= rv ]\n" + " [ flowblind | srchost | dsthost | = hosts | flows ]\n" + " [ atm ]\n"); +} + +static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv, + struct nlmsghdr *n) +{ + int unlimited =3D 0; + unsigned bandwidth =3D 0; + unsigned diffserv =3D 0; + int flowmode =3D -1; + int atm =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "bandwidth") =3D=3D 0) { + NEXT_ARG(); + if (get_rate(&bandwidth, *argv)) { + fprintf(stderr, "Illegal \"bandwidth\"\n"); + return -1; + } + unlimited =3D 0; + } else if (strcmp(*argv, "unlimited") =3D=3D 0) { + bandwidth =3D 0; + unlimited =3D 1; + + } else if (strcmp(*argv, "besteffort") =3D=3D 0) { + diffserv =3D 1; + } else if (strcmp(*argv, "precedence") =3D=3D 0) { + diffserv =3D 2; + } else if (strcmp(*argv, "diffserv") =3D=3D 0) { + diffserv =3D 3; + + } else if (strcmp(*argv, "flowblind") =3D=3D 0) { + flowmode =3D 0; + } else if (strcmp(*argv, "srchost") =3D=3D 0) { + flowmode =3D 1; + } else if (strcmp(*argv, "dsthost") =3D=3D 0) { + flowmode =3D 2; + } else if (strcmp(*argv, "hosts") =3D=3D 0) { + flowmode =3D 3; + } else if (strcmp(*argv, "flows") =3D=3D 0) { + flowmode =3D 4; + + } else if (strcmp(*argv, "atm") =3D=3D 0) { + atm =3D 1; + } else if (strcmp(*argv, "noatm") =3D=3D 0) { + atm =3D 0; + + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (bandwidth || unlimited) + addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwi= dth)); + if (diffserv) + addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(dif= fserv)); + if (atm !=3D -1) + addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm)); + if (flowmode !=3D -1) + addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmod= e)); + tail->rta_len =3D (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 =3D 0; + unsigned diffserv =3D 0; + unsigned flowmode =3D 0; + int atm =3D -1; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_CAKE_MAX, opt); + + if (tb[TCA_CAKE_BASE_RATE] && + RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >=3D sizeof(__u32)) { + bandwidth =3D 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_DIFFSERV_MODE] && + RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >=3D sizeof(__u32)) { + diffserv =3D 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, "diffserv "); + break; + default: + fprintf(f, "(?diffserv?) "); + break; + }; + } + if (tb[TCA_CAKE_FLOW_MODE] && + RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >=3D sizeof(__u32)) { + flowmode =3D 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; + default: + fprintf(f, "(?flowmode?) "); + break; + }; + } + if (tb[TCA_CAKE_ATM] && + RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >=3D sizeof(__u32)) { + atm =3D rta_getattr_u32(tb[TCA_CAKE_ATM]); + if (atm) + fprintf(f, "atm "); + } + + 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 *stc; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(st->type)) + return -1; + + st =3D RTA_DATA(xstats); + stc =3D RTA_DATA(xstats); + + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats)= >=3D sizeof(*st)) { + fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u e= cn_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 =3D=3D TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(= xstats) >=3D 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 (stc->type =3D=3D 0xCAFE && RTA_PAYLOAD(xstats) >=3D sizeo= f(*stc)) { + int i; + + fprintf(f, " "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, " Class %u ", i); + fprintf(f, "\n"); + + fprintf(f, " rate "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_rate(stc->cls[i].rate, b1)); + fprintf(f, "\n"); + + fprintf(f, " target"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_time(stc->cls[i].target_us, b1)); + fprintf(f, "\n"); + + fprintf(f, "interval"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_time(stc->cls[i].interval_us, b1))= ; + fprintf(f, "\n"); + + fprintf(f, " delay "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_time(stc->cls[i].peak_delay, b1));= + fprintf(f, "\n"); + + fprintf(f, " pkts "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10u", stc->cls[i].packets); + fprintf(f, "\n"); + + fprintf(f, " bytes "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10llu", stc->cls[i].bytes); + fprintf(f, "\n"); + + fprintf(f, " drops "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10u", stc->cls[i].dropped); + fprintf(f, "\n"); + + fprintf(f, " marks "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10u", stc->cls[i].ecn_marked); + } else { + return -1; + } + return 0; +} + +struct qdisc_util cake0_qdisc_util =3D { + .id =3D "cake0", + .parse_qopt =3D cake_parse_opt, + .print_qopt =3D cake_print_opt, + .print_xstats =3D cake_print_xstats, +}; diff --git a/tc/q_cake2.c b/tc/q_cake2.c new file mode 100644 index 0000000..a4d3f7c --- /dev/null +++ b/tc/q_cake2.c @@ -0,0 +1,296 @@ +/* + * Common Applications Kept Enhanced -- CAKE + * + * Copyright (C) 2014 Jonathan Morton + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... cake2 [ bandwidth RATE | unlimited ]\n" + " [ besteffort | precedence | diffser= v ]\n" + " [ flowblind | srchost | dsthost | h= osts | flows ]\n" + " [ atm ]\n"); +} + +static int cake_parse_opt(struct qdisc_util *qu, int argc, char **argv, + struct nlmsghdr *n) +{ + int unlimited =3D 0; + unsigned bandwidth =3D 0; + unsigned diffserv =3D 0; + int flowmode =3D -1; + int atm =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "bandwidth") =3D=3D 0) { + NEXT_ARG(); + if (get_rate(&bandwidth, *argv)) { + fprintf(stderr, "Illegal \"bandwidth\"\n"); + return -1; + } + unlimited =3D 0; + } else if (strcmp(*argv, "unlimited") =3D=3D 0) { + bandwidth =3D 0; + unlimited =3D 1; + + } else if (strcmp(*argv, "besteffort") =3D=3D 0) { + diffserv =3D 1; + } else if (strcmp(*argv, "precedence") =3D=3D 0) { + diffserv =3D 2; + } else if (strcmp(*argv, "diffserv") =3D=3D 0) { + diffserv =3D 3; + + } else if (strcmp(*argv, "flowblind") =3D=3D 0) { + flowmode =3D 0; + } else if (strcmp(*argv, "srchost") =3D=3D 0) { + flowmode =3D 1; + } else if (strcmp(*argv, "dsthost") =3D=3D 0) { + flowmode =3D 2; + } else if (strcmp(*argv, "hosts") =3D=3D 0) { + flowmode =3D 3; + } else if (strcmp(*argv, "flows") =3D=3D 0) { + flowmode =3D 4; + + } else if (strcmp(*argv, "atm") =3D=3D 0) { + atm =3D 1; + } else if (strcmp(*argv, "noatm") =3D=3D 0) { + atm =3D 0; + + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (bandwidth || unlimited) + addattr_l(n, 1024, TCA_CAKE_BASE_RATE, &bandwidth, sizeof(bandwi= dth)); + if (diffserv) + addattr_l(n, 1024, TCA_CAKE_DIFFSERV_MODE, &diffserv, sizeof(dif= fserv)); + if (atm !=3D -1) + addattr_l(n, 1024, TCA_CAKE_ATM, &atm, sizeof(atm)); + if (flowmode !=3D -1) + addattr_l(n, 1024, TCA_CAKE_FLOW_MODE, &flowmode, sizeof(flowmod= e)); + tail->rta_len =3D (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 =3D 0; + unsigned diffserv =3D 0; + unsigned flowmode =3D 0; + int atm =3D -1; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_CAKE_MAX, opt); + + if (tb[TCA_CAKE_BASE_RATE] && + RTA_PAYLOAD(tb[TCA_CAKE_BASE_RATE]) >=3D sizeof(__u32)) { + bandwidth =3D 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_DIFFSERV_MODE] && + RTA_PAYLOAD(tb[TCA_CAKE_DIFFSERV_MODE]) >=3D sizeof(__u32)) { + diffserv =3D 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, "diffserv "); + break; + default: + fprintf(f, "(?diffserv?) "); + break; + }; + } + if (tb[TCA_CAKE_FLOW_MODE] && + RTA_PAYLOAD(tb[TCA_CAKE_FLOW_MODE]) >=3D sizeof(__u32)) { + flowmode =3D 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; + default: + fprintf(f, "(?flowmode?) "); + break; + }; + } + if (tb[TCA_CAKE_ATM] && + RTA_PAYLOAD(tb[TCA_CAKE_ATM]) >=3D sizeof(__u32)) { + atm =3D rta_getattr_u32(tb[TCA_CAKE_ATM]); + if (atm) + fprintf(f, "atm "); + } + + 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 *stc; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(st->type)) + return -1; + + st =3D RTA_DATA(xstats); + stc =3D RTA_DATA(xstats); + + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_QDISC && RTA_PAYLOAD(xstats)= >=3D sizeof(*st)) { + fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u e= cn_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 =3D=3D TCA_FQ_CODEL_XSTATS_CLASS && RTA_PAYLOAD(= xstats) >=3D 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 (stc->type =3D=3D 0xCAFE && RTA_PAYLOAD(xstats) >=3D sizeo= f(*stc)) { + int i; + + fprintf(f, " "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, " Class %u ", i); + fprintf(f, "\n"); + + fprintf(f, " rate "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_rate(stc->cls[i].rate, b1)); + fprintf(f, "\n"); + + fprintf(f, " target"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_time(stc->cls[i].target_us, b1)); + fprintf(f, "\n"); + + fprintf(f, "interval"); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10s", sprint_time(stc->cls[i].interval_us, b1))= ; + fprintf(f, "\n"); + + fprintf(f, " pkts "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10u", stc->cls[i].packets); + fprintf(f, "\n"); + + fprintf(f, " bytes "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10llu", stc->cls[i].bytes); + fprintf(f, "\n"); + + fprintf(f, " drops "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10u", stc->cls[i].dropped); + fprintf(f, "\n"); + + fprintf(f, " marks "); + for(i=3D0; i < stc->class_cnt; i++) + fprintf(f, "%10u", stc->cls[i].ecn_marked); + } else { + return -1; + } + return 0; +} + +struct qdisc_util cake2_qdisc_util =3D { + .id =3D "cake2", + .parse_qopt =3D cake_parse_opt, + .print_qopt =3D cake_print_opt, + .print_xstats =3D cake_print_xstats, +}; diff --git a/tc/q_efq_codel.c b/tc/q_efq_codel.c new file mode 100644 index 0000000..b80e5e4 --- /dev/null +++ b/tc/q_efq_codel.c @@ -0,0 +1,232 @@ +/* + * Fair Queue Codel + * + * Copyright (C) 2012 Eric Dumazet + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... efq_codel [ limit PACKETS ] [ flows NUMB= ER ]\n"); + fprintf(stderr, " [ target TIME] [ interval TIME = ]\n"); + fprintf(stderr, " [ quantum BYTES ] [ [no]ecn ]\n= "); +} + +static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **ar= gv, + struct nlmsghdr *n) +{ + unsigned limit =3D 0; + unsigned flows =3D 0; + unsigned target =3D 0; + unsigned interval =3D 0; + unsigned quantum =3D 0; + int ecn =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "limit") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&limit, *argv, 0)) { + fprintf(stderr, "Illegal \"limit\"\n"); + return -1; + } + } else if (strcmp(*argv, "flows") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&flows, *argv, 0)) { + fprintf(stderr, "Illegal \"flows\"\n"); + return -1; + } + } else if (strcmp(*argv, "quantum") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&quantum, *argv, 0)) { + fprintf(stderr, "Illegal \"quantum\"\n"); + return -1; + } + } else if (strcmp(*argv, "target") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&target, *argv)) { + fprintf(stderr, "Illegal \"target\"\n"); + return -1; + } + } else if (strcmp(*argv, "interval") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&interval, *argv)) { + fprintf(stderr, "Illegal \"interval\"\n"); + return -1; + } + } else if (strcmp(*argv, "ecn") =3D=3D 0) { + ecn =3D 1; + } else if (strcmp(*argv, "noecn") =3D=3D 0) { + ecn =3D 0; + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (limit) + addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &limit, sizeof(limit)); + if (flows) + addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &flows, sizeof(flows)); + if (quantum) + addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &quantum, sizeof(quantu= m)); + if (interval) + addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &interval, sizeof(inte= rval)); + if (target) + addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &target, sizeof(target))= ; + if (ecn !=3D -1) + addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &ecn, sizeof(ecn)); + tail->rta_len =3D (void *) NLMSG_TAIL(n) - (void *) tail; + return 0; +} + +static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rta= ttr *opt) +{ + struct rtattr *tb[TCA_FQ_CODEL_MAX + 1]; + unsigned limit; + unsigned flows; + unsigned interval; + unsigned target; + unsigned ecn; + unsigned quantum; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_FQ_CODEL_MAX, opt); + + if (tb[TCA_FQ_CODEL_LIMIT] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >=3D sizeof(__u32)) { + limit =3D rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]); + fprintf(f, "limit %up ", limit); + } + if (tb[TCA_FQ_CODEL_FLOWS] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >=3D sizeof(__u32)) { + flows =3D rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]); + fprintf(f, "flows %u ", flows); + } + if (tb[TCA_FQ_CODEL_QUANTUM] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >=3D sizeof(__u32)) { + quantum =3D rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]); + fprintf(f, "quantum %u ", quantum); + } + if (tb[TCA_FQ_CODEL_TARGET] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >=3D sizeof(__u32)) { + target =3D rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]); + fprintf(f, "target %s ", sprint_time(target, b1)); + } + if (tb[TCA_FQ_CODEL_INTERVAL] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >=3D sizeof(__u32)) { + interval =3D rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); + fprintf(f, "interval %s ", sprint_time(interval, b1)); + } + if (tb[TCA_FQ_CODEL_ECN] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >=3D sizeof(__u32)) { + ecn =3D rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); + if (ecn) + fprintf(f, "ecn "); + } + + return 0; +} + +static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, + struct rtattr *xstats) +{ + struct tc_fq_codel_xstats *st; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(*st)) + return -1; + + st =3D RTA_DATA(xstats); + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_QDISC) { + fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u e= cn_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); + } + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_CLASS) { + 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)); + } + } + return 0; + +} + +struct qdisc_util efq_codel_qdisc_util =3D { + .id =3D "efq_codel", + .parse_qopt =3D fq_codel_parse_opt, + .print_qopt =3D fq_codel_print_opt, + .print_xstats =3D fq_codel_print_xstats, +}; diff --git a/tc/q_nfq_codel.c b/tc/q_nfq_codel.c new file mode 100644 index 0000000..ef24909 --- /dev/null +++ b/tc/q_nfq_codel.c @@ -0,0 +1,232 @@ +/* + * Fair Queue Codel + * + * Copyright (C) 2012 Eric Dumazet + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... nfq_codel [ limit PACKETS ] [ flows NUMB= ER ]\n"); + fprintf(stderr, " [ target TIME] [ interval TIME = ]\n"); + fprintf(stderr, " [ quantum BYTES ] [ [no]ecn ]\n= "); +} + +static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **ar= gv, + struct nlmsghdr *n) +{ + unsigned limit =3D 0; + unsigned flows =3D 0; + unsigned target =3D 0; + unsigned interval =3D 0; + unsigned quantum =3D 0; + int ecn =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "limit") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&limit, *argv, 0)) { + fprintf(stderr, "Illegal \"limit\"\n"); + return -1; + } + } else if (strcmp(*argv, "flows") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&flows, *argv, 0)) { + fprintf(stderr, "Illegal \"flows\"\n"); + return -1; + } + } else if (strcmp(*argv, "quantum") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&quantum, *argv, 0)) { + fprintf(stderr, "Illegal \"quantum\"\n"); + return -1; + } + } else if (strcmp(*argv, "target") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&target, *argv)) { + fprintf(stderr, "Illegal \"target\"\n"); + return -1; + } + } else if (strcmp(*argv, "interval") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&interval, *argv)) { + fprintf(stderr, "Illegal \"interval\"\n"); + return -1; + } + } else if (strcmp(*argv, "ecn") =3D=3D 0) { + ecn =3D 1; + } else if (strcmp(*argv, "noecn") =3D=3D 0) { + ecn =3D 0; + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (limit) + addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &limit, sizeof(limit)); + if (flows) + addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &flows, sizeof(flows)); + if (quantum) + addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &quantum, sizeof(quantu= m)); + if (interval) + addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &interval, sizeof(inte= rval)); + if (target) + addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &target, sizeof(target))= ; + if (ecn !=3D -1) + addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &ecn, sizeof(ecn)); + tail->rta_len =3D (void *) NLMSG_TAIL(n) - (void *) tail; + return 0; +} + +static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rta= ttr *opt) +{ + struct rtattr *tb[TCA_FQ_CODEL_MAX + 1]; + unsigned limit; + unsigned flows; + unsigned interval; + unsigned target; + unsigned ecn; + unsigned quantum; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_FQ_CODEL_MAX, opt); + + if (tb[TCA_FQ_CODEL_LIMIT] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >=3D sizeof(__u32)) { + limit =3D rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]); + fprintf(f, "limit %up ", limit); + } + if (tb[TCA_FQ_CODEL_FLOWS] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >=3D sizeof(__u32)) { + flows =3D rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]); + fprintf(f, "flows %u ", flows); + } + if (tb[TCA_FQ_CODEL_QUANTUM] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >=3D sizeof(__u32)) { + quantum =3D rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]); + fprintf(f, "quantum %u ", quantum); + } + if (tb[TCA_FQ_CODEL_TARGET] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >=3D sizeof(__u32)) { + target =3D rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]); + fprintf(f, "target %s ", sprint_time(target, b1)); + } + if (tb[TCA_FQ_CODEL_INTERVAL] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >=3D sizeof(__u32)) { + interval =3D rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); + fprintf(f, "interval %s ", sprint_time(interval, b1)); + } + if (tb[TCA_FQ_CODEL_ECN] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >=3D sizeof(__u32)) { + ecn =3D rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); + if (ecn) + fprintf(f, "ecn "); + } + + return 0; +} + +static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, + struct rtattr *xstats) +{ + struct tc_fq_codel_xstats *st; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(*st)) + return -1; + + st =3D RTA_DATA(xstats); + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_QDISC) { + fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u e= cn_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); + } + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_CLASS) { + 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)); + } + } + return 0; + +} + +struct qdisc_util nfq_codel_qdisc_util =3D { + .id =3D "nfq_codel", + .parse_qopt =3D fq_codel_parse_opt, + .print_qopt =3D fq_codel_print_opt, + .print_xstats =3D fq_codel_print_xstats, +}; diff --git a/tc/q_ns2_codel.c b/tc/q_ns2_codel.c new file mode 100644 index 0000000..223a971 --- /dev/null +++ b/tc/q_ns2_codel.c @@ -0,0 +1,188 @@ +/* + * Codel - The Controlled-Delay Active Queue Management algorithm + * + * Copyright (C) 2011-2012 Kathleen Nichols + * Copyright (C) 2011-2012 Van Jacobson + * Copyright (C) 2012 Michael D. Taht + * Copyright (C) 2012 Eric Dumazet + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... ns2_codel [ limit PACKETS ] [ target TIM= E]\n"); + fprintf(stderr, " [ interval TIME ] [ ecn | noecn ]\= n"); +} + +static int codel_parse_opt(struct qdisc_util *qu, int argc, char **argv,= + struct nlmsghdr *n) +{ + unsigned limit =3D 0; + unsigned target =3D 0; + unsigned interval =3D 0; + int ecn =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "limit") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&limit, *argv, 0)) { + fprintf(stderr, "Illegal \"limit\"\n"); + return -1; + } + } else if (strcmp(*argv, "target") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&target, *argv)) { + fprintf(stderr, "Illegal \"target\"\n"); + return -1; + } + } else if (strcmp(*argv, "interval") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&interval, *argv)) { + fprintf(stderr, "Illegal \"interval\"\n"); + return -1; + } + } else if (strcmp(*argv, "ecn") =3D=3D 0) { + ecn =3D 1; + } else if (strcmp(*argv, "noecn") =3D=3D 0) { + ecn =3D 0; + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (limit) + addattr_l(n, 1024, TCA_CODEL_LIMIT, &limit, sizeof(limit)); + if (interval) + addattr_l(n, 1024, TCA_CODEL_INTERVAL, &interval, sizeof(interva= l)); + if (target) + addattr_l(n, 1024, TCA_CODEL_TARGET, &target, sizeof(target)); + if (ecn !=3D -1) + addattr_l(n, 1024, TCA_CODEL_ECN, &ecn, sizeof(ecn)); + tail->rta_len =3D (void *) NLMSG_TAIL(n) - (void *) tail; + return 0; +} + +static int codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr= *opt) +{ + struct rtattr *tb[TCA_CODEL_MAX + 1]; + unsigned limit; + unsigned interval; + unsigned target; + unsigned ecn; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_CODEL_MAX, opt); + + if (tb[TCA_CODEL_LIMIT] && + RTA_PAYLOAD(tb[TCA_CODEL_LIMIT]) >=3D sizeof(__u32)) { + limit =3D rta_getattr_u32(tb[TCA_CODEL_LIMIT]); + fprintf(f, "limit %up ", limit); + } + if (tb[TCA_CODEL_TARGET] && + RTA_PAYLOAD(tb[TCA_CODEL_TARGET]) >=3D sizeof(__u32)) { + target =3D rta_getattr_u32(tb[TCA_CODEL_TARGET]); + fprintf(f, "target %s ", sprint_time(target, b1)); + } + if (tb[TCA_CODEL_INTERVAL] && + RTA_PAYLOAD(tb[TCA_CODEL_INTERVAL]) >=3D sizeof(__u32)) { + interval =3D rta_getattr_u32(tb[TCA_CODEL_INTERVAL]); + fprintf(f, "interval %s ", sprint_time(interval, b1)); + } + if (tb[TCA_CODEL_ECN] && + RTA_PAYLOAD(tb[TCA_CODEL_ECN]) >=3D sizeof(__u32)) { + ecn =3D rta_getattr_u32(tb[TCA_CODEL_ECN]); + if (ecn) + fprintf(f, "ecn "); + } + + return 0; +} + +static int codel_print_xstats(struct qdisc_util *qu, FILE *f, + struct rtattr *xstats) +{ + struct tc_codel_xstats *st; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(*st)) + return -1; + + st =3D RTA_DATA(xstats); + fprintf(f, " count %u lastcount %u ldelay %s", + st->count, st->lastcount, sprint_time(st->ldelay, b1)); + if (st->dropping) + fprintf(f, " dropping"); + if (st->drop_next < 0) + fprintf(f, " drop_next -%s", sprint_time(-st->drop_next, b1)); + else + fprintf(f, " drop_next %s", sprint_time(st->drop_next, b1)); + fprintf(f, "\n maxpacket %u ecn_mark %u drop_overlimit %u", + st->maxpacket, st->ecn_mark, st->drop_overlimit); + return 0; + +} + +struct qdisc_util ns2_codel_qdisc_util =3D { + .id =3D "ns2_codel", + .parse_qopt =3D codel_parse_opt, + .print_qopt =3D codel_print_opt, + .print_xstats =3D codel_print_xstats, +}; diff --git a/tc/q_ns4_codel.c b/tc/q_ns4_codel.c new file mode 100644 index 0000000..0aaa349 --- /dev/null +++ b/tc/q_ns4_codel.c @@ -0,0 +1,188 @@ +/* + * Codel - The Controlled-Delay Active Queue Management algorithm + * + * Copyright (C) 2011-2012 Kathleen Nichols + * Copyright (C) 2011-2012 Van Jacobson + * Copyright (C) 2012 Michael D. Taht + * Copyright (C) 2012 Eric Dumazet + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... ns4_codel [ limit PACKETS ] [ target TIM= E]\n"); + fprintf(stderr, " [ interval TIME ] [ ecn | noecn ]\= n"); +} + +static int codel_parse_opt(struct qdisc_util *qu, int argc, char **argv,= + struct nlmsghdr *n) +{ + unsigned limit =3D 0; + unsigned target =3D 0; + unsigned interval =3D 0; + int ecn =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "limit") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&limit, *argv, 0)) { + fprintf(stderr, "Illegal \"limit\"\n"); + return -1; + } + } else if (strcmp(*argv, "target") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&target, *argv)) { + fprintf(stderr, "Illegal \"target\"\n"); + return -1; + } + } else if (strcmp(*argv, "interval") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&interval, *argv)) { + fprintf(stderr, "Illegal \"interval\"\n"); + return -1; + } + } else if (strcmp(*argv, "ecn") =3D=3D 0) { + ecn =3D 1; + } else if (strcmp(*argv, "noecn") =3D=3D 0) { + ecn =3D 0; + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (limit) + addattr_l(n, 1024, TCA_CODEL_LIMIT, &limit, sizeof(limit)); + if (interval) + addattr_l(n, 1024, TCA_CODEL_INTERVAL, &interval, sizeof(interva= l)); + if (target) + addattr_l(n, 1024, TCA_CODEL_TARGET, &target, sizeof(target)); + if (ecn !=3D -1) + addattr_l(n, 1024, TCA_CODEL_ECN, &ecn, sizeof(ecn)); + tail->rta_len =3D (void *) NLMSG_TAIL(n) - (void *) tail; + return 0; +} + +static int codel_print_opt(struct qdisc_util *qu, FILE *f, struct rtattr= *opt) +{ + struct rtattr *tb[TCA_CODEL_MAX + 1]; + unsigned limit; + unsigned interval; + unsigned target; + unsigned ecn; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_CODEL_MAX, opt); + + if (tb[TCA_CODEL_LIMIT] && + RTA_PAYLOAD(tb[TCA_CODEL_LIMIT]) >=3D sizeof(__u32)) { + limit =3D rta_getattr_u32(tb[TCA_CODEL_LIMIT]); + fprintf(f, "limit %up ", limit); + } + if (tb[TCA_CODEL_TARGET] && + RTA_PAYLOAD(tb[TCA_CODEL_TARGET]) >=3D sizeof(__u32)) { + target =3D rta_getattr_u32(tb[TCA_CODEL_TARGET]); + fprintf(f, "target %s ", sprint_time(target, b1)); + } + if (tb[TCA_CODEL_INTERVAL] && + RTA_PAYLOAD(tb[TCA_CODEL_INTERVAL]) >=3D sizeof(__u32)) { + interval =3D rta_getattr_u32(tb[TCA_CODEL_INTERVAL]); + fprintf(f, "interval %s ", sprint_time(interval, b1)); + } + if (tb[TCA_CODEL_ECN] && + RTA_PAYLOAD(tb[TCA_CODEL_ECN]) >=3D sizeof(__u32)) { + ecn =3D rta_getattr_u32(tb[TCA_CODEL_ECN]); + if (ecn) + fprintf(f, "ecn "); + } + + return 0; +} + +static int codel_print_xstats(struct qdisc_util *qu, FILE *f, + struct rtattr *xstats) +{ + struct tc_codel_xstats *st; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(*st)) + return -1; + + st =3D RTA_DATA(xstats); + fprintf(f, " count %u lastcount %u ldelay %s", + st->count, st->lastcount, sprint_time(st->ldelay, b1)); + if (st->dropping) + fprintf(f, " dropping"); + if (st->drop_next < 0) + fprintf(f, " drop_next -%s", sprint_time(-st->drop_next, b1)); + else + fprintf(f, " drop_next %s", sprint_time(st->drop_next, b1)); + fprintf(f, "\n maxpacket %u ecn_mark %u drop_overlimit %u", + st->maxpacket, st->ecn_mark, st->drop_overlimit); + return 0; + +} + +struct qdisc_util ns4_codel_qdisc_util =3D { + .id =3D "ns4_codel", + .parse_qopt =3D codel_parse_opt, + .print_qopt =3D codel_print_opt, + .print_xstats =3D codel_print_xstats, +}; diff --git a/tc/q_pfq_codel.c b/tc/q_pfq_codel.c new file mode 100644 index 0000000..52c5160 --- /dev/null +++ b/tc/q_pfq_codel.c @@ -0,0 +1,232 @@ +/* + * Fair Queue Codel + * + * Copyright (C) 2012 Eric Dumazet + * + * 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 th= e + * documentation and/or other materials provided with the distributio= n. + * 3. The names of the authors may not be used to endorse or promote pro= ducts + * derived from this software without specific prior written permissi= on. + * + * 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 +#include +#include +#include +#include +#include +#include +#include +#include + +#include "utils.h" +#include "tc_util.h" + +static void explain(void) +{ + fprintf(stderr, "Usage: ... pfq_codel [ limit PACKETS ] [ flows NUMB= ER ]\n"); + fprintf(stderr, " [ target TIME] [ interval TIME = ]\n"); + fprintf(stderr, " [ quantum BYTES ] [ [no]ecn ]\n= "); +} + +static int fq_codel_parse_opt(struct qdisc_util *qu, int argc, char **ar= gv, + struct nlmsghdr *n) +{ + unsigned limit =3D 0; + unsigned flows =3D 0; + unsigned target =3D 0; + unsigned interval =3D 0; + unsigned quantum =3D 0; + int ecn =3D -1; + struct rtattr *tail; + + while (argc > 0) { + if (strcmp(*argv, "limit") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&limit, *argv, 0)) { + fprintf(stderr, "Illegal \"limit\"\n"); + return -1; + } + } else if (strcmp(*argv, "flows") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&flows, *argv, 0)) { + fprintf(stderr, "Illegal \"flows\"\n"); + return -1; + } + } else if (strcmp(*argv, "quantum") =3D=3D 0) { + NEXT_ARG(); + if (get_unsigned(&quantum, *argv, 0)) { + fprintf(stderr, "Illegal \"quantum\"\n"); + return -1; + } + } else if (strcmp(*argv, "target") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&target, *argv)) { + fprintf(stderr, "Illegal \"target\"\n"); + return -1; + } + } else if (strcmp(*argv, "interval") =3D=3D 0) { + NEXT_ARG(); + if (get_time(&interval, *argv)) { + fprintf(stderr, "Illegal \"interval\"\n"); + return -1; + } + } else if (strcmp(*argv, "ecn") =3D=3D 0) { + ecn =3D 1; + } else if (strcmp(*argv, "noecn") =3D=3D 0) { + ecn =3D 0; + } else if (strcmp(*argv, "help") =3D=3D 0) { + explain(); + return -1; + } else { + fprintf(stderr, "What is \"%s\"?\n", *argv); + explain(); + return -1; + } + argc--; argv++; + } + + tail =3D NLMSG_TAIL(n); + addattr_l(n, 1024, TCA_OPTIONS, NULL, 0); + if (limit) + addattr_l(n, 1024, TCA_FQ_CODEL_LIMIT, &limit, sizeof(limit)); + if (flows) + addattr_l(n, 1024, TCA_FQ_CODEL_FLOWS, &flows, sizeof(flows)); + if (quantum) + addattr_l(n, 1024, TCA_FQ_CODEL_QUANTUM, &quantum, sizeof(quantu= m)); + if (interval) + addattr_l(n, 1024, TCA_FQ_CODEL_INTERVAL, &interval, sizeof(inte= rval)); + if (target) + addattr_l(n, 1024, TCA_FQ_CODEL_TARGET, &target, sizeof(target))= ; + if (ecn !=3D -1) + addattr_l(n, 1024, TCA_FQ_CODEL_ECN, &ecn, sizeof(ecn)); + tail->rta_len =3D (void *) NLMSG_TAIL(n) - (void *) tail; + return 0; +} + +static int fq_codel_print_opt(struct qdisc_util *qu, FILE *f, struct rta= ttr *opt) +{ + struct rtattr *tb[TCA_FQ_CODEL_MAX + 1]; + unsigned limit; + unsigned flows; + unsigned interval; + unsigned target; + unsigned ecn; + unsigned quantum; + SPRINT_BUF(b1); + + if (opt =3D=3D NULL) + return 0; + + parse_rtattr_nested(tb, TCA_FQ_CODEL_MAX, opt); + + if (tb[TCA_FQ_CODEL_LIMIT] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_LIMIT]) >=3D sizeof(__u32)) { + limit =3D rta_getattr_u32(tb[TCA_FQ_CODEL_LIMIT]); + fprintf(f, "limit %up ", limit); + } + if (tb[TCA_FQ_CODEL_FLOWS] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_FLOWS]) >=3D sizeof(__u32)) { + flows =3D rta_getattr_u32(tb[TCA_FQ_CODEL_FLOWS]); + fprintf(f, "flows %u ", flows); + } + if (tb[TCA_FQ_CODEL_QUANTUM] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_QUANTUM]) >=3D sizeof(__u32)) { + quantum =3D rta_getattr_u32(tb[TCA_FQ_CODEL_QUANTUM]); + fprintf(f, "quantum %u ", quantum); + } + if (tb[TCA_FQ_CODEL_TARGET] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_TARGET]) >=3D sizeof(__u32)) { + target =3D rta_getattr_u32(tb[TCA_FQ_CODEL_TARGET]); + fprintf(f, "target %s ", sprint_time(target, b1)); + } + if (tb[TCA_FQ_CODEL_INTERVAL] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_INTERVAL]) >=3D sizeof(__u32)) { + interval =3D rta_getattr_u32(tb[TCA_FQ_CODEL_INTERVAL]); + fprintf(f, "interval %s ", sprint_time(interval, b1)); + } + if (tb[TCA_FQ_CODEL_ECN] && + RTA_PAYLOAD(tb[TCA_FQ_CODEL_ECN]) >=3D sizeof(__u32)) { + ecn =3D rta_getattr_u32(tb[TCA_FQ_CODEL_ECN]); + if (ecn) + fprintf(f, "ecn "); + } + + return 0; +} + +static int fq_codel_print_xstats(struct qdisc_util *qu, FILE *f, + struct rtattr *xstats) +{ + struct tc_fq_codel_xstats *st; + SPRINT_BUF(b1); + + if (xstats =3D=3D NULL) + return 0; + + if (RTA_PAYLOAD(xstats) < sizeof(*st)) + return -1; + + st =3D RTA_DATA(xstats); + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_QDISC) { + fprintf(f, " maxpacket %u drop_overlimit %u new_flow_count %u e= cn_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); + } + if (st->type =3D=3D TCA_FQ_CODEL_XSTATS_CLASS) { + 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)); + } + } + return 0; + +} + +struct qdisc_util pfq_codel_qdisc_util =3D { + .id =3D "pfq_codel", + .parse_qopt =3D fq_codel_parse_opt, + .print_qopt =3D fq_codel_print_opt, + .print_xstats =3D fq_codel_print_xstats, +}; 141-cake-add-support.patch --------------070100020904050000080609 Content-Type: text/plain; charset=windows-1252; name="140-cake-add-support.patch" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="140-cake-add-support.patch" ZGlmZiAtLWdpdCBhL2luY2x1ZGUvbGludXgvcGt0X3NjaGVkLmggYi9pbmNsdWRlL2xpbnV4 L3BrdF9zY2hlZC5oCmluZGV4IDUzNGI4NDcuLmExZDdiNjcgMTAwNjQ0Ci0tLSBhL2luY2x1 ZGUvbGludXgvcGt0X3NjaGVkLmgKKysrIGIvaW5jbHVkZS9saW51eC9wa3Rfc2NoZWQuaApA QCAtODQ1LDQgKzg0NSwzOCBAQCBzdHJ1Y3QgdGNfcGllX3hzdGF0cyB7CiAJX191MzIgbWF4 cTsgICAgICAgICAgICAgLyogbWF4aW11bSBxdWV1ZSBzaXplICovCiAJX191MzIgZWNuX21h cms7ICAgICAgICAgLyogcGFja2V0cyBtYXJrZWQgd2l0aCBlY24qLwogfTsKKworLyogQ0FL RSAqLworZW51bSB7CisJVENBX0NBS0VfVU5TUEVDLAorCVRDQV9DQUtFX0JBU0VfUkFURSwK KwlUQ0FfQ0FLRV9ESUZGU0VSVl9NT0RFLAorCVRDQV9DQUtFX0FUTSwKKwlUQ0FfQ0FLRV9G TE9XX01PREUsCisJX19UQ0FfQ0FLRV9NQVgKK307CisjZGVmaW5lIFRDQV9DQUtFX01BWAko X19UQ0FfQ0FLRV9NQVggLSAxKQorCitzdHJ1Y3QgdGNfY2FrZV94c3RhdHMgeworCV9fdTE2 IHR5cGU7ICAvKiBjb25zdGFudCBtYWdpYyAweENBRkUgKi8KKwlfX3UxNiBjbGFzc19jbnQ7 CisJc3RydWN0IHsKKwkJX191MzIgcmF0ZTsKKwkJX191MzIgdGFyZ2V0X3VzOworCQlfX3Uz MiBwYWNrZXRzOworCQlfX3UzMiBpbnRlcnZhbF91czsKKwkJX191NjQgYnl0ZXM7CisJCV9f dTMyIGRyb3BwZWQ7CisJCV9fdTMyIGVjbl9tYXJrZWQ7CisJCV9fdTMyIHdheV9pbmRpcmVj dF9oaXRzOworCQlfX3UzMiB3YXlfbWlzc2VzOworCQlfX3UzMiB3YXlfY29sbGlzaW9uczsK KwkJX191MzIgYmFja2xvZ19ieXRlczsKKwkJX191MzIgcGVha19kZWxheTsgLyogZGVsYXkg dG8gZmF0IGZsb3dzICovCisJCV9fdTMyIGF2Z2VfZGVsYXk7CisJCV9fdTMyIGJhc2VfZGVs YXk7IC8qIGRlbGF5IHRvIHNwYXJzZSBmbG93cyAqLworCQlfX3UzMiBkdW1teTI7CisJfSBj bHNbOF07Cit9OworCiAjZW5kaWYKZGlmZiAtLWdpdCBhL3RjL01ha2VmaWxlIGIvdGMvTWFr ZWZpbGUKaW5kZXggZDgzMWExNS4uZTUwM2M4YSAxMDA2NDQKLS0tIGEvdGMvTWFrZWZpbGUK KysrIGIvdGMvTWFrZWZpbGUKQEAgLTU5LDggKzU5LDE3IEBAIFRDTU9EVUxFUyArPSBlbV9t ZXRhLm8KIFRDTU9EVUxFUyArPSBxX21xcHJpby5vCiBUQ01PRFVMRVMgKz0gcV9jb2RlbC5v CiBUQ01PRFVMRVMgKz0gcV9mcV9jb2RlbC5vCitUQ01PRFVMRVMgKz0gcV9uZnFfY29kZWwu bworVENNT0RVTEVTICs9IHFfZWZxX2NvZGVsLm8KK1RDTU9EVUxFUyArPSBxX3NmcV9jb2Rl bC5vCitUQ01PRFVMRVMgKz0gcV9wZnFfY29kZWwubworVENNT0RVTEVTICs9IHFfbnMyX2Nv ZGVsLm8KK1RDTU9EVUxFUyArPSBxX25zNF9jb2RlbC5vCiBUQ01PRFVMRVMgKz0gcV9mcS5v CiBUQ01PRFVMRVMgKz0gcV9waWUubworVENNT0RVTEVTICs9IHFfY2FrZS5vCitUQ01PRFVM RVMgKz0gcV9jYWtlMC5vCitUQ01PRFVMRVMgKz0gcV9jYWtlMi5vCiBUQ01PRFVMRVMgKz0g cV9oaGYubwogCiBpZmVxICgkKFRDX0NPTkZJR19JUFNFVCksIHkpCmRpZmYgLS1naXQgYS90 Yy9xX2Nha2UuYyBiL3RjL3FfY2FrZS5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAw MDAwMDAuLmQ5NDE1ZDMKLS0tIC9kZXYvbnVsbAorKysgYi90Yy9xX2Nha2UuYwpAQCAtMCww ICsxLDMzMyBAQAorLyoKKyAqIENvbW1vbiBBcHBsaWNhdGlvbnMgS2VwdCBFbmhhbmNlZCAg LS0gIENBS0UKKyAqCisgKiAgQ29weXJpZ2h0IChDKSAyMDE0LTIwMTUgSm9uYXRoYW4gTW9y dG9uIDxjaHJvbWF0aXg5OUBnbWFpbC5jb20+CisgKgorICogUmVkaXN0cmlidXRpb24gYW5k IHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBt b2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5n IGNvbmRpdGlvbnMKKyAqIGFyZSBtZXQ6CisgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291 cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNl LCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1l ciwKKyAqICAgIHdpdGhvdXQgbW9kaWZpY2F0aW9uLgorICogMi4gUmVkaXN0cmlidXRpb25z IGluIGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAq ICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcg ZGlzY2xhaW1lciBpbiB0aGUKKyAqICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1h dGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisgKiAzLiBUaGUgbmFt ZXMgb2YgdGhlIGF1dGhvcnMgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90 ZSBwcm9kdWN0cworICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBz cGVjaWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogQWx0ZXJuYXRpdmVs eSwgcHJvdmlkZWQgdGhhdCB0aGlzIG5vdGljZSBpcyByZXRhaW5lZCBpbiBmdWxsLCB0aGlz CisgKiBzb2Z0d2FyZSBtYXkgYmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRo ZSBHTlUgR2VuZXJhbAorICogUHVibGljIExpY2Vuc2UgKCJHUEwiKSB2ZXJzaW9uIDIsIGlu IHdoaWNoIGNhc2UgdGhlIHByb3Zpc2lvbnMgb2YgdGhlCisgKiBHUEwgYXBwbHkgSU5TVEVB RCBPRiB0aG9zZSBnaXZlbiBhYm92ZS4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJ REVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMg SVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywg QlVUIE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJD SEFOVEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBB UkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dO RVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1Qs IElOQ0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwg REFNQUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVO VCBPRiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERB VEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVT RUQgQU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05U UkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdF TkNFIE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisg KiBPRiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZ IE9GIFNVQ0gKKyAqIERBTUFHRS4KKyAqCisgKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+Cisj aW5jbHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8c3lz bG9nLmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+Cisj aW5jbHVkZSA8bmV0aW5ldC9pbi5oPgorI2luY2x1ZGUgPGFycGEvaW5ldC5oPgorI2luY2x1 ZGUgPHN0cmluZy5oPgorCisjaW5jbHVkZSAidXRpbHMuaCIKKyNpbmNsdWRlICJ0Y191dGls LmgiCisKK3N0YXRpYyB2b2lkIGV4cGxhaW4odm9pZCkKK3sKKwlmcHJpbnRmKHN0ZGVyciwg IlVzYWdlOiAuLi4gY2FrZSBbIGJhbmR3aWR0aCBSQVRFIHwgdW5saW1pdGVkIF1cbiIKKwkg ICAgICAgICAgICAgICAgIiAgICAgICAgICAgICAgICBbIGJlc3RlZmZvcnQgfCBwcmVjZWRl bmNlIHwgZGlmZnNlcnY4IHwgZGlmZnNlcnY0IF1cbiIKKwkgICAgICAgICAgICAgICAgIiAg ICAgICAgICAgICAgICBbIGZsb3dibGluZCB8IHNyY2hvc3QgfCBkc3Rob3N0IHwgaG9zdHMg fCBmbG93cyBdXG4iCisJICAgICAgICAgICAgICAgICIgICAgICAgICAgICAgICAgWyBhdG0g XVxuIik7Cit9CisKK3N0YXRpYyBpbnQgY2FrZV9wYXJzZV9vcHQoc3RydWN0IHFkaXNjX3V0 aWwgKnF1LCBpbnQgYXJnYywgY2hhciAqKmFyZ3YsCisJCQkgICAgICBzdHJ1Y3Qgbmxtc2do ZHIgKm4pCit7CisJaW50IHVubGltaXRlZCA9IDA7CisJdW5zaWduZWQgYmFuZHdpZHRoID0g MDsKKwl1bnNpZ25lZCBkaWZmc2VydiA9IDA7CisJaW50IGZsb3dtb2RlID0gLTE7CisJaW50 IGF0bSA9IC0xOworCXN0cnVjdCBydGF0dHIgKnRhaWw7CisKKwl3aGlsZSAoYXJnYyA+IDAp IHsKKwkJaWYgKHN0cmNtcCgqYXJndiwgImJhbmR3aWR0aCIpID09IDApIHsKKwkJCU5FWFRf QVJHKCk7CisJCQlpZiAoZ2V0X3JhdGUoJmJhbmR3aWR0aCwgKmFyZ3YpKSB7CisJCQkJZnBy aW50ZihzdGRlcnIsICJJbGxlZ2FsIFwiYmFuZHdpZHRoXCJcbiIpOworCQkJCXJldHVybiAt MTsKKwkJCX0KKwkJCXVubGltaXRlZCA9IDA7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2 LCAidW5saW1pdGVkIikgPT0gMCkgeworCQkJYmFuZHdpZHRoID0gMDsKKwkJCXVubGltaXRl ZCA9IDE7CisKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJiZXN0ZWZmb3J0IikgPT0g MCkgeworCQkJZGlmZnNlcnYgPSAxOworCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgInBy ZWNlZGVuY2UiKSA9PSAwKSB7CisJCQlkaWZmc2VydiA9IDI7CisJCX0gZWxzZSBpZiAoc3Ry Y21wKCphcmd2LCAiZGlmZnNlcnY4IikgPT0gMCkgeworCQkJZGlmZnNlcnYgPSAzOworCQl9 IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgImRpZmZzZXJ2NCIpID09IDApIHsKKwkJCWRpZmZz ZXJ2ID0gNDsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJkaWZmc2VydiIpID09IDAp IHsKKwkJCWRpZmZzZXJ2ID0gNDsKKworCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgImZs b3dibGluZCIpID09IDApIHsKKwkJCWZsb3dtb2RlID0gMDsKKwkJfSBlbHNlIGlmIChzdHJj bXAoKmFyZ3YsICJzcmNob3N0IikgPT0gMCkgeworCQkJZmxvd21vZGUgPSAxOworCQl9IGVs c2UgaWYgKHN0cmNtcCgqYXJndiwgImRzdGhvc3QiKSA9PSAwKSB7CisJCQlmbG93bW9kZSA9 IDI7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiaG9zdHMiKSA9PSAwKSB7CisJCQlm bG93bW9kZSA9IDM7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiZmxvd3MiKSA9PSAw KSB7CisJCQlmbG93bW9kZSA9IDQ7CisKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJh dG0iKSA9PSAwKSB7CisJCQlhdG0gPSAxOworCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwg Im5vYXRtIikgPT0gMCkgeworCQkJYXRtID0gMDsKKworCQl9IGVsc2UgaWYgKHN0cmNtcCgq YXJndiwgImhlbHAiKSA9PSAwKSB7CisJCQlleHBsYWluKCk7CisJCQlyZXR1cm4gLTE7CisJ CX0gZWxzZSB7CisJCQlmcHJpbnRmKHN0ZGVyciwgIldoYXQgaXMgXCIlc1wiP1xuIiwgKmFy Z3YpOworCQkJZXhwbGFpbigpOworCQkJcmV0dXJuIC0xOworCQl9CisJCWFyZ2MtLTsgYXJn disrOworCX0KKworCXRhaWwgPSBOTE1TR19UQUlMKG4pOworCWFkZGF0dHJfbChuLCAxMDI0 LCBUQ0FfT1BUSU9OUywgTlVMTCwgMCk7CisJaWYgKGJhbmR3aWR0aCB8fCB1bmxpbWl0ZWQp CisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfQ0FLRV9CQVNFX1JBVEUsICZiYW5kd2lkdGgs IHNpemVvZihiYW5kd2lkdGgpKTsKKwlpZiAoZGlmZnNlcnYpCisJCWFkZGF0dHJfbChuLCAx MDI0LCBUQ0FfQ0FLRV9ESUZGU0VSVl9NT0RFLCAmZGlmZnNlcnYsIHNpemVvZihkaWZmc2Vy dikpOworCWlmIChhdG0gIT0gLTEpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfQ0FLRV9B VE0sICZhdG0sIHNpemVvZihhdG0pKTsKKwlpZiAoZmxvd21vZGUgIT0gLTEpCisJCWFkZGF0 dHJfbChuLCAxMDI0LCBUQ0FfQ0FLRV9GTE9XX01PREUsICZmbG93bW9kZSwgc2l6ZW9mKGZs b3dtb2RlKSk7CisJdGFpbC0+cnRhX2xlbiA9ICh2b2lkICopIE5MTVNHX1RBSUwobikgLSAo dm9pZCAqKSB0YWlsOworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGNha2VfcHJpbnRf b3B0KHN0cnVjdCBxZGlzY191dGlsICpxdSwgRklMRSAqZiwgc3RydWN0IHJ0YXR0ciAqb3B0 KQoreworCXN0cnVjdCBydGF0dHIgKnRiW1RDQV9DQUtFX01BWCArIDFdOworCXVuc2lnbmVk IGJhbmR3aWR0aCA9IDA7CisJdW5zaWduZWQgZGlmZnNlcnYgPSAwOworCXVuc2lnbmVkIGZs b3dtb2RlID0gMDsKKwlpbnQgYXRtID0gLTE7CisJU1BSSU5UX0JVRihiMSk7CisKKwlpZiAo b3B0ID09IE5VTEwpCisJCXJldHVybiAwOworCisJcGFyc2VfcnRhdHRyX25lc3RlZCh0Yiwg VENBX0NBS0VfTUFYLCBvcHQpOworCisJaWYgKHRiW1RDQV9DQUtFX0JBU0VfUkFURV0gJiYK KwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0NBS0VfQkFTRV9SQVRFXSkgPj0gc2l6ZW9mKF9f dTMyKSkgeworCQliYW5kd2lkdGggPSBydGFfZ2V0YXR0cl91MzIodGJbVENBX0NBS0VfQkFT RV9SQVRFXSk7CisJCWlmKGJhbmR3aWR0aCkKKwkJCWZwcmludGYoZiwgImJhbmR3aWR0aCAl cyAiLCBzcHJpbnRfcmF0ZShiYW5kd2lkdGgsIGIxKSk7CisJCWVsc2UKKwkJCWZwcmludGYo ZiwgInVubGltaXRlZCAiKTsKKwl9CisJaWYgKHRiW1RDQV9DQUtFX0RJRkZTRVJWX01PREVd ICYmCisJICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9DQUtFX0RJRkZTRVJWX01PREVdKSA+PSBz aXplb2YoX191MzIpKSB7CisJCWRpZmZzZXJ2ID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9D QUtFX0RJRkZTRVJWX01PREVdKTsKKwkJc3dpdGNoKGRpZmZzZXJ2KSB7CisJCWNhc2UgMToK KwkJCWZwcmludGYoZiwgImJlc3RlZmZvcnQgIik7CisJCQlicmVhazsKKwkJY2FzZSAyOgor CQkJZnByaW50ZihmLCAicHJlY2VkZW5jZSAiKTsKKwkJCWJyZWFrOworCQljYXNlIDM6CisJ CQlmcHJpbnRmKGYsICJkaWZmc2VydjggIik7CisJCQlicmVhazsKKwkJY2FzZSA0OgorCQkJ ZnByaW50ZihmLCAiZGlmZnNlcnY0ICIpOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlm cHJpbnRmKGYsICIoP2RpZmZzZXJ2PykgIik7CisJCQlicmVhazsKKwkJfTsKKwl9CisJaWYg KHRiW1RDQV9DQUtFX0ZMT1dfTU9ERV0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0NB S0VfRkxPV19NT0RFXSkgPj0gc2l6ZW9mKF9fdTMyKSkgeworCQlmbG93bW9kZSA9IHJ0YV9n ZXRhdHRyX3UzMih0YltUQ0FfQ0FLRV9GTE9XX01PREVdKTsKKwkJc3dpdGNoKGZsb3dtb2Rl KSB7CisJCWNhc2UgMDoKKwkJCWZwcmludGYoZiwgImZsb3dibGluZCAiKTsKKwkJCWJyZWFr OworCQljYXNlIDE6CisJCQlmcHJpbnRmKGYsICJzcmNob3N0ICIpOworCQkJYnJlYWs7CisJ CWNhc2UgMjoKKwkJCWZwcmludGYoZiwgImRzdGhvc3QgIik7CisJCQlicmVhazsKKwkJY2Fz ZSAzOgorCQkJZnByaW50ZihmLCAiaG9zdHMgIik7CisJCQlicmVhazsKKwkJY2FzZSA0Ogor CQkJZnByaW50ZihmLCAiZmxvd3MgIik7CisJCQlicmVhazsKKwkJZGVmYXVsdDoKKwkJCWZw cmludGYoZiwgIig/Zmxvd21vZGU/KSAiKTsKKwkJCWJyZWFrOworCQl9OworCX0KKwlpZiAo dGJbVENBX0NBS0VfQVRNXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfQ0FLRV9BVE1d KSA+PSBzaXplb2YoX191MzIpKSB7CisJCWF0bSA9IHJ0YV9nZXRhdHRyX3UzMih0YltUQ0Ff Q0FLRV9BVE1dKTsKKwkJaWYgKGF0bSkKKwkJCWZwcmludGYoZiwgImF0bSAiKTsKKwl9CisK KwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBjYWtlX3ByaW50X3hzdGF0cyhzdHJ1Y3Qg cWRpc2NfdXRpbCAqcXUsIEZJTEUgKmYsCisJCQkJIHN0cnVjdCBydGF0dHIgKnhzdGF0cykK K3sKKwkvKiBmcV9jb2RlbCBzdGF0cyBmb3JtYXQgYm9ycm93ZWQgKi8KKwlzdHJ1Y3QgdGNf ZnFfY29kZWxfeHN0YXRzICpzdDsKKwlzdHJ1Y3QgdGNfY2FrZV94c3RhdHMgICAgICpzdGM7 CisJU1BSSU5UX0JVRihiMSk7CisKKwlpZiAoeHN0YXRzID09IE5VTEwpCisJCXJldHVybiAw OworCisJaWYgKFJUQV9QQVlMT0FEKHhzdGF0cykgPCBzaXplb2Yoc3QtPnR5cGUpKQorCQly ZXR1cm4gLTE7CisKKwlzdCAgPSBSVEFfREFUQSh4c3RhdHMpOworCXN0YyA9IFJUQV9EQVRB KHhzdGF0cyk7CisKKwlpZiAoc3QtPnR5cGUgPT0gVENBX0ZRX0NPREVMX1hTVEFUU19RRElT QyAmJiBSVEFfUEFZTE9BRCh4c3RhdHMpID49IHNpemVvZigqc3QpKSB7CisJCWZwcmludGYo ZiwgIiAgbWF4cGFja2V0ICV1IGRyb3Bfb3ZlcmxpbWl0ICV1IG5ld19mbG93X2NvdW50ICV1 IGVjbl9tYXJrICV1IiwKKwkJCXN0LT5xZGlzY19zdGF0cy5tYXhwYWNrZXQsCisJCQlzdC0+ cWRpc2Nfc3RhdHMuZHJvcF9vdmVybGltaXQsCisJCQlzdC0+cWRpc2Nfc3RhdHMubmV3X2Zs b3dfY291bnQsCisJCQlzdC0+cWRpc2Nfc3RhdHMuZWNuX21hcmspOworCQlmcHJpbnRmKGYs ICJcbiAgbmV3X2Zsb3dzX2xlbiAldSBvbGRfZmxvd3NfbGVuICV1IiwKKwkJCXN0LT5xZGlz Y19zdGF0cy5uZXdfZmxvd3NfbGVuLAorCQkJc3QtPnFkaXNjX3N0YXRzLm9sZF9mbG93c19s ZW4pOworCX0gZWxzZSBpZiAoc3QtPnR5cGUgPT0gVENBX0ZRX0NPREVMX1hTVEFUU19DTEFT UyAmJiBSVEFfUEFZTE9BRCh4c3RhdHMpID49IHNpemVvZigqc3QpKSB7CisJCWZwcmludGYo ZiwgIiAgZGVmaWNpdCAlZCBjb3VudCAldSBsYXN0Y291bnQgJXUgbGRlbGF5ICVzIiwKKwkJ CXN0LT5jbGFzc19zdGF0cy5kZWZpY2l0LAorCQkJc3QtPmNsYXNzX3N0YXRzLmNvdW50LAor CQkJc3QtPmNsYXNzX3N0YXRzLmxhc3Rjb3VudCwKKwkJCXNwcmludF90aW1lKHN0LT5jbGFz c19zdGF0cy5sZGVsYXksIGIxKSk7CisJCWlmIChzdC0+Y2xhc3Nfc3RhdHMuZHJvcHBpbmcp IHsKKwkJCWZwcmludGYoZiwgIiBkcm9wcGluZyIpOworCQkJaWYgKHN0LT5jbGFzc19zdGF0 cy5kcm9wX25leHQgPCAwKQorCQkJCWZwcmludGYoZiwgIiBkcm9wX25leHQgLSVzIiwKKwkJ CQkJc3ByaW50X3RpbWUoLXN0LT5jbGFzc19zdGF0cy5kcm9wX25leHQsIGIxKSk7CisJCQll bHNlCisJCQkJZnByaW50ZihmLCAiIGRyb3BfbmV4dCAlcyIsCisJCQkJCXNwcmludF90aW1l KHN0LT5jbGFzc19zdGF0cy5kcm9wX25leHQsIGIxKSk7CisJCX0KKwl9IGVsc2UgaWYgKHN0 Yy0+dHlwZSA9PSAweENBRkUgJiYgUlRBX1BBWUxPQUQoeHN0YXRzKSA+PSBzaXplb2YoKnN0 YykpIHsKKwkJaW50IGk7CisKKwkJZnByaW50ZihmLCAiICAgICAgICAiKTsKKwkJZm9yKGk9 MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRmKGYsICIgICBDbGFzcyAl dSAgIiwgaSk7CisJCWZwcmludGYoZiwgIlxuIik7CisKKwkJZnByaW50ZihmLCAiICByYXRl ICAiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRm KGYsICIlMTJzIiwgc3ByaW50X3JhdGUoc3RjLT5jbHNbaV0ucmF0ZSwgYjEpKTsKKwkJZnBy aW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRmKGYsICIgIHRhcmdldCIpOworCQlmb3IoaT0w OyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJCWZwcmludGYoZiwgIiUxMnMiLCBzcHJp bnRfdGltZShzdGMtPmNsc1tpXS50YXJnZXRfdXMsIGIxKSk7CisJCWZwcmludGYoZiwgIlxu Iik7CisKKwkJZnByaW50ZihmLCAiaW50ZXJ2YWwiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+ Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRmKGYsICIlMTJzIiwgc3ByaW50X3RpbWUoc3Rj LT5jbHNbaV0uaW50ZXJ2YWxfdXMsIGIxKSk7CisJCWZwcmludGYoZiwgIlxuIik7CisKKwkJ ZnByaW50ZihmLCAiUGsgZGVsYXkiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250 OyBpKyspCisJCQlmcHJpbnRmKGYsICIlMTJzIiwgc3ByaW50X3RpbWUoc3RjLT5jbHNbaV0u cGVha19kZWxheSwgYjEpKTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRmKGYs ICJBdiBkZWxheSIpOworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJ CWZwcmludGYoZiwgIiUxMnMiLCBzcHJpbnRfdGltZShzdGMtPmNsc1tpXS5hdmdlX2RlbGF5 LCBiMSkpOworCQlmcHJpbnRmKGYsICJcbiIpOworCisJCWZwcmludGYoZiwgIlNwIGRlbGF5 Iik7CisJCWZvcihpPTA7IGkgPCBzdGMtPmNsYXNzX2NudDsgaSsrKQorCQkJZnByaW50Zihm LCAiJTEycyIsIHNwcmludF90aW1lKHN0Yy0+Y2xzW2ldLmJhc2VfZGVsYXksIGIxKSk7CisJ CWZwcmludGYoZiwgIlxuIik7CisKKwkJZnByaW50ZihmLCAiICBwa3RzICAiKTsKKwkJZm9y KGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRmKGYsICIlMTJ1Iiwg c3RjLT5jbHNbaV0ucGFja2V0cyk7CisJCWZwcmludGYoZiwgIlxuIik7CisKKwkJZnByaW50 ZihmLCAid2F5IGluZHMiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKysp CisJCQlmcHJpbnRmKGYsICIlMTJ1Iiwgc3RjLT5jbHNbaV0ud2F5X2luZGlyZWN0X2hpdHMp OworCQlmcHJpbnRmKGYsICJcbiIpOworCisJCWZwcmludGYoZiwgIndheSBtaXNzIik7CisJ CWZvcihpPTA7IGkgPCBzdGMtPmNsYXNzX2NudDsgaSsrKQorCQkJZnByaW50ZihmLCAiJTEy dSIsIHN0Yy0+Y2xzW2ldLndheV9taXNzZXMpOworCQlmcHJpbnRmKGYsICJcbiIpOworCisJ CWZwcmludGYoZiwgIndheSBjb2xzIik7CisJCWZvcihpPTA7IGkgPCBzdGMtPmNsYXNzX2Nu dDsgaSsrKQorCQkJZnByaW50ZihmLCAiJTEydSIsIHN0Yy0+Y2xzW2ldLndheV9jb2xsaXNp b25zKTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRmKGYsICIgIGJ5dGVzICIp OworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJCWZwcmludGYoZiwg IiUxMmxsdSIsIHN0Yy0+Y2xzW2ldLmJ5dGVzKTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKwor CQlmcHJpbnRmKGYsICIgIGRyb3BzICIpOworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19j bnQ7IGkrKykKKwkJCWZwcmludGYoZiwgIiUxMnUiLCBzdGMtPmNsc1tpXS5kcm9wcGVkKTsK KwkJZnByaW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRmKGYsICIgIG1hcmtzICIpOworCQlm b3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJCWZwcmludGYoZiwgIiUxMnUi LCBzdGMtPmNsc1tpXS5lY25fbWFya2VkKTsKKwl9IGVsc2UgeworCQlyZXR1cm4gLTE7CisJ fQorCXJldHVybiAwOworfQorCitzdHJ1Y3QgcWRpc2NfdXRpbCBjYWtlX3FkaXNjX3V0aWwg PSB7CisJLmlkCQk9ICJjYWtlIiwKKwkucGFyc2VfcW9wdAk9IGNha2VfcGFyc2Vfb3B0LAor CS5wcmludF9xb3B0CT0gY2FrZV9wcmludF9vcHQsCisJLnByaW50X3hzdGF0cwk9IGNha2Vf cHJpbnRfeHN0YXRzLAorfTsKZGlmZiAtLWdpdCBhL3RjL3FfY2FrZTAuYyBiL3RjL3FfY2Fr ZTAuYwpuZXcgZmlsZSBtb2RlIDEwMDY0NAppbmRleCAwMDAwMDAwLi45ZmI2M2VkCi0tLSAv ZGV2L251bGwKKysrIGIvdGMvcV9jYWtlMC5jCkBAIC0wLDAgKzEsMzAxIEBACisvKgorICog Q29tbW9uIEFwcGxpY2F0aW9ucyBLZXB0IEVuaGFuY2VkICAtLSAgQ0FLRQorICoKKyAqICBD b3B5cmlnaHQgKEMpIDIwMTQgSm9uYXRoYW4gTW9ydG9uIDxjaHJvbWF0aXg5OUBnbWFpbC5j b20+CisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJpbmFy eSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0 ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKKyAqIGFyZSBtZXQ6 CisgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhl IGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0aW9u cywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciwKKyAqICAgIHdpdGhvdXQgbW9kaWZp Y2F0aW9uLgorICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3QgcmVw cm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9m IGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKKyAqICAg IGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRo ZSBkaXN0cmlidXRpb24uCisgKiAzLiBUaGUgbmFtZXMgb2YgdGhlIGF1dGhvcnMgbWF5IG5v dCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cworICogICAgZGVyaXZl ZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVuIHBl cm1pc3Npb24uCisgKgorICogQWx0ZXJuYXRpdmVseSwgcHJvdmlkZWQgdGhhdCB0aGlzIG5v dGljZSBpcyByZXRhaW5lZCBpbiBmdWxsLCB0aGlzCisgKiBzb2Z0d2FyZSBtYXkgYmUgZGlz dHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbAorICogUHVibGlj IExpY2Vuc2UgKCJHUEwiKSB2ZXJzaW9uIDIsIGluIHdoaWNoIGNhc2UgdGhlIHByb3Zpc2lv bnMgb2YgdGhlCisgKiBHUEwgYXBwbHkgSU5TVEVBRCBPRiB0aG9zZSBnaXZlbiBhYm92ZS4K KyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9M REVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBPUiBJ TVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywg VEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5FU1Mg Rk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8gRVZF TlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJFIExJ QUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVDSUFM LCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBCVVQg Tk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RTIE9S IFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJVU0lO RVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhFT1JZ IE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwg T1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJU0lO RyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBFVkVO IElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0gKKyAqIERBTUFHRS4KKyAq CisgKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+CisjaW5j bHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8c3lzbG9nLmg+CisjaW5jbHVkZSA8ZmNudGwu aD4KKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CisjaW5jbHVkZSA8bmV0aW5ldC9pbi5oPgor I2luY2x1ZGUgPGFycGEvaW5ldC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaW5jbHVk ZSAidXRpbHMuaCIKKyNpbmNsdWRlICJ0Y191dGlsLmgiCisKK3N0YXRpYyB2b2lkIGV4cGxh aW4odm9pZCkKK3sKKwlmcHJpbnRmKHN0ZGVyciwgIlVzYWdlOiAuLi4gY2FrZTAgWyBiYW5k d2lkdGggUkFURSB8IHVubGltaXRlZCBdXG4iCisJICAgICAgICAgICAgICAgICIgICAgICAg ICAgICAgICAgIFsgYmVzdGVmZm9ydCB8IHByZWNlZGVuY2UgfCBkaWZmc2VydiBdXG4iCisJ ICAgICAgICAgICAgICAgICIgICAgICAgICAgICAgICAgIFsgZmxvd2JsaW5kIHwgc3JjaG9z dCB8IGRzdGhvc3QgfCBob3N0cyB8IGZsb3dzIF1cbiIKKwkgICAgICAgICAgICAgICAgIiAg ICAgICAgICAgICAgICAgWyBhdG0gXVxuIik7Cit9CisKK3N0YXRpYyBpbnQgY2FrZV9wYXJz ZV9vcHQoc3RydWN0IHFkaXNjX3V0aWwgKnF1LCBpbnQgYXJnYywgY2hhciAqKmFyZ3YsCisJ CQkgICAgICBzdHJ1Y3Qgbmxtc2doZHIgKm4pCit7CisJaW50IHVubGltaXRlZCA9IDA7CisJ dW5zaWduZWQgYmFuZHdpZHRoID0gMDsKKwl1bnNpZ25lZCBkaWZmc2VydiA9IDA7CisJaW50 IGZsb3dtb2RlID0gLTE7CisJaW50IGF0bSA9IC0xOworCXN0cnVjdCBydGF0dHIgKnRhaWw7 CisKKwl3aGlsZSAoYXJnYyA+IDApIHsKKwkJaWYgKHN0cmNtcCgqYXJndiwgImJhbmR3aWR0 aCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3JhdGUoJmJhbmR3aWR0 aCwgKmFyZ3YpKSB7CisJCQkJZnByaW50ZihzdGRlcnIsICJJbGxlZ2FsIFwiYmFuZHdpZHRo XCJcbiIpOworCQkJCXJldHVybiAtMTsKKwkJCX0KKwkJCXVubGltaXRlZCA9IDA7CisJCX0g ZWxzZSBpZiAoc3RyY21wKCphcmd2LCAidW5saW1pdGVkIikgPT0gMCkgeworCQkJYmFuZHdp ZHRoID0gMDsKKwkJCXVubGltaXRlZCA9IDE7CisKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFy Z3YsICJiZXN0ZWZmb3J0IikgPT0gMCkgeworCQkJZGlmZnNlcnYgPSAxOworCQl9IGVsc2Ug aWYgKHN0cmNtcCgqYXJndiwgInByZWNlZGVuY2UiKSA9PSAwKSB7CisJCQlkaWZmc2VydiA9 IDI7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiZGlmZnNlcnYiKSA9PSAwKSB7CisJ CQlkaWZmc2VydiA9IDM7CisKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJmbG93Ymxp bmQiKSA9PSAwKSB7CisJCQlmbG93bW9kZSA9IDA7CisJCX0gZWxzZSBpZiAoc3RyY21wKCph cmd2LCAic3JjaG9zdCIpID09IDApIHsKKwkJCWZsb3dtb2RlID0gMTsKKwkJfSBlbHNlIGlm IChzdHJjbXAoKmFyZ3YsICJkc3Rob3N0IikgPT0gMCkgeworCQkJZmxvd21vZGUgPSAyOwor CQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgImhvc3RzIikgPT0gMCkgeworCQkJZmxvd21v ZGUgPSAzOworCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgImZsb3dzIikgPT0gMCkgewor CQkJZmxvd21vZGUgPSA0OworCisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiYXRtIikg PT0gMCkgeworCQkJYXRtID0gMTsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJub2F0 bSIpID09IDApIHsKKwkJCWF0bSA9IDA7CisKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3Ys ICJoZWxwIikgPT0gMCkgeworCQkJZXhwbGFpbigpOworCQkJcmV0dXJuIC0xOworCQl9IGVs c2UgeworCQkJZnByaW50ZihzdGRlcnIsICJXaGF0IGlzIFwiJXNcIj9cbiIsICphcmd2KTsK KwkJCWV4cGxhaW4oKTsKKwkJCXJldHVybiAtMTsKKwkJfQorCQlhcmdjLS07IGFyZ3YrKzsK Kwl9CisKKwl0YWlsID0gTkxNU0dfVEFJTChuKTsKKwlhZGRhdHRyX2wobiwgMTAyNCwgVENB X09QVElPTlMsIE5VTEwsIDApOworCWlmIChiYW5kd2lkdGggfHwgdW5saW1pdGVkKQorCQlh ZGRhdHRyX2wobiwgMTAyNCwgVENBX0NBS0VfQkFTRV9SQVRFLCAmYmFuZHdpZHRoLCBzaXpl b2YoYmFuZHdpZHRoKSk7CisJaWYgKGRpZmZzZXJ2KQorCQlhZGRhdHRyX2wobiwgMTAyNCwg VENBX0NBS0VfRElGRlNFUlZfTU9ERSwgJmRpZmZzZXJ2LCBzaXplb2YoZGlmZnNlcnYpKTsK KwlpZiAoYXRtICE9IC0xKQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENBX0NBS0VfQVRNLCAm YXRtLCBzaXplb2YoYXRtKSk7CisJaWYgKGZsb3dtb2RlICE9IC0xKQorCQlhZGRhdHRyX2wo biwgMTAyNCwgVENBX0NBS0VfRkxPV19NT0RFLCAmZmxvd21vZGUsIHNpemVvZihmbG93bW9k ZSkpOworCXRhaWwtPnJ0YV9sZW4gPSAodm9pZCAqKSBOTE1TR19UQUlMKG4pIC0gKHZvaWQg KikgdGFpbDsKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBjYWtlX3ByaW50X29wdChz dHJ1Y3QgcWRpc2NfdXRpbCAqcXUsIEZJTEUgKmYsIHN0cnVjdCBydGF0dHIgKm9wdCkKK3sK KwlzdHJ1Y3QgcnRhdHRyICp0YltUQ0FfQ0FLRV9NQVggKyAxXTsKKwl1bnNpZ25lZCBiYW5k d2lkdGggPSAwOworCXVuc2lnbmVkIGRpZmZzZXJ2ID0gMDsKKwl1bnNpZ25lZCBmbG93bW9k ZSA9IDA7CisJaW50IGF0bSA9IC0xOworCVNQUklOVF9CVUYoYjEpOworCisJaWYgKG9wdCA9 PSBOVUxMKQorCQlyZXR1cm4gMDsKKworCXBhcnNlX3J0YXR0cl9uZXN0ZWQodGIsIFRDQV9D QUtFX01BWCwgb3B0KTsKKworCWlmICh0YltUQ0FfQ0FLRV9CQVNFX1JBVEVdICYmCisJICAg IFJUQV9QQVlMT0FEKHRiW1RDQV9DQUtFX0JBU0VfUkFURV0pID49IHNpemVvZihfX3UzMikp IHsKKwkJYmFuZHdpZHRoID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9DQUtFX0JBU0VfUkFU RV0pOworCQlpZihiYW5kd2lkdGgpCisJCQlmcHJpbnRmKGYsICJiYW5kd2lkdGggJXMgIiwg c3ByaW50X3JhdGUoYmFuZHdpZHRoLCBiMSkpOworCQllbHNlCisJCQlmcHJpbnRmKGYsICJ1 bmxpbWl0ZWQiKTsKKwl9CisJaWYgKHRiW1RDQV9DQUtFX0RJRkZTRVJWX01PREVdICYmCisJ ICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9DQUtFX0RJRkZTRVJWX01PREVdKSA+PSBzaXplb2Yo X191MzIpKSB7CisJCWRpZmZzZXJ2ID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9DQUtFX0RJ RkZTRVJWX01PREVdKTsKKwkJc3dpdGNoKGRpZmZzZXJ2KSB7CisJCWNhc2UgMToKKwkJCWZw cmludGYoZiwgImJlc3RlZmZvcnQgIik7CisJCQlicmVhazsKKwkJY2FzZSAyOgorCQkJZnBy aW50ZihmLCAicHJlY2VkZW5jZSAiKTsKKwkJCWJyZWFrOworCQljYXNlIDM6CisJCQlmcHJp bnRmKGYsICJkaWZmc2VydiAiKTsKKwkJCWJyZWFrOworCQlkZWZhdWx0OgorCQkJZnByaW50 ZihmLCAiKD9kaWZmc2Vydj8pICIpOworCQkJYnJlYWs7CisJCX07CisJfQorCWlmICh0YltU Q0FfQ0FLRV9GTE9XX01PREVdICYmCisJICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9DQUtFX0ZM T1dfTU9ERV0pID49IHNpemVvZihfX3UzMikpIHsKKwkJZmxvd21vZGUgPSBydGFfZ2V0YXR0 cl91MzIodGJbVENBX0NBS0VfRkxPV19NT0RFXSk7CisJCXN3aXRjaChmbG93bW9kZSkgewor CQljYXNlIDA6CisJCQlmcHJpbnRmKGYsICJmbG93YmxpbmQgIik7CisJCQlicmVhazsKKwkJ Y2FzZSAxOgorCQkJZnByaW50ZihmLCAic3JjaG9zdCAiKTsKKwkJCWJyZWFrOworCQljYXNl IDI6CisJCQlmcHJpbnRmKGYsICJkc3Rob3N0ICIpOworCQkJYnJlYWs7CisJCWNhc2UgMzoK KwkJCWZwcmludGYoZiwgImhvc3RzICIpOworCQkJYnJlYWs7CisJCWNhc2UgNDoKKwkJCWZw cmludGYoZiwgImZsb3dzICIpOworCQkJYnJlYWs7CisJCWRlZmF1bHQ6CisJCQlmcHJpbnRm KGYsICIoP2Zsb3dtb2RlPykgIik7CisJCQlicmVhazsKKwkJfTsKKwl9CisJaWYgKHRiW1RD QV9DQUtFX0FUTV0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0NBS0VfQVRNXSkgPj0g c2l6ZW9mKF9fdTMyKSkgeworCQlhdG0gPSBydGFfZ2V0YXR0cl91MzIodGJbVENBX0NBS0Vf QVRNXSk7CisJCWlmIChhdG0pCisJCQlmcHJpbnRmKGYsICJhdG0gIik7CisJfQorCisJcmV0 dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgY2FrZV9wcmludF94c3RhdHMoc3RydWN0IHFkaXNj X3V0aWwgKnF1LCBGSUxFICpmLAorCQkJCSBzdHJ1Y3QgcnRhdHRyICp4c3RhdHMpCit7CisJ LyogZnFfY29kZWwgc3RhdHMgZm9ybWF0IGJvcnJvd2VkICovCisJc3RydWN0IHRjX2ZxX2Nv ZGVsX3hzdGF0cyAqc3Q7CisJc3RydWN0IHRjX2Nha2VfeHN0YXRzICAgICAqc3RjOworCVNQ UklOVF9CVUYoYjEpOworCisJaWYgKHhzdGF0cyA9PSBOVUxMKQorCQlyZXR1cm4gMDsKKwor CWlmIChSVEFfUEFZTE9BRCh4c3RhdHMpIDwgc2l6ZW9mKHN0LT50eXBlKSkKKwkJcmV0dXJu IC0xOworCisJc3QgID0gUlRBX0RBVEEoeHN0YXRzKTsKKwlzdGMgPSBSVEFfREFUQSh4c3Rh dHMpOworCisJaWYgKHN0LT50eXBlID09IFRDQV9GUV9DT0RFTF9YU1RBVFNfUURJU0MgJiYg UlRBX1BBWUxPQUQoeHN0YXRzKSA+PSBzaXplb2YoKnN0KSkgeworCQlmcHJpbnRmKGYsICIg IG1heHBhY2tldCAldSBkcm9wX292ZXJsaW1pdCAldSBuZXdfZmxvd19jb3VudCAldSBlY25f bWFyayAldSIsCisJCQlzdC0+cWRpc2Nfc3RhdHMubWF4cGFja2V0LAorCQkJc3QtPnFkaXNj X3N0YXRzLmRyb3Bfb3ZlcmxpbWl0LAorCQkJc3QtPnFkaXNjX3N0YXRzLm5ld19mbG93X2Nv dW50LAorCQkJc3QtPnFkaXNjX3N0YXRzLmVjbl9tYXJrKTsKKwkJZnByaW50ZihmLCAiXG4g IG5ld19mbG93c19sZW4gJXUgb2xkX2Zsb3dzX2xlbiAldSIsCisJCQlzdC0+cWRpc2Nfc3Rh dHMubmV3X2Zsb3dzX2xlbiwKKwkJCXN0LT5xZGlzY19zdGF0cy5vbGRfZmxvd3NfbGVuKTsK Kwl9IGVsc2UgaWYgKHN0LT50eXBlID09IFRDQV9GUV9DT0RFTF9YU1RBVFNfQ0xBU1MgJiYg UlRBX1BBWUxPQUQoeHN0YXRzKSA+PSBzaXplb2YoKnN0KSkgeworCQlmcHJpbnRmKGYsICIg IGRlZmljaXQgJWQgY291bnQgJXUgbGFzdGNvdW50ICV1IGxkZWxheSAlcyIsCisJCQlzdC0+ Y2xhc3Nfc3RhdHMuZGVmaWNpdCwKKwkJCXN0LT5jbGFzc19zdGF0cy5jb3VudCwKKwkJCXN0 LT5jbGFzc19zdGF0cy5sYXN0Y291bnQsCisJCQlzcHJpbnRfdGltZShzdC0+Y2xhc3Nfc3Rh dHMubGRlbGF5LCBiMSkpOworCQlpZiAoc3QtPmNsYXNzX3N0YXRzLmRyb3BwaW5nKSB7CisJ CQlmcHJpbnRmKGYsICIgZHJvcHBpbmciKTsKKwkJCWlmIChzdC0+Y2xhc3Nfc3RhdHMuZHJv cF9uZXh0IDwgMCkKKwkJCQlmcHJpbnRmKGYsICIgZHJvcF9uZXh0IC0lcyIsCisJCQkJCXNw cmludF90aW1lKC1zdC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0LCBiMSkpOworCQkJZWxzZQor CQkJCWZwcmludGYoZiwgIiBkcm9wX25leHQgJXMiLAorCQkJCQlzcHJpbnRfdGltZShzdC0+ Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0LCBiMSkpOworCQl9CisJfSBlbHNlIGlmIChzdGMtPnR5 cGUgPT0gMHhDQUZFICYmIFJUQV9QQVlMT0FEKHhzdGF0cykgPj0gc2l6ZW9mKCpzdGMpKSB7 CisJCWludCBpOworCisJCWZwcmludGYoZiwgIiAgICAgICAgIik7CisJCWZvcihpPTA7IGkg PCBzdGMtPmNsYXNzX2NudDsgaSsrKQorCQkJZnByaW50ZihmLCAiICBDbGFzcyAldSAiLCBp KTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRmKGYsICIgIHJhdGUgICIpOwor CQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJCWZwcmludGYoZiwgIiUx MHMiLCBzcHJpbnRfcmF0ZShzdGMtPmNsc1tpXS5yYXRlLCBiMSkpOworCQlmcHJpbnRmKGYs ICJcbiIpOworCisJCWZwcmludGYoZiwgIiAgdGFyZ2V0Iik7CisJCWZvcihpPTA7IGkgPCBz dGMtPmNsYXNzX2NudDsgaSsrKQorCQkJZnByaW50ZihmLCAiJTEwcyIsIHNwcmludF90aW1l KHN0Yy0+Y2xzW2ldLnRhcmdldF91cywgYjEpKTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKwor CQlmcHJpbnRmKGYsICJpbnRlcnZhbCIpOworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19j bnQ7IGkrKykKKwkJCWZwcmludGYoZiwgIiUxMHMiLCBzcHJpbnRfdGltZShzdGMtPmNsc1tp XS5pbnRlcnZhbF91cywgYjEpKTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRm KGYsICIgIGRlbGF5ICIpOworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykK KwkJCWZwcmludGYoZiwgIiUxMHMiLCBzcHJpbnRfdGltZShzdGMtPmNsc1tpXS5wZWFrX2Rl bGF5LCBiMSkpOworCQlmcHJpbnRmKGYsICJcbiIpOworCisJCWZwcmludGYoZiwgIiAgcGt0 cyAgIik7CisJCWZvcihpPTA7IGkgPCBzdGMtPmNsYXNzX2NudDsgaSsrKQorCQkJZnByaW50 ZihmLCAiJTEwdSIsIHN0Yy0+Y2xzW2ldLnBhY2tldHMpOworCQlmcHJpbnRmKGYsICJcbiIp OworCisJCWZwcmludGYoZiwgIiAgYnl0ZXMgIik7CisJCWZvcihpPTA7IGkgPCBzdGMtPmNs YXNzX2NudDsgaSsrKQorCQkJZnByaW50ZihmLCAiJTEwbGx1Iiwgc3RjLT5jbHNbaV0uYnl0 ZXMpOworCQlmcHJpbnRmKGYsICJcbiIpOworCisJCWZwcmludGYoZiwgIiAgZHJvcHMgIik7 CisJCWZvcihpPTA7IGkgPCBzdGMtPmNsYXNzX2NudDsgaSsrKQorCQkJZnByaW50ZihmLCAi JTEwdSIsIHN0Yy0+Y2xzW2ldLmRyb3BwZWQpOworCQlmcHJpbnRmKGYsICJcbiIpOworCisJ CWZwcmludGYoZiwgIiAgbWFya3MgIik7CisJCWZvcihpPTA7IGkgPCBzdGMtPmNsYXNzX2Nu dDsgaSsrKQorCQkJZnByaW50ZihmLCAiJTEwdSIsIHN0Yy0+Y2xzW2ldLmVjbl9tYXJrZWQp OworCX0gZWxzZSB7CisJCXJldHVybiAtMTsKKwl9CisJcmV0dXJuIDA7Cit9CisKK3N0cnVj dCBxZGlzY191dGlsIGNha2UwX3FkaXNjX3V0aWwgPSB7CisJLmlkCQk9ICJjYWtlMCIsCisJ LnBhcnNlX3FvcHQJPSBjYWtlX3BhcnNlX29wdCwKKwkucHJpbnRfcW9wdAk9IGNha2VfcHJp bnRfb3B0LAorCS5wcmludF94c3RhdHMJPSBjYWtlX3ByaW50X3hzdGF0cywKK307CmRpZmYg LS1naXQgYS90Yy9xX2Nha2UyLmMgYi90Yy9xX2Nha2UyLmMKbmV3IGZpbGUgbW9kZSAxMDA2 NDQKaW5kZXggMDAwMDAwMC4uYTRkM2Y3YwotLS0gL2Rldi9udWxsCisrKyBiL3RjL3FfY2Fr ZTIuYwpAQCAtMCwwICsxLDI5NiBAQAorLyoKKyAqIENvbW1vbiBBcHBsaWNhdGlvbnMgS2Vw dCBFbmhhbmNlZCAgLS0gIENBS0UKKyAqCisgKiAgQ29weXJpZ2h0IChDKSAyMDE0IEpvbmF0 aGFuIE1vcnRvbiA8Y2hyb21hdGl4OTlAZ21haWwuY29tPgorICoKKyAqIFJlZGlzdHJpYnV0 aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91 dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZv bGxvd2luZyBjb25kaXRpb25zCisgKiBhcmUgbWV0OgorICogMS4gUmVkaXN0cmlidXRpb25z IG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAg IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMsIGFuZCB0aGUgZm9sbG93aW5nIGRp c2NsYWltZXIsCisgKiAgICB3aXRob3V0IG1vZGlmaWNhdGlvbi4KKyAqIDIuIFJlZGlzdHJp YnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJp Z2h0CisgKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9s bG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBv dGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorICogMy4g VGhlIG5hbWVzIG9mIHRoZSBhdXRob3JzIG1heSBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9y IHByb21vdGUgcHJvZHVjdHMKKyAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdp dGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIEFsdGVy bmF0aXZlbHksIHByb3ZpZGVkIHRoYXQgdGhpcyBub3RpY2UgaXMgcmV0YWluZWQgaW4gZnVs bCwgdGhpcworICogc29mdHdhcmUgbWF5IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJt cyBvZiB0aGUgR05VIEdlbmVyYWwKKyAqIFB1YmxpYyBMaWNlbnNlICgiR1BMIikgdmVyc2lv biAyLCBpbiB3aGljaCBjYXNlIHRoZSBwcm92aXNpb25zIG9mIHRoZQorICogR1BMIGFwcGx5 IElOU1RFQUQgT0YgdGhvc2UgZ2l2ZW4gYWJvdmUuCisgKgorICogVEhJUyBTT0ZUV0FSRSBJ UyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUwor ICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNM VURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMg T0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBV UlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQK KyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElO RElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFV RU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJP Q1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0Us CisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VW RVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIg SU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcg TkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhF IFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NT SUJJTElUWSBPRiBTVUNICisgKiBEQU1BR0UuCisgKgorICovCisKKyNpbmNsdWRlIDxzdGRp by5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1 ZGUgPHN5c2xvZy5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c3lzL3NvY2tl dC5oPgorI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KKyNpbmNsdWRlIDxhcnBhL2luZXQuaD4K KyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgInV0aWxzLmgiCisjaW5jbHVkZSAi dGNfdXRpbC5oIgorCitzdGF0aWMgdm9pZCBleHBsYWluKHZvaWQpCit7CisJZnByaW50Zihz dGRlcnIsICJVc2FnZTogLi4uIGNha2UyIFsgYmFuZHdpZHRoIFJBVEUgfCB1bmxpbWl0ZWQg XVxuIgorCSAgICAgICAgICAgICAgICAiICAgICAgICAgICAgICAgIFsgYmVzdGVmZm9ydCB8 IHByZWNlZGVuY2UgfCBkaWZmc2VydiBdXG4iCisJICAgICAgICAgICAgICAgICIgICAgICAg ICAgICAgICAgWyBmbG93YmxpbmQgfCBzcmNob3N0IHwgZHN0aG9zdCB8IGhvc3RzIHwgZmxv d3MgXVxuIgorCSAgICAgICAgICAgICAgICAiICAgICAgICAgICAgICAgIFsgYXRtIF1cbiIp OworfQorCitzdGF0aWMgaW50IGNha2VfcGFyc2Vfb3B0KHN0cnVjdCBxZGlzY191dGlsICpx dSwgaW50IGFyZ2MsIGNoYXIgKiphcmd2LAorCQkJICAgICAgc3RydWN0IG5sbXNnaGRyICpu KQoreworCWludCB1bmxpbWl0ZWQgPSAwOworCXVuc2lnbmVkIGJhbmR3aWR0aCA9IDA7CisJ dW5zaWduZWQgZGlmZnNlcnYgPSAwOworCWludCBmbG93bW9kZSA9IC0xOworCWludCBhdG0g PSAtMTsKKwlzdHJ1Y3QgcnRhdHRyICp0YWlsOworCisJd2hpbGUgKGFyZ2MgPiAwKSB7CisJ CWlmIChzdHJjbXAoKmFyZ3YsICJiYW5kd2lkdGgiKSA9PSAwKSB7CisJCQlORVhUX0FSRygp OworCQkJaWYgKGdldF9yYXRlKCZiYW5kd2lkdGgsICphcmd2KSkgeworCQkJCWZwcmludGYo c3RkZXJyLCAiSWxsZWdhbCBcImJhbmR3aWR0aFwiXG4iKTsKKwkJCQlyZXR1cm4gLTE7CisJ CQl9CisJCQl1bmxpbWl0ZWQgPSAwOworCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgInVu bGltaXRlZCIpID09IDApIHsKKwkJCWJhbmR3aWR0aCA9IDA7CisJCQl1bmxpbWl0ZWQgPSAx OworCisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiYmVzdGVmZm9ydCIpID09IDApIHsK KwkJCWRpZmZzZXJ2ID0gMTsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJwcmVjZWRl bmNlIikgPT0gMCkgeworCQkJZGlmZnNlcnYgPSAyOworCQl9IGVsc2UgaWYgKHN0cmNtcCgq YXJndiwgImRpZmZzZXJ2IikgPT0gMCkgeworCQkJZGlmZnNlcnYgPSAzOworCisJCX0gZWxz ZSBpZiAoc3RyY21wKCphcmd2LCAiZmxvd2JsaW5kIikgPT0gMCkgeworCQkJZmxvd21vZGUg PSAwOworCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgInNyY2hvc3QiKSA9PSAwKSB7CisJ CQlmbG93bW9kZSA9IDE7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiZHN0aG9zdCIp ID09IDApIHsKKwkJCWZsb3dtb2RlID0gMjsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3Ys ICJob3N0cyIpID09IDApIHsKKwkJCWZsb3dtb2RlID0gMzsKKwkJfSBlbHNlIGlmIChzdHJj bXAoKmFyZ3YsICJmbG93cyIpID09IDApIHsKKwkJCWZsb3dtb2RlID0gNDsKKworCQl9IGVs c2UgaWYgKHN0cmNtcCgqYXJndiwgImF0bSIpID09IDApIHsKKwkJCWF0bSA9IDE7CisJCX0g ZWxzZSBpZiAoc3RyY21wKCphcmd2LCAibm9hdG0iKSA9PSAwKSB7CisJCQlhdG0gPSAwOwor CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiaGVscCIpID09IDApIHsKKwkJCWV4cGxh aW4oKTsKKwkJCXJldHVybiAtMTsKKwkJfSBlbHNlIHsKKwkJCWZwcmludGYoc3RkZXJyLCAi V2hhdCBpcyBcIiVzXCI/XG4iLCAqYXJndik7CisJCQlleHBsYWluKCk7CisJCQlyZXR1cm4g LTE7CisJCX0KKwkJYXJnYy0tOyBhcmd2Kys7CisJfQorCisJdGFpbCA9IE5MTVNHX1RBSUwo bik7CisJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9PUFRJT05TLCBOVUxMLCAwKTsKKwlpZiAo YmFuZHdpZHRoIHx8IHVubGltaXRlZCkKKwkJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9DQUtF X0JBU0VfUkFURSwgJmJhbmR3aWR0aCwgc2l6ZW9mKGJhbmR3aWR0aCkpOworCWlmIChkaWZm c2VydikKKwkJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9DQUtFX0RJRkZTRVJWX01PREUsICZk aWZmc2Vydiwgc2l6ZW9mKGRpZmZzZXJ2KSk7CisJaWYgKGF0bSAhPSAtMSkKKwkJYWRkYXR0 cl9sKG4sIDEwMjQsIFRDQV9DQUtFX0FUTSwgJmF0bSwgc2l6ZW9mKGF0bSkpOworCWlmIChm bG93bW9kZSAhPSAtMSkKKwkJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9DQUtFX0ZMT1dfTU9E RSwgJmZsb3dtb2RlLCBzaXplb2YoZmxvd21vZGUpKTsKKwl0YWlsLT5ydGFfbGVuID0gKHZv aWQgKikgTkxNU0dfVEFJTChuKSAtICh2b2lkICopIHRhaWw7CisJcmV0dXJuIDA7Cit9CisK K3N0YXRpYyBpbnQgY2FrZV9wcmludF9vcHQoc3RydWN0IHFkaXNjX3V0aWwgKnF1LCBGSUxF ICpmLCBzdHJ1Y3QgcnRhdHRyICpvcHQpCit7CisJc3RydWN0IHJ0YXR0ciAqdGJbVENBX0NB S0VfTUFYICsgMV07CisJdW5zaWduZWQgYmFuZHdpZHRoID0gMDsKKwl1bnNpZ25lZCBkaWZm c2VydiA9IDA7CisJdW5zaWduZWQgZmxvd21vZGUgPSAwOworCWludCBhdG0gPSAtMTsKKwlT UFJJTlRfQlVGKGIxKTsKKworCWlmIChvcHQgPT0gTlVMTCkKKwkJcmV0dXJuIDA7CisKKwlw YXJzZV9ydGF0dHJfbmVzdGVkKHRiLCBUQ0FfQ0FLRV9NQVgsIG9wdCk7CisKKwlpZiAodGJb VENBX0NBS0VfQkFTRV9SQVRFXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfQ0FLRV9C QVNFX1JBVEVdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCWJhbmR3aWR0aCA9IHJ0YV9nZXRh dHRyX3UzMih0YltUQ0FfQ0FLRV9CQVNFX1JBVEVdKTsKKwkJaWYoYmFuZHdpZHRoKQorCQkJ ZnByaW50ZihmLCAiYmFuZHdpZHRoICVzICIsIHNwcmludF9yYXRlKGJhbmR3aWR0aCwgYjEp KTsKKwkJZWxzZQorCQkJZnByaW50ZihmLCAidW5saW1pdGVkIik7CisJfQorCWlmICh0YltU Q0FfQ0FLRV9ESUZGU0VSVl9NT0RFXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfQ0FL RV9ESUZGU0VSVl9NT0RFXSkgPj0gc2l6ZW9mKF9fdTMyKSkgeworCQlkaWZmc2VydiA9IHJ0 YV9nZXRhdHRyX3UzMih0YltUQ0FfQ0FLRV9ESUZGU0VSVl9NT0RFXSk7CisJCXN3aXRjaChk aWZmc2VydikgeworCQljYXNlIDE6CisJCQlmcHJpbnRmKGYsICJiZXN0ZWZmb3J0ICIpOwor CQkJYnJlYWs7CisJCWNhc2UgMjoKKwkJCWZwcmludGYoZiwgInByZWNlZGVuY2UgIik7CisJ CQlicmVhazsKKwkJY2FzZSAzOgorCQkJZnByaW50ZihmLCAiZGlmZnNlcnYgIik7CisJCQli cmVhazsKKwkJZGVmYXVsdDoKKwkJCWZwcmludGYoZiwgIig/ZGlmZnNlcnY/KSAiKTsKKwkJ CWJyZWFrOworCQl9OworCX0KKwlpZiAodGJbVENBX0NBS0VfRkxPV19NT0RFXSAmJgorCSAg ICBSVEFfUEFZTE9BRCh0YltUQ0FfQ0FLRV9GTE9XX01PREVdKSA+PSBzaXplb2YoX191MzIp KSB7CisJCWZsb3dtb2RlID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9DQUtFX0ZMT1dfTU9E RV0pOworCQlzd2l0Y2goZmxvd21vZGUpIHsKKwkJY2FzZSAwOgorCQkJZnByaW50ZihmLCAi Zmxvd2JsaW5kICIpOworCQkJYnJlYWs7CisJCWNhc2UgMToKKwkJCWZwcmludGYoZiwgInNy Y2hvc3QgIik7CisJCQlicmVhazsKKwkJY2FzZSAyOgorCQkJZnByaW50ZihmLCAiZHN0aG9z dCAiKTsKKwkJCWJyZWFrOworCQljYXNlIDM6CisJCQlmcHJpbnRmKGYsICJob3N0cyAiKTsK KwkJCWJyZWFrOworCQljYXNlIDQ6CisJCQlmcHJpbnRmKGYsICJmbG93cyAiKTsKKwkJCWJy ZWFrOworCQlkZWZhdWx0OgorCQkJZnByaW50ZihmLCAiKD9mbG93bW9kZT8pICIpOworCQkJ YnJlYWs7CisJCX07CisJfQorCWlmICh0YltUQ0FfQ0FLRV9BVE1dICYmCisJICAgIFJUQV9Q QVlMT0FEKHRiW1RDQV9DQUtFX0FUTV0pID49IHNpemVvZihfX3UzMikpIHsKKwkJYXRtID0g cnRhX2dldGF0dHJfdTMyKHRiW1RDQV9DQUtFX0FUTV0pOworCQlpZiAoYXRtKQorCQkJZnBy aW50ZihmLCAiYXRtICIpOworCX0KKworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGNh a2VfcHJpbnRfeHN0YXRzKHN0cnVjdCBxZGlzY191dGlsICpxdSwgRklMRSAqZiwKKwkJCQkg c3RydWN0IHJ0YXR0ciAqeHN0YXRzKQoreworCS8qIGZxX2NvZGVsIHN0YXRzIGZvcm1hdCBi b3Jyb3dlZCAqLworCXN0cnVjdCB0Y19mcV9jb2RlbF94c3RhdHMgKnN0OworCXN0cnVjdCB0 Y19jYWtlX3hzdGF0cyAgICAgKnN0YzsKKwlTUFJJTlRfQlVGKGIxKTsKKworCWlmICh4c3Rh dHMgPT0gTlVMTCkKKwkJcmV0dXJuIDA7CisKKwlpZiAoUlRBX1BBWUxPQUQoeHN0YXRzKSA8 IHNpemVvZihzdC0+dHlwZSkpCisJCXJldHVybiAtMTsKKworCXN0ICA9IFJUQV9EQVRBKHhz dGF0cyk7CisJc3RjID0gUlRBX0RBVEEoeHN0YXRzKTsKKworCWlmIChzdC0+dHlwZSA9PSBU Q0FfRlFfQ09ERUxfWFNUQVRTX1FESVNDICYmIFJUQV9QQVlMT0FEKHhzdGF0cykgPj0gc2l6 ZW9mKCpzdCkpIHsKKwkJZnByaW50ZihmLCAiICBtYXhwYWNrZXQgJXUgZHJvcF9vdmVybGlt aXQgJXUgbmV3X2Zsb3dfY291bnQgJXUgZWNuX21hcmsgJXUiLAorCQkJc3QtPnFkaXNjX3N0 YXRzLm1heHBhY2tldCwKKwkJCXN0LT5xZGlzY19zdGF0cy5kcm9wX292ZXJsaW1pdCwKKwkJ CXN0LT5xZGlzY19zdGF0cy5uZXdfZmxvd19jb3VudCwKKwkJCXN0LT5xZGlzY19zdGF0cy5l Y25fbWFyayk7CisJCWZwcmludGYoZiwgIlxuICBuZXdfZmxvd3NfbGVuICV1IG9sZF9mbG93 c19sZW4gJXUiLAorCQkJc3QtPnFkaXNjX3N0YXRzLm5ld19mbG93c19sZW4sCisJCQlzdC0+ cWRpc2Nfc3RhdHMub2xkX2Zsb3dzX2xlbik7CisJfSBlbHNlIGlmIChzdC0+dHlwZSA9PSBU Q0FfRlFfQ09ERUxfWFNUQVRTX0NMQVNTICYmIFJUQV9QQVlMT0FEKHhzdGF0cykgPj0gc2l6 ZW9mKCpzdCkpIHsKKwkJZnByaW50ZihmLCAiICBkZWZpY2l0ICVkIGNvdW50ICV1IGxhc3Rj b3VudCAldSBsZGVsYXkgJXMiLAorCQkJc3QtPmNsYXNzX3N0YXRzLmRlZmljaXQsCisJCQlz dC0+Y2xhc3Nfc3RhdHMuY291bnQsCisJCQlzdC0+Y2xhc3Nfc3RhdHMubGFzdGNvdW50LAor CQkJc3ByaW50X3RpbWUoc3QtPmNsYXNzX3N0YXRzLmxkZWxheSwgYjEpKTsKKwkJaWYgKHN0 LT5jbGFzc19zdGF0cy5kcm9wcGluZykgeworCQkJZnByaW50ZihmLCAiIGRyb3BwaW5nIik7 CisJCQlpZiAoc3QtPmNsYXNzX3N0YXRzLmRyb3BfbmV4dCA8IDApCisJCQkJZnByaW50Zihm LCAiIGRyb3BfbmV4dCAtJXMiLAorCQkJCQlzcHJpbnRfdGltZSgtc3QtPmNsYXNzX3N0YXRz LmRyb3BfbmV4dCwgYjEpKTsKKwkJCWVsc2UKKwkJCQlmcHJpbnRmKGYsICIgZHJvcF9uZXh0 ICVzIiwKKwkJCQkJc3ByaW50X3RpbWUoc3QtPmNsYXNzX3N0YXRzLmRyb3BfbmV4dCwgYjEp KTsKKwkJfQorCX0gZWxzZSBpZiAoc3RjLT50eXBlID09IDB4Q0FGRSAmJiBSVEFfUEFZTE9B RCh4c3RhdHMpID49IHNpemVvZigqc3RjKSkgeworCQlpbnQgaTsKKworCQlmcHJpbnRmKGYs ICIgICAgICAgICIpOworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJ CWZwcmludGYoZiwgIiAgQ2xhc3MgJXUgIiwgaSk7CisJCWZwcmludGYoZiwgIlxuIik7CisK KwkJZnByaW50ZihmLCAiICByYXRlICAiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3Nf Y250OyBpKyspCisJCQlmcHJpbnRmKGYsICIlMTBzIiwgc3ByaW50X3JhdGUoc3RjLT5jbHNb aV0ucmF0ZSwgYjEpKTsKKwkJZnByaW50ZihmLCAiXG4iKTsKKworCQlmcHJpbnRmKGYsICIg IHRhcmdldCIpOworCQlmb3IoaT0wOyBpIDwgc3RjLT5jbGFzc19jbnQ7IGkrKykKKwkJCWZw cmludGYoZiwgIiUxMHMiLCBzcHJpbnRfdGltZShzdGMtPmNsc1tpXS50YXJnZXRfdXMsIGIx KSk7CisJCWZwcmludGYoZiwgIlxuIik7CisKKwkJZnByaW50ZihmLCAiaW50ZXJ2YWwiKTsK KwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRmKGYsICIl MTBzIiwgc3ByaW50X3RpbWUoc3RjLT5jbHNbaV0uaW50ZXJ2YWxfdXMsIGIxKSk7CisJCWZw cmludGYoZiwgIlxuIik7CisKKwkJZnByaW50ZihmLCAiICBwa3RzICAiKTsKKwkJZm9yKGk9 MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRmKGYsICIlMTB1Iiwgc3Rj LT5jbHNbaV0ucGFja2V0cyk7CisJCWZwcmludGYoZiwgIlxuIik7CisKKwkJZnByaW50Zihm LCAiICBieXRlcyAiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJ CQlmcHJpbnRmKGYsICIlMTBsbHUiLCBzdGMtPmNsc1tpXS5ieXRlcyk7CisJCWZwcmludGYo ZiwgIlxuIik7CisKKwkJZnByaW50ZihmLCAiICBkcm9wcyAiKTsKKwkJZm9yKGk9MDsgaSA8 IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJpbnRmKGYsICIlMTB1Iiwgc3RjLT5jbHNb aV0uZHJvcHBlZCk7CisJCWZwcmludGYoZiwgIlxuIik7CisKKwkJZnByaW50ZihmLCAiICBt YXJrcyAiKTsKKwkJZm9yKGk9MDsgaSA8IHN0Yy0+Y2xhc3NfY250OyBpKyspCisJCQlmcHJp bnRmKGYsICIlMTB1Iiwgc3RjLT5jbHNbaV0uZWNuX21hcmtlZCk7CisJfSBlbHNlIHsKKwkJ cmV0dXJuIC0xOworCX0KKwlyZXR1cm4gMDsKK30KKworc3RydWN0IHFkaXNjX3V0aWwgY2Fr ZTJfcWRpc2NfdXRpbCA9IHsKKwkuaWQJCT0gImNha2UyIiwKKwkucGFyc2VfcW9wdAk9IGNh a2VfcGFyc2Vfb3B0LAorCS5wcmludF9xb3B0CT0gY2FrZV9wcmludF9vcHQsCisJLnByaW50 X3hzdGF0cwk9IGNha2VfcHJpbnRfeHN0YXRzLAorfTsKZGlmZiAtLWdpdCBhL3RjL3FfZWZx X2NvZGVsLmMgYi90Yy9xX2VmcV9jb2RlbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAuLmI4MGU1ZTQKLS0tIC9kZXYvbnVsbAorKysgYi90Yy9xX2VmcV9jb2RlbC5j CkBAIC0wLDAgKzEsMjMyIEBACisvKgorICogRmFpciBRdWV1ZSBDb2RlbAorICoKKyAqICBD b3B5cmlnaHQgKEMpIDIwMTIgRXJpYyBEdW1hemV0IDxlZHVtYXpldEBnb29nbGUuY29tPgor ICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9y bXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHBy b3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCisgKiBhcmUgbWV0OgorICog MS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92 ZSBjb3B5cmlnaHQKKyAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMsIGFu ZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIsCisgKiAgICB3aXRob3V0IG1vZGlmaWNhdGlv bi4KKyAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVj ZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25k aXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICBkb2N1 bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlz dHJpYnV0aW9uLgorICogMy4gVGhlIG5hbWVzIG9mIHRoZSBhdXRob3JzIG1heSBub3QgYmUg dXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKKyAqICAgIGRlcml2ZWQgZnJv bSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNz aW9uLgorICoKKyAqIEFsdGVybmF0aXZlbHksIHByb3ZpZGVkIHRoYXQgdGhpcyBub3RpY2Ug aXMgcmV0YWluZWQgaW4gZnVsbCwgdGhpcworICogc29mdHdhcmUgbWF5IGJlIGRpc3RyaWJ1 dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwKKyAqIFB1YmxpYyBMaWNl bnNlICgiR1BMIikgdmVyc2lvbiAyLCBpbiB3aGljaCBjYXNlIHRoZSBwcm92aXNpb25zIG9m IHRoZQorICogR1BMIGFwcGx5IElOU1RFQUQgT0YgdGhvc2UgZ2l2ZW4gYWJvdmUuCisgKgor ICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMg QU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElF RCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJ TVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgor ICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNI QUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUg Rk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhF TVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAor ICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJW SUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJ TlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBM SUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRP UlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4g QU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBB RFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNICisgKiBEQU1BR0UuCisgKgorICov CisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUg PHVuaXN0ZC5oPgorI2luY2x1ZGUgPHN5c2xvZy5oPgorI2luY2x1ZGUgPGZjbnRsLmg+Cisj aW5jbHVkZSA8c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KKyNpbmNs dWRlIDxhcnBhL2luZXQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgInV0 aWxzLmgiCisjaW5jbHVkZSAidGNfdXRpbC5oIgorCitzdGF0aWMgdm9pZCBleHBsYWluKHZv aWQpCit7CisJZnByaW50ZihzdGRlcnIsICJVc2FnZTogLi4uIGVmcV9jb2RlbCBbIGxpbWl0 IFBBQ0tFVFMgXSBbIGZsb3dzIE5VTUJFUiBdXG4iKTsKKwlmcHJpbnRmKHN0ZGVyciwgIiAg ICAgICAgICAgICAgICAgICAgWyB0YXJnZXQgVElNRV0gWyBpbnRlcnZhbCBUSU1FIF1cbiIp OworCWZwcmludGYoc3RkZXJyLCAiICAgICAgICAgICAgICAgICAgICBbIHF1YW50dW0gQllU RVMgXSBbIFtub11lY24gXVxuIik7Cit9CisKK3N0YXRpYyBpbnQgZnFfY29kZWxfcGFyc2Vf b3B0KHN0cnVjdCBxZGlzY191dGlsICpxdSwgaW50IGFyZ2MsIGNoYXIgKiphcmd2LAorCQkJ ICAgICAgc3RydWN0IG5sbXNnaGRyICpuKQoreworCXVuc2lnbmVkIGxpbWl0ID0gMDsKKwl1 bnNpZ25lZCBmbG93cyA9IDA7CisJdW5zaWduZWQgdGFyZ2V0ID0gMDsKKwl1bnNpZ25lZCBp bnRlcnZhbCA9IDA7CisJdW5zaWduZWQgcXVhbnR1bSA9IDA7CisJaW50IGVjbiA9IC0xOwor CXN0cnVjdCBydGF0dHIgKnRhaWw7CisKKwl3aGlsZSAoYXJnYyA+IDApIHsKKwkJaWYgKHN0 cmNtcCgqYXJndiwgImxpbWl0IikgPT0gMCkgeworCQkJTkVYVF9BUkcoKTsKKwkJCWlmIChn ZXRfdW5zaWduZWQoJmxpbWl0LCAqYXJndiwgMCkpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwg IklsbGVnYWwgXCJsaW1pdFwiXG4iKTsKKwkJCQlyZXR1cm4gLTE7CisJCQl9CisJCX0gZWxz ZSBpZiAoc3RyY21wKCphcmd2LCAiZmxvd3MiKSA9PSAwKSB7CisJCQlORVhUX0FSRygpOwor CQkJaWYgKGdldF91bnNpZ25lZCgmZmxvd3MsICphcmd2LCAwKSkgeworCQkJCWZwcmludGYo c3RkZXJyLCAiSWxsZWdhbCBcImZsb3dzXCJcbiIpOworCQkJCXJldHVybiAtMTsKKwkJCX0K KwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJxdWFudHVtIikgPT0gMCkgeworCQkJTkVY VF9BUkcoKTsKKwkJCWlmIChnZXRfdW5zaWduZWQoJnF1YW50dW0sICphcmd2LCAwKSkgewor CQkJCWZwcmludGYoc3RkZXJyLCAiSWxsZWdhbCBcInF1YW50dW1cIlxuIik7CisJCQkJcmV0 dXJuIC0xOworCQkJfQorCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgInRhcmdldCIpID09 IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3RpbWUoJnRhcmdldCwgKmFyZ3Yp KSB7CisJCQkJZnByaW50ZihzdGRlcnIsICJJbGxlZ2FsIFwidGFyZ2V0XCJcbiIpOworCQkJ CXJldHVybiAtMTsKKwkJCX0KKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJpbnRlcnZh bCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3RpbWUoJmludGVydmFs LCAqYXJndikpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwgIklsbGVnYWwgXCJpbnRlcnZhbFwi XG4iKTsKKwkJCQlyZXR1cm4gLTE7CisJCQl9CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2 LCAiZWNuIikgPT0gMCkgeworCQkJZWNuID0gMTsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFy Z3YsICJub2VjbiIpID09IDApIHsKKwkJCWVjbiA9IDA7CisJCX0gZWxzZSBpZiAoc3RyY21w KCphcmd2LCAiaGVscCIpID09IDApIHsKKwkJCWV4cGxhaW4oKTsKKwkJCXJldHVybiAtMTsK KwkJfSBlbHNlIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiV2hhdCBpcyBcIiVzXCI/XG4iLCAq YXJndik7CisJCQlleHBsYWluKCk7CisJCQlyZXR1cm4gLTE7CisJCX0KKwkJYXJnYy0tOyBh cmd2Kys7CisJfQorCisJdGFpbCA9IE5MTVNHX1RBSUwobik7CisJYWRkYXR0cl9sKG4sIDEw MjQsIFRDQV9PUFRJT05TLCBOVUxMLCAwKTsKKwlpZiAobGltaXQpCisJCWFkZGF0dHJfbChu LCAxMDI0LCBUQ0FfRlFfQ09ERUxfTElNSVQsICZsaW1pdCwgc2l6ZW9mKGxpbWl0KSk7CisJ aWYgKGZsb3dzKQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENBX0ZRX0NPREVMX0ZMT1dTLCAm Zmxvd3MsIHNpemVvZihmbG93cykpOworCWlmIChxdWFudHVtKQorCQlhZGRhdHRyX2wobiwg MTAyNCwgVENBX0ZRX0NPREVMX1FVQU5UVU0sICZxdWFudHVtLCBzaXplb2YocXVhbnR1bSkp OworCWlmIChpbnRlcnZhbCkKKwkJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9GUV9DT0RFTF9J TlRFUlZBTCwgJmludGVydmFsLCBzaXplb2YoaW50ZXJ2YWwpKTsKKwlpZiAodGFyZ2V0KQor CQlhZGRhdHRyX2wobiwgMTAyNCwgVENBX0ZRX0NPREVMX1RBUkdFVCwgJnRhcmdldCwgc2l6 ZW9mKHRhcmdldCkpOworCWlmIChlY24gIT0gLTEpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBU Q0FfRlFfQ09ERUxfRUNOLCAmZWNuLCBzaXplb2YoZWNuKSk7CisJdGFpbC0+cnRhX2xlbiA9 ICh2b2lkICopIE5MTVNHX1RBSUwobikgLSAodm9pZCAqKSB0YWlsOworCXJldHVybiAwOwor fQorCitzdGF0aWMgaW50IGZxX2NvZGVsX3ByaW50X29wdChzdHJ1Y3QgcWRpc2NfdXRpbCAq cXUsIEZJTEUgKmYsIHN0cnVjdCBydGF0dHIgKm9wdCkKK3sKKwlzdHJ1Y3QgcnRhdHRyICp0 YltUQ0FfRlFfQ09ERUxfTUFYICsgMV07CisJdW5zaWduZWQgbGltaXQ7CisJdW5zaWduZWQg Zmxvd3M7CisJdW5zaWduZWQgaW50ZXJ2YWw7CisJdW5zaWduZWQgdGFyZ2V0OworCXVuc2ln bmVkIGVjbjsKKwl1bnNpZ25lZCBxdWFudHVtOworCVNQUklOVF9CVUYoYjEpOworCisJaWYg KG9wdCA9PSBOVUxMKQorCQlyZXR1cm4gMDsKKworCXBhcnNlX3J0YXR0cl9uZXN0ZWQodGIs IFRDQV9GUV9DT0RFTF9NQVgsIG9wdCk7CisKKwlpZiAodGJbVENBX0ZRX0NPREVMX0xJTUlU XSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfRlFfQ09ERUxfTElNSVRdKSA+PSBzaXpl b2YoX191MzIpKSB7CisJCWxpbWl0ID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9GUV9DT0RF TF9MSU1JVF0pOworCQlmcHJpbnRmKGYsICJsaW1pdCAldXAgIiwgbGltaXQpOworCX0KKwlp ZiAodGJbVENBX0ZRX0NPREVMX0ZMT1dTXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0Ff RlFfQ09ERUxfRkxPV1NdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCWZsb3dzID0gcnRhX2dl dGF0dHJfdTMyKHRiW1RDQV9GUV9DT0RFTF9GTE9XU10pOworCQlmcHJpbnRmKGYsICJmbG93 cyAldSAiLCBmbG93cyk7CisJfQorCWlmICh0YltUQ0FfRlFfQ09ERUxfUVVBTlRVTV0gJiYK KwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0ZRX0NPREVMX1FVQU5UVU1dKSA+PSBzaXplb2Yo X191MzIpKSB7CisJCXF1YW50dW0gPSBydGFfZ2V0YXR0cl91MzIodGJbVENBX0ZRX0NPREVM X1FVQU5UVU1dKTsKKwkJZnByaW50ZihmLCAicXVhbnR1bSAldSAiLCBxdWFudHVtKTsKKwl9 CisJaWYgKHRiW1RDQV9GUV9DT0RFTF9UQVJHRVRdICYmCisJICAgIFJUQV9QQVlMT0FEKHRi W1RDQV9GUV9DT0RFTF9UQVJHRVRdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCXRhcmdldCA9 IHJ0YV9nZXRhdHRyX3UzMih0YltUQ0FfRlFfQ09ERUxfVEFSR0VUXSk7CisJCWZwcmludGYo ZiwgInRhcmdldCAlcyAiLCBzcHJpbnRfdGltZSh0YXJnZXQsIGIxKSk7CisJfQorCWlmICh0 YltUQ0FfRlFfQ09ERUxfSU5URVJWQUxdICYmCisJICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9G UV9DT0RFTF9JTlRFUlZBTF0pID49IHNpemVvZihfX3UzMikpIHsKKwkJaW50ZXJ2YWwgPSBy dGFfZ2V0YXR0cl91MzIodGJbVENBX0ZRX0NPREVMX0lOVEVSVkFMXSk7CisJCWZwcmludGYo ZiwgImludGVydmFsICVzICIsIHNwcmludF90aW1lKGludGVydmFsLCBiMSkpOworCX0KKwlp ZiAodGJbVENBX0ZRX0NPREVMX0VDTl0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0ZR X0NPREVMX0VDTl0pID49IHNpemVvZihfX3UzMikpIHsKKwkJZWNuID0gcnRhX2dldGF0dHJf dTMyKHRiW1RDQV9GUV9DT0RFTF9FQ05dKTsKKwkJaWYgKGVjbikKKwkJCWZwcmludGYoZiwg ImVjbiAiKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBmcV9jb2RlbF9w cmludF94c3RhdHMoc3RydWN0IHFkaXNjX3V0aWwgKnF1LCBGSUxFICpmLAorCQkJCSBzdHJ1 Y3QgcnRhdHRyICp4c3RhdHMpCit7CisJc3RydWN0IHRjX2ZxX2NvZGVsX3hzdGF0cyAqc3Q7 CisJU1BSSU5UX0JVRihiMSk7CisKKwlpZiAoeHN0YXRzID09IE5VTEwpCisJCXJldHVybiAw OworCisJaWYgKFJUQV9QQVlMT0FEKHhzdGF0cykgPCBzaXplb2YoKnN0KSkKKwkJcmV0dXJu IC0xOworCisJc3QgPSBSVEFfREFUQSh4c3RhdHMpOworCWlmIChzdC0+dHlwZSA9PSBUQ0Ff RlFfQ09ERUxfWFNUQVRTX1FESVNDKSB7CisJCWZwcmludGYoZiwgIiAgbWF4cGFja2V0ICV1 IGRyb3Bfb3ZlcmxpbWl0ICV1IG5ld19mbG93X2NvdW50ICV1IGVjbl9tYXJrICV1IiwKKwkJ CXN0LT5xZGlzY19zdGF0cy5tYXhwYWNrZXQsCisJCQlzdC0+cWRpc2Nfc3RhdHMuZHJvcF9v dmVybGltaXQsCisJCQlzdC0+cWRpc2Nfc3RhdHMubmV3X2Zsb3dfY291bnQsCisJCQlzdC0+ cWRpc2Nfc3RhdHMuZWNuX21hcmspOworCQlmcHJpbnRmKGYsICJcbiAgbmV3X2Zsb3dzX2xl biAldSBvbGRfZmxvd3NfbGVuICV1IiwKKwkJCXN0LT5xZGlzY19zdGF0cy5uZXdfZmxvd3Nf bGVuLAorCQkJc3QtPnFkaXNjX3N0YXRzLm9sZF9mbG93c19sZW4pOworCX0KKwlpZiAoc3Qt PnR5cGUgPT0gVENBX0ZRX0NPREVMX1hTVEFUU19DTEFTUykgeworCQlmcHJpbnRmKGYsICIg IGRlZmljaXQgJWQgY291bnQgJXUgbGFzdGNvdW50ICV1IGxkZWxheSAlcyIsCisJCQlzdC0+ Y2xhc3Nfc3RhdHMuZGVmaWNpdCwKKwkJCXN0LT5jbGFzc19zdGF0cy5jb3VudCwKKwkJCXN0 LT5jbGFzc19zdGF0cy5sYXN0Y291bnQsCisJCQlzcHJpbnRfdGltZShzdC0+Y2xhc3Nfc3Rh dHMubGRlbGF5LCBiMSkpOworCQlpZiAoc3QtPmNsYXNzX3N0YXRzLmRyb3BwaW5nKSB7CisJ CQlmcHJpbnRmKGYsICIgZHJvcHBpbmciKTsKKwkJCWlmIChzdC0+Y2xhc3Nfc3RhdHMuZHJv cF9uZXh0IDwgMCkKKwkJCQlmcHJpbnRmKGYsICIgZHJvcF9uZXh0IC0lcyIsCisJCQkJCXNw cmludF90aW1lKC1zdC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0LCBiMSkpOworCQkJZWxzZQor CQkJCWZwcmludGYoZiwgIiBkcm9wX25leHQgJXMiLAorCQkJCQlzcHJpbnRfdGltZShzdC0+ Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0LCBiMSkpOworCQl9CisJfQorCXJldHVybiAwOworCit9 CisKK3N0cnVjdCBxZGlzY191dGlsIGVmcV9jb2RlbF9xZGlzY191dGlsID0geworCS5pZAkJ PSAiZWZxX2NvZGVsIiwKKwkucGFyc2VfcW9wdAk9IGZxX2NvZGVsX3BhcnNlX29wdCwKKwku cHJpbnRfcW9wdAk9IGZxX2NvZGVsX3ByaW50X29wdCwKKwkucHJpbnRfeHN0YXRzCT0gZnFf Y29kZWxfcHJpbnRfeHN0YXRzLAorfTsKZGlmZiAtLWdpdCBhL3RjL3FfbmZxX2NvZGVsLmMg Yi90Yy9xX25mcV9jb2RlbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAu LmVmMjQ5MDkKLS0tIC9kZXYvbnVsbAorKysgYi90Yy9xX25mcV9jb2RlbC5jCkBAIC0wLDAg KzEsMjMyIEBACisvKgorICogRmFpciBRdWV1ZSBDb2RlbAorICoKKyAqICBDb3B5cmlnaHQg KEMpIDIwMTIgRXJpYyBEdW1hemV0IDxlZHVtYXpldEBnb29nbGUuY29tPgorICoKKyAqIFJl ZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGgg b3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRo YXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zCisgKiBhcmUgbWV0OgorICogMS4gUmVkaXN0 cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmln aHQKKyAqICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMsIGFuZCB0aGUgZm9s bG93aW5nIGRpc2NsYWltZXIsCisgKiAgICB3aXRob3V0IG1vZGlmaWNhdGlvbi4KKyAqIDIu IFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJv dmUgY29weXJpZ2h0CisgKiAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFu ZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlCisgKiAgICBkb2N1bWVudGF0aW9u IGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9u LgorICogMy4gVGhlIG5hbWVzIG9mIHRoZSBhdXRob3JzIG1heSBub3QgYmUgdXNlZCB0byBl bmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMKKyAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNv ZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoK KyAqIEFsdGVybmF0aXZlbHksIHByb3ZpZGVkIHRoYXQgdGhpcyBub3RpY2UgaXMgcmV0YWlu ZWQgaW4gZnVsbCwgdGhpcworICogc29mdHdhcmUgbWF5IGJlIGRpc3RyaWJ1dGVkIHVuZGVy IHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwKKyAqIFB1YmxpYyBMaWNlbnNlICgiR1BM IikgdmVyc2lvbiAyLCBpbiB3aGljaCBjYXNlIHRoZSBwcm92aXNpb25zIG9mIHRoZQorICog R1BMIGFwcGx5IElOU1RFQUQgT0YgdGhvc2UgZ2l2ZW4gYWJvdmUuCisgKgorICogVEhJUyBT T0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUgQ09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRS SUJVVE9SUworICogIkFTIElTIiBBTkQgQU5ZIEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5U SUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAqIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdB UlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZIEFORCBGSVRORVNTIEZPUgorICogQSBQQVJU SUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBD T1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRSSUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBE SVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBP UiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRF RCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJVFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9T UyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJ T04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBBTlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFks IFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklDVCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJ TkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhFUldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBP VVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9G IFRIRSBQT1NTSUJJTElUWSBPRiBTVUNICisgKiBEQU1BR0UuCisgKgorICovCisKKyNpbmNs dWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0ZGxpYi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5o PgorI2luY2x1ZGUgPHN5c2xvZy5oPgorI2luY2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8 c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPG5ldGluZXQvaW4uaD4KKyNpbmNsdWRlIDxhcnBh L2luZXQuaD4KKyNpbmNsdWRlIDxzdHJpbmcuaD4KKworI2luY2x1ZGUgInV0aWxzLmgiCisj aW5jbHVkZSAidGNfdXRpbC5oIgorCitzdGF0aWMgdm9pZCBleHBsYWluKHZvaWQpCit7CisJ ZnByaW50ZihzdGRlcnIsICJVc2FnZTogLi4uIG5mcV9jb2RlbCBbIGxpbWl0IFBBQ0tFVFMg XSBbIGZsb3dzIE5VTUJFUiBdXG4iKTsKKwlmcHJpbnRmKHN0ZGVyciwgIiAgICAgICAgICAg ICAgICAgICAgWyB0YXJnZXQgVElNRV0gWyBpbnRlcnZhbCBUSU1FIF1cbiIpOworCWZwcmlu dGYoc3RkZXJyLCAiICAgICAgICAgICAgICAgICAgICBbIHF1YW50dW0gQllURVMgXSBbIFtu b11lY24gXVxuIik7Cit9CisKK3N0YXRpYyBpbnQgZnFfY29kZWxfcGFyc2Vfb3B0KHN0cnVj dCBxZGlzY191dGlsICpxdSwgaW50IGFyZ2MsIGNoYXIgKiphcmd2LAorCQkJICAgICAgc3Ry dWN0IG5sbXNnaGRyICpuKQoreworCXVuc2lnbmVkIGxpbWl0ID0gMDsKKwl1bnNpZ25lZCBm bG93cyA9IDA7CisJdW5zaWduZWQgdGFyZ2V0ID0gMDsKKwl1bnNpZ25lZCBpbnRlcnZhbCA9 IDA7CisJdW5zaWduZWQgcXVhbnR1bSA9IDA7CisJaW50IGVjbiA9IC0xOworCXN0cnVjdCBy dGF0dHIgKnRhaWw7CisKKwl3aGlsZSAoYXJnYyA+IDApIHsKKwkJaWYgKHN0cmNtcCgqYXJn diwgImxpbWl0IikgPT0gMCkgeworCQkJTkVYVF9BUkcoKTsKKwkJCWlmIChnZXRfdW5zaWdu ZWQoJmxpbWl0LCAqYXJndiwgMCkpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwgIklsbGVnYWwg XCJsaW1pdFwiXG4iKTsKKwkJCQlyZXR1cm4gLTE7CisJCQl9CisJCX0gZWxzZSBpZiAoc3Ry Y21wKCphcmd2LCAiZmxvd3MiKSA9PSAwKSB7CisJCQlORVhUX0FSRygpOworCQkJaWYgKGdl dF91bnNpZ25lZCgmZmxvd3MsICphcmd2LCAwKSkgeworCQkJCWZwcmludGYoc3RkZXJyLCAi SWxsZWdhbCBcImZsb3dzXCJcbiIpOworCQkJCXJldHVybiAtMTsKKwkJCX0KKwkJfSBlbHNl IGlmIChzdHJjbXAoKmFyZ3YsICJxdWFudHVtIikgPT0gMCkgeworCQkJTkVYVF9BUkcoKTsK KwkJCWlmIChnZXRfdW5zaWduZWQoJnF1YW50dW0sICphcmd2LCAwKSkgeworCQkJCWZwcmlu dGYoc3RkZXJyLCAiSWxsZWdhbCBcInF1YW50dW1cIlxuIik7CisJCQkJcmV0dXJuIC0xOwor CQkJfQorCQl9IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgInRhcmdldCIpID09IDApIHsKKwkJ CU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3RpbWUoJnRhcmdldCwgKmFyZ3YpKSB7CisJCQkJ ZnByaW50ZihzdGRlcnIsICJJbGxlZ2FsIFwidGFyZ2V0XCJcbiIpOworCQkJCXJldHVybiAt MTsKKwkJCX0KKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJpbnRlcnZhbCIpID09IDAp IHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3RpbWUoJmludGVydmFsLCAqYXJndikp IHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwgIklsbGVnYWwgXCJpbnRlcnZhbFwiXG4iKTsKKwkJ CQlyZXR1cm4gLTE7CisJCQl9CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiZWNuIikg PT0gMCkgeworCQkJZWNuID0gMTsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJub2Vj biIpID09IDApIHsKKwkJCWVjbiA9IDA7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAi aGVscCIpID09IDApIHsKKwkJCWV4cGxhaW4oKTsKKwkJCXJldHVybiAtMTsKKwkJfSBlbHNl IHsKKwkJCWZwcmludGYoc3RkZXJyLCAiV2hhdCBpcyBcIiVzXCI/XG4iLCAqYXJndik7CisJ CQlleHBsYWluKCk7CisJCQlyZXR1cm4gLTE7CisJCX0KKwkJYXJnYy0tOyBhcmd2Kys7CisJ fQorCisJdGFpbCA9IE5MTVNHX1RBSUwobik7CisJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9P UFRJT05TLCBOVUxMLCAwKTsKKwlpZiAobGltaXQpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBU Q0FfRlFfQ09ERUxfTElNSVQsICZsaW1pdCwgc2l6ZW9mKGxpbWl0KSk7CisJaWYgKGZsb3dz KQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENBX0ZRX0NPREVMX0ZMT1dTLCAmZmxvd3MsIHNp emVvZihmbG93cykpOworCWlmIChxdWFudHVtKQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENB X0ZRX0NPREVMX1FVQU5UVU0sICZxdWFudHVtLCBzaXplb2YocXVhbnR1bSkpOworCWlmIChp bnRlcnZhbCkKKwkJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9GUV9DT0RFTF9JTlRFUlZBTCwg JmludGVydmFsLCBzaXplb2YoaW50ZXJ2YWwpKTsKKwlpZiAodGFyZ2V0KQorCQlhZGRhdHRy X2wobiwgMTAyNCwgVENBX0ZRX0NPREVMX1RBUkdFVCwgJnRhcmdldCwgc2l6ZW9mKHRhcmdl dCkpOworCWlmIChlY24gIT0gLTEpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfRlFfQ09E RUxfRUNOLCAmZWNuLCBzaXplb2YoZWNuKSk7CisJdGFpbC0+cnRhX2xlbiA9ICh2b2lkICop IE5MTVNHX1RBSUwobikgLSAodm9pZCAqKSB0YWlsOworCXJldHVybiAwOworfQorCitzdGF0 aWMgaW50IGZxX2NvZGVsX3ByaW50X29wdChzdHJ1Y3QgcWRpc2NfdXRpbCAqcXUsIEZJTEUg KmYsIHN0cnVjdCBydGF0dHIgKm9wdCkKK3sKKwlzdHJ1Y3QgcnRhdHRyICp0YltUQ0FfRlFf Q09ERUxfTUFYICsgMV07CisJdW5zaWduZWQgbGltaXQ7CisJdW5zaWduZWQgZmxvd3M7CisJ dW5zaWduZWQgaW50ZXJ2YWw7CisJdW5zaWduZWQgdGFyZ2V0OworCXVuc2lnbmVkIGVjbjsK Kwl1bnNpZ25lZCBxdWFudHVtOworCVNQUklOVF9CVUYoYjEpOworCisJaWYgKG9wdCA9PSBO VUxMKQorCQlyZXR1cm4gMDsKKworCXBhcnNlX3J0YXR0cl9uZXN0ZWQodGIsIFRDQV9GUV9D T0RFTF9NQVgsIG9wdCk7CisKKwlpZiAodGJbVENBX0ZRX0NPREVMX0xJTUlUXSAmJgorCSAg ICBSVEFfUEFZTE9BRCh0YltUQ0FfRlFfQ09ERUxfTElNSVRdKSA+PSBzaXplb2YoX191MzIp KSB7CisJCWxpbWl0ID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9GUV9DT0RFTF9MSU1JVF0p OworCQlmcHJpbnRmKGYsICJsaW1pdCAldXAgIiwgbGltaXQpOworCX0KKwlpZiAodGJbVENB X0ZRX0NPREVMX0ZMT1dTXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfRlFfQ09ERUxf RkxPV1NdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCWZsb3dzID0gcnRhX2dldGF0dHJfdTMy KHRiW1RDQV9GUV9DT0RFTF9GTE9XU10pOworCQlmcHJpbnRmKGYsICJmbG93cyAldSAiLCBm bG93cyk7CisJfQorCWlmICh0YltUQ0FfRlFfQ09ERUxfUVVBTlRVTV0gJiYKKwkgICAgUlRB X1BBWUxPQUQodGJbVENBX0ZRX0NPREVMX1FVQU5UVU1dKSA+PSBzaXplb2YoX191MzIpKSB7 CisJCXF1YW50dW0gPSBydGFfZ2V0YXR0cl91MzIodGJbVENBX0ZRX0NPREVMX1FVQU5UVU1d KTsKKwkJZnByaW50ZihmLCAicXVhbnR1bSAldSAiLCBxdWFudHVtKTsKKwl9CisJaWYgKHRi W1RDQV9GUV9DT0RFTF9UQVJHRVRdICYmCisJICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9GUV9D T0RFTF9UQVJHRVRdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCXRhcmdldCA9IHJ0YV9nZXRh dHRyX3UzMih0YltUQ0FfRlFfQ09ERUxfVEFSR0VUXSk7CisJCWZwcmludGYoZiwgInRhcmdl dCAlcyAiLCBzcHJpbnRfdGltZSh0YXJnZXQsIGIxKSk7CisJfQorCWlmICh0YltUQ0FfRlFf Q09ERUxfSU5URVJWQUxdICYmCisJICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9GUV9DT0RFTF9J TlRFUlZBTF0pID49IHNpemVvZihfX3UzMikpIHsKKwkJaW50ZXJ2YWwgPSBydGFfZ2V0YXR0 cl91MzIodGJbVENBX0ZRX0NPREVMX0lOVEVSVkFMXSk7CisJCWZwcmludGYoZiwgImludGVy dmFsICVzICIsIHNwcmludF90aW1lKGludGVydmFsLCBiMSkpOworCX0KKwlpZiAodGJbVENB X0ZRX0NPREVMX0VDTl0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0ZRX0NPREVMX0VD Tl0pID49IHNpemVvZihfX3UzMikpIHsKKwkJZWNuID0gcnRhX2dldGF0dHJfdTMyKHRiW1RD QV9GUV9DT0RFTF9FQ05dKTsKKwkJaWYgKGVjbikKKwkJCWZwcmludGYoZiwgImVjbiAiKTsK Kwl9CisKKwlyZXR1cm4gMDsKK30KKworc3RhdGljIGludCBmcV9jb2RlbF9wcmludF94c3Rh dHMoc3RydWN0IHFkaXNjX3V0aWwgKnF1LCBGSUxFICpmLAorCQkJCSBzdHJ1Y3QgcnRhdHRy ICp4c3RhdHMpCit7CisJc3RydWN0IHRjX2ZxX2NvZGVsX3hzdGF0cyAqc3Q7CisJU1BSSU5U X0JVRihiMSk7CisKKwlpZiAoeHN0YXRzID09IE5VTEwpCisJCXJldHVybiAwOworCisJaWYg KFJUQV9QQVlMT0FEKHhzdGF0cykgPCBzaXplb2YoKnN0KSkKKwkJcmV0dXJuIC0xOworCisJ c3QgPSBSVEFfREFUQSh4c3RhdHMpOworCWlmIChzdC0+dHlwZSA9PSBUQ0FfRlFfQ09ERUxf WFNUQVRTX1FESVNDKSB7CisJCWZwcmludGYoZiwgIiAgbWF4cGFja2V0ICV1IGRyb3Bfb3Zl cmxpbWl0ICV1IG5ld19mbG93X2NvdW50ICV1IGVjbl9tYXJrICV1IiwKKwkJCXN0LT5xZGlz Y19zdGF0cy5tYXhwYWNrZXQsCisJCQlzdC0+cWRpc2Nfc3RhdHMuZHJvcF9vdmVybGltaXQs CisJCQlzdC0+cWRpc2Nfc3RhdHMubmV3X2Zsb3dfY291bnQsCisJCQlzdC0+cWRpc2Nfc3Rh dHMuZWNuX21hcmspOworCQlmcHJpbnRmKGYsICJcbiAgbmV3X2Zsb3dzX2xlbiAldSBvbGRf Zmxvd3NfbGVuICV1IiwKKwkJCXN0LT5xZGlzY19zdGF0cy5uZXdfZmxvd3NfbGVuLAorCQkJ c3QtPnFkaXNjX3N0YXRzLm9sZF9mbG93c19sZW4pOworCX0KKwlpZiAoc3QtPnR5cGUgPT0g VENBX0ZRX0NPREVMX1hTVEFUU19DTEFTUykgeworCQlmcHJpbnRmKGYsICIgIGRlZmljaXQg JWQgY291bnQgJXUgbGFzdGNvdW50ICV1IGxkZWxheSAlcyIsCisJCQlzdC0+Y2xhc3Nfc3Rh dHMuZGVmaWNpdCwKKwkJCXN0LT5jbGFzc19zdGF0cy5jb3VudCwKKwkJCXN0LT5jbGFzc19z dGF0cy5sYXN0Y291bnQsCisJCQlzcHJpbnRfdGltZShzdC0+Y2xhc3Nfc3RhdHMubGRlbGF5 LCBiMSkpOworCQlpZiAoc3QtPmNsYXNzX3N0YXRzLmRyb3BwaW5nKSB7CisJCQlmcHJpbnRm KGYsICIgZHJvcHBpbmciKTsKKwkJCWlmIChzdC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0IDwg MCkKKwkJCQlmcHJpbnRmKGYsICIgZHJvcF9uZXh0IC0lcyIsCisJCQkJCXNwcmludF90aW1l KC1zdC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0LCBiMSkpOworCQkJZWxzZQorCQkJCWZwcmlu dGYoZiwgIiBkcm9wX25leHQgJXMiLAorCQkJCQlzcHJpbnRfdGltZShzdC0+Y2xhc3Nfc3Rh dHMuZHJvcF9uZXh0LCBiMSkpOworCQl9CisJfQorCXJldHVybiAwOworCit9CisKK3N0cnVj dCBxZGlzY191dGlsIG5mcV9jb2RlbF9xZGlzY191dGlsID0geworCS5pZAkJPSAibmZxX2Nv ZGVsIiwKKwkucGFyc2VfcW9wdAk9IGZxX2NvZGVsX3BhcnNlX29wdCwKKwkucHJpbnRfcW9w dAk9IGZxX2NvZGVsX3ByaW50X29wdCwKKwkucHJpbnRfeHN0YXRzCT0gZnFfY29kZWxfcHJp bnRfeHN0YXRzLAorfTsKZGlmZiAtLWdpdCBhL3RjL3FfbnMyX2NvZGVsLmMgYi90Yy9xX25z Ml9jb2RlbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjIyM2E5NzEK LS0tIC9kZXYvbnVsbAorKysgYi90Yy9xX25zMl9jb2RlbC5jCkBAIC0wLDAgKzEsMTg4IEBA CisvKgorICogQ29kZWwgLSBUaGUgQ29udHJvbGxlZC1EZWxheSBBY3RpdmUgUXVldWUgTWFu YWdlbWVudCBhbGdvcml0aG0KKyAqCisgKiAgQ29weXJpZ2h0IChDKSAyMDExLTIwMTIgS2F0 aGxlZW4gTmljaG9scyA8bmljaG9sc0Bwb2xsZXJlLmNvbT4KKyAqICBDb3B5cmlnaHQgKEMp IDIwMTEtMjAxMiBWYW4gSmFjb2Jzb24gPHZhbkBwb2xsZXJlLmNvbT4KKyAqICBDb3B5cmln aHQgKEMpIDIwMTIgTWljaGFlbCBELiBUYWh0IDxkYXZlLnRhaHRAYnVmZmVyYmxvYXQubmV0 PgorICogIENvcHlyaWdodCAoQykgMjAxMiBFcmljIER1bWF6ZXQgPGVkdW1hemV0QGdvb2ds ZS5jb20+CisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVzZSBpbiBzb3VyY2UgYW5kIGJp bmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2RpZmljYXRpb24sIGFyZSBwZXJt aXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMKKyAqIGFyZSBt ZXQ6CisgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4g dGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0aGlzIGxpc3Qgb2YgY29uZGl0 aW9ucywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciwKKyAqICAgIHdpdGhvdXQgbW9k aWZpY2F0aW9uLgorICogMi4gUmVkaXN0cmlidXRpb25zIGluIGJpbmFyeSBmb3JtIG11c3Qg cmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgIG5vdGljZSwgdGhpcyBsaXN0 IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciBpbiB0aGUKKyAq ICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRo IHRoZSBkaXN0cmlidXRpb24uCisgKiAzLiBUaGUgbmFtZXMgb2YgdGhlIGF1dGhvcnMgbWF5 IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0cworICogICAgZGVy aXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVjaWZpYyBwcmlvciB3cml0dGVu IHBlcm1pc3Npb24uCisgKgorICogQWx0ZXJuYXRpdmVseSwgcHJvdmlkZWQgdGhhdCB0aGlz IG5vdGljZSBpcyByZXRhaW5lZCBpbiBmdWxsLCB0aGlzCisgKiBzb2Z0d2FyZSBtYXkgYmUg ZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbAorICogUHVi bGljIExpY2Vuc2UgKCJHUEwiKSB2ZXJzaW9uIDIsIGluIHdoaWNoIGNhc2UgdGhlIHByb3Zp c2lvbnMgb2YgdGhlCisgKiBHUEwgYXBwbHkgSU5TVEVBRCBPRiB0aG9zZSBnaXZlbiBhYm92 ZS4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQg SE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMiIEFORCBBTlkgRVhQUkVTUyBP UiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBU TywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFOVEFCSUxJVFkgQU5EIEZJVE5F U1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUgRElTQ0xBSU1FRC4gSU4gTk8g RVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIgT1IgQ09OVFJJQlVUT1JTIEJF IExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElOQ0lERU5UQUwsCisgKiBTUEVD SUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFUyAoSU5DTFVESU5HLCBC VVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBPRiBTVUJTVElUVVRFIEdPT0RT IE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEsIE9SIFBST0ZJVFM7IE9SIEJV U0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQgQU5EIE9OIEFOWQorICogVEhF T1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElU WSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNFIE9SIE9USEVSV0lTRSkgQVJJ U0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBPRiBUSElTIFNPRlRXQVJFLCBF VkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9GIFNVQ0gKKyAqIERBTUFHRS4K KyAqCisgKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5jbHVkZSA8c3RkbGliLmg+Cisj aW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8c3lzbG9nLmg+CisjaW5jbHVkZSA8ZmNu dGwuaD4KKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CisjaW5jbHVkZSA8bmV0aW5ldC9pbi5o PgorI2luY2x1ZGUgPGFycGEvaW5ldC5oPgorI2luY2x1ZGUgPHN0cmluZy5oPgorCisjaW5j bHVkZSAidXRpbHMuaCIKKyNpbmNsdWRlICJ0Y191dGlsLmgiCisKK3N0YXRpYyB2b2lkIGV4 cGxhaW4odm9pZCkKK3sKKwlmcHJpbnRmKHN0ZGVyciwgIlVzYWdlOiAuLi4gbnMyX2NvZGVs IFsgbGltaXQgUEFDS0VUUyBdIFsgdGFyZ2V0IFRJTUVdXG4iKTsKKwlmcHJpbnRmKHN0ZGVy ciwgIiAgICAgICAgICAgICAgICAgWyBpbnRlcnZhbCBUSU1FIF0gWyBlY24gfCBub2VjbiBd XG4iKTsKK30KKworc3RhdGljIGludCBjb2RlbF9wYXJzZV9vcHQoc3RydWN0IHFkaXNjX3V0 aWwgKnF1LCBpbnQgYXJnYywgY2hhciAqKmFyZ3YsCisJCQkgICBzdHJ1Y3Qgbmxtc2doZHIg Km4pCit7CisJdW5zaWduZWQgbGltaXQgPSAwOworCXVuc2lnbmVkIHRhcmdldCA9IDA7CisJ dW5zaWduZWQgaW50ZXJ2YWwgPSAwOworCWludCBlY24gPSAtMTsKKwlzdHJ1Y3QgcnRhdHRy ICp0YWlsOworCisJd2hpbGUgKGFyZ2MgPiAwKSB7CisJCWlmIChzdHJjbXAoKmFyZ3YsICJs aW1pdCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3Vuc2lnbmVkKCZs aW1pdCwgKmFyZ3YsIDApKSB7CisJCQkJZnByaW50ZihzdGRlcnIsICJJbGxlZ2FsIFwibGlt aXRcIlxuIik7CisJCQkJcmV0dXJuIC0xOworCQkJfQorCQl9IGVsc2UgaWYgKHN0cmNtcCgq YXJndiwgInRhcmdldCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3Rp bWUoJnRhcmdldCwgKmFyZ3YpKSB7CisJCQkJZnByaW50ZihzdGRlcnIsICJJbGxlZ2FsIFwi dGFyZ2V0XCJcbiIpOworCQkJCXJldHVybiAtMTsKKwkJCX0KKwkJfSBlbHNlIGlmIChzdHJj bXAoKmFyZ3YsICJpbnRlcnZhbCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAo Z2V0X3RpbWUoJmludGVydmFsLCAqYXJndikpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwgIkls bGVnYWwgXCJpbnRlcnZhbFwiXG4iKTsKKwkJCQlyZXR1cm4gLTE7CisJCQl9CisJCX0gZWxz ZSBpZiAoc3RyY21wKCphcmd2LCAiZWNuIikgPT0gMCkgeworCQkJZWNuID0gMTsKKwkJfSBl bHNlIGlmIChzdHJjbXAoKmFyZ3YsICJub2VjbiIpID09IDApIHsKKwkJCWVjbiA9IDA7CisJ CX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiaGVscCIpID09IDApIHsKKwkJCWV4cGxhaW4o KTsKKwkJCXJldHVybiAtMTsKKwkJfSBlbHNlIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiV2hh dCBpcyBcIiVzXCI/XG4iLCAqYXJndik7CisJCQlleHBsYWluKCk7CisJCQlyZXR1cm4gLTE7 CisJCX0KKwkJYXJnYy0tOyBhcmd2Kys7CisJfQorCisJdGFpbCA9IE5MTVNHX1RBSUwobik7 CisJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9PUFRJT05TLCBOVUxMLCAwKTsKKwlpZiAobGlt aXQpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfQ09ERUxfTElNSVQsICZsaW1pdCwgc2l6 ZW9mKGxpbWl0KSk7CisJaWYgKGludGVydmFsKQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENB X0NPREVMX0lOVEVSVkFMLCAmaW50ZXJ2YWwsIHNpemVvZihpbnRlcnZhbCkpOworCWlmICh0 YXJnZXQpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfQ09ERUxfVEFSR0VULCAmdGFyZ2V0 LCBzaXplb2YodGFyZ2V0KSk7CisJaWYgKGVjbiAhPSAtMSkKKwkJYWRkYXR0cl9sKG4sIDEw MjQsIFRDQV9DT0RFTF9FQ04sICZlY24sIHNpemVvZihlY24pKTsKKwl0YWlsLT5ydGFfbGVu ID0gKHZvaWQgKikgTkxNU0dfVEFJTChuKSAtICh2b2lkICopIHRhaWw7CisJcmV0dXJuIDA7 Cit9CisKK3N0YXRpYyBpbnQgY29kZWxfcHJpbnRfb3B0KHN0cnVjdCBxZGlzY191dGlsICpx dSwgRklMRSAqZiwgc3RydWN0IHJ0YXR0ciAqb3B0KQoreworCXN0cnVjdCBydGF0dHIgKnRi W1RDQV9DT0RFTF9NQVggKyAxXTsKKwl1bnNpZ25lZCBsaW1pdDsKKwl1bnNpZ25lZCBpbnRl cnZhbDsKKwl1bnNpZ25lZCB0YXJnZXQ7CisJdW5zaWduZWQgZWNuOworCVNQUklOVF9CVUYo YjEpOworCisJaWYgKG9wdCA9PSBOVUxMKQorCQlyZXR1cm4gMDsKKworCXBhcnNlX3J0YXR0 cl9uZXN0ZWQodGIsIFRDQV9DT0RFTF9NQVgsIG9wdCk7CisKKwlpZiAodGJbVENBX0NPREVM X0xJTUlUXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfQ09ERUxfTElNSVRdKSA+PSBz aXplb2YoX191MzIpKSB7CisJCWxpbWl0ID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9DT0RF TF9MSU1JVF0pOworCQlmcHJpbnRmKGYsICJsaW1pdCAldXAgIiwgbGltaXQpOworCX0KKwlp ZiAodGJbVENBX0NPREVMX1RBUkdFVF0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0NP REVMX1RBUkdFVF0pID49IHNpemVvZihfX3UzMikpIHsKKwkJdGFyZ2V0ID0gcnRhX2dldGF0 dHJfdTMyKHRiW1RDQV9DT0RFTF9UQVJHRVRdKTsKKwkJZnByaW50ZihmLCAidGFyZ2V0ICVz ICIsIHNwcmludF90aW1lKHRhcmdldCwgYjEpKTsKKwl9CisJaWYgKHRiW1RDQV9DT0RFTF9J TlRFUlZBTF0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0NPREVMX0lOVEVSVkFMXSkg Pj0gc2l6ZW9mKF9fdTMyKSkgeworCQlpbnRlcnZhbCA9IHJ0YV9nZXRhdHRyX3UzMih0YltU Q0FfQ09ERUxfSU5URVJWQUxdKTsKKwkJZnByaW50ZihmLCAiaW50ZXJ2YWwgJXMgIiwgc3By aW50X3RpbWUoaW50ZXJ2YWwsIGIxKSk7CisJfQorCWlmICh0YltUQ0FfQ09ERUxfRUNOXSAm JgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfQ09ERUxfRUNOXSkgPj0gc2l6ZW9mKF9fdTMy KSkgeworCQllY24gPSBydGFfZ2V0YXR0cl91MzIodGJbVENBX0NPREVMX0VDTl0pOworCQlp ZiAoZWNuKQorCQkJZnByaW50ZihmLCAiZWNuICIpOworCX0KKworCXJldHVybiAwOworfQor CitzdGF0aWMgaW50IGNvZGVsX3ByaW50X3hzdGF0cyhzdHJ1Y3QgcWRpc2NfdXRpbCAqcXUs IEZJTEUgKmYsCisJCQkgICAgICBzdHJ1Y3QgcnRhdHRyICp4c3RhdHMpCit7CisJc3RydWN0 IHRjX2NvZGVsX3hzdGF0cyAqc3Q7CisJU1BSSU5UX0JVRihiMSk7CisKKwlpZiAoeHN0YXRz ID09IE5VTEwpCisJCXJldHVybiAwOworCisJaWYgKFJUQV9QQVlMT0FEKHhzdGF0cykgPCBz aXplb2YoKnN0KSkKKwkJcmV0dXJuIC0xOworCisJc3QgPSBSVEFfREFUQSh4c3RhdHMpOwor CWZwcmludGYoZiwgIiAgY291bnQgJXUgbGFzdGNvdW50ICV1IGxkZWxheSAlcyIsCisJCXN0 LT5jb3VudCwgc3QtPmxhc3Rjb3VudCwgc3ByaW50X3RpbWUoc3QtPmxkZWxheSwgYjEpKTsK KwlpZiAoc3QtPmRyb3BwaW5nKQorCQlmcHJpbnRmKGYsICIgZHJvcHBpbmciKTsKKwlpZiAo c3QtPmRyb3BfbmV4dCA8IDApCisJCWZwcmludGYoZiwgIiBkcm9wX25leHQgLSVzIiwgc3By aW50X3RpbWUoLXN0LT5kcm9wX25leHQsIGIxKSk7CisJZWxzZQorCQlmcHJpbnRmKGYsICIg ZHJvcF9uZXh0ICVzIiwgc3ByaW50X3RpbWUoc3QtPmRyb3BfbmV4dCwgYjEpKTsKKwlmcHJp bnRmKGYsICJcbiAgbWF4cGFja2V0ICV1IGVjbl9tYXJrICV1IGRyb3Bfb3ZlcmxpbWl0ICV1 IiwKKwkJc3QtPm1heHBhY2tldCwgc3QtPmVjbl9tYXJrLCBzdC0+ZHJvcF9vdmVybGltaXQp OworCXJldHVybiAwOworCit9CisKK3N0cnVjdCBxZGlzY191dGlsIG5zMl9jb2RlbF9xZGlz Y191dGlsID0geworCS5pZAkJPSAibnMyX2NvZGVsIiwKKwkucGFyc2VfcW9wdAk9IGNvZGVs X3BhcnNlX29wdCwKKwkucHJpbnRfcW9wdAk9IGNvZGVsX3ByaW50X29wdCwKKwkucHJpbnRf eHN0YXRzCT0gY29kZWxfcHJpbnRfeHN0YXRzLAorfTsKZGlmZiAtLWdpdCBhL3RjL3FfbnM0 X2NvZGVsLmMgYi90Yy9xX25zNF9jb2RlbC5jCm5ldyBmaWxlIG1vZGUgMTAwNjQ0CmluZGV4 IDAwMDAwMDAuLjBhYWEzNDkKLS0tIC9kZXYvbnVsbAorKysgYi90Yy9xX25zNF9jb2RlbC5j CkBAIC0wLDAgKzEsMTg4IEBACisvKgorICogQ29kZWwgLSBUaGUgQ29udHJvbGxlZC1EZWxh eSBBY3RpdmUgUXVldWUgTWFuYWdlbWVudCBhbGdvcml0aG0KKyAqCisgKiAgQ29weXJpZ2h0 IChDKSAyMDExLTIwMTIgS2F0aGxlZW4gTmljaG9scyA8bmljaG9sc0Bwb2xsZXJlLmNvbT4K KyAqICBDb3B5cmlnaHQgKEMpIDIwMTEtMjAxMiBWYW4gSmFjb2Jzb24gPHZhbkBwb2xsZXJl LmNvbT4KKyAqICBDb3B5cmlnaHQgKEMpIDIwMTIgTWljaGFlbCBELiBUYWh0IDxkYXZlLnRh aHRAYnVmZmVyYmxvYXQubmV0PgorICogIENvcHlyaWdodCAoQykgMjAxMiBFcmljIER1bWF6 ZXQgPGVkdW1hemV0QGdvb2dsZS5jb20+CisgKgorICogUmVkaXN0cmlidXRpb24gYW5kIHVz ZSBpbiBzb3VyY2UgYW5kIGJpbmFyeSBmb3Jtcywgd2l0aCBvciB3aXRob3V0CisgKiBtb2Rp ZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNv bmRpdGlvbnMKKyAqIGFyZSBtZXQ6CisgKiAxLiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNl IGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodAorICogICAgbm90aWNlLCB0 aGlzIGxpc3Qgb2YgY29uZGl0aW9ucywgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lciwK KyAqICAgIHdpdGhvdXQgbW9kaWZpY2F0aW9uLgorICogMi4gUmVkaXN0cmlidXRpb25zIGlu IGJpbmFyeSBmb3JtIG11c3QgcmVwcm9kdWNlIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAg IG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlz Y2xhaW1lciBpbiB0aGUKKyAqICAgIGRvY3VtZW50YXRpb24gYW5kL29yIG90aGVyIG1hdGVy aWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uCisgKiAzLiBUaGUgbmFtZXMg b2YgdGhlIGF1dGhvcnMgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBw cm9kdWN0cworICogICAgZGVyaXZlZCBmcm9tIHRoaXMgc29mdHdhcmUgd2l0aG91dCBzcGVj aWZpYyBwcmlvciB3cml0dGVuIHBlcm1pc3Npb24uCisgKgorICogQWx0ZXJuYXRpdmVseSwg cHJvdmlkZWQgdGhhdCB0aGlzIG5vdGljZSBpcyByZXRhaW5lZCBpbiBmdWxsLCB0aGlzCisg KiBzb2Z0d2FyZSBtYXkgYmUgZGlzdHJpYnV0ZWQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBH TlUgR2VuZXJhbAorICogUHVibGljIExpY2Vuc2UgKCJHUEwiKSB2ZXJzaW9uIDIsIGluIHdo aWNoIGNhc2UgdGhlIHByb3Zpc2lvbnMgb2YgdGhlCisgKiBHUEwgYXBwbHkgSU5TVEVBRCBP RiB0aG9zZSBnaXZlbiBhYm92ZS4KKyAqCisgKiBUSElTIFNPRlRXQVJFIElTIFBST1ZJREVE IEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTCisgKiAiQVMgSVMi IEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVU IE5PVAorICogTElNSVRFRCBUTywgVEhFIElNUExJRUQgV0FSUkFOVElFUyBPRiBNRVJDSEFO VEFCSUxJVFkgQU5EIEZJVE5FU1MgRk9SCisgKiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBUkUg RElTQ0xBSU1FRC4gSU4gTk8gRVZFTlQgU0hBTEwgVEhFIENPUFlSSUdIVAorICogT1dORVIg T1IgQ09OVFJJQlVUT1JTIEJFIExJQUJMRSBGT1IgQU5ZIERJUkVDVCwgSU5ESVJFQ1QsIElO Q0lERU5UQUwsCisgKiBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFN QUdFUyAoSU5DTFVESU5HLCBCVVQgTk9UCisgKiBMSU1JVEVEIFRPLCBQUk9DVVJFTUVOVCBP RiBTVUJTVElUVVRFIEdPT0RTIE9SIFNFUlZJQ0VTOyBMT1NTIE9GIFVTRSwKKyAqIERBVEEs IE9SIFBST0ZJVFM7IE9SIEJVU0lORVNTIElOVEVSUlVQVElPTikgSE9XRVZFUiBDQVVTRUQg QU5EIE9OIEFOWQorICogVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFD VCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVAorICogKElOQ0xVRElORyBORUdMSUdFTkNF IE9SIE9USEVSV0lTRSkgQVJJU0lORyBJTiBBTlkgV0FZIE9VVCBPRiBUSEUgVVNFCisgKiBP RiBUSElTIFNPRlRXQVJFLCBFVkVOIElGIEFEVklTRUQgT0YgVEhFIFBPU1NJQklMSVRZIE9G IFNVQ0gKKyAqIERBTUFHRS4KKyAqCisgKi8KKworI2luY2x1ZGUgPHN0ZGlvLmg+CisjaW5j bHVkZSA8c3RkbGliLmg+CisjaW5jbHVkZSA8dW5pc3RkLmg+CisjaW5jbHVkZSA8c3lzbG9n Lmg+CisjaW5jbHVkZSA8ZmNudGwuaD4KKyNpbmNsdWRlIDxzeXMvc29ja2V0Lmg+CisjaW5j bHVkZSA8bmV0aW5ldC9pbi5oPgorI2luY2x1ZGUgPGFycGEvaW5ldC5oPgorI2luY2x1ZGUg PHN0cmluZy5oPgorCisjaW5jbHVkZSAidXRpbHMuaCIKKyNpbmNsdWRlICJ0Y191dGlsLmgi CisKK3N0YXRpYyB2b2lkIGV4cGxhaW4odm9pZCkKK3sKKwlmcHJpbnRmKHN0ZGVyciwgIlVz YWdlOiAuLi4gbnM0X2NvZGVsIFsgbGltaXQgUEFDS0VUUyBdIFsgdGFyZ2V0IFRJTUVdXG4i KTsKKwlmcHJpbnRmKHN0ZGVyciwgIiAgICAgICAgICAgICAgICAgWyBpbnRlcnZhbCBUSU1F IF0gWyBlY24gfCBub2VjbiBdXG4iKTsKK30KKworc3RhdGljIGludCBjb2RlbF9wYXJzZV9v cHQoc3RydWN0IHFkaXNjX3V0aWwgKnF1LCBpbnQgYXJnYywgY2hhciAqKmFyZ3YsCisJCQkg ICBzdHJ1Y3Qgbmxtc2doZHIgKm4pCit7CisJdW5zaWduZWQgbGltaXQgPSAwOworCXVuc2ln bmVkIHRhcmdldCA9IDA7CisJdW5zaWduZWQgaW50ZXJ2YWwgPSAwOworCWludCBlY24gPSAt MTsKKwlzdHJ1Y3QgcnRhdHRyICp0YWlsOworCisJd2hpbGUgKGFyZ2MgPiAwKSB7CisJCWlm IChzdHJjbXAoKmFyZ3YsICJsaW1pdCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlp ZiAoZ2V0X3Vuc2lnbmVkKCZsaW1pdCwgKmFyZ3YsIDApKSB7CisJCQkJZnByaW50ZihzdGRl cnIsICJJbGxlZ2FsIFwibGltaXRcIlxuIik7CisJCQkJcmV0dXJuIC0xOworCQkJfQorCQl9 IGVsc2UgaWYgKHN0cmNtcCgqYXJndiwgInRhcmdldCIpID09IDApIHsKKwkJCU5FWFRfQVJH KCk7CisJCQlpZiAoZ2V0X3RpbWUoJnRhcmdldCwgKmFyZ3YpKSB7CisJCQkJZnByaW50Zihz dGRlcnIsICJJbGxlZ2FsIFwidGFyZ2V0XCJcbiIpOworCQkJCXJldHVybiAtMTsKKwkJCX0K KwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJpbnRlcnZhbCIpID09IDApIHsKKwkJCU5F WFRfQVJHKCk7CisJCQlpZiAoZ2V0X3RpbWUoJmludGVydmFsLCAqYXJndikpIHsKKwkJCQlm cHJpbnRmKHN0ZGVyciwgIklsbGVnYWwgXCJpbnRlcnZhbFwiXG4iKTsKKwkJCQlyZXR1cm4g LTE7CisJCQl9CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiZWNuIikgPT0gMCkgewor CQkJZWNuID0gMTsKKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJub2VjbiIpID09IDAp IHsKKwkJCWVjbiA9IDA7CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiaGVscCIpID09 IDApIHsKKwkJCWV4cGxhaW4oKTsKKwkJCXJldHVybiAtMTsKKwkJfSBlbHNlIHsKKwkJCWZw cmludGYoc3RkZXJyLCAiV2hhdCBpcyBcIiVzXCI/XG4iLCAqYXJndik7CisJCQlleHBsYWlu KCk7CisJCQlyZXR1cm4gLTE7CisJCX0KKwkJYXJnYy0tOyBhcmd2Kys7CisJfQorCisJdGFp bCA9IE5MTVNHX1RBSUwobik7CisJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9PUFRJT05TLCBO VUxMLCAwKTsKKwlpZiAobGltaXQpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfQ09ERUxf TElNSVQsICZsaW1pdCwgc2l6ZW9mKGxpbWl0KSk7CisJaWYgKGludGVydmFsKQorCQlhZGRh dHRyX2wobiwgMTAyNCwgVENBX0NPREVMX0lOVEVSVkFMLCAmaW50ZXJ2YWwsIHNpemVvZihp bnRlcnZhbCkpOworCWlmICh0YXJnZXQpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfQ09E RUxfVEFSR0VULCAmdGFyZ2V0LCBzaXplb2YodGFyZ2V0KSk7CisJaWYgKGVjbiAhPSAtMSkK KwkJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9DT0RFTF9FQ04sICZlY24sIHNpemVvZihlY24p KTsKKwl0YWlsLT5ydGFfbGVuID0gKHZvaWQgKikgTkxNU0dfVEFJTChuKSAtICh2b2lkICop IHRhaWw7CisJcmV0dXJuIDA7Cit9CisKK3N0YXRpYyBpbnQgY29kZWxfcHJpbnRfb3B0KHN0 cnVjdCBxZGlzY191dGlsICpxdSwgRklMRSAqZiwgc3RydWN0IHJ0YXR0ciAqb3B0KQorewor CXN0cnVjdCBydGF0dHIgKnRiW1RDQV9DT0RFTF9NQVggKyAxXTsKKwl1bnNpZ25lZCBsaW1p dDsKKwl1bnNpZ25lZCBpbnRlcnZhbDsKKwl1bnNpZ25lZCB0YXJnZXQ7CisJdW5zaWduZWQg ZWNuOworCVNQUklOVF9CVUYoYjEpOworCisJaWYgKG9wdCA9PSBOVUxMKQorCQlyZXR1cm4g MDsKKworCXBhcnNlX3J0YXR0cl9uZXN0ZWQodGIsIFRDQV9DT0RFTF9NQVgsIG9wdCk7CisK KwlpZiAodGJbVENBX0NPREVMX0xJTUlUXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0Ff Q09ERUxfTElNSVRdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCWxpbWl0ID0gcnRhX2dldGF0 dHJfdTMyKHRiW1RDQV9DT0RFTF9MSU1JVF0pOworCQlmcHJpbnRmKGYsICJsaW1pdCAldXAg IiwgbGltaXQpOworCX0KKwlpZiAodGJbVENBX0NPREVMX1RBUkdFVF0gJiYKKwkgICAgUlRB X1BBWUxPQUQodGJbVENBX0NPREVMX1RBUkdFVF0pID49IHNpemVvZihfX3UzMikpIHsKKwkJ dGFyZ2V0ID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9DT0RFTF9UQVJHRVRdKTsKKwkJZnBy aW50ZihmLCAidGFyZ2V0ICVzICIsIHNwcmludF90aW1lKHRhcmdldCwgYjEpKTsKKwl9CisJ aWYgKHRiW1RDQV9DT0RFTF9JTlRFUlZBTF0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENB X0NPREVMX0lOVEVSVkFMXSkgPj0gc2l6ZW9mKF9fdTMyKSkgeworCQlpbnRlcnZhbCA9IHJ0 YV9nZXRhdHRyX3UzMih0YltUQ0FfQ09ERUxfSU5URVJWQUxdKTsKKwkJZnByaW50ZihmLCAi aW50ZXJ2YWwgJXMgIiwgc3ByaW50X3RpbWUoaW50ZXJ2YWwsIGIxKSk7CisJfQorCWlmICh0 YltUQ0FfQ09ERUxfRUNOXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfQ09ERUxfRUNO XSkgPj0gc2l6ZW9mKF9fdTMyKSkgeworCQllY24gPSBydGFfZ2V0YXR0cl91MzIodGJbVENB X0NPREVMX0VDTl0pOworCQlpZiAoZWNuKQorCQkJZnByaW50ZihmLCAiZWNuICIpOworCX0K KworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGNvZGVsX3ByaW50X3hzdGF0cyhzdHJ1 Y3QgcWRpc2NfdXRpbCAqcXUsIEZJTEUgKmYsCisJCQkgICAgICBzdHJ1Y3QgcnRhdHRyICp4 c3RhdHMpCit7CisJc3RydWN0IHRjX2NvZGVsX3hzdGF0cyAqc3Q7CisJU1BSSU5UX0JVRihi MSk7CisKKwlpZiAoeHN0YXRzID09IE5VTEwpCisJCXJldHVybiAwOworCisJaWYgKFJUQV9Q QVlMT0FEKHhzdGF0cykgPCBzaXplb2YoKnN0KSkKKwkJcmV0dXJuIC0xOworCisJc3QgPSBS VEFfREFUQSh4c3RhdHMpOworCWZwcmludGYoZiwgIiAgY291bnQgJXUgbGFzdGNvdW50ICV1 IGxkZWxheSAlcyIsCisJCXN0LT5jb3VudCwgc3QtPmxhc3Rjb3VudCwgc3ByaW50X3RpbWUo c3QtPmxkZWxheSwgYjEpKTsKKwlpZiAoc3QtPmRyb3BwaW5nKQorCQlmcHJpbnRmKGYsICIg ZHJvcHBpbmciKTsKKwlpZiAoc3QtPmRyb3BfbmV4dCA8IDApCisJCWZwcmludGYoZiwgIiBk cm9wX25leHQgLSVzIiwgc3ByaW50X3RpbWUoLXN0LT5kcm9wX25leHQsIGIxKSk7CisJZWxz ZQorCQlmcHJpbnRmKGYsICIgZHJvcF9uZXh0ICVzIiwgc3ByaW50X3RpbWUoc3QtPmRyb3Bf bmV4dCwgYjEpKTsKKwlmcHJpbnRmKGYsICJcbiAgbWF4cGFja2V0ICV1IGVjbl9tYXJrICV1 IGRyb3Bfb3ZlcmxpbWl0ICV1IiwKKwkJc3QtPm1heHBhY2tldCwgc3QtPmVjbl9tYXJrLCBz dC0+ZHJvcF9vdmVybGltaXQpOworCXJldHVybiAwOworCit9CisKK3N0cnVjdCBxZGlzY191 dGlsIG5zNF9jb2RlbF9xZGlzY191dGlsID0geworCS5pZAkJPSAibnM0X2NvZGVsIiwKKwku cGFyc2VfcW9wdAk9IGNvZGVsX3BhcnNlX29wdCwKKwkucHJpbnRfcW9wdAk9IGNvZGVsX3By aW50X29wdCwKKwkucHJpbnRfeHN0YXRzCT0gY29kZWxfcHJpbnRfeHN0YXRzLAorfTsKZGlm ZiAtLWdpdCBhL3RjL3FfcGZxX2NvZGVsLmMgYi90Yy9xX3BmcV9jb2RlbC5jCm5ldyBmaWxl IG1vZGUgMTAwNjQ0CmluZGV4IDAwMDAwMDAuLjUyYzUxNjAKLS0tIC9kZXYvbnVsbAorKysg Yi90Yy9xX3BmcV9jb2RlbC5jCkBAIC0wLDAgKzEsMjMyIEBACisvKgorICogRmFpciBRdWV1 ZSBDb2RlbAorICoKKyAqICBDb3B5cmlnaHQgKEMpIDIwMTIgRXJpYyBEdW1hemV0IDxlZHVt YXpldEBnb29nbGUuY29tPgorICoKKyAqIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291 cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dAorICogbW9kaWZpY2F0aW9u LCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25z CisgKiBhcmUgbWV0OgorICogMS4gUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11 c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHQKKyAqICAgIG5vdGljZSwgdGhpcyBsaXN0 IG9mIGNvbmRpdGlvbnMsIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIsCisgKiAgICB3 aXRob3V0IG1vZGlmaWNhdGlvbi4KKyAqIDIuIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkg Zm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0CisgKiAgICBub3RpY2Us IHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIg aW4gdGhlCisgKiAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJv dmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLgorICogMy4gVGhlIG5hbWVzIG9mIHRoZSBh dXRob3JzIG1heSBub3QgYmUgdXNlZCB0byBlbmRvcnNlIG9yIHByb21vdGUgcHJvZHVjdHMK KyAqICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJp b3Igd3JpdHRlbiBwZXJtaXNzaW9uLgorICoKKyAqIEFsdGVybmF0aXZlbHksIHByb3ZpZGVk IHRoYXQgdGhpcyBub3RpY2UgaXMgcmV0YWluZWQgaW4gZnVsbCwgdGhpcworICogc29mdHdh cmUgbWF5IGJlIGRpc3RyaWJ1dGVkIHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVy YWwKKyAqIFB1YmxpYyBMaWNlbnNlICgiR1BMIikgdmVyc2lvbiAyLCBpbiB3aGljaCBjYXNl IHRoZSBwcm92aXNpb25zIG9mIHRoZQorICogR1BMIGFwcGx5IElOU1RFQUQgT0YgdGhvc2Ug Z2l2ZW4gYWJvdmUuCisgKgorICogVEhJUyBTT0ZUV0FSRSBJUyBQUk9WSURFRCBCWSBUSEUg Q09QWVJJR0hUIEhPTERFUlMgQU5EIENPTlRSSUJVVE9SUworICogIkFTIElTIiBBTkQgQU5Z IEVYUFJFU1MgT1IgSU1QTElFRCBXQVJSQU5USUVTLCBJTkNMVURJTkcsIEJVVCBOT1QKKyAq IExJTUlURUQgVE8sIFRIRSBJTVBMSUVEIFdBUlJBTlRJRVMgT0YgTUVSQ0hBTlRBQklMSVRZ IEFORCBGSVRORVNTIEZPUgorICogQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFIERJU0NMQUlN RUQuIElOIE5PIEVWRU5UIFNIQUxMIFRIRSBDT1BZUklHSFQKKyAqIE9XTkVSIE9SIENPTlRS SUJVVE9SUyBCRSBMSUFCTEUgRk9SIEFOWSBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFM LAorICogU1BFQ0lBTCwgRVhFTVBMQVJZLCBPUiBDT05TRVFVRU5USUFMIERBTUFHRVMgKElO Q0xVRElORywgQlVUIE5PVAorICogTElNSVRFRCBUTywgUFJPQ1VSRU1FTlQgT0YgU1VCU1RJ VFVURSBHT09EUyBPUiBTRVJWSUNFUzsgTE9TUyBPRiBVU0UsCisgKiBEQVRBLCBPUiBQUk9G SVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORCBPTiBB TlkKKyAqIFRIRU9SWSBPRiBMSUFCSUxJVFksIFdIRVRIRVIgSU4gQ09OVFJBQ1QsIFNUUklD VCBMSUFCSUxJVFksIE9SIFRPUlQKKyAqIChJTkNMVURJTkcgTkVHTElHRU5DRSBPUiBPVEhF UldJU0UpIEFSSVNJTkcgSU4gQU5ZIFdBWSBPVVQgT0YgVEhFIFVTRQorICogT0YgVEhJUyBT T0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNICisg KiBEQU1BR0UuCisgKgorICovCisKKyNpbmNsdWRlIDxzdGRpby5oPgorI2luY2x1ZGUgPHN0 ZGxpYi5oPgorI2luY2x1ZGUgPHVuaXN0ZC5oPgorI2luY2x1ZGUgPHN5c2xvZy5oPgorI2lu Y2x1ZGUgPGZjbnRsLmg+CisjaW5jbHVkZSA8c3lzL3NvY2tldC5oPgorI2luY2x1ZGUgPG5l dGluZXQvaW4uaD4KKyNpbmNsdWRlIDxhcnBhL2luZXQuaD4KKyNpbmNsdWRlIDxzdHJpbmcu aD4KKworI2luY2x1ZGUgInV0aWxzLmgiCisjaW5jbHVkZSAidGNfdXRpbC5oIgorCitzdGF0 aWMgdm9pZCBleHBsYWluKHZvaWQpCit7CisJZnByaW50ZihzdGRlcnIsICJVc2FnZTogLi4u IHBmcV9jb2RlbCBbIGxpbWl0IFBBQ0tFVFMgXSBbIGZsb3dzIE5VTUJFUiBdXG4iKTsKKwlm cHJpbnRmKHN0ZGVyciwgIiAgICAgICAgICAgICAgICAgICAgWyB0YXJnZXQgVElNRV0gWyBp bnRlcnZhbCBUSU1FIF1cbiIpOworCWZwcmludGYoc3RkZXJyLCAiICAgICAgICAgICAgICAg ICAgICBbIHF1YW50dW0gQllURVMgXSBbIFtub11lY24gXVxuIik7Cit9CisKK3N0YXRpYyBp bnQgZnFfY29kZWxfcGFyc2Vfb3B0KHN0cnVjdCBxZGlzY191dGlsICpxdSwgaW50IGFyZ2Ms IGNoYXIgKiphcmd2LAorCQkJICAgICAgc3RydWN0IG5sbXNnaGRyICpuKQoreworCXVuc2ln bmVkIGxpbWl0ID0gMDsKKwl1bnNpZ25lZCBmbG93cyA9IDA7CisJdW5zaWduZWQgdGFyZ2V0 ID0gMDsKKwl1bnNpZ25lZCBpbnRlcnZhbCA9IDA7CisJdW5zaWduZWQgcXVhbnR1bSA9IDA7 CisJaW50IGVjbiA9IC0xOworCXN0cnVjdCBydGF0dHIgKnRhaWw7CisKKwl3aGlsZSAoYXJn YyA+IDApIHsKKwkJaWYgKHN0cmNtcCgqYXJndiwgImxpbWl0IikgPT0gMCkgeworCQkJTkVY VF9BUkcoKTsKKwkJCWlmIChnZXRfdW5zaWduZWQoJmxpbWl0LCAqYXJndiwgMCkpIHsKKwkJ CQlmcHJpbnRmKHN0ZGVyciwgIklsbGVnYWwgXCJsaW1pdFwiXG4iKTsKKwkJCQlyZXR1cm4g LTE7CisJCQl9CisJCX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiZmxvd3MiKSA9PSAwKSB7 CisJCQlORVhUX0FSRygpOworCQkJaWYgKGdldF91bnNpZ25lZCgmZmxvd3MsICphcmd2LCAw KSkgeworCQkJCWZwcmludGYoc3RkZXJyLCAiSWxsZWdhbCBcImZsb3dzXCJcbiIpOworCQkJ CXJldHVybiAtMTsKKwkJCX0KKwkJfSBlbHNlIGlmIChzdHJjbXAoKmFyZ3YsICJxdWFudHVt IikgPT0gMCkgeworCQkJTkVYVF9BUkcoKTsKKwkJCWlmIChnZXRfdW5zaWduZWQoJnF1YW50 dW0sICphcmd2LCAwKSkgeworCQkJCWZwcmludGYoc3RkZXJyLCAiSWxsZWdhbCBcInF1YW50 dW1cIlxuIik7CisJCQkJcmV0dXJuIC0xOworCQkJfQorCQl9IGVsc2UgaWYgKHN0cmNtcCgq YXJndiwgInRhcmdldCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAoZ2V0X3Rp bWUoJnRhcmdldCwgKmFyZ3YpKSB7CisJCQkJZnByaW50ZihzdGRlcnIsICJJbGxlZ2FsIFwi dGFyZ2V0XCJcbiIpOworCQkJCXJldHVybiAtMTsKKwkJCX0KKwkJfSBlbHNlIGlmIChzdHJj bXAoKmFyZ3YsICJpbnRlcnZhbCIpID09IDApIHsKKwkJCU5FWFRfQVJHKCk7CisJCQlpZiAo Z2V0X3RpbWUoJmludGVydmFsLCAqYXJndikpIHsKKwkJCQlmcHJpbnRmKHN0ZGVyciwgIkls bGVnYWwgXCJpbnRlcnZhbFwiXG4iKTsKKwkJCQlyZXR1cm4gLTE7CisJCQl9CisJCX0gZWxz ZSBpZiAoc3RyY21wKCphcmd2LCAiZWNuIikgPT0gMCkgeworCQkJZWNuID0gMTsKKwkJfSBl bHNlIGlmIChzdHJjbXAoKmFyZ3YsICJub2VjbiIpID09IDApIHsKKwkJCWVjbiA9IDA7CisJ CX0gZWxzZSBpZiAoc3RyY21wKCphcmd2LCAiaGVscCIpID09IDApIHsKKwkJCWV4cGxhaW4o KTsKKwkJCXJldHVybiAtMTsKKwkJfSBlbHNlIHsKKwkJCWZwcmludGYoc3RkZXJyLCAiV2hh dCBpcyBcIiVzXCI/XG4iLCAqYXJndik7CisJCQlleHBsYWluKCk7CisJCQlyZXR1cm4gLTE7 CisJCX0KKwkJYXJnYy0tOyBhcmd2Kys7CisJfQorCisJdGFpbCA9IE5MTVNHX1RBSUwobik7 CisJYWRkYXR0cl9sKG4sIDEwMjQsIFRDQV9PUFRJT05TLCBOVUxMLCAwKTsKKwlpZiAobGlt aXQpCisJCWFkZGF0dHJfbChuLCAxMDI0LCBUQ0FfRlFfQ09ERUxfTElNSVQsICZsaW1pdCwg c2l6ZW9mKGxpbWl0KSk7CisJaWYgKGZsb3dzKQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENB X0ZRX0NPREVMX0ZMT1dTLCAmZmxvd3MsIHNpemVvZihmbG93cykpOworCWlmIChxdWFudHVt KQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENBX0ZRX0NPREVMX1FVQU5UVU0sICZxdWFudHVt LCBzaXplb2YocXVhbnR1bSkpOworCWlmIChpbnRlcnZhbCkKKwkJYWRkYXR0cl9sKG4sIDEw MjQsIFRDQV9GUV9DT0RFTF9JTlRFUlZBTCwgJmludGVydmFsLCBzaXplb2YoaW50ZXJ2YWwp KTsKKwlpZiAodGFyZ2V0KQorCQlhZGRhdHRyX2wobiwgMTAyNCwgVENBX0ZRX0NPREVMX1RB UkdFVCwgJnRhcmdldCwgc2l6ZW9mKHRhcmdldCkpOworCWlmIChlY24gIT0gLTEpCisJCWFk ZGF0dHJfbChuLCAxMDI0LCBUQ0FfRlFfQ09ERUxfRUNOLCAmZWNuLCBzaXplb2YoZWNuKSk7 CisJdGFpbC0+cnRhX2xlbiA9ICh2b2lkICopIE5MTVNHX1RBSUwobikgLSAodm9pZCAqKSB0 YWlsOworCXJldHVybiAwOworfQorCitzdGF0aWMgaW50IGZxX2NvZGVsX3ByaW50X29wdChz dHJ1Y3QgcWRpc2NfdXRpbCAqcXUsIEZJTEUgKmYsIHN0cnVjdCBydGF0dHIgKm9wdCkKK3sK KwlzdHJ1Y3QgcnRhdHRyICp0YltUQ0FfRlFfQ09ERUxfTUFYICsgMV07CisJdW5zaWduZWQg bGltaXQ7CisJdW5zaWduZWQgZmxvd3M7CisJdW5zaWduZWQgaW50ZXJ2YWw7CisJdW5zaWdu ZWQgdGFyZ2V0OworCXVuc2lnbmVkIGVjbjsKKwl1bnNpZ25lZCBxdWFudHVtOworCVNQUklO VF9CVUYoYjEpOworCisJaWYgKG9wdCA9PSBOVUxMKQorCQlyZXR1cm4gMDsKKworCXBhcnNl X3J0YXR0cl9uZXN0ZWQodGIsIFRDQV9GUV9DT0RFTF9NQVgsIG9wdCk7CisKKwlpZiAodGJb VENBX0ZRX0NPREVMX0xJTUlUXSAmJgorCSAgICBSVEFfUEFZTE9BRCh0YltUQ0FfRlFfQ09E RUxfTElNSVRdKSA+PSBzaXplb2YoX191MzIpKSB7CisJCWxpbWl0ID0gcnRhX2dldGF0dHJf dTMyKHRiW1RDQV9GUV9DT0RFTF9MSU1JVF0pOworCQlmcHJpbnRmKGYsICJsaW1pdCAldXAg IiwgbGltaXQpOworCX0KKwlpZiAodGJbVENBX0ZRX0NPREVMX0ZMT1dTXSAmJgorCSAgICBS VEFfUEFZTE9BRCh0YltUQ0FfRlFfQ09ERUxfRkxPV1NdKSA+PSBzaXplb2YoX191MzIpKSB7 CisJCWZsb3dzID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9GUV9DT0RFTF9GTE9XU10pOwor CQlmcHJpbnRmKGYsICJmbG93cyAldSAiLCBmbG93cyk7CisJfQorCWlmICh0YltUQ0FfRlFf Q09ERUxfUVVBTlRVTV0gJiYKKwkgICAgUlRBX1BBWUxPQUQodGJbVENBX0ZRX0NPREVMX1FV QU5UVU1dKSA+PSBzaXplb2YoX191MzIpKSB7CisJCXF1YW50dW0gPSBydGFfZ2V0YXR0cl91 MzIodGJbVENBX0ZRX0NPREVMX1FVQU5UVU1dKTsKKwkJZnByaW50ZihmLCAicXVhbnR1bSAl dSAiLCBxdWFudHVtKTsKKwl9CisJaWYgKHRiW1RDQV9GUV9DT0RFTF9UQVJHRVRdICYmCisJ ICAgIFJUQV9QQVlMT0FEKHRiW1RDQV9GUV9DT0RFTF9UQVJHRVRdKSA+PSBzaXplb2YoX191 MzIpKSB7CisJCXRhcmdldCA9IHJ0YV9nZXRhdHRyX3UzMih0YltUQ0FfRlFfQ09ERUxfVEFS R0VUXSk7CisJCWZwcmludGYoZiwgInRhcmdldCAlcyAiLCBzcHJpbnRfdGltZSh0YXJnZXQs IGIxKSk7CisJfQorCWlmICh0YltUQ0FfRlFfQ09ERUxfSU5URVJWQUxdICYmCisJICAgIFJU QV9QQVlMT0FEKHRiW1RDQV9GUV9DT0RFTF9JTlRFUlZBTF0pID49IHNpemVvZihfX3UzMikp IHsKKwkJaW50ZXJ2YWwgPSBydGFfZ2V0YXR0cl91MzIodGJbVENBX0ZRX0NPREVMX0lOVEVS VkFMXSk7CisJCWZwcmludGYoZiwgImludGVydmFsICVzICIsIHNwcmludF90aW1lKGludGVy dmFsLCBiMSkpOworCX0KKwlpZiAodGJbVENBX0ZRX0NPREVMX0VDTl0gJiYKKwkgICAgUlRB X1BBWUxPQUQodGJbVENBX0ZRX0NPREVMX0VDTl0pID49IHNpemVvZihfX3UzMikpIHsKKwkJ ZWNuID0gcnRhX2dldGF0dHJfdTMyKHRiW1RDQV9GUV9DT0RFTF9FQ05dKTsKKwkJaWYgKGVj bikKKwkJCWZwcmludGYoZiwgImVjbiAiKTsKKwl9CisKKwlyZXR1cm4gMDsKK30KKworc3Rh dGljIGludCBmcV9jb2RlbF9wcmludF94c3RhdHMoc3RydWN0IHFkaXNjX3V0aWwgKnF1LCBG SUxFICpmLAorCQkJCSBzdHJ1Y3QgcnRhdHRyICp4c3RhdHMpCit7CisJc3RydWN0IHRjX2Zx X2NvZGVsX3hzdGF0cyAqc3Q7CisJU1BSSU5UX0JVRihiMSk7CisKKwlpZiAoeHN0YXRzID09 IE5VTEwpCisJCXJldHVybiAwOworCisJaWYgKFJUQV9QQVlMT0FEKHhzdGF0cykgPCBzaXpl b2YoKnN0KSkKKwkJcmV0dXJuIC0xOworCisJc3QgPSBSVEFfREFUQSh4c3RhdHMpOworCWlm IChzdC0+dHlwZSA9PSBUQ0FfRlFfQ09ERUxfWFNUQVRTX1FESVNDKSB7CisJCWZwcmludGYo ZiwgIiAgbWF4cGFja2V0ICV1IGRyb3Bfb3ZlcmxpbWl0ICV1IG5ld19mbG93X2NvdW50ICV1 IGVjbl9tYXJrICV1IiwKKwkJCXN0LT5xZGlzY19zdGF0cy5tYXhwYWNrZXQsCisJCQlzdC0+ cWRpc2Nfc3RhdHMuZHJvcF9vdmVybGltaXQsCisJCQlzdC0+cWRpc2Nfc3RhdHMubmV3X2Zs b3dfY291bnQsCisJCQlzdC0+cWRpc2Nfc3RhdHMuZWNuX21hcmspOworCQlmcHJpbnRmKGYs ICJcbiAgbmV3X2Zsb3dzX2xlbiAldSBvbGRfZmxvd3NfbGVuICV1IiwKKwkJCXN0LT5xZGlz Y19zdGF0cy5uZXdfZmxvd3NfbGVuLAorCQkJc3QtPnFkaXNjX3N0YXRzLm9sZF9mbG93c19s ZW4pOworCX0KKwlpZiAoc3QtPnR5cGUgPT0gVENBX0ZRX0NPREVMX1hTVEFUU19DTEFTUykg eworCQlmcHJpbnRmKGYsICIgIGRlZmljaXQgJWQgY291bnQgJXUgbGFzdGNvdW50ICV1IGxk ZWxheSAlcyIsCisJCQlzdC0+Y2xhc3Nfc3RhdHMuZGVmaWNpdCwKKwkJCXN0LT5jbGFzc19z dGF0cy5jb3VudCwKKwkJCXN0LT5jbGFzc19zdGF0cy5sYXN0Y291bnQsCisJCQlzcHJpbnRf dGltZShzdC0+Y2xhc3Nfc3RhdHMubGRlbGF5LCBiMSkpOworCQlpZiAoc3QtPmNsYXNzX3N0 YXRzLmRyb3BwaW5nKSB7CisJCQlmcHJpbnRmKGYsICIgZHJvcHBpbmciKTsKKwkJCWlmIChz dC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0IDwgMCkKKwkJCQlmcHJpbnRmKGYsICIgZHJvcF9u ZXh0IC0lcyIsCisJCQkJCXNwcmludF90aW1lKC1zdC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0 LCBiMSkpOworCQkJZWxzZQorCQkJCWZwcmludGYoZiwgIiBkcm9wX25leHQgJXMiLAorCQkJ CQlzcHJpbnRfdGltZShzdC0+Y2xhc3Nfc3RhdHMuZHJvcF9uZXh0LCBiMSkpOworCQl9CisJ fQorCXJldHVybiAwOworCit9CisKK3N0cnVjdCBxZGlzY191dGlsIHBmcV9jb2RlbF9xZGlz Y191dGlsID0geworCS5pZAkJPSAicGZxX2NvZGVsIiwKKwkucGFyc2VfcW9wdAk9IGZxX2Nv ZGVsX3BhcnNlX29wdCwKKwkucHJpbnRfcW9wdAk9IGZxX2NvZGVsX3ByaW50X29wdCwKKwku cHJpbnRfeHN0YXRzCT0gZnFfY29kZWxfcHJpbnRfeHN0YXRzLAorfTsK --------------070100020904050000080609 Content-Type: text/plain; charset=windows-1252; name="141-cake-disable-sfq-codel.patch" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="141-cake-disable-sfq-codel.patch" ZGlmZiAtLWdpdCBhL3RjL01ha2VmaWxlIGIvdGMvTWFrZWZpbGUKaW5kZXggZTUwM2M4YS4u M2RjZTUzMyAxMDA2NDQKLS0tIGEvdGMvTWFrZWZpbGUKKysrIGIvdGMvTWFrZWZpbGUKQEAg LTYxLDcgKzYxLDcgQEAgVENNT0RVTEVTICs9IHFfY29kZWwubwogVENNT0RVTEVTICs9IHFf ZnFfY29kZWwubwogVENNT0RVTEVTICs9IHFfbmZxX2NvZGVsLm8KIFRDTU9EVUxFUyArPSBx X2VmcV9jb2RlbC5vCi1UQ01PRFVMRVMgKz0gcV9zZnFfY29kZWwubworI1RDTU9EVUxFUyAr PSBxX3NmcV9jb2RlbC5vCiBUQ01PRFVMRVMgKz0gcV9wZnFfY29kZWwubwogVENNT0RVTEVT ICs9IHFfbnMyX2NvZGVsLm8KIFRDTU9EVUxFUyArPSBxX25zNF9jb2RlbC5vCg== --------------070100020904050000080609-- --------------ms070009000207070405030806 Content-Type: application/pkcs7-signature; name="smime.p7s" Content-Transfer-Encoding: base64 Content-Disposition: attachment; filename="smime.p7s" Content-Description: S/MIME Cryptographic Signature MIAGCSqGSIb3DQEHAqCAMIACAQExCzAJBgUrDgMCGgUAMIAGCSqGSIb3DQEHAQAAoIINnDCC BjQwggQcoAMCAQICAR4wDQYJKoZIhvcNAQEFBQAwfTELMAkGA1UEBhMCSUwxFjAUBgNVBAoT DVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENlcnRpZmljYXRlIFNp Z25pbmcxKTAnBgNVBAMTIFN0YXJ0Q29tIENlcnRpZmljYXRpb24gQXV0aG9yaXR5MB4XDTA3 MTAyNDIxMDE1NVoXDTE3MTAyNDIxMDE1NVowgYwxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1T dGFydENvbSBMdGQuMSswKQYDVQQLEyJTZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWdu aW5nMTgwNgYDVQQDEy9TdGFydENvbSBDbGFzcyAxIFByaW1hcnkgSW50ZXJtZWRpYXRlIENs aWVudCBDQTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAMcJg8zOLdgasSmkLhOr lr6KMoOMpohBllVHrdRvEg/q6r8jR+EK75xCGhR8ToREoqe7zM9/UnC6TS2y9UKTpT1v7RSM zR0t6ndl0TWBuUr/UXBhPk+Kmy7bI4yW4urC+y7P3/1/X7U8ocb8VpH/Clt+4iq7nirMcNh6 qJR+xjOhV+VHzQMALuGYn5KZmc1NbJQYclsGkDxDz2UbFqE2+6vIZoL+jb9x4Pa5gNf1TwSD kOkikZB1xtB4ZqtXThaABSONdfmv/Z1pua3FYxnCFmdr/+N2JLKutIxMYqQOJebr/f/h5t95 m4JgrM3Y/w7YX9d7YAL9jvN4SydHsU6n65cCAwEAAaOCAa0wggGpMA8GA1UdEwEB/wQFMAMB Af8wDgYDVR0PAQH/BAQDAgEGMB0GA1UdDgQWBBRTcu2SnODaywFcfH6WNU7y1LhRgjAfBgNV HSMEGDAWgBROC+8apEBbpRdphzDKNGhD0EGu8jBmBggrBgEFBQcBAQRaMFgwJwYIKwYBBQUH MAGGG2h0dHA6Ly9vY3NwLnN0YXJ0c3NsLmNvbS9jYTAtBggrBgEFBQcwAoYhaHR0cDovL3d3 dy5zdGFydHNzbC5jb20vc2ZzY2EuY3J0MFsGA1UdHwRUMFIwJ6AloCOGIWh0dHA6Ly93d3cu c3RhcnRzc2wuY29tL3Nmc2NhLmNybDAnoCWgI4YhaHR0cDovL2NybC5zdGFydHNzbC5jb20v c2ZzY2EuY3JsMIGABgNVHSAEeTB3MHUGCysGAQQBgbU3AQIBMGYwLgYIKwYBBQUHAgEWImh0 dHA6Ly93d3cuc3RhcnRzc2wuY29tL3BvbGljeS5wZGYwNAYIKwYBBQUHAgEWKGh0dHA6Ly93 d3cuc3RhcnRzc2wuY29tL2ludGVybWVkaWF0ZS5wZGYwDQYJKoZIhvcNAQEFBQADggIBAAqD CH14qywGXLhjjF6uHLkjd02hcdh9hrw+VUsv+q1eeQWB21jWj3kJ96AUlPCoEGZ/ynJNScWy 6QMVQjbbMXltUfO4n4bGGdKo3awPWp61tjAFgraLJgDk+DsSvUD6EowjMTNx25GQgyYJ5RPI zKKR9tQW8gGK+2+RHxkUCTbYFnL6kl8Ch507rUdPPipJ9CgJFws3kDS3gOS5WFMxcjO5DwKf KSETEPrHh7p5shuuNktvsv6hxHTLhiMKX893gxdT3XLS9OKmCv87vkINQcNEcIIoFWbP9HOR z9v3vQwR4e3ksLc2JZOAFK+ssS5XMEoznzpihEP0PLc4dCBYjbvSD7kxgDwZ+Aj8Q9PkbvE9 sIPP7ON0fz095HdThKjiVJe6vofq+n6b1NBc8XdrQvBmunwxD5nvtTW4vtN6VY7mUCmxsCie uoBJ9OlqmsVWQvifIYf40dJPZkk9YgGTzWLpXDSfLSplbY2LL9C9U0ptvjcDjefLTvqSFc7t w1sEhF0n/qpA2r0GpvkLRDmcSwVyPvmjFBGqUp/pNy8ZuPGQmHwFi2/14+xeSUDG2bwnsYJQ G2EdJCB6luQ57GEnTA/yKZSTKI8dDQa8Sd3zfXb19mOgSF0bBdXbuKhEpuP9wirslFe6fQ1t 5j5R0xi72MZ8ikMu1RQZKCyDbMwazlHiMIIHYDCCBkigAwIBAgIDCm0/MA0GCSqGSIb3DQEB BQUAMIGMMQswCQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMi U2VjdXJlIERpZ2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20g Q2xhc3MgMSBQcmltYXJ5IEludGVybWVkaWF0ZSBDbGllbnQgQ0EwHhcNMTQwNzAzMTE1NjM5 WhcNMTUwNzA0MTc0MjQ1WjBxMRkwFwYDVQQNExA2dVNGb1pMU1d2dGgyd2tNMSYwJAYDVQQD DB1rZXZpbkBkYXJieXNoaXJlLWJyeWFudC5tZS51azEsMCoGCSqGSIb3DQEJARYda2V2aW5A ZGFyYnlzaGlyZS1icnlhbnQubWUudWswggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIKAoIC AQDqCZMbkat9lukbtY+VQ4HBVkcHtcUU1sWZlg7foJ6XEQXCb3ArlyY7V+AldkNY6qRlrlVt YZmSFtDsors5e3Z1VWlEYBZEbnR57t5jmfGYmaaDzc8YsWr5gsUTa+MV/MNHpuAlf9GwgQCQ e7SC7kEzkQZApfB8/zG/a5JxgVXD9c3vK40p3OW27ZqVN9rie5SoLi1KEfQbA//VyPPeDpus oDwYGq6AA82lLFvgBxi1JPlS7M9zToUQCXpvDexQPiok1iqhwYBwX3qmSInlVWnudgaJ25iL m8/9bG5nCIo+dOEZP/bOCEsMzV8n9RaCNu8ilpjMXsHbkgrlvng81CTUFlYWhdMg58CM7N9y gSBjCKuHmJwQbIdsCmuKEOFVLZR8OZzoue6e/HAQlunWEfrr/H4+UYp8yTNLybqfcyZ3k7Sg i207jicY5dVKKFFY8eSB8Ps2svxj6BgrNPZMGzW36zRwaK1MpOZxHItCcuyXo+WkI3/61BZ5 mg34ejrgalQ04887n+4u3XPKnM/IwXfivlOD+n8bOOAGR8iZVlLTVmvypMdX3+wL/yB/w8g1 Ojj9Bk5/ksZb9Eh+3q1cVOOuXa/hcCLLqetNFzlxHjbVXzBKwO9pOs50DVxtv070KalD3iqz 8hCwnDt7odkGHwXyZAErmUSjc6tqVMivid/1swIDAQABo4IC4zCCAt8wCQYDVR0TBAIwADAL BgNVHQ8EBAMCBLAwHQYDVR0lBBYwFAYIKwYBBQUHAwIGCCsGAQUFBwMEMB0GA1UdDgQWBBSg QyTrQHiayWJq77xyyu7kpPmJ2jAfBgNVHSMEGDAWgBRTcu2SnODaywFcfH6WNU7y1LhRgjAo BgNVHREEITAfgR1rZXZpbkBkYXJieXNoaXJlLWJyeWFudC5tZS51azCCAUwGA1UdIASCAUMw ggE/MIIBOwYLKwYBBAGBtTcBAgMwggEqMC4GCCsGAQUFBwIBFiJodHRwOi8vd3d3LnN0YXJ0 c3NsLmNvbS9wb2xpY3kucGRmMIH3BggrBgEFBQcCAjCB6jAnFiBTdGFydENvbSBDZXJ0aWZp Y2F0aW9uIEF1dGhvcml0eTADAgEBGoG+VGhpcyBjZXJ0aWZpY2F0ZSB3YXMgaXNzdWVkIGFj Y29yZGluZyB0byB0aGUgQ2xhc3MgMSBWYWxpZGF0aW9uIHJlcXVpcmVtZW50cyBvZiB0aGUg U3RhcnRDb20gQ0EgcG9saWN5LCByZWxpYW5jZSBvbmx5IGZvciB0aGUgaW50ZW5kZWQgcHVy cG9zZSBpbiBjb21wbGlhbmNlIG9mIHRoZSByZWx5aW5nIHBhcnR5IG9ibGlnYXRpb25zLjA2 BgNVHR8ELzAtMCugKaAnhiVodHRwOi8vY3JsLnN0YXJ0c3NsLmNvbS9jcnR1MS1jcmwuY3Js MIGOBggrBgEFBQcBAQSBgTB/MDkGCCsGAQUFBzABhi1odHRwOi8vb2NzcC5zdGFydHNzbC5j b20vc3ViL2NsYXNzMS9jbGllbnQvY2EwQgYIKwYBBQUHMAKGNmh0dHA6Ly9haWEuc3RhcnRz c2wuY29tL2NlcnRzL3N1Yi5jbGFzczEuY2xpZW50LmNhLmNydDAjBgNVHRIEHDAahhhodHRw Oi8vd3d3LnN0YXJ0c3NsLmNvbS8wDQYJKoZIhvcNAQEFBQADggEBAChYSPOI6HHjtB2zQSGb 7vqo2f/QAum648uoNCFXf/ZmpU42ca6hq/JqsugqbnCY72hNTpCh3JZwTTaBWBvj1vzjjMra pLixIvceaAqMj6vd+L43APuMMmTH9tUUNS1ksXdA2r6STVIbr4p2sbVV3WktLGFnNAy5uXbr mLHay5w6jcmSfTAh1aA49sSvp+8CB6q6uDef2j9X8OE9Ajr5l0mcnGdVOkLZU6Zq20G8jb3p sdqoO9MU5UbKfZCN4/ibr+/0Pj3VZIE3jCEW2DwguN6DIDAYVc6b7RFGf3cWadJrSa887Sc/ 9wzXymTKAyBvfgRQeWcZ+5w4RlOI/TmpNfwxggTdMIIE2QIBATCBlDCBjDELMAkGA1UEBhMC SUwxFjAUBgNVBAoTDVN0YXJ0Q29tIEx0ZC4xKzApBgNVBAsTIlNlY3VyZSBEaWdpdGFsIENl cnRpZmljYXRlIFNpZ25pbmcxODA2BgNVBAMTL1N0YXJ0Q29tIENsYXNzIDEgUHJpbWFyeSBJ bnRlcm1lZGlhdGUgQ2xpZW50IENBAgMKbT8wCQYFKw4DAhoFAKCCAh0wGAYJKoZIhvcNAQkD MQsGCSqGSIb3DQEHATAcBgkqhkiG9w0BCQUxDxcNMTUwNTAxMDk1MDI1WjAjBgkqhkiG9w0B CQQxFgQU+YGydkmU93xf2cHvH4SVyLgxXQEwbAYJKoZIhvcNAQkPMV8wXTALBglghkgBZQME ASowCwYJYIZIAWUDBAECMAoGCCqGSIb3DQMHMA4GCCqGSIb3DQMCAgIAgDANBggqhkiG9w0D AgIBQDAHBgUrDgMCBzANBggqhkiG9w0DAgIBKDCBpQYJKwYBBAGCNxAEMYGXMIGUMIGMMQsw CQYDVQQGEwJJTDEWMBQGA1UEChMNU3RhcnRDb20gTHRkLjErMCkGA1UECxMiU2VjdXJlIERp Z2l0YWwgQ2VydGlmaWNhdGUgU2lnbmluZzE4MDYGA1UEAxMvU3RhcnRDb20gQ2xhc3MgMSBQ cmltYXJ5IEludGVybWVkaWF0ZSBDbGllbnQgQ0ECAwptPzCBpwYLKoZIhvcNAQkQAgsxgZeg gZQwgYwxCzAJBgNVBAYTAklMMRYwFAYDVQQKEw1TdGFydENvbSBMdGQuMSswKQYDVQQLEyJT ZWN1cmUgRGlnaXRhbCBDZXJ0aWZpY2F0ZSBTaWduaW5nMTgwNgYDVQQDEy9TdGFydENvbSBD bGFzcyAxIFByaW1hcnkgSW50ZXJtZWRpYXRlIENsaWVudCBDQQIDCm0/MA0GCSqGSIb3DQEB AQUABIICAGc/6wCOrJA4SLw+zlzL+Cl/4YMfH6woBoEeTDf4TIyOT5+UenPfoKE0dEfa2286 MQkRPXfrW9bq+jrVKU0ji1NhkafLSFQ03vU+VaoW9bPIMgnJEWHSoo6bh9x2sB4noRVUQHKV 8lrdFvZ4dbGpH4o5gvcQDE4U6SKL0ci1UIhDr8Zbo5c7Lv6GXHZGJeq40K/13aDAbT3y8P7p V13XBCJh+7UCDi2SYMgQzYzvCU8L8X0+BSClhSdGWUx5PnXFYs6IMX0PeHva9aDtkJLRJ0Oi zg1MVZLxsfXrwGttszFlJvQFCXULaBpSG1CYw5ydO5gBPGBaaXaD2/IwaImQUCA12z5BOPpL 5vV8sdIl9icjnyWx6t0yQNzTxNKzUYu+yxbaoSM+g5p6Tq7GUGygBtGchU+OIYdDkWdtP/AF 3+oaxgqPyiNhqHL+Y30Neao1prWMljGMdRk+VPe/W6V8I9IE1ZQ7/teKyQFwuYOcPWwXntO2 sr4UaXssDqzZFmfFiSH1UWB/krSzMexzEPN+Fak3JRTQslS6xcT/QoxH3KrU1vCxS2ktSDBT KejIaZPRXxxdkb1TmHrTlWri6arFgoBnGH3+phx/flPyLY9Y0lgGf8E8h6DTkciEA4C763sy Rgf2ehMhA8awhfOxp29wvtld2V7+l4g/qjyPuDYJwTwDAAAAAAAA --------------ms070009000207070405030806--