Re: [Idr] Fwd: Slot request in IDR to present https://www.ietf.org/internet-drafts/draft-idr-bgp-route-refresh-options-00.txt

Tony Przygienda <tonysietf@gmail.com> Thu, 21 July 2016 16:06 UTC

Return-Path: <tonysietf@gmail.com>
X-Original-To: idr@ietfa.amsl.com
Delivered-To: idr@ietfa.amsl.com
Received: from localhost (localhost [127.0.0.1]) by ietfa.amsl.com (Postfix) with ESMTP id CE9DF12D78E for <idr@ietfa.amsl.com>; Thu, 21 Jul 2016 09:06:44 -0700 (PDT)
X-Virus-Scanned: amavisd-new at amsl.com
X-Spam-Flag: NO
X-Spam-Score: -2.699
X-Spam-Level:
X-Spam-Status: No, score=-2.699 tagged_above=-999 required=5 tests=[BAYES_00=-1.9, DKIM_SIGNED=0.1, DKIM_VALID=-0.1, DKIM_VALID_AU=-0.1, FREEMAIL_FROM=0.001, HTML_MESSAGE=0.001, RCVD_IN_DNSWL_LOW=-0.7, SPF_PASS=-0.001] autolearn=ham autolearn_force=no
Authentication-Results: ietfa.amsl.com (amavisd-new); dkim=pass (2048-bit key) header.d=gmail.com
Received: from mail.ietf.org ([4.31.198.44]) by localhost (ietfa.amsl.com [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 4wIMCq6yYJPC for <idr@ietfa.amsl.com>; Thu, 21 Jul 2016 09:06:31 -0700 (PDT)
Received: from mail-it0-x230.google.com (mail-it0-x230.google.com [IPv6:2607:f8b0:4001:c0b::230]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by ietfa.amsl.com (Postfix) with ESMTPS id E815D12D754 for <idr@ietf.org>; Thu, 21 Jul 2016 09:06:30 -0700 (PDT)
Received: by mail-it0-x230.google.com with SMTP id j124so22303568ith.1 for <idr@ietf.org>; Thu, 21 Jul 2016 09:06:30 -0700 (PDT)
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:from:date:message-id:subject:to :cc; bh=Zuu5Q7lGuvo4F6O6YS4iMjp4PiMhgCT/pMKY/qdrd6Q=; b=mEGNoeWbUFlnKK9oWIxfO6Jix3BmIdDbZn437Tcf6xlICjfQeXZEaOmsQav1dEQmhe hKa+dLJem7bc9PN7OeWVJkvedgMBrHX6KELjieNZX4hfte2R5zFt+c0bQ+r6KKHS3hYM buxnCLlfNxMWSPYWzeuJM8kHrokXX8QNu8y2CWWdKLqgldllwW8+yJbG7SF8c0KlUJt5 RWDPsKVdecLuxbQUqTsXkHSiVWHxG30JESwfdAb9uZk5uOil0wd3tEoYRoR0xwPHUMrh m/cbw5J6OO8TYuDnntGd+hJCydrbY7Wep06VURKOjz3aVy9MYc70ftCa8jdEmhRX+3gl ZX6Q==
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:from:date :message-id:subject:to:cc; bh=Zuu5Q7lGuvo4F6O6YS4iMjp4PiMhgCT/pMKY/qdrd6Q=; b=llHqGOLoVyfUSqKyhWtPBI8y2RkNPN59De6gPfxOarsOxgTG7Ij+o+LrmVCOkHmuVs y7QtfA/TPPkTd+Ul/oj6mq67ikpQjEGf417xrYo4I1aiEd/ygSr/709phNul1LDk3Ns1 8W+6Mn5JXOd4Bcv0z3UFPsfmXMK64aMLfN4xqlMa7d9bdjvddPSyvsahcqgUeuEEqf0u LKYEWK+l9EP/SVsIHu9iTp+qDYxJ64zyKrUVII7OUy+VR1bf+HsN7AJ1EMxx0m6lX1Pm WvKomA/4EsMk99epv9vWLSwINTxpaxH9w+B4aU/edMaLxztV8pgB4HbMmlZa0p0zDKOV QZqg==
X-Gm-Message-State: ALyK8tI5b9WUErZJQxMX7WKxtUWmsDWsLg8pB7D8Krqloh3RYE8DjT11oa8xBo5QRFRZ532rM8XcargeaGkZHw==
X-Received: by 10.36.87.140 with SMTP id u134mr15366683ita.38.1469117189175; Thu, 21 Jul 2016 09:06:29 -0700 (PDT)
MIME-Version: 1.0
Received: by 10.107.158.82 with HTTP; Thu, 21 Jul 2016 09:05:49 -0700 (PDT)
In-Reply-To: <CA+b+ERm39+UjahPJpQrGkAEGTguEQ_yQzNBoufR9wo7dOXDDbQ@mail.gmail.com>
References: <CA+wi2hM+y_K+_50Q_QRS64VBdzgBWtx8hL-6iepsVqed+NtqTw@mail.gmail.com> <CA+b+ERm2AnRAYeJRDdsAh=hLX81aQUTVd7Pe5PYLpWmHNvbgtQ@mail.gmail.com> <CA+wi2hMsbVetW_D+HpsdXEHyh75yZkx+QTpj+FoX2hMTcqbrzw@mail.gmail.com> <CA+wi2hNk2+GLY0G800Uo8qgdZQWh=9AzFGhZTk+fWRd6isgriw@mail.gmail.com> <76CD132C3ADEF848BD84D028D243C92774EEF7CF@NKGEML515-MBX.china.huawei.com> <CA+b+ERnkkhYK7Cz5eG_8fuQ_cdeo3TSCK3sBQtA0SyfkGktwAg@mail.gmail.com> <D3B3F3D9.47283%keyupate@cisco.com> <CA+b+ERm+2HSu+QyU7pHsEXO9WKh9uavX2y4MtuSX=WADDYx_vg@mail.gmail.com> <D3B5343D.474BD%keyupate@cisco.com> <CA+b+ERn7Rb2=d7UFyxKC01dh7=JFpbnf+dd+_uL+UvAarnkE6w@mail.gmail.com> <CA+wi2hNjD+4Y3vfoDMXW2yzYiyv+9+Xhv=3ZTRumKkZcjY22Hg@mail.gmail.com> <CA+b+ER=_7P_Zg9GQYVT+RVMm9XB6H5o-r86axc0zyLnHf1f8fQ@mail.gmail.com> <CA+b+ERnr_9y9ta3VW99xbDbtRS=9jnNy9mtkk+h6MZ8r2Rj3AQ@mail.gmail.com> <CA+b+ERm39+UjahPJpQrGkAEGTguEQ_yQzNBoufR9wo7dOXDDbQ@mail.gmail.com>
From: Tony Przygienda <tonysietf@gmail.com>
Date: Thu, 21 Jul 2016 09:05:49 -0700
Message-ID: <CA+wi2hNMtzhkugis35ja_NbtvckaGSeb+QdFUyj1uMHq6oRWng@mail.gmail.com>
To: Robert Raszuk <robert@raszuk.net>
Content-Type: multipart/alternative; boundary="001a1135018c3200fb0538278021"
Archived-At: <https://mailarchive.ietf.org/arch/msg/idr/EIIeFBYKbLslnfQELynYWvsqxCs>
Cc: "Keyur Patel (keyupate)" <keyupate@cisco.com>, idr wg <idr@ietf.org>
Subject: Re: [Idr] Fwd: Slot request in IDR to present https://www.ietf.org/internet-drafts/draft-idr-bgp-route-refresh-options-00.txt
X-BeenThere: idr@ietf.org
X-Mailman-Version: 2.1.17
Precedence: list
List-Id: Inter-Domain Routing <idr.ietf.org>
List-Unsubscribe: <https://www.ietf.org/mailman/options/idr>, <mailto:idr-request@ietf.org?subject=unsubscribe>
List-Archive: <https://mailarchive.ietf.org/arch/browse/idr/>
List-Post: <mailto:idr@ietf.org>
List-Help: <mailto:idr-request@ietf.org?subject=help>
List-Subscribe: <https://www.ietf.org/mailman/listinfo/idr>, <mailto:idr-request@ietf.org?subject=subscribe>
X-List-Received-Date: Thu, 21 Jul 2016 16:06:45 -0000

Robert, in the draft there are enough of first examples, I repeated several
times other ones we were seeing outside the idr room and later and each
time it seems it is being dismissed and discussion goes into abstract
"let's do publish-subscribe because it's better". So I won't repeat all
that again. I suggest we will update the draft with more and more of stuff
we saw and justified talking about it.

You didn't respond to any of the "what to do with type-6 refresh" or "how
will I make one ORF filter update multiple subsets [possibly disjoint] I
need to refresh without getting flooded to death with the AFI/SAFI stuff"
and "how will I implement ORF except a full walk on any change" which
happen to be pretty massive issues if you want decent BGP convergence on
more and more AFI/SAFIs, routes, types & other zoo sneaking upon BGP ...

sorry if I'm a tad acerbic ...

--- tony

On Thu, Jul 21, 2016 at 8:50 AM, Robert Raszuk <robert@raszuk.net> wrote:

> Tony,
>
> You have nicely summarized various discussed this week sub threads
> happening bith on and off the list.
>
> Except .. you did not list the most important .. to enumerate real
> protocol level use cases which would justify this addition.
>
> If we start with the problem (rather then just starting with "when we need
> subset of routes") then perhaps it will be easy to adopt this work or we go
> back and fix protocol encoding which are root cause of the problem you are
> trying to patch with solutions like selective overlapping route refresh
> messages.
>
> Best,
> R.
>
> On Jul 21, 2016 5:42 PM, "Tony Przygienda" <tonysietf@gmail.com> wrote:
>
> Read the "longish" thread by now and between all this "let's do
> filter/let's do pull (refresh)" I try to take a step back to see the forest:
>
> a) To validate Niloo's point: 'f an implementation chooses to drop things
> based on configuration/policy (multicast EVPN routes) extending ORF will
> cause a complete refresh of EVPN (including type-2 MACs) unless you go and
> "install filter type-2, then refresh, then remove-filter-2" and after
> requesting type-6  (you can't defer remove-filter-2 step, otherwise you
> won't receive type-2 updates anymore!) floods you with all MACs. Pub-sub
> with a single "filter-list" is simply NOT a good model to request arbitrary
> pieces of routes missing (which is where the world is going, BGP database
> is sharding to the point specs are recommending to "drop when you don't
> need it" and we have the need to ask for very specific sets @ given points
> in time [as the use cases describe]).
>
> b) A much _bigger_ problem IMO is the fact that ORF language does not seem
> to be an algebra, it's a program and you can only build a closure of
> procedural programs by running them normally (not good to restrict sets you
> process). In less abstract terms a refresh with filters that are OR'ed and
> AND'ed (first order logic transitive closure) determines the cone you need
> to walk on the RIB very easily (people implementing heavy-duty BGP will
> know precisely what that means) whereas any change to the filter will cause
> a full walk on the RIB possibly (in case of arbitrary mix of accepts and
> rejects) without a lot of possibly hard logic to write (I didn't think
> fully through it but I think it may be actually possible to write something
> delivering closure from a generic ORF filter so it's an interesting
> discussion). Even if you can build the closure, you can only run one at a
> time (one ORF filter) unless the peer does some crazy state-ful query
> optimization language to do wonders to squeeze multiple queries it needs
> into a single ORFs it's doing (SQL query optimizers are _really_ complex
> beasts) while the "you can put a filter on something to suppress it on
> refresh but you can hammered with it anyway the moment you remove it"
> persists.
>
> For that 2 cases my take  is that it's better to move towards the model
> proposed by a "filtered refresh" (independently of being co-author) rather
> than a 'pub-sub'.
>
> As ultimate, wider angle view of the world.
>
> BGP will be offered more cycles to run (it already is ) but not in the
> form of a single faster and faster CPU anymore but in form of multiple
> cores/machines. A set of filtered refreshes can be parallelized fairly
> easily when requested. A single ORF filter being manipulated on/off will as
> described in a) possibly cause huge spurious refreshes and in b) a single
> threat of execution serializing the synchronization between peers.
>
> I hope that all can be parsed ...
>
> Very good discussion overall no matter which way it goes ...
>
> --- tony
>
>
> On Wed, Jul 20, 2016 at 3:14 PM, Robert Raszuk <robert@raszuk.net> wrote:
>
>> Hi Keyur,
>>
>> On the EVPN topic which defines BGP protocol extensions without any IDR
>> WG review the more I hear about cases like you bring below (and this is not
>> the first one btw) the more I think it is really quite badly designed.
>>
>> And such bad protocol extensions should not be a justification to
>> introduce even more questionable knobs in BGP.
>>
>> In this specific case just get all SAFI refreshed modulo to RTC or ORF
>> filters and you are done. Case solved :).
>>
>> Best,
>> R.
>>
>>
>> On Wed, Jul 20, 2016 at 11:05 PM, Keyur Patel (keyupate) <
>> keyupate@cisco.com> wrote:
>>
>>> Hi Robert,
>>>
>>> One interesting use case is with EVPN address family where a new
>>> route-type is introduced without a capability.  A PE may have had safi
>>> enabled but not have accepted its route-type (or set of route-types) all
>>> mapping to a same RT. A transactional filter attempts to solve it.
>>>
>>> We can clarify in the next revision of the draft.
>>>
>>> One more comment inlined #Keyur
>>>
>>> From: Robert Raszuk <robert@raszuk.net>
>>> Date: Tuesday, July 19, 2016 at 3:29 PM
>>> To: Keyur Patel <keyupate@cisco.com>
>>> Cc: "Dongjie (Jimmy)" <jie.dong@huawei.com>, idr wg <idr@ietf.org>
>>> Subject: Re: [Idr] Fwd: Slot request in IDR to present
>>> https://www.ietf.org/internet-drafts/draft-idr-bgp-route-refresh-options-00.txt
>>>
>>> Hi Keyur,
>>>
>>> The missing part seems to be justification if we really need
>>> "transaction based filters" as opposed to simply having permanent ones.
>>>
>>> What real problem "transaction based filters" solve ? IMO the draft
>>> needs to state it clearly.
>>>
>>> The other point is that "permanent" are not really permanent anyway ..
>>> they are installed from update to withdraw of a given filter - regardless
>>> what filtering mechanism you choose (ORF, RTC, XYZ ...). And if you go with
>>> the notion that permanent are sufficient the entire aparatus allowing you
>>> to have concurrent route refresh requests in flight goes away :)
>>>
>>> #Keyur: Ack your right. My reference to a permanent filter was in
>>> context of a session life time and I agree with you that it could be
>>> modified or withdrawn at any given time. I was trying to differentiate it
>>> from transactional filters.
>>>
>>> Regards,
>>> Keyur
>>>
>>> Thx,
>>> r.
>>>
>>>
>>> On Wed, Jul 20, 2016 at 12:18 AM, Keyur Patel (keyupate) <
>>> keyupate@cisco.com> wrote:
>>>
>>>> Robert, Dongjie,
>>>>
>>>> Comments inlined #Keyur
>>>>
>>>> From: Robert Raszuk <robert@raszuk.net>
>>>> Date: Tuesday, July 19, 2016 at 2:52 PM
>>>> To: "Dongjie (Jimmy)" <jie.dong@huawei.com>
>>>> Cc: idr wg <idr@ietf.org>
>>>> Subject: Re: [Idr] Fwd: Slot request in IDR to present
>>>> https://www.ietf.org/internet-drafts/draft-idr-bgp-route-refresh-options-00.txt
>>>>
>>>> Hi Jie,
>>>>
>>>> To me what is perhaps missing is just a new draft to define *Route
>>>> Type* ORF to address some of those EVPN new NLRI encodings.
>>>>
>>>> #Keyur: ORFs are permanent filters. We wanted to decouple the
>>>> transaction based filters (one time per refresh) from the permanent filters
>>>> and hence chose to modify refresh message as opposed to an ORF.
>>>>
>>>> I am not that much convinced if one time ORF is needed as you are free
>>>> to INSTALL and REMOVE ORF effectively producing one time behavior.
>>>>
>>>> #Keyur: Ack.
>>>>
>>>> Also existing Enhanced Route Refresh should work with ORF too.
>>>>
>>>> #Keyur: There are modifications needed if the refresh is going to be
>>>> for selective prefixes only. Furthermore, if we want to support multiple
>>>> concurrent selective refreshes then the changes needed are very much along
>>>> the lines of the solution suggested in the draft.
>>>>
>>>> Regards,
>>>> Keyur
>>>>
>>>>
>>>>
>>>> Many thx,
>>>> R.
>>>>
>>>>
>>>>
>>>>
>>>> On Tue, Jul 19, 2016 at 11:47 PM, Dongjie (Jimmy) <jie.dong@huawei.com>
>>>> wrote:
>>>>
>>>>> Hi Tony,
>>>>>
>>>>>
>>>>>
>>>>> Please see some comments inline with [Jie]:
>>>>>
>>>>>
>>>>>
>>>>> *From:* Idr [mailto:idr-bounces@ietf.org] *On Behalf Of *Tony
>>>>> Przygienda
>>>>> *Sent:* Tuesday, July 19, 2016 6:04 PM
>>>>> *To:* Robert Raszuk; idr wg
>>>>> *Subject:* [Idr] Fwd: Slot request in IDR to present
>>>>> https://www.ietf.org/internet-drafts/draft-idr-bgp-route-refresh-options-00.txt
>>>>>
>>>>>
>>>>>
>>>>> Resending ...
>>>>>
>>>>>
>>>>>
>>>>> ---------- Forwarded message ----------
>>>>> From: *Tony Przygienda* <tonysietf@gmail.com>
>>>>> Date: Mon, Jul 11, 2016 at 3:04 PM
>>>>> Subject: Re: [Idr] Slot request in IDR to present
>>>>> https://www.ietf.org/internet-drafts/draft-idr-bgp-route-refresh-options-00.txt
>>>>> To: Robert Raszuk <robert@raszuk.net>
>>>>> Cc: idr wg <idr@ietf.org>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> On Mon, Jul 11, 2016 at 1:47 PM, Robert Raszuk <robert@raszuk.net>
>>>>> wrote:
>>>>>
>>>>> Hi Tony,
>>>>>
>>>>>
>>>>>
>>>>> Hey Robert, thanks for chiming in. Good questions. I speak here for
>>>>> myself, other authors of the draft may have differing opinions.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Can you clarify what is the expected behaviour as far as per peer
>>>>> filter-list when you negotiate both Refresh with options, ORF and RTC ?
>>>>> Note that ORF also includes recent extension as described in RFC7543 -
>>>>> would all of those be always a logical AND towards a peer which pushed
>>>>> those ?
>>>>>
>>>>>
>>>>>
>>>>> We didn't discuss that one through but the only logical conclusion for
>>>>> me is that the ORF/CP-ORF installed are respected (i.e. it's an implicit
>>>>> AND). I see ORF as statefull, remote-pushed policy on the peer that is not
>>>>> being flipped around all the time (albeit AFAIR there were some attempts @
>>>>> non-persistent, one shot ORF but that ended up expiring?)
>>>>>
>>>>>
>>>>>
>>>>> [Jie] I think the attempts you mentioned here are the one-time ORF
>>>>> drafts: draft-zeng-idr-one-time-prefix-orf  and
>>>>> draft-dong-idr-one-time-ext-community-orf. After several revisions, these
>>>>> drafts got expired due to lack of requirements at that time. If people
>>>>> found some new use cases of these kinds of mechanisms, the authors would be
>>>>> happy to bring them back to discussion.
>>>>>
>>>>>
>>>>>
>>>>> The motivation for this work were scenarios where a single-shot
>>>>> refresh is needed, actually concurrent bunch of those based on
>>>>> configuration changes, peer having dropped received routes based on specs
>>>>> (A-D), in policy changes, joining VPNs, EVIs and so on. Putting ORF on a
>>>>> peer, refresh and remove ORFs is significantly heavier process that may
>>>>> interfere on top with normal update process going on and needs to be done
>>>>> one-by-one (since you have to wait for single BoRR/EoRR pair) unless one is
>>>>> very smart about combining ORF possibly & playing with the
>>>>> DEFER/IMMEDIATEs. As we indicated, if the AFI/SAFI is covered by RTC and
>>>>> RTC is supported & one is willing to configure RTs for each subset of
>>>>> routes that may need refreshing, RT will be doing the same job just fine.
>>>>>
>>>>>
>>>>>
>>>>> [Jie] The motivations look similar to what we described for the
>>>>> one-time ORF drafts.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> Would you always carry ORF with separate Refresh_ID value ?
>>>>>
>>>>>
>>>>>
>>>>> Yes, Refresh-ID# is strictly monotonic so there is never a
>>>>> misunderstanding WHAT the BoRR belongs to. Observe that the draft does NOT
>>>>> mandate that a request MUST be followed by according BoRR, only that BoRRs
>>>>> must follow same sequence as requests (i.e. are also strictly monotonic).
>>>>> However, we should probably specify that options _and_ ORF can NOT be mixed
>>>>> in the same type #3 message but it's either one or the other (and anything
>>>>> else is error). This will allow ORF operations like today + benefit of the
>>>>> Refresh ID#  on the BoRR so the IMMEDIATE can go on @ the same time as
>>>>> another request with higher Refresh ID# (de facto we allow multiple
>>>>> parallel refreshes as you see).  In case of DEFER there will be simply no
>>>>> BoRR for it.
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> If one requests full Adj_RIB_Out in the new model and sends refresh
>>>>> message with new refresh_id and no options however there are ORF entries
>>>>> already installed in the past would he get just the subset of routes
>>>>> against all ORF entries ? In other words I think the draft should state
>>>>> that Refresh_IDs have no impact to ORF ADDs or REMOVE actions - don't you
>>>>> think ?
>>>>>
>>>>>
>>>>>
>>>>> I agree. Yes, ORF is kind of  "permanent filter" on the peer while the
>>>>> intent of this draft is to have bunch of "small refreshes" going on @ same
>>>>> time possibly (if you request the refreshes from a good implementation
>>>>> while low-end implementations may serialize the requests to simplify
>>>>> internal logic ;-).
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> As far as current types why not add regular/extended community ?
>>>>>
>>>>>
>>>>>
>>>>> Discussion came up. Feeling was it's an immediate encroach on RT
>>>>> territory. I argued for it ;-)  Ultimately, taking a more relaxed view, we
>>>>> chose to wait and see what the response is and most pressing use cases
>>>>> people bring to it and then we start to define bits and bytes of the
>>>>> options supported, possibly borrowing to an extent from the ORF specs ;-)
>>>>>  As in "most sincere form of flattery" and such ... ;-)
>>>>>
>>>>>
>>>>>
>>>>> [Jie] Actually before the one-time ORF drafts were submitted, we
>>>>> initially considered to make it a “selective route refresh” mechanism. Then
>>>>> we realized that the filters will be quite similar to the ones already
>>>>> defined for ORF. In order to reuse the ORF filters, we then decided to
>>>>> define this mechanism as new “one-time” ORF types.  Just to provide some
>>>>> background information since you also plan to reuse the format of the
>>>>> existing ORF types.
>>>>>
>>>>>
>>>>>
>>>>> Best regards,
>>>>>
>>>>> Jie
>>>>>
>>>>>
>>>>>
>>>>> -- tony
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>>
>>>>> --
>>>>>
>>>>> *We’ve heard that a million monkeys at a million keyboards could
>>>>> produce the complete works of Shakespeare; now, thanks to the Internet, we
>>>>> know that is not true.*
>>>>>
>>>>> —Robert Wilensky
>>>>>
>>>>
>>>>
>>>
>>
>> _______________________________________________
>> Idr mailing list
>> Idr@ietf.org
>> https://www.ietf.org/mailman/listinfo/idr
>>
>>
>
>
> --
> *We’ve heard that a million monkeys at a million keyboards could produce
> the complete works of Shakespeare; now, thanks to the Internet, we know
> that is not true.*
> —Robert Wilensky
>
>
>


-- 
*We’ve heard that a million monkeys at a million keyboards could produce
the complete works of Shakespeare; now, thanks to the Internet, we know
that is not true.*
—Robert Wilensky