[Click] AGNOSTIC vs. PUSH/PULL

Cliff Frey cliff at meraki.com
Mon Mar 1 19:12:48 EST 2010


Jesse,

Generally simple_action() is only used for elements with exactly one input
and one or two outputs.

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.

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) -> ...

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
>
>


More information about the click mailing list