2#ifndef CLICK_ELEMENT_HH
3#define CLICK_ELEMENT_HH
4#include <click/glue.hh>
8#include <click/packetbatch.hh>
32#define BATCH_MAX_PULL 256
38#ifndef CLICK_ELEMENT_DEPRECATED
39# define CLICK_ELEMENT_DEPRECATED CLICK_DEPRECATED
46 static int nelements_allocated;
54 virtual PacketBatch* pull_batch(
int port,
unsigned max) CLICK_WARN_UNUSED_RESULT;
59 virtual bool run_idle_task(IdleTask *task);
61 enum { SELECT_READ = 1, SELECT_WRITE = 2 };
62 virtual void selected(
int fd,
int mask);
69 static std::mt19937 generator;
71 inline static void*
operator new(
size_t sz)
73 char * env = getenv(
"CLICK_ELEM_RAND_MAX");
80 int rand = generator() / (generator.max() / max);
85 void* m = aligned_alloc(
alignof(
Element), sz + of);
92 return ((
unsigned char*)m) + of;
94 static void*
operator new(
size_t sz,
void* p)
99 static void operator delete(
void* m)
106 enum batch_mode {BATCH_MODE_NO, BATCH_MODE_IFPOSSIBLE, BATCH_MODE_NEEDED, BATCH_MODE_YES};
115 static const char PORTS_0_0[];
116 static const char PORTS_0_1[];
117 static const char PORTS_1_0[];
118 static const char PORTS_1_1[];
119 static const char PORTS_1_1X2[];
122 static const char AGNOSTIC[];
123 static const char PUSH[];
124 static const char PULL[];
125 static const char PUSH_TO_PULL[];
126 static const char PULL_TO_PUSH[];
127 static const char PROCESSING_A_AH[];
130 static const char COMPLETE_FLOW[];
132 virtual const char *
flags()
const;
135 virtual void *
cast(
const char *
name);
139 enum ConfigurePhase {
140 CONFIGURE_PHASE_FIRST = 0,
141 CONFIGURE_PHASE_INFO = 20,
142 CONFIGURE_PHASE_PRIVILEGED = 90,
143 CONFIGURE_PHASE_DEFAULT = 100,
144 CONFIGURE_PHASE_LAST = 2000
159 CLEANUP_BEFORE_CONFIGURE = CLEANUP_NO_ROUTER,
160 CLEANUP_CONFIGURE_FAILED,
162 CLEANUP_INITIALIZE_FAILED,
164 CLEANUP_THREAD_INITIALZE_FAILED,
165 CLEANUP_THREAD_INITIALIZED,
166 CLEANUP_ROUTER_INITIALIZED,
169 virtual void cleanup(CleanupStage stage);
179 inline int eindex()
const;
183 inline Master *
master()
const;
192 inline int nports(
bool isoutput)
const;
197 inline const Port &
port(
bool isoutput,
int port)
const;
198 inline const Port &
input(
int port)
const;
219 Bitvector get_passing_threads(
bool forward,
int port,
Element* origin,
bool &_is_fullpush,
int level = 0,
bool touching =
false);
220 Bitvector get_passing_threads(
Element* origin,
int level = 0,
bool touching =
false);
221 Bitvector get_passing_threads(
bool touching =
false);
226 virtual bool is_mt_safe();
228 void add_remote_element(
Element* e);
231 enum ThreadReconfigurationStage {
233 THREAD_RECONFIGURE_UP_PRE,
234 THREAD_RECONFIGURE_UP_POST,
235 THREAD_RECONFIGURE_DOWN_PRE,
236 THREAD_RECONFIGURE_DOWN_POST,
239 virtual int thread_configure(ThreadReconfigurationStage stage,
ErrorHandler* errh,
Bitvector threads);
243 virtual bool get_runnable_threads(
Bitvector&)
final =
delete;
259 void set_handler(
const String &
name,
int flags, HandlerCallback callback,
const void *read_user_data = 0,
const void *write_user_data = 0);
261 void set_handler(
const char *
name,
int flags, HandlerCallback callback,
int read_user_data = 0,
int write_user_data = 0);
263 enum { TASKHANDLER_WRITE_SCHEDULED = 1,
264 TASKHANDLER_WRITE_TICKETS = 2,
265 TASKHANDLER_WRITE_HOME_THREAD = 4,
266 TASKHANDLER_WRITE_ALL = 7,
267 TASKHANDLER_DEFAULT = 6 };
303 virtual int llrpc(
unsigned command,
void* arg);
308 inline bool active()
const;
310 inline int port()
const;
316 inline PacketBatch* pull_batch(
unsigned max)
const;
318 inline void start_batch();
319 inline void end_batch();
322 inline void set_unstack(
bool unstack) {
325 inline bool unstack()
const {
331 unsigned npackets()
const {
return _packets; }
334 inline void assign_peer(
bool isoutput,
Element *e,
int port,
bool unstack=
false);
340 #ifdef HAVE_AUTO_BATCH
347#if HAVE_BOUND_PORT_TRANSFER
361 mutable unsigned _packets;
368 inline void assign_owner(
bool isoutput,
Element *owner,
Element *e,
int port,
bool unstack=
false);
371 friend class BatchElement;
377 String id() const CLICK_DEPRECATED;
378 String landmark() const CLICK_DEPRECATED;
387 enum { INLINE_PORTS = 4 };
390 Port _inline_ports[INLINE_PORTS];
398#if HAVE_FULLPUSH_NONATOMIC
404 unsigned _xfer_calls;
405 click_cycles_t _xfer_own_cycles;
406 click_cycles_t _child_cycles;
408 unsigned _task_calls;
409 click_cycles_t _task_own_cycles;
411 unsigned _timer_calls;
412 click_cycles_t _timer_own_cycles;
414 inline void reset_cycles() {
415 _xfer_calls = _task_calls = _timer_calls = 0;
416 _xfer_own_cycles = _task_own_cycles = _timer_own_cycles = _child_cycles = 0;
426 int set_nports(
int,
int);
428 enum Processing { VAGNOSTIC, VPUSH, VPULL };
429 static int next_processing_code(
const char*& p,
ErrorHandler* errh);
430 void processing_vector(
int* input_codes,
int* output_codes,
ErrorHandler*)
const;
432 void initialize_ports(
const int* input_codes,
const int* output_codes);
433 int connect_port(
bool isoutput,
int port,
Element*,
int);
435 static String read_handlers_handler(
Element *e,
void *user_data);
436 void add_default_handlers(
bool writable_config);
439 friend class BatchElement;
444 friend class TimerSet;
446 friend class SelectSet;
535 return (
router() == r ? _eindex : -1);
543 return _nports[isoutput];
568 assert((
unsigned)
port < (
unsigned) _nports[isoutput]);
569 return _ports[isoutput][
port];
607 return (
unsigned)
port < (unsigned)
nports(isoutput)
626 return (
unsigned)
port < (unsigned)
nports(
true)
645 return (
unsigned)
port < (unsigned)
nports(
false)
650# define PORT_ASSIGN(o) _packets = 0; _owner = (o)
651#elif CLICK_STATS >= 1
652# define PORT_ASSIGN(o) _packets = 0; (void) (o)
654# define PORT_ASSIGN(o) (void) (o)
667#pragma GCC diagnostic push
668#pragma GCC diagnostic ignored "-Wpmf-conversions"
671Element::Port::assign_peer(
bool isoutput,
Element *e,
int port,
bool unstack)
680#ifdef HAVE_AUTO_BATCH
681 for (
unsigned i = 0; i < current_batch.weight() ; i++)
682 current_batch.set_value(i,0);
685#if HAVE_BOUND_PORT_TRANSFER
692 _bound_batch.push_batch = (void (*)(
Element *, int,
PacketBatch *)) (e->*pushbatcher);
699 _bound_batch.pull_batch = (
PacketBatch *(*)(
Element *,
int,
unsigned)) (e->*pullbatcher);
706#pragma GCC diagnostic pop
709Element::Port::assign_owner(
bool isoutput,
Element *owner,
Element *e,
int port,
bool unstack)
712 assign_peer(isoutput, e,
port, unstack);
769 FlowControlBlock* tmp_stack = 0;
771 tmp_stack = fcb_stack;
772 fcb_stack->release(1);
776#ifdef HAVE_AUTO_BATCH
777 if (likely(_e->in_batch_mode == BATCH_MODE_YES)) {
778 if (*current_batch != 0) {
782 (*current_batch)->append_packet(p);
788 assert(!_e->receives_batch);
796 ++_e->input(_port)._packets;
797 click_cycles_t start_cycles = click_get_cycles(),
798 start_child_cycles = _e->_child_cycles;
799# if HAVE_BOUND_PORT_TRANSFER
800 _bound.push(_e, _port, p);
804 click_cycles_t all_delta = click_get_cycles() - start_cycles,
805 own_delta = all_delta - (_e->_child_cycles - start_child_cycles);
806 _e->_xfer_calls += 1;
807 _e->_xfer_own_cycles += own_delta;
808 _owner->_child_cycles += all_delta;
810# if HAVE_BOUND_PORT_TRANSFER
811 _bound.push(_e, _port, p);
819 fcb_stack = tmp_stack;
845 click_cycles_t start_cycles = click_get_cycles(),
846 old_child_cycles = _e->_child_cycles;
847# if HAVE_BOUND_PORT_TRANSFER
853 _e->output(_port)._packets += 1;
854 click_cycles_t all_delta = click_get_cycles() - start_cycles,
855 own_delta = all_delta - (_e->_child_cycles - old_child_cycles);
856 _e->_xfer_calls += 1;
857 _e->_xfer_own_cycles += own_delta;
858 _owner->_child_cycles += all_delta;
860# if HAVE_BOUND_PORT_TRANSFER
878Element::Port::push_batch(
PacketBatch* batch)
const {
880 FlowControlBlock* tmp_stack = 0;
881 if (unlikely(_unstack && fcb_stack)) {
882 tmp_stack = fcb_stack;
883 fcb_stack->release(batch->
count());
889 click_chatter(
"Pushing batch of %d packets to %p{element}",batch->
count(),_e);
891#if HAVE_BOUND_PORT_TRANSFER
892 _bound_batch.push_batch(_e,_port,batch);
894 _e->push_batch(_port,batch);
897 if (unlikely(_unstack)) {
898 fcb_stack = tmp_stack;
903#ifdef HAVE_AUTO_BATCH
905Element::Port::start_batch() {
911#if HAVE_AUTO_BATCH == AUTO_BATCH_JUMP
913 click_chatter(
"Passing start batch message in port to %p{element}",_e);
915 if (_e->in_batch_mode == BATCH_MODE_YES) {
916 if (*current_batch == 0)
919 for (
int i = 0; i < _e->noutputs(); i++) {
920 if (_e->output_is_push(i))
921 _e->_ports[1][i].start_batch();
924#elif HAVE_AUTO_BATCH == AUTO_BATCH_PORT
926 click_chatter(
"Starting batch in port to %p{element}",_e);
928 if (_e->in_batch_mode == BATCH_MODE_YES) {
929 if (*current_batch == 0)
932#elif HAVE_AUTO_BATCH == AUTO_BATCH_LIST
934 click_chatter(
"Starting batch in port to %p{element}",_e);
936 assert(*current_batch == 0);
939 #error "Unknown batch auto mode"
944Element::Port::end_batch() {
947 click_chatter(
"Ending batch in port to %p{element}",_e);
954#if HAVE_AUTO_BATCH == AUTO_BATCH_JUMP
955 if (_e->in_batch_mode == BATCH_MODE_YES)
963 assert(cur->find_count() == cur->
count());
965 _e->push_batch(_port,cur);
970#if HAVE_AUTO_BATCH == AUTO_BATCH_JUMP
973 for (
int i = 0; i < _e->noutputs(); i++) {
974 if (_e->output_is_push(i))
975 _e->_ports[1][i].end_batch();
983Element::Port::pull_batch(
unsigned max)
const {
985#if HAVE_BOUND_PORT_TRANSFER
986 batch = _bound_batch.pull_batch(_e,_port, max);
988 batch = _e->pull_batch(_port, max);
1010#if HAVE_FULLPUSH_NONATOMIC
1011 return _is_fullpush;
Vector of bits.
Definition bitvector.hh:21
An Element's ports.
Definition element.hh:306
Packet * pull() const
Pull a packet over this port and return it.
Definition element.hh:841
int port() const
Returns the port number of the port connected to this active port.
Definition element.hh:738
bool active() const
Returns whether this port is active (a push output or a pull input).
Definition element.hh:720
Element * element() const
Returns the element connected to this active port.
Definition element.hh:729
void push(Packet *p) const
Push packet p over this port.
Definition element.hh:765
Base class for Click elements.
Definition element.hh:42
bool output_is_push(int port) const
Check whether output port is push.
Definition element.hh:615
const Port & port(bool isoutput, int port) const
Return one of the element's ports.
Definition element.hh:566
String name() const
Return the element's name.
Definition element.cc:555
virtual int llrpc(unsigned command, void *arg)
Handle a low-level remote procedure call.
Definition element.cc:3095
void add_read_handler(const String &name, ReadHandlerCallback read_callback, const void *user_data=0, uint32_t flags=0)
Register a read handler named name.
Definition element.cc:2020
bool is_fullpush() const
Tell if the path up to this element is a full push path, always served by the same thread.
Definition element.hh:1009
static int reconfigure_positional_handler(const String &, Element *, void *, ErrorHandler *)
Standard write handler for reconfiguring an element by changing one of its positional arguments.
Definition element.cc:3022
void port_flow(bool isoutput, int port, Bitvector *) const
Analyze internal packet flow with respect to port p.
Definition element.cc:1041
void set_handler(const String &name, int flags, HandlerCallback callback, const void *read_user_data=0, const void *write_user_data=0)
Register a comprehensive handler named name.
Definition element.cc:2147
void add_write_handler(const String &name, WriteHandlerCallback write_callback, const void *user_data=0, uint32_t flags=0)
Register a write handler named name.
Definition element.cc:2079
virtual Element * hotswap_element() const
Return a compatible element in the hotswap router.
Definition element.cc:1537
bool input_is_push(int port) const
Check whether input port is push.
Definition element.hh:643
virtual int configure_phase() const
Return the element's configure phase, which determines the order in which elements are configured and...
Definition element.cc:1308
static void static_initialize()
Initialize static data for this element class.
Definition element.hh:481
virtual const char * processing() const
Return the element's processing specifier.
Definition element.cc:1139
virtual const char * port_count() const
Return the element's port count specifier.
Definition element.cc:710
RouterThread * home_thread() const
Return the element's home thread.
Definition element.cc:1675
bool port_active(bool isoutput, int port) const
Check whether a port is active.
Definition element.hh:605
virtual int live_reconfigure(Vector< String > &, ErrorHandler *)
Reconfigure the element while the router is running.
Definition element.cc:1649
enum batch_mode in_batch_mode
Definition element.hh:382
virtual void add_handlers()
Install the element's handlers.
Definition element.cc:1401
const Port & output(int port) const
Return one of the element's output ports.
Definition element.hh:591
virtual const char * flags() const
Return the element's flags.
Definition element.cc:1234
int noutputs() const
Return the number of output ports.
Definition element.hh:555
int eindex() const
Return the element's index within its router.
Definition element.hh:524
int remove_select(int fd, int mask)
Remove interest in mask events on file descriptor fd.
Definition element.cc:1981
int add_select(int fd, int mask)
Register interest in mask events on file descriptor fd.
Definition element.cc:1962
static int reconfigure_keyword_handler(const String &, Element *, void *, ErrorHandler *)
Standard write handler for reconfiguring an element by changing one of its keyword arguments.
Definition element.cc:3062
void add_data_handlers(const char *name, int flags, uint8_t *data)
Register read and/or write handlers accessing data.
Definition element.cc:2727
bool output_is_pull(int port) const
Check whether output port is pull.
Definition element.hh:624
int ninputs() const
Return the number of input ports.
Definition element.hh:548
virtual bool can_live_reconfigure() const
Return whether an element supports live reconfiguration.
Definition element.cc:1618
virtual Packet * simple_action(Packet *p)
Process a packet for a simple packet filter.
Definition element.cc:3252
virtual void * port_cast(bool isoutput, int port, const char *name)
Attempt to cast an element's port to a named type.
Definition element.cc:544
int set_handler_flags(const String &name, int set_flags, int clear_flags=0)
Set flags for the handler named name.
Definition element.cc:2188
int nports(bool isoutput) const
Return the number of input or output ports.
Definition element.hh:541
virtual void cleanup(CleanupStage stage)
Clean up the element's state.
Definition element.cc:1601
void add_net_order_data_handlers(const char *name, int flags, uint16_t *data)
Register read and/or write handlers accessing data in network byte order.
Definition element.cc:2864
virtual void selected(int fd, int mask)
Handle a file descriptor event.
Definition element.cc:1913
virtual const char * flow_code() const
Return the element's internal packet flow specifier (its flow code).
Definition element.cc:946
Element()
Construct an Element.
Definition element.cc:422
bool input_is_pull(int port) const
Check whether input port is pull.
Definition element.hh:634
virtual int configure(Vector< String > &conf, ErrorHandler *errh)
Parse the element's configuration arguments.
Definition element.cc:1372
virtual bool run_task(Task *task)
Run the element's task.
Definition element.cc:3267
Master * master() const
Return the element's master.
Definition master.hh:222
virtual String declaration() const
Return a string giving the element's name and class name.
Definition element.cc:595
const Port & input(int port) const
Return one of the element's input ports.
Definition element.hh:579
virtual void take_state(Element *old_element, ErrorHandler *errh)
Initialize the element for hotswap, where the element should take old_element's state,...
Definition element.cc:1511
static String read_keyword_handler(Element *, void *)
Standard read handler returning a keyword argument.
Definition element.cc:2985
int home_thread_id() const
Return the element's home thread id.
Definition element.cc:1682
virtual int initialize(ErrorHandler *errh)
Initialize the element.
Definition element.cc:1460
static void static_cleanup()
Clean up static data for this element class.
Definition element.hh:509
int flag_value(int flag) const
Return the flag value for flag in flags().
Definition element.cc:1246
virtual Packet * pull(int port)
Pull a packet from pull output port.
Definition element.cc:3162
static String read_positional_handler(Element *, void *)
Standard read handler returning a positional argument.
Definition element.cc:2949
virtual const char * class_name() const =0
Return the element's class name.
virtual bool get_spawning_threads(Bitvector &b, bool isoutput, int port)
Definition element.cc:1727
virtual void run_timer(Timer *timer)
Run the element's timer.
Definition element.cc:3290
virtual void * cast(const char *name)
Attempt to cast the element to a named type.
Definition element.cc:515
String configuration() const
Return the element's current configuration string.
Definition element.cc:1664
Packet * checked_input_pull(int port) const
Pull a packet from input port, or return 0 if port is out of range.
Definition element.hh:1050
void checked_output_push(int port, Packet *p) const
Push packet p to output port, or kill it if port is out of range.
Definition element.hh:1031
void add_task_handlers(Task *task, NotifierSignal *signal, int flags, const String &prefix=String())
Register handlers for a task.
Definition element.cc:2493
Router * router() const
Return the element's router.
Definition element.hh:515
int local_llrpc(unsigned command, void *arg)
Execute an LLRPC from within the configuration.
Definition element.cc:3111
virtual void push(int port, Packet *p)
Push packet p onto push input port.
Definition element.cc:3142
void trigger_thread_reconfiguration(bool is_up, std::function< void()> ready, Bitvector threads)
Definition element.cc:1877
Error reporting class.
Definition error.hh:90
An Ethernet address.
Definition etheraddress.hh:9
An IPv4 address.
Definition ipaddress.hh:16
An activity signal.
Definition notifier.hh:12
Definition packetbatch.hh:415
unsigned count()
Definition packetbatch.hh:475
static PacketBatch * make_from_packet(Packet *p)
Definition packetbatch.hh:664
A network packet.
Definition packet.hh:68
void kill()
Delete this packet.
Definition packet.hh:1804
void pull(uint32_t len)
Remove a header from the front of the packet.
Definition packet.hh:2122
A router configuration.
Definition router.hh:28
A set of Tasks scheduled on the same CPU.
Definition routerthread.hh:32
A string of characters.
Definition string.hh:22
Represents a frequently-scheduled computational task.
Definition task.hh:49
Triggers execution at a given time.
Definition timer.hh:14
Represents a moment or interval in time.
Definition timestamp.hh:125
Vector template.
Definition vector.hh:111
A 32-bit integer with support for atomic operations.
Definition atomic.hh:71
The Handler class for router handlers.
The Packet class models packets in Click.
Classes for synchronizing among multiple CPUs, particularly in the Linux kernel.
Click's vector container template.