[Click] AGNOSTIC vs. PUSH/PULL

Jesse Brown jesse.r.brown at lmco.com
Tue Mar 2 11:45:37 EST 2010


Cliff:

Sorry for the duplicate, I forgot to include the list in my original reply.


Cliff Frey wrote:
> Jesse,
>
> Generally simple_action() is only used for elements with exactly one input
> and one or two outputs.
>   
Well, in the push case it would have to be N-to-1 (input to output) and 
pull would be 1-to-N, right?
> If you want to make an element that maps many-to-many, then you would need
> to define push() and/or pull() methods.  There is no need to override the
> simple_action method if you override push/pull.
>   
Yes, I misspoke in my description. What I meant to say was that if I use 
an AGNOSTIC element in any multi-input/multi-output configuration it is 
no longer sufficient to just define simple_action.
> Changing the default element behavior does not seem like the right decision
> to me.
>
> However, in most cases where you want an element with many inputs and
> outputs, it is actually useful to break it up into many elements with a
> shared state element.... so you end up with something like:
>
> foo_table :: FooTable(); // no inputs or outputs
>
> cl [0] -> FooListener(TABLE foo_table) -> IPPrint(tcp) -> ...
> cl [1] -> FooListener(TABLE foo_table) -> IPPrint(udp) -> ...
>   
This will work just fine for my needs; I forgot that I could pass 
elements as arguments to other elements in the router.
However, I still find it interesting that the default behavior for 
Element push/pull ignores ports. The documentation for Element::pull 
states "Often, pull() methods will request packets from upstream using 
input(i).pull()". I'm definitely not an authority on the subject, I just 
found that behavior counter-intuitive.
> or something along those lines... however without knowing more details about
> what you are trying to do, I don't know if that is a good fit or not.
>
> Cliff
>
> On Mon, Mar 1, 2010 at 1:12 PM, Jesse Brown <jesse.r.brown at lmco.com> wrote:
>
>   
>> All:
>>
>> I am currently working on a router config that looks similar to the
>> following:
>>
>>  elementclass Monitor {
>>     input ->
>>     ipc :: IPClassifier (tcp, udp, icmp, -);
>>     f :: Foo;
>>
>>     ipc[0] -> Print("tcp-in") -> [0]f[0] -> Print("tcp-out") -> output;
>>     ipc[1] -> Print("udp-in") -> [1]f[1] -> Print("udp-out") -> output;
>>     ipc[2] -> Print("icmp-in") -> [2]f[2] -> Print("icmp-out") -> output;
>>     ipc[3] -> Print("other-in") -> [3]f[3] -> Print("other-out") -> output;
>>  }
>>
>>  FromDevice(eth0, PROMISC true) ->
>>     ... ->
>>     Monitor ->
>>     ... ->
>>     Queue -> ToDevice(eth1);
>>
>>
>> This is obviously simplified but conveys my point, I think.
>> If I define Foo as
>>  const char *class_name() const    { return "Foo"; }
>>  const char *port_count() const    { return "-/-"; }
>>  const char *processing() const    { return AGNOSTIC; }
>>
>>  Packet *simple_action(Packet *);
>>
>> Then I will always get
>>
>>  icmp-in:   98 | 00151715 a8e50015 17163621 08004500 00540000 40004001
>>  tcp-out:   98 | 00151715 a8e50015 17163621 08004500 00540000 40004001
>>
>> Due to how Element::push behaves.
>>
>> In order to have a single copy of this element that can be located anywhere
>> in a router I have to define Foo::simple_action, Foo::pull, and Foo::push.
>> Is there a more standard way to get the behavior I am after? My desired
>> result would look like:
>>
>>  icmp-in:   98 | 00151715 a8e50015 17163621 08004500 00540000 40004001
>>  icmp-out:   98 | 00151715 a8e50015 17163621 08004500 00540000 40004001
>>
>> in the above example.
>>
>> Also, is there a reason that both Element::push and Element::pull ignore
>> the port by default? Would the attached patch break existing behavior?
>>
>> Thanks,
>>
>> Jesse
>>
>>
>> diff -cr old/lib/element.cc new/lib/element.cc
>> *** old/lib/element.cc  Sun Feb 28 10:22:28 2010
>> --- new/lib/element.cc  Mon Mar  1 13:58:08 2010
>> ***************
>> *** 2706,2715 ****
>>  void
>>  Element::push(int port, Packet *p)
>>  {
>> -     (void) port;
>>      p = simple_action(p);
>>      if (p)
>> !       output(0).push(p);
>>  }
>>
>>  /** @brief Pull a packet from pull output @a port.
>> --- 2706,2714 ----
>>  void
>>  Element::push(int port, Packet *p)
>>  {
>>      p = simple_action(p);
>>      if (p)
>> !       output(port).push(p);
>>  }
>>
>>  /** @brief Pull a packet from pull output @a port.
>> ***************
>> *** 2727,2734 ****
>>  Packet *
>>  Element::pull(int port)
>>  {
>> !     (void) port;
>> !     Packet *p = input(0).pull();
>>      if (p)
>>        p = simple_action(p);
>>      return p;
>> --- 2726,2732 ----
>>  Packet *
>>  Element::pull(int port)
>>  {
>> !     Packet *p = input(port).pull();
>>      if (p)
>>        p = simple_action(p);
>>      return p;
>>
>> _______________________________________________
>> click mailing list
>> click at amsterdam.lcs.mit.edu
>> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
>>
>>
>>     
>
>   

Jesse



More information about the click mailing list