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 <[email protected]> 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 >> [email protected] >> https://amsterdam.lcs.mit.edu/mailman/listinfo/click >> >> >> > > Jesse _______________________________________________ click mailing list [email protected] https://amsterdam.lcs.mit.edu/mailman/listinfo/click
