[Click] "Graft" ports

Philip Prindeville philipp_subx at redfish-solutions.com
Fri Jan 28 14:05:18 EST 2011


On 1/21/11 6:48 PM, Eddie Kohler wrote:
> On 01/21/2011 05:42 PM, Philip Prindeville wrote:
>> The original concern (with exposing global objects into the guts of an
>> elementclass) was that this would only work for a single instance is valid...
>> that is, if A imports B, then you can only have a single object of class A.
>
> No, you could have many.  But any element of class A will refer to the same imported element.  Sometimes that's not what you want.  Sometimes it is.
>
> The idea of "default connections" is interesting -- "include this connection only if the port was previously unused."  You could get a somewhat similar effect with compound element overloading, but only somewhat similar.
>
> Eddie

What's involved in coding up a patch for prototype testing?

I've not looked into the innards of the click parser and intermediate code generator.

Thanks.

-Philip


>> The advantage of graft points was that you'd have to plumb instances
>> individually, same as for input and output ports.
>>
>> My only point about graft point was that (a) they would simplify keeping track
>> of indices on complex objects (especially for objects that are generated from
>> scripts with variable numbers of inputs and outputs); (b) they would simplify
>> notation by specifying both input and output to the grafted-to object at the
>> same time, and (c) they would impose rules about graft points being used in
>> pairs that doesn't exist for inputs and outputs which are orthogonal to each
>> other (at least with respect to an object's perspective of the outside world).
>>
>> I thought about it some more, and if the default for any unspecified (graft)
>> connection was :: { input -> output } then that would make it very easy to
>> "pepper" an object with various inspection and instrumentation points, or
>> points where you might later want to apply additional processing on a packet
>> as it flows through the innards of a class.
>>
>> I could easily foresee a complex object where I had graft points for:
>>
>> [0] the packet at ingress;
>> [1] the packet after it has SNATting performed;
>> [2] the packet after deep inspection into layer 7 and rewriting of addresses;
>> [3] resetting the timer on the association;
>> ...
>> [n] the packet at egress;
>>
>> And you wouldn't need to recode an object to add to peek into it at various
>> well-known (and previously defined) places.
>>
>> Like I said: graft points are just a notational convenience. At the end of the
>> day, they would just map into pairs of input and output ports... but the
>> implementation would be handled by the preprocessor.
>>
>>
>> On 1/21/11 4:47 PM, Eddie Kohler wrote:
>>> Hey, a couple points.
>>>
>>> (1) Unlike Cliff and Ian, I see some value for importing external elements
>>> into a compound. Perhaps a statement like "import(ELEMENTNAME)" would be
>>> required. Although new errors could happen, they'd be pretty easy to
>>> understand even now, and the messages could be improved.
>>>
>>> (2) On the below, we generally write debuggers like this:
>>>
>>> // elementclass Debugger {$tag | input -> output};
>>> elementclass Debugger {$tag | input -> IPPrint($tag, MAXLENGTH 64) -> output};
>>>
>>> Then you refer to Debugger as an element.
>>>
>>> I want to note that graft points as used in THIS mail are supported now;
>>> they are implemented as normal inputs and outputs. I don't understand what
>>> you gain by treating grafts as separate from normal inputs and outputs. They
>>> must always be connected or there are errors.
>>>
>>> Eddie
>>>
>>>
>>> On 01/20/2011 04:11 PM, Philip Prindeville wrote:
>>>> One other nice property about graft-points is this:
>>>>
>>>> elementclass MyIncrediblyHairyObject {
>>>> ...
>>>> }
>>>>
>>>> miho :: MyIncrediblyHairyObject;
>>>> ...
>>>>
>>>> miho [0]<-> null :: { input -> output }<-> [0] miho;
>>>> // miho [0]<-> dbg0 :: { IPPrint("Inspection 0", MAXLENGTH=64) }<-> [0] miho;
>>>>
>>>>
>>>> and by just moving the comment prefix around, I can turn on or off
>>>> debugging, without having to disturb the body of the elementclass itself.
>>>>
>>>>
>>>>
>>>>
>>>> On 1/20/11 3:59 PM, Philip Prindeville wrote:
>>>>> I've been thinking about this some more...
>>>>>
>>>>> If I have the following:
>>>>>
>>>>> elementclass Foo {
>>>>>
>>>>> stuff1 -> external-object -> stuff2;
>>>>>
>>>>> }
>>>>>
>>>>> then this can be rewritten as:
>>>>>
>>>>> elementclass Foo {
>>>>> stuff1 -> [N] output;
>>>>> input [M] -> stuff2;
>>>>> }
>>>>>
>>>>> f :: Foo;
>>>>>
>>>>> f [N] -> external-object -> [M] f;
>>>>>
>>>>> I'd like to propose a notational convenience called "graft" (as in a
>>>>> graft-point).
>>>>>
>>>>> graft[0] would be short-hand for 1+ the highest used input, and [0] graft
>>>>> would be 1+ the highest used input.
>>>>>
>>>>> (and so on for [1], [2], etc.)
>>>>>
>>>>> We'd need a new operator for graft-points. Maybe:
>>>>>
>>>>> f [G]<-> [a] external-object [b]<-> [G] f;
>>>>>
>>>>> it would be a syntactic error to mismatch subscripts for the object being
>>>>> grafted to.
>>>>>
>>>>> The notation inside the elementclass would be:
>>>>>
>>>>> elementclass Foo {
>>>>> stuff1 -> graft [G] -> stuff2; // or ... [G] graft ...
>>>>> }
>>>>>
>>>>> Does that make sense?
>>>>>
>>>>> -Philip
>>>>>
>>>>>
>>>>> On 1/18/11 3:43 PM, Beyers Cronje wrote:
>>>>>> The config you posted below Ian explicitly states "This would be legal:" at
>>>>>> the top. I think Ian is referring to the second config that will cause
>>>>>> issues:
>>>>>>
>>>>>> "
>>>>>> I think this should complain that fd[0] is being used twice (port
>>>>>> connection error), although it may take a minute to see why that's the
>>>>>> case (and would be much trickier to see in a more complex config):
>>>>>> --------------------------------------
>>>>>> fd::FromDevice(...);
>>>>>>
>>>>>> elementclass Bar {
>>>>>> fd[0] -> Print() -> [0]output;
>>>>>> }
>>>>>>
>>>>>> a::Bar() -> Discard();
>>>>>> b::Bar() -> Discard();
>>>>>> --------------------------------------
>>>>>> "
>>>>>>
>>>>>>
>>>>>> On Wed, Jan 19, 2011 at 12:32 AM, Philip Prindeville<
>>>>>> philipp_subx at redfish-solutions.com> wrote:
>>>>>>
>>>>>>> On 1/18/11 7:34 AM, Ian Rose wrote:
>>>>>>>> If I am thinking this through correctly, IMHO it wouldn't be a good idea
>>>>>>>> to allow elementclasses to do this. Reason being that in some cases you
>>>>>>>> could create port connection errors merely through declaring multiple
>>>>>>>> elements of your new elementclass type. This would be an unexpected and
>>>>>>>> confusing error since its impossible to do currently. AFAIK currently
>>>>>>>> there are no errors that can occur merely by *declaring* too many
>>>>>>>> elements of some type. So this would introduce a whole new category of
>>>>>>>> error. Some examples:
>>>>>>>>
>>>>>>>> This would be legal:
>>>>>>>> --------------------------------------
>>>>>>>> fd::FromDevice(...);
>>>>>>>>
>>>>>>>> elementclass Bar {
>>>>>>>> fd[0] -> Print() -> [0]output;
>>>>>>>> }
>>>>>>>>
>>>>>>>> a::Bar() -> Discard();
>>>>>>>> --------------------------------------
>>>>>>>>
>>>>>>>> I think this should complain that fd[0] is being used twice (port
>>>>>>>> connection error), although it may take a minute to see why that's the
>>>>>>>> case (and would be much trickier to see in a more complex config):
>>>>>>> Sorry, not seeing why the above case represents using the port twice...
>>>>>>>
>>>>>>>
>>>>>>>> --------------------------------------
>>>>>>>> fd::FromDevice(...);
>>>>>>>>
>>>>>>>> elementclass Bar {
>>>>>>>> fd[0] -> Print() -> [0]output;
>>>>>>>> }
>>>>>>>>
>>>>>>>> a::Bar() -> Discard();
>>>>>>>> b::Bar() -> Discard();
>>>>>>>> --------------------------------------
>>>>>>>>
>>>>>>>> In order to cause this same error currently (without the proposed
>>>>>>>> elementclass enhancement) you'd have to do this, which I think makes the
>>>>>>>> error more obvious:
>>>>>>>> --------------------------------------
>>>>>>>> fd::FromDevice(...);
>>>>>>>>
>>>>>>>> elementclass Bar {
>>>>>>>> input[0] -> Print() -> [0]output;
>>>>>>>> }
>>>>>>>>
>>>>>>>> fd[0] -> a::Bar() -> Discard();
>>>>>>>> fd[0] -> b::Bar() -> Discard();
>>>>>>>> --------------------------------------
>>>>>>>>
>>>>>>>>
>>>>>>>> Just my $0.02.
>>>>>>>>
>>>>>>>> - Ian
>>>>>>>>
>>>>>>>>
>>>>>>>> On 01/17/2011 07:55 PM, Philip Prindeville wrote:
>>>>>>>>> Yeah, it especially makes sense to have arpfoo be global if it needs to
>>>>>>> be accessible from two different elementclass's, one that deals with the IP
>>>>>>> flow (input [0] and output [0]) and another one that deals strictly with
>>>>>>> the
>>>>>>> ARP request/reply flow (input [1] and output [1]).
>>>>>>>>> Someone else will have to come up with the patches... I've not yet
>>>>>>> dabbled in the code itself.
>>>>>>>>>
>>>>>>>>> On 1/17/11 4:35 PM, Eddie Kohler wrote:
>>>>>>>>>> Hi Philip,
>>>>>>>>>>
>>>>>>>>>> I can see why you thought compound elements would work that way, but
>>>>>>> they don't. They are very strictly encapsulated: all connections to other
>>>>>>> elements must take place through explicit inputs and outputs.
>>>>>>>>>> I admit it would make sense to do it the way you've imagined. Patches
>>>>>>> welcome...
>>>>>>>>>> Eddie
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> On 1/15/11 2:53 PM, Philip Prindeville wrote:
>>>>>>>>>>> I've got a configuration where I do:
>>>>>>>>>>>
>>>>>>>>>>> ...
>>>>>>>>>>> arpfoo :: ARPQuerier(...);
>>>>>>>>>>>
>>>>>>>>>>> elementclass Bar {
>>>>>>>>>>> ...
>>>>>>>>>>> class :: classifier(...);
>>>>>>>>>>> ...
>>>>>>>>>>> class [2] -> [1] arpfoo;
>>>>>>>>>>> ...
>>>>>>>>>>> }
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> but it complains that "unknown element class 'arpfoo'" in a few
>>>>>>> places, and that input 1 isn't used...
>>>>>>>>>>> So I'm confused. Everything is scoped globally... even stuff defined
>>>>>>> within an elementclass gets scoped globally.
>>>>>>>>>>> Why then can't I access a global variable from within an
>>>>>>> elementclass's scope?
>>>>>>>>>>> What am I missing?
>>>>>>>>>>>
>>>>>>>>>>> Thanks,
>>>>>>>>>>>
>>>>>>>>>>> -Philip
>>>>>>>
>>>>>
>>>>
>>



More information about the click mailing list