From owner-freebsd-ipfw@freebsd.org Wed Jan 13 19:55:48 2016 Return-Path: Delivered-To: freebsd-ipfw@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 3C7E9A81C23; Wed, 13 Jan 2016 19:55:48 +0000 (UTC) (envelope-from fodillemlinkarim@gmail.com) Received: from mail-qg0-x235.google.com (mail-qg0-x235.google.com [IPv6:2607:f8b0:400d:c04::235]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id EEFD71822; Wed, 13 Jan 2016 19:55:47 +0000 (UTC) (envelope-from fodillemlinkarim@gmail.com) Received: by mail-qg0-x235.google.com with SMTP id b35so333313488qge.0; Wed, 13 Jan 2016 11:55:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=from:subject:to:message-id:date:user-agent:mime-version :content-type:content-transfer-encoding; bh=qPvXWG8esyUaJCoz31MnAjocoz76NoB0VSRaEsTG01s=; b=nZqkraSXxFoyxXuXs1z3roVSRqyLVQAE+LN3e7k6xXaw1CuDYeW2UrMo5/CfY8ERvy K5jB1C7uzLFSYey7WsAI4QtsI9c8m5++5pnwufNtopHr7CtjYUIZgMx1XNp9A0lrUv6b KRbJg1v59PQuxe2WV4PvhLzD9/pgetEgAlh2Q59dVmXo2tsQE/S84/MI73X2RH7z6lTH s7DPue4VsiyMo5Z8iBzuVlpGPOutOCMAO+HNiZO5J97ETwx0GnJPdCgWang2Nukepng1 8plirT3wg5EpPFF4NnpKliu9F49KrLGbTXE9dkw1jwEj2mCENbmpfKVZ7R34iV80hYxy tONQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:subject:to:message-id:date:user-agent :mime-version:content-type:content-transfer-encoding; bh=qPvXWG8esyUaJCoz31MnAjocoz76NoB0VSRaEsTG01s=; b=BBmWSEz7WVSlDcGE4aVQBr+zoI2U5F0oJW60ogI1yYWKUcKEVS1sItz8myFpS2MU8i +C6vBh3DP9CLbLLXwTIMnw3cZu/ATfQDcaEy3vzyQHDFtZVvn6zQ09baqh7YM+ethcNS p/6k913jXWv54jrcdHLCw0KQSPOFTRFc5fcDQo0/eXbAlsuov2GKwRA0msNffN7ECOTN BeM/mXJtq8Fu7lCYWBr0veXfoufMMGGeC10rlEpZp7B+BmrXnjkdnZnY9of1Xqz9vgHO oAQplnxERQJKYv03WqNhpS7vxj9qgxFuw/IVtSej76F9Ocyga0Bftmhoik0hZiTisv7W KnWw== X-Gm-Message-State: ALoCoQmOawuewJVKDxhXAaKcQ4zS3l4iSVQwOudqnqZatKPsQPWIL3sQoJpZhx2NsjySqEK1oizalDl0rAX9ut1uW66eCzv68A== X-Received: by 10.140.172.84 with SMTP id s81mr88848qhs.40.1452714947101; Wed, 13 Jan 2016 11:55:47 -0800 (PST) Received: from [10.10.1.47] ([192.252.130.194]) by smtp.googlemail.com with ESMTPSA id v187sm1092968qhb.27.2016.01.13.11.55.46 (version=TLSv1/SSLv3 cipher=OTHER); Wed, 13 Jan 2016 11:55:46 -0800 (PST) From: Karim Fodil-Lemelin Subject: ipfw NAT, igb and hardware checksums To: freebsd-ipfw@freebsd.org, freebsd-net Message-ID: <5696ABBE.4050709@gmail.com> Date: Wed, 13 Jan 2016 14:55:42 -0500 User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:38.0) Gecko/20100101 Thunderbird/38.5.1 MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8; format=flowed Content-Transfer-Encoding: 7bit X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2016 19:55:48 -0000 Hi, I've hit a very interesting problem with ipfw-nat and local TCP traffic that has enough TCP options to hit a special case in m_megapullup(). Here is the story: I am using the following NIC: igb0@pci0:4:0:0: class=0x020000 card=0x00008086 chip=0x150e8086 rev=0x01 hdr=0x00 And when I do ipfw nat to locally emitted packets I see packets not being processed in the igb driver for HW checksum. Now a quick search for m_pullup in the igb driver code will show that our igb driver expects a contiguous ethernet + ip header in igb_tx_ctx_setup(). Now the friendly m_megapullup() in alias.c doesn't reserve any space before the ip header for the ethernet header after its call to m_getcl like tcp_output.c (see m->m_data += max_linkhdr in tcp_output.c). So the call to M_PREPEND() in ether_output() is forced to prepend a new mbuf for the ethernet header, leading to a non contiguous ether + ip. This in turn leads to a failure to properly read the IP protocol in the igb driver and apply the proper HW checksum function. Particularly this call in igb_tcp_ctx_setup(): ip = (struct ip *)(mp->m_data + ehdrlen); To reproduce the issue I simply create a NAT rule for an igb interface and initiate a TCP connection locally going out through that interface (it should go through NAT obviously) something like: ipfw nat 1 config igb0 reset ipfw add 10 nat 1 via igb0 Although you need to make sure you fill enough of the SYN packet to trigger the allocation of new memory in m_megapullup. You can do this by using enough TCP options so its filling up almost all of the 256 mbuf or make RESERVE something like 300 bytes in alias.c. The fix I propose is very simple and faster for all drivers, including the ones that do perform a check for ether + ip to be contiguous upon accessing the IP header. If the leading space is available it doesn't allocate any extra space (as it should for most cases) but if for some reason the mbuf used doesn't have 100 bytes (RESERVE in megapullup) of free space it will reserve some at the front too. If the leading space isn't necessary then it won't cause any harm. -Subproject commit cfe39807fe9b1a23c13f73aabde302046736fa1c +Subproject commit cfe39807fe9b1a23c13f73aabde302046736fa1c-dirty diff --git a/freebsd/sys/netinet/libalias/alias.c b/freebsd/sys/netinet/libalias/alias.c index 876e958..dc424a6 100644 --- a/freebsd/sys/netinet/libalias/alias.c +++ b/freebsd/sys/netinet/libalias/alias.c @@ -1757,7 +1757,8 @@ m_megapullup(struct mbuf *m, int len) { * writable and has some extra space for expansion. * XXX: Constant 100bytes is completely empirical. */ #define RESERVE 100 - if (m->m_next == NULL && M_WRITABLE(m) && M_TRAILINGSPACE(m) >= RESERVE) + if (m->m_next == NULL && M_WRITABLE(m) && + M_TRAILINGSPACE(m) >= RESERVE && M_LEADINGSPACE(m) >= max_linkhdr) return (m); if (len <= MCLBYTES - RESERVE) { @@ -1779,6 +1780,7 @@ m_megapullup(struct mbuf *m, int len) { goto bad; m_move_pkthdr(mcl, m); + mcl->m_data += max_linkhdr; m_copydata(m, 0, len, mtod(mcl, caddr_t)); mcl->m_len = mcl->m_pkthdr.len = len; m_freem(m); It would be nice if some FBSD comitter could review and hopefully add this patch to FBSD. Thank you, Karim. From owner-freebsd-ipfw@freebsd.org Wed Jan 13 20:23:04 2016 Return-Path: Delivered-To: freebsd-ipfw@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 2272BA81759; Wed, 13 Jan 2016 20:23:04 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: from mail-ig0-x231.google.com (mail-ig0-x231.google.com [IPv6:2607:f8b0:4001:c05::231]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (Client CN "smtp.gmail.com", Issuer "Google Internet Authority G2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id E4BD21619; Wed, 13 Jan 2016 20:23:03 +0000 (UTC) (envelope-from adrian.chadd@gmail.com) Received: by mail-ig0-x231.google.com with SMTP id z14so160032336igp.1; Wed, 13 Jan 2016 12:23:03 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=vTf4yu8hLzQst0drsSbRfIo2LRx2XhELZkmJYlvufPs=; b=ueHgo7AM8FiO53G/64yHRRv8b5m9Mj4XG5YrdO3A1xSeTY2tR3rjE0+sOnkOtLlJt1 dVkg4mVscjKN4LCWaMyyrRSpt/CVNs52LCbyIpbBTk62NpBljGZOyOehqM3jSUADMNgu CcxqzAL0x4UyjHx4MCUkhr4DtKhWyQR51waYIW2tanSGT4MdqFDhvxCJ7fqQI9II/+rD d8wlstBXclFRUoHWKGnc3MgwNNyF8i3gon12bpPM4V3p2pFZ+C+ARxSosaw/P3T0BZE2 t1j25+S5hGl1CiIXQ9okx231b5Wdnai47QOdtb2Fvcda+kxWEQam8UGueG5HH8gmXRWD j1og== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:mime-version:in-reply-to:references:date :message-id:subject:from:to:cc:content-type; bh=vTf4yu8hLzQst0drsSbRfIo2LRx2XhELZkmJYlvufPs=; b=P2HRa4abUz7SAcOBJYqgBUc3WoBTUxh6HEJF+7ma+9RVYEbAdR6OWsrzhHk3y2N3SF OLlfWXcYaheX4bGR8MTBJClmNKLJ4HDb9uObLprSGN8BtjE/Pg86J97ns7RIHJ22mgSI 0G5HIWP8rKzBaqL0fDGKUwgsYH2wNUAbwuNXQmNG1OjI0fuvNDpza9hWA47VBIMz2riY z/DRLQZBzhB8HCpf/E6QuJn8WphbiAxditi0yNYjn4o201K7ivMFc0oJILkpo4hjAt6X qeFsK6Metd5OsuKhogvbiAErMYtqTk5Nb0ILBaeHzKKN/o6jmfu+6R1yj5TeghukJj3p dRww== X-Gm-Message-State: ALoCoQmVQl/sFGU5iiCR9JZTPhZqmcDBbziAMuK+0Kd7t+gQsylsu28ULluWeIyN4SFLL5QTPt+cHmU5k0dAQLaEONXqKMi0Vw== MIME-Version: 1.0 X-Received: by 10.50.122.100 with SMTP id lr4mr14271562igb.37.1452716583368; Wed, 13 Jan 2016 12:23:03 -0800 (PST) Received: by 10.36.121.202 with HTTP; Wed, 13 Jan 2016 12:23:03 -0800 (PST) In-Reply-To: <5696ABBE.4050709@gmail.com> References: <5696ABBE.4050709@gmail.com> Date: Wed, 13 Jan 2016 12:23:03 -0800 Message-ID: Subject: Re: ipfw NAT, igb and hardware checksums From: Adrian Chadd To: Karim Fodil-Lemelin Cc: freebsd-ipfw@freebsd.org, freebsd-net Content-Type: text/plain; charset=UTF-8 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2016 20:23:04 -0000 This looks mostly sensible. hm! -a On 13 January 2016 at 11:55, Karim Fodil-Lemelin wrote: > Hi, > > I've hit a very interesting problem with ipfw-nat and local TCP traffic that > has enough TCP options to hit a special case in m_megapullup(). Here is the > story: > > I am using the following NIC: > > igb0@pci0:4:0:0: class=0x020000 card=0x00008086 chip=0x150e8086 > rev=0x01 hdr=0x00 > > And when I do ipfw nat to locally emitted packets I see packets not being > processed in the igb driver for HW checksum. Now a quick search for m_pullup > in the igb driver code will show that our igb driver expects a contiguous > ethernet + ip header in igb_tx_ctx_setup(). Now the friendly m_megapullup() > in alias.c doesn't reserve any space before the ip header for the ethernet > header after its call to m_getcl like tcp_output.c (see m->m_data += > max_linkhdr in tcp_output.c). > > So the call to M_PREPEND() in ether_output() is forced to prepend a new mbuf > for the ethernet header, leading to a non contiguous ether + ip. This in > turn leads to a failure to properly read the IP protocol in the igb driver > and apply the proper HW checksum function. Particularly this call in > igb_tcp_ctx_setup(): ip = (struct ip *)(mp->m_data + ehdrlen); > > To reproduce the issue I simply create a NAT rule for an igb interface and > initiate a TCP connection locally going out through that interface (it > should go through NAT obviously) something like: > > ipfw nat 1 config igb0 reset > ipfw add 10 nat 1 via igb0 > > Although you need to make sure you fill enough of the SYN packet to trigger > the allocation of new memory in m_megapullup. You can do this by using > enough TCP options so its filling up almost all of the 256 mbuf or make > RESERVE something like 300 bytes in alias.c. > > The fix I propose is very simple and faster for all drivers, including the > ones that do perform a check for ether + ip to be contiguous upon accessing > the IP header. If the leading space is available it doesn't allocate any > extra space (as it should for most cases) but if for some reason the mbuf > used doesn't have 100 bytes (RESERVE in megapullup) of free space it will > reserve some at the front too. If the leading space isn't necessary then it > won't cause any harm. > > > -Subproject commit cfe39807fe9b1a23c13f73aabde302046736fa1c > +Subproject commit cfe39807fe9b1a23c13f73aabde302046736fa1c-dirty > diff --git a/freebsd/sys/netinet/libalias/alias.c > b/freebsd/sys/netinet/libalias/alias.c > index 876e958..dc424a6 100644 > --- a/freebsd/sys/netinet/libalias/alias.c > +++ b/freebsd/sys/netinet/libalias/alias.c > @@ -1757,7 +1757,8 @@ m_megapullup(struct mbuf *m, int len) { > * writable and has some extra space for expansion. > * XXX: Constant 100bytes is completely empirical. */ > #define RESERVE 100 > - if (m->m_next == NULL && M_WRITABLE(m) && M_TRAILINGSPACE(m) >= RESERVE) > + if (m->m_next == NULL && M_WRITABLE(m) && > + M_TRAILINGSPACE(m) >= RESERVE && M_LEADINGSPACE(m) >= > max_linkhdr) > return (m); > > if (len <= MCLBYTES - RESERVE) { > @@ -1779,6 +1780,7 @@ m_megapullup(struct mbuf *m, int len) { > goto bad; > > m_move_pkthdr(mcl, m); > + mcl->m_data += max_linkhdr; > m_copydata(m, 0, len, mtod(mcl, caddr_t)); > mcl->m_len = mcl->m_pkthdr.len = len; > m_freem(m); > > It would be nice if some FBSD comitter could review and hopefully add this > patch to FBSD. > > Thank you, > > Karim. > _______________________________________________ > freebsd-net@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" From owner-freebsd-ipfw@freebsd.org Wed Jan 13 22:14:52 2016 Return-Path: Delivered-To: freebsd-ipfw@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id 86301A815D8; Wed, 13 Jan 2016 22:14:52 +0000 (UTC) (envelope-from melifaro@ipfw.ru) Received: from forward6h.cmail.yandex.net (forward6h.cmail.yandex.net [87.250.230.217]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (Client CN "forwards.mail.yandex.net", Issuer "Yandex CA" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4458B1DC0; Wed, 13 Jan 2016 22:14:51 +0000 (UTC) (envelope-from melifaro@ipfw.ru) Received: from web11h.yandex.ru (web11h.yandex.ru [IPv6:2a02:6b8:0:f05::21]) by forward6h.cmail.yandex.net (Yandex) with ESMTP id 3549C210F2; Thu, 14 Jan 2016 01:14:21 +0300 (MSK) Received: from 127.0.0.1 (localhost [127.0.0.1]) by web11h.yandex.ru (Yandex) with ESMTP id 540A31226BF; Thu, 14 Jan 2016 01:14:21 +0300 (MSK) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=ipfw.ru; s=mail; t=1452723261; bh=Lcy6LSFjnSgPJ2i5Fn2YvhYFwdy7kQpobPvVfz2aQLA=; h=From:To:In-Reply-To:References:Subject:Date; b=LQ6xsbZbXYs568YtNbpjbIzqQ4/C0l01nw+88blM9jXcbkSnsFnkdttKHciYRsC0O 4tbw6mCEImOC02uCMuKBSB84mwZhnbfcG3PSbF/J1PbvJEfZ06as9ix5grCBNxTrWy lpznQVzjWg4FvPdJzcMNDhki9e/3ut+WRoWjPAzg= Received: by web11h.yandex.ru with HTTP; Thu, 14 Jan 2016 01:14:21 +0300 From: Alexander V. Chernikov To: Karim Fodil-Lemelin , "freebsd-ipfw@freebsd.org" , freebsd-net In-Reply-To: <5696ABBE.4050709@gmail.com> References: null <5696ABBE.4050709@gmail.com> Subject: Re: ipfw NAT, igb and hardware checksums MIME-Version: 1.0 Message-Id: <552671452723261@web11h.yandex.ru> X-Mailer: Yamail [ http://yandex.ru ] 5.0 Date: Thu, 14 Jan 2016 01:14:21 +0300 Content-Transfer-Encoding: 7bit Content-Type: text/plain X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 13 Jan 2016 22:14:52 -0000 13.01.2016, 22:56, "Karim Fodil-Lemelin" : > Hi, > > I've hit a very interesting problem with ipfw-nat and local TCP traffic > that has enough TCP options to hit a special case in m_megapullup(). > Here is the story: > > I am using the following NIC: > > igb0@pci0:4:0:0: class=0x020000 card=0x00008086 chip=0x150e8086 > rev=0x01 hdr=0x00 > > And when I do ipfw nat to locally emitted packets I see packets not > being processed in the igb driver for HW checksum. Now a quick search > for m_pullup in the igb driver code will show that our igb driver > expects a contiguous ethernet + ip header in igb_tx_ctx_setup(). Now the > friendly m_megapullup() in alias.c doesn't reserve any space before the > ip header for the ethernet header after its call to m_getcl like > tcp_output.c (see m->m_data += max_linkhdr in tcp_output.c). > > So the call to M_PREPEND() in ether_output() is forced to prepend a new > mbuf for the ethernet header, leading to a non contiguous ether + ip. > This in turn leads to a failure to properly read the IP protocol in the > igb driver and apply the proper HW checksum function. Particularly this > call in igb_tcp_ctx_setup(): ip = (struct ip *)(mp->m_data + ehdrlen); Thanks for the detailed explanation. Looks reasonable. I'll do several more tests on that and commit. > > It would be nice if some FBSD comitter could review and hopefully add > this patch to FBSD. > > Thank you, > > Karim. > _______________________________________________ > freebsd-net@freebsd.org mailing list > https://lists.freebsd.org/mailman/listinfo/freebsd-net > To unsubscribe, send any mail to "freebsd-net-unsubscribe@freebsd.org" From owner-freebsd-ipfw@freebsd.org Thu Jan 14 16:23:38 2016 Return-Path: Delivered-To: freebsd-ipfw@mailman.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by mailman.ysv.freebsd.org (Postfix) with ESMTP id F3BAAA8281F for ; Thu, 14 Jan 2016 16:23:37 +0000 (UTC) (envelope-from heroldmathajf@outlook.com) Received: from COL004-OMC1S8.hotmail.com (col004-omc1s8.hotmail.com [65.55.34.18]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-SHA384 (256/256 bits)) (Client CN "*.outlook.com", Issuer "MSIT Machine Auth CA 2" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id D01901FFD for ; Thu, 14 Jan 2016 16:23:37 +0000 (UTC) (envelope-from heroldmathajf@outlook.com) Received: from COL125-W1 ([65.55.34.7]) by COL004-OMC1S8.hotmail.com over TLS secured channel with Microsoft SMTPSVC(7.5.7601.23008); Thu, 14 Jan 2016 08:23:31 -0800 X-TMN: [PSgJH1F/70gpcfgOcW9MemtG1GwjebMx] X-Originating-Email: [heroldmathajf@outlook.com] Message-ID: From: Antonio Guillen To: "freebsd-ipfw@freebsd.org" Subject: ipfw Date: Thu, 14 Jan 2016 16:23:31 +0000 Importance: Normal MIME-Version: 1.0 X-OriginalArrivalTime: 14 Jan 2016 16:23:31.0357 (UTC) FILETIME=[E8617CD0:01D14EE7] Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: base64 X-Content-Filtered-By: Mailman/MimeDel 2.1.20 X-BeenThere: freebsd-ipfw@freebsd.org X-Mailman-Version: 2.1.20 Precedence: list List-Id: IPFW Technical Discussions List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 14 Jan 2016 16:23:38 -0000 SGV5IEhhbmRzb21lISBMZXQncyBwbGF5IHR0byB0aGUgZXJpdGljIGdhbWUpKSBJIHdhbnQgdG8g ZG8gdGhpcyB3aXRoIHlvdS4gSSdsbCBzZWR1Y2UgeW91IHdpdGggZ3JlYXQgcGFzc2lvbiBhbmQg ZGVzaXJlLiBNeSBCcmVhc3RzIHdpbGwgYmUgdmVyeSBleGNpdGVkIHRvIGJ1cm4gb2ZmIG15IGZl ZWxpbmdzIGFuZCBkZXNpcmVzLiBEbyB5b3Ugd2lsbCB3YW50IHRvIGtpc3MgaXQ/KSkgIEkgd291 bGQgbGlrZSB0byBlbmpveSAgdGhlIG9yYWwgc2V4IHdpdGggeW91LiBJIGNhbiBpbWFnaW5lIGhv dyB3ZSdyZSBkb2luZyBhbmQgaG93IGdvb2Qgd2UgYXJlIGZyb20gb3VyIGVtb3Rpb25zIGFuZCBm ZWVsaW5ncy4gQW5kIHRoZW4geW91IHdpbGwgd2FudCB0byBnZXQgYWxsIG9mIG1lLiAgSSdtIHdh aXRpbmcgZm9yIHlvdS4NCk15IHBob3RvcyA6IGdnZGo3amJoLmhyZXdpbmRzci50dW1ibHIuY29t DQptZW51Y3JhaWdzbGlzdCA+IGhvdXNpbmdDTGFyZWFsb3MgYW5nZWxlcz5zdWJhcmVhd2VzdHNp ZGUtc291dGhiYXk+c2VjdGlvbmhvdXNpbmc+Y2F0ZWdvcnlhcHRzL2hvdXNpbmcgZm9yIHJlbnRn b3Bvc3Rwb3N0IHRvIGNsYXNzaWZpZWRzWyBhY2NvdW50bXkgYWNjb3VudCBdMCBmYXZvcml0ZXNy ZXBseSDinIkg4piOcmVwbHl4IHByb2hpYml0ZWRbP11Qb3N0ZWQ6IDIwMTYtMDEtMTEgMTE6MjBw beKXgCBwcmV2IOKWsiBuZXh0IOKWtiBwcmludCQ0NDA1IC8gM2JyIC0gMTkzNGZ0MiAtIENyYWZ0 c21hbiBTdHlsZSIgUXVhbGl0eSBDb25zdHJ1Y3Rpb24gZGVzaWduZWQgYnkgTWlrdSAoTi4gUmVk b25kbyBCZWFjaC9WaWxsYXMgU291dGgpPD4oZ29vZ2xlIG1hcCkzQlIgLyAzQmEgMTkzNGZ0MiBh dmFpbGFibGUgamFuIDExY2F0cyBhcmUgT0sgLSBwdXJycg0KZG9ncyBhcmUgT0sgLSB3b29vZg0K Y29uZG8NCkNyYWZ0c21hbiBTdHlsZSIgUXVhbGl0eSBDb25zdHJ1Y3Rpb24gZGVzaWduZWQgYnkg TWlrdSB3aXRoICJEcmVhbSBIb21lIERlc2lnbnMsSW5jIiBCdWlsdCBieSBQYXRydSB3aXRoICJC ZXN0IEJ1aWx0IENvbnN0cnVjdGlvbiwgSW5jIi4gWW91IHdpbGwgbG92ZSB0aGUgZmluaXNoIHRv dWNoZXMgb24gdGhpcyBob21lLiBJdCBoYXMgYWxsIHRoZSB1cGdyYWRlcyBpbmNsdWRpbmcgY3Vz dG9tIHdpbmRvdyBjb3ZlcmluZ3MgYW5kIGRvdWJsZSBzaWRlZCBmcmlkZ2UuIFR3byBiZWRyb29t cyBvbiB0aGUgZmlyc3QgbGV2ZWwgd2l0aCBsYW1pbmF0ZWQgd29vZCBmbG9vcnMsIGZ1bGwgYmF0 aCwgbGF1bmRyeSwgdHdvIGNhciBnYXJhZ2Ugd2l0aCBzdG9yYWdlIGFyZWEgYW5kIGRvb3IgbGVh ZGluZyB0byBzaWRlIHlhcmQuIEVuY2xvc2VkIGZyb250IHlhcmQuIExpdmluZyBhcmVhIGFuZCBt YXN0ZXIgYmVkcm9vbSBvbiB0aGUgc2Vjb25kIGZsb29yIHdpdGggbGFtaW5hdGVkIHdvb2QgZmxv b3JzLiBTbGF0ZSBmbG9vcmluZyBvbiB0aGUgZW50cnkgLCBkYXJrIHdvb2QgZmxvb3JzIG9uIHRo ZSBzdGFpcnMgYW5kIGxpdmluZyBhcmVhLiAxMCcgY2VpbGluZ3Mgb24gdGhlIGZpcnN0IGZsb29y IHdpdGggOCcgc29saWQgZG9vcnMgYW5kIHZhdWx0ZWQgY2VpbGluZ3Mgb24gdGhlIHNlY29uZC4g Q2VpbGluZyBmYW5zIGFuZCBsYW1pbmF0ZWQgd29vZCBmbG9vcnMgaW4gYWxsIGJlZHJvb21zLCBv dmVyLXNpemVkIGJhc2Vib2FyZHMgYW5kIGNyb3duIG1vbGRpbmdzLiBMb3RzIG9mIHdvb2QgZGV0 YWlscyBvbiBhbGwgd2luZG93cy4gQUMgaW5jbHVkZWQuIExhcmdlIG9wZW4gbGl2aW5nIHJvb20g d2l0aCBmaXJlcGxhY2UgYW5kIHByZS13aXJlZCBhYm92ZSB0aGUgZmlyZXBsYWNlIGZvciBmbGF0 IHNjcmVlbiB0diBjZWlsaW5nIHNwZWFrZXJzIGluY2x1ZGVkLiBTbGlkaW5nIGRvb3IgbGVhZGlu ZyB0byBsYXJnZSBkZWNrIHdpdGggbmF0dXJhbCBnYXMgZm9yIEJRIC4gQ2F0IDUgd2lyaW5nLHBy ZS13aXJlZCBmb3IgY29tcHV0ZXIgbmV0d29ya2luZyBhbmQgZm9yIHN1cnJvdW5kIHNvdW5kLiBH cmVhdCBsb2NhdGlvbiEgQ2xvc2UgdG8gYmVhY2gsIFNob3BzLCBTY2hvb2xzLCBMQVgsIEZyZWV3 YXlzICYgcmVzdGF1cmFudHMuIEEgbXVzdCBzZWUhDQpQQzEyLVBWMTUyNjU3ODhNUi4gUGxlYXNl IGNhbGxzaG93IGNvbnRhY3QgaW5mb2RvIE5PVCBjb250YWN0IG1lIHdpdGggdW5zb2xpY2l0ZWQg c2VydmljZXMgb3Igb2ZmZXJzcG9zdCBpZDogNTM5OTA0MDYyNg0KcG9zdGVkOiAyMDE2LTAxLTEx IDExOjIwcG1lbWFpbCB0byBmcmllbmTimaUgYmVzdCBvZiBbP11QbGVhc2UgZmxhZ2Rpc2NyaW1p bmF0b3J5IGhvdXNpbmcgYWRzQXZvaWQgc2NhbXMsIGRlYWwgbG9jYWxseSFETyBOT1Qgd2lyZSBm dW5kcyAoZS5nLiBXZXN0ZXJuIFVuaW9uKSwgb3IgYnV5L3JlbnQgc2lnaHQgdW5zZWVuwqkgMjAx NiBjcmFpZ3NsaXN0Q0xoZWxwc2FmZXR5cHJpdmFjeWZlZWRiYWNrY2wgam9ic3Rlcm1zYWJvdXRt b2JpbGVkZXNrdG9wIAkJIAkgICAJCSAg