[Click] "Graft" ports
Eddie Kohler
kohler at cs.ucla.edu
Mon Jan 31 21:12:18 EST 2011
Parser changes are among some of the more difficult to make
successfully. The code is shall we say compressed?
A mod to the language manual (doc/click.5) describing how you think the
feature should look, would be a fine place to start.
Eddie
On 1/28/11 11:08 AM, Cliff Frey wrote:
> Eddie very recently made changes to the parser, allowing for new syntax
> and types of connections, so I would look at his recent commits.
>
> Cliff
>
> On Fri, Jan 28, 2011 at 11:05 AM, Philip Prindeville
> <philipp_subx at redfish-solutions.com
> <mailto:philipp_subx at redfish-solutions.com>> wrote:
>
> 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
> <mailto: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