Click
Loading...
Searching...
No Matches
Classes | Public Types | Public Member Functions | Static Public Member Functions | Static Public Attributes | Protected Attributes | List of all members
Element Class Referenceabstract

Base class for Click elements. More...

Inherited by AddressInfo, AlignmentInfo, BatchElement, ErrorElement, Lexer::Compound, PortInfo, and ScheduleInfo.

Classes

class  Port
 An Element's ports. More...
 

Public Types

enum  { SELECT_READ = 1 , SELECT_WRITE = 2 }
 
enum  batch_mode { BATCH_MODE_NO , BATCH_MODE_IFPOSSIBLE , BATCH_MODE_NEEDED , BATCH_MODE_YES }
 
enum  ConfigurePhase {
  CONFIGURE_PHASE_FIRST = 0 , CONFIGURE_PHASE_INFO = 20 , CONFIGURE_PHASE_PRIVILEGED = 90 , CONFIGURE_PHASE_DEFAULT = 100 ,
  CONFIGURE_PHASE_LAST = 2000
}
 
enum  CleanupStage {
  CLEANUP_NO_ROUTER , CLEANUP_BEFORE_CONFIGURE = CLEANUP_NO_ROUTER , CLEANUP_CONFIGURE_FAILED , CLEANUP_CONFIGURED ,
  CLEANUP_INITIALIZE_FAILED , CLEANUP_INITIALIZED , CLEANUP_THREAD_INITIALZE_FAILED , CLEANUP_THREAD_INITIALIZED ,
  CLEANUP_ROUTER_INITIALIZED , CLEANUP_MANUAL
}
 
enum  ThreadReconfigurationStage {
  THREAD_INITIALIZE , THREAD_RECONFIGURE_UP_PRE , THREAD_RECONFIGURE_UP_POST , THREAD_RECONFIGURE_DOWN_PRE ,
  THREAD_RECONFIGURE_DOWN_POST
}
 
enum  {
  TASKHANDLER_WRITE_SCHEDULED = 1 , TASKHANDLER_WRITE_TICKETS = 2 , TASKHANDLER_WRITE_HOME_THREAD = 4 , TASKHANDLER_WRITE_ALL = 7 ,
  TASKHANDLER_DEFAULT = 6
}
 

Public Member Functions

 Element ()
 Construct an Element.
 
virtual void push (int port, Packet *p)
 Push packet p onto push input port.
 
virtual Packet * pull (int port)
 Pull a packet from pull output port.
 
virtual Packet * simple_action (Packet *p)
 Process a packet for a simple packet filter.
 
virtual bool run_task (Task *task)
 Run the element's task.
 
virtual void run_timer (Timer *timer)
 Run the element's timer.
 
virtual bool run_idle_task (IdleTask *task)
 
virtual void selected (int fd, int mask)
 Handle a file descriptor event.
 
virtual void selected (int fd)
 Handle a file descriptor event.
 
bool is_fullpush () const
 Tell if the path up to this element is a full push path, always served by the same thread.
 
void checked_output_push (int port, Packet *p) const
 Push packet p to output port, or kill it if port is out of range.
 
Packet * checked_input_pull (int port) const
 Pull a packet from input port, or return 0 if port is out of range.
 
virtual const char * class_name () const =0
 Return the element's class name.
 
virtual const char * port_count () const
 Return the element's port count specifier.
 
virtual const char * processing () const
 Return the element's processing specifier.
 
virtual const char * flow_code () const
 Return the element's internal packet flow specifier (its flow code).
 
virtual const char * flags () const
 Return the element's flags.
 
int flag_value (int flag) const
 Return the flag value for flag in flags().
 
virtual void * cast (const char *name)
 Attempt to cast the element to a named type.
 
virtual void * port_cast (bool isoutput, int port, const char *name)
 Attempt to cast an element's port to a named type.
 
virtual int configure_phase () const
 Return the element's configure phase, which determines the order in which elements are configured and initialized.
 
virtual int configure (Vector< String > &conf, ErrorHandler *errh)
 Parse the element's configuration arguments.
 
virtual void add_handlers ()
 Install the element's handlers.
 
virtual int initialize (ErrorHandler *errh)
 Initialize the element.
 
virtual void take_state (Element *old_element, ErrorHandler *errh)
 Initialize the element for hotswap, where the element should take old_element's state, if possible.
 
virtual Element * hotswap_element () const
 Return a compatible element in the hotswap router.
 
virtual void cleanup (CleanupStage stage)
 Clean up the element's state.
 
String name () const
 Return the element's name.
 
virtual String declaration () const
 Return a string giving the element's name and class name.
 
Router * router () const
 Return the element's router.
 
int eindex () const
 Return the element's index within its router.
 
int eindex (Router *r) const
 Return the element's index within router r.
 
Master * master () const
 Return the element's master.
 
void attach_router (Router *r, int eindex)
 
int nports (bool isoutput) const
 Return the number of input or output ports.
 
int ninputs () const
 Return the number of input ports.
 
int noutputs () const
 Return the number of output ports.
 
const Port & port (bool isoutput, int port) const
 Return one of the element's ports.
 
const Port & input (int port) const
 Return one of the element's input ports.
 
const Port & output (int port) const
 Return one of the element's output ports.
 
bool port_active (bool isoutput, int port) const
 Check whether a port is active.
 
bool input_is_push (int port) const
 Check whether input port is push.
 
bool input_is_pull (int port) const
 Check whether input port is pull.
 
bool output_is_push (int port) const
 Check whether output port is push.
 
bool output_is_pull (int port) const
 Check whether output port is pull.
 
void port_flow (bool isoutput, int port, Bitvector *) const
 Analyze internal packet flow with respect to port p.
 
String configuration () const
 Return the element's current configuration string.
 
virtual bool can_live_reconfigure () const
 Return whether an element supports live reconfiguration.
 
virtual int live_reconfigure (Vector< String > &, ErrorHandler *)
 Reconfigure the element while the router is running.
 
RouterThread * home_thread () const
 Return the element's home thread.
 
virtual bool get_spawning_threads (Bitvector &b, bool isoutput, int port)
 
Bitvector get_pushing_threads ()
 
Bitvector get_passing_threads (bool forward, int port, Element *origin, bool &_is_fullpush, int level=0, bool touching=false)
 
Bitvector get_passing_threads (Element *origin, int level=0, bool touching=false)
 
Bitvector get_passing_threads (bool touching=false)
 
Bitvector get_spawning_threads ()
 
int home_thread_id () const
 Return the element's home thread id.
 
virtual bool is_mt_safe ()
 
virtual bool do_mt_safe_check (ErrorHandler *)
 
void add_remote_element (Element *e)
 
virtual int thread_configure (ThreadReconfigurationStage stage, ErrorHandler *errh, Bitvector threads)
 
void trigger_thread_reconfiguration (bool is_up, std::function< void()> ready, Bitvector threads)
 
virtual bool get_runnable_threads (Bitvector &) final=delete
 
virtual bool get_spawning_threads (Bitvector &) final=delete
 
int add_select (int fd, int mask)
 Register interest in mask events on file descriptor fd.
 
int remove_select (int fd, int mask)
 Remove interest in mask events on file descriptor fd.
 
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.
 
void add_read_handler (const String &name, ReadHandlerCallback read_callback, int user_data, uint32_t flags=0)
 Register a read handler named name.
 
void add_read_handler (const char *name, ReadHandlerCallback read_callback, int user_data=0, uint32_t flags=0)
 Register a read handler named name.
 
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.
 
void add_write_handler (const String &name, WriteHandlerCallback write_callback, int user_data, uint32_t flags=0)
 Register a write handler named name.
 
void add_write_handler (const char *name, WriteHandlerCallback write_callback, int user_data=0, uint32_t flags=0)
 Register a write handler named name.
 
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.
 
void set_handler (const String &name, int flags, HandlerCallback callback, int read_user_data, int write_user_data=0)
 Register a comprehensive handler named name.
 
void set_handler (const char *name, int flags, HandlerCallback callback, int read_user_data=0, int write_user_data=0)
 Register a comprehensive handler named name.
 
int set_handler_flags (const String &name, int set_flags, int clear_flags=0)
 Set flags for the handler named name.
 
void add_task_handlers (Task *task, NotifierSignal *signal, int flags, const String &prefix=String())
 Register handlers for a task.
 
void add_task_handlers (Task *task, NotifierSignal *signal, const String &prefix=String())
 
void add_task_handlers (Task *task, const String &prefix=String())
 
void add_data_handlers (const char *name, int flags, uint8_t *data)
 Register read and/or write handlers accessing data.
 
void add_data_handlers (const char *name, int flags, bool *data)
 
void add_data_handlers (const char *name, int flags, uint16_t *data)
 
void add_data_handlers (const char *name, int flags, int *data)
 
void add_data_handlers (const char *name, int flags, unsigned *data)
 
void add_data_handlers (const char *name, int flags, atomic_uint32_t *data)
 
void add_data_handlers (const char *name, int flags, long *data)
 
void add_data_handlers (const char *name, int flags, unsigned long *data)
 
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.
 
void add_net_order_data_handlers (const char *name, int flags, uint32_t *data)
 
void add_data_handlers (const char *name, int flags, double *data)
 
void add_data_handlers (const char *name, int flags, String *data)
 Register read and/or write handlers accessing data.
 
void add_data_handlers (const char *name, int flags, IPAddress *data)
 
void add_data_handlers (const char *name, int flags, EtherAddress *data)
 
void add_data_handlers (const char *name, int flags, Timestamp *data, bool is_interval=false)
 Register read and/or write handlers accessing data.
 
virtual int llrpc (unsigned command, void *arg)
 Handle a low-level remote procedure call.
 
int local_llrpc (unsigned command, void *arg)
 Execute an LLRPC from within the configuration.
 

Static Public Member Functions

static void static_initialize ()
 Initialize static data for this element class.
 
static void static_cleanup ()
 Clean up static data for this element class.
 
static String read_positional_handler (Element *, void *)
 Standard read handler returning a positional argument.
 
static String read_keyword_handler (Element *, void *)
 Standard read handler returning a keyword argument.
 
static int reconfigure_positional_handler (const String &, Element *, void *, ErrorHandler *)
 Standard write handler for reconfiguring an element by changing one of its positional arguments.
 
static int reconfigure_keyword_handler (const String &, Element *, void *, ErrorHandler *)
 Standard write handler for reconfiguring an element by changing one of its keyword arguments.
 

Static Public Attributes

static int nelements_allocated = 0
 
static const char PORTS_0_0 [] = "0"
 
static const char PORTS_0_1 [] = "0/1"
 
static const char PORTS_1_0 [] = "1/0"
 
static const char PORTS_1_1 [] = "1"
 
static const char PORTS_1_1X2 [] = "1/1-2"
 
static const char AGNOSTIC [] = "a"
 
static const char PUSH [] = "h"
 
static const char PULL [] = "l"
 
static const char PUSH_TO_PULL [] = "h/l"
 
static const char PULL_TO_PUSH [] = "l/h"
 
static const char PROCESSING_A_AH [] = "a/ah"
 
static const char COMPLETE_FLOW [] = "x/x"
 

Protected Attributes

enum batch_mode in_batch_mode
 
bool receives_batch
 

Detailed Description

Base class for Click elements.

Click programmers spend most of their time writing elements, which are subclasses of class Element. Element provides functionality of its own, particularly the input() and output() methods and associated Element::Port objects. More important, however, is the set of functions that derived classes override to define element behavior. Good Click programmers understand how the Click system uses these functions to manipulate and initialize elements. These functions fall into several categories:

Behavior specifications
These functions return static constants that describe element properties, such as class names, valid numbers of ports, and port processing types. Their values are automatically extracted from element source code for use by tools, so your source code should follow a specific syntax. Examples: class_name(), port_count(), processing(), flow_code(), flags().
Configuration, initialization, and cleanup
Configuration and initialization functions are called to set up an element as a router is initialized (or when the element itself is reconfigured). Most of the functions are passed an ErrorHandler argument, to which they should report any errors. By returning negative values, they can prevent the router from initializing. Other functions clean up elements when a router is removed and reconfigure an element as the router runs. Examples: cast(), configure(), configure_phase(), add_handlers(), initialize(), take_state(), cleanup(), can_live_reconfigure(), live_reconfigure().
Packet and event processing
These functions are called as the router runs to process packets and other events. Examples: push(), pull(), simple_action(), run_task(), run_timer(), selected().

Examples

Here is the simplest possible element definition.

class MyNothingElement : public Element { public:
MyNothingElement() { }
~MyNothingElement() { }
const char *class_name() const { return "MyNothingElement"; }
};
Base class for Click elements.
Definition element.hh:42

This element has no ports and accepts no configuration arguments; it does nothing. The required class_name() function informs Click's infrastructure of the element's class name.

Although this element is code-complete, Click's build process requires a bit more boilerplate, like so:

// ================== elements/local/mynothingelement.hh ==================
#ifndef CLICK_MYNOTHINGELEMENT_HH
#define CLICK_MYNOTHINGELEMENT_HH
#include <click/element.hh>
CLICK_DECLS
class MyNothingElement : public Element { public:
MyNothingElement() { }
~MyNothingElement() { }
const char *class_name() const { return "MyNothingElement"; }
};
CLICK_ENDDECLS
#endif
// ================== elements/local/mynothingelement.cc ==================
#include <click/config.h>
#include "mynothingelement.hh"
CLICK_DECLS
// Non-inline element code would go here.
CLICK_ENDDECLS
EXPORT_ELEMENT(MyNothingElement)
Click's Element class.

Some things to notice:

This slightly more complex example illustrates some more of Click's element infrastructure.

class MyNullElement : public Element { public:
MyNullElement() { }
~MyNullElement() { }
const char *class_name() const { return "MyNullElement"; }
const char *port_count() const { return PORTS_1_1; }
const char *processing() const { return PUSH; }
void push(int port, Packet *p) {
output(0).push(p);
}
};
virtual void push(int port, Packet *p)
Push packet p onto push input port.
Definition element.cc:3142
A network packet.
Definition packet.hh:68

This element processes packets in push mode, much like the standard PushNull element.

Packet Accounting

Element run-time methods, such as push(), pull(), run_task(), and run_timer(), must always obey the following rules:

Beginning Click programmers often violate these rules. Here are some examples to make them concrete.

This incorrect version of Click's Tee element attempts to duplicate a packet and send the duplicates to two different outputs.

void BadTee::push(int port, Packet *p) {
output(0).push(p);
output(1).push(p);
}
void push(Packet *p) const
Push packet p over this port.
Definition element.hh:765
const Port & port(bool isoutput, int port) const
Return one of the element's ports.
Definition element.hh:566
const Port & output(int port) const
Return one of the element's output ports.
Definition element.hh:591

A single packet pointer p has been pushed to two different outputs. This is always illegal; the rest of the configuration may have modified or even freed the packet before returning control to BadTee, so output(1).push(p) would probably touch freed memory! This situation requires the Packet::clone() method, which makes a copy of a packet:

void BetterTee::push(int port, Packet *p) {
output(0).push(p->clone());
output(1).push(p);
}
Packet * clone(bool fast=false)
Create a clone of this packet.
Definition packet.cc:1104

However, BetterTee would fail if the router ran out of memory for packet clones. p->clone() would return null, and passing a null pointer to another element's push() method isn't allowed. Here's how to fix this:

void BestTee::push(int port, Packet *p) {
if (Packet *clone = p->clone())
output(0).push(clone);
output(1).push(p);
}

Here's an example of a push() method with an obvious leak:

void LeakyCounter::push(int port, Packet *p) {
_counter++;
}

The method doesn't do anything with p, so its memory will never be reclaimed. Instead, it should either free the packet or pass it on to another element:

void BetterCounter1::push(int port, Packet *p) {
_counter++;
p->kill(); // free packet
}
void BetterCounter2::push(int port, Packet *p) {
_counter++;
output(0).push(p); // push packet on
}
void kill()
Delete this packet.
Definition packet.hh:1804

Leaks involving error conditions are more common in practice. For instance, this push() method counts IP packets. The programmer has defensively checked whether or not the input packet's network header pointer is set.

void LeakyIPCounter::push(int port, Packet *p) {
if (!p->has_network_header())
return;
_counter++;
output(0).push(p);
}
bool has_network_header() const
Return true iff the packet's network header pointer is set.
Definition packet.hh:1435

Close, but no cigar: if the input packet has no network header pointer, the packet will leak. Here are some better versions.

void BetterIPCounter1::push(int port, Packet *p) {
// In this version, non-IP packets are dropped. This is closest to LeakyIPCounter's intended functionality.
if (!p->has_network_header()) {
p->kill();
return;
}
_counter++;
output(0).push(p);
}
void BetterIPCounter2::push(int port, Packet *p) {
// This programmer thinks non-IP packets are serious errors and should cause a crash.
assert(p->has_network_header());
_counter++;
output(0).push(p);
}
void BetterIPCounter3::push(int port, Packet *p) {
// This programmer passes non-IP packets through without counting them.
_counter++;
output(0).push(p);
}

Initialization Phases

The Click infrastructure calls element initialization functions in a specific order during router initialization. Errors at any stage prevent later stages from running.

  1. Collects element properties, specifically configure_phase(), port_count(), flow_code(), processing(), and can_live_reconfigure().
  2. Calculates how many of each element's input and output ports are used in the configuration. There is an error if port_count() doesn't allow the result.
  3. Calculates each port's push or pull status. This depends on processing() values, and for agnostic ports, a constraint satisfaction algorithm that uses flow_code().
  4. Checks that every connection is between two push ports or two pull ports; that there are no agnostic port conflicts (each port is used as push or pull, never both); that no port goes unused; and that push output ports and pull input ports are connected exactly once. Violations cause an error.
  5. Sorts the elements by configure_phase() to construct a configuration order.
  6. Calls each element's configure() method in order, passing its configuration arguments and an ErrorHandler. All configure() functions are called, even if a prior configure() function returns an error.
  7. Calls every element's add_handlers() method.
  8. Calls every element's initialize() method in configuration order. Initialization is aborted as soon as any method returns an error (i.e., some initialize() methods might not be called).
  9. At this point, the router will definitely be installed. If the router was installed with a hotswap option, then Click searches the old and new router for potentially compatible pairs using hotswap_element(), and calls take_state() for each pair. Any errors are ignored.
  10. Installs the router.

Router cleanup takes place as follows. Click:

  1. Removes all element handlers.
  2. Calls each element's cleanup() function in reverse configuration order. The argument to cleanup() indicates where the initialization process completed for that element. See cleanup() for the specific constant names.
  3. Deletes each element. This step might be delayed relative to cleanup() to allow the programmer to examine an erroneous router's state.

Constructor & Destructor Documentation

◆ Element()

Element::Element ( )

Construct an Element.

Member Function Documentation

◆ push()

void Element::push ( int  port,
Packet *  p 
)
virtual

Push packet p onto push input port.

Parameters
portthe input port number on which the packet arrives
pthe packet

An upstream element transferred packet p to this element over a push connection. This element should process the packet as necessary and return. The packet arrived on input port port. push() must account for the packet either by pushing it further downstream, by freeing it, or by storing it temporarily.

The default implementation calls simple_action().

Reimplemented in SimpleBatchElement< T >, SimpleElement< T >, and ClassifyElement< T, Base >.

◆ pull()

Packet * Element::pull ( int  port)
virtual

Pull a packet from pull output port.

Parameters
portthe output port number receiving the pull request.
Returns
a packet

A downstream element initiated a packet transfer from this element over a pull connection. This element should return a packet pointer, or null if no packet is available. The pull request arrived on output port port.

Often, pull() methods will request packets from upstream using input(i).pull(). The default implementation calls simple_action().

Reimplemented in SimpleBatchElement< T >, and SimpleElement< T >.

◆ simple_action()

Packet * Element::simple_action ( Packet *  p)
virtual

Process a packet for a simple packet filter.

Parameters
pthe input packet
Returns
the output packet, or null

Many elements act as simple packet filters: they receive a packet from upstream using input 0, process that packet, and forward it downstream using output 0. The simple_action() method automates this process. The p argument is the input packet. simple_action() should process the packet and return a packet pointer – either the same packet, a different packet, or null. If the return value isn't null, Click will forward that packet downstream.

simple_action() must account for p, either by returning it, by freeing it, or by emitting it on some alternate push output port. (An optional second push output port 1 is often used to emit erroneous packets.)

simple_action() works equally well for push or pull port pairs. The default push() method calls simple_action() this way:

if ((p = simple_action(p)))
output(0).push(p);
virtual Packet * simple_action(Packet *p)
Process a packet for a simple packet filter.
Definition element.cc:3252

The default pull() method calls it this way instead:

if (Packet *p = input(0).pull())
if ((p = simple_action(p)))
return p;
return 0;
const Port & input(int port) const
Return one of the element's input ports.
Definition element.hh:579
virtual Packet * pull(int port)
Pull a packet from pull output port.
Definition element.cc:3162

An element that implements its processing with simple_action() should have a processing() code like AGNOSTIC or "a/ah", and a flow_code() like COMPLETE_FLOW or "x/x" indicating that packets can flow between the first input and the first output.

Most elements that use simple_action() have exactly one input and one output. However, simple_action() may be used for any number of inputs and outputs; a packet arriving on input port P will be emitted or output port P.

For technical branch prediction-related reasons, elements that use simple_action() can perform quite a bit slower than elements that use push() and pull() directly. The devirtualizer (click-devirtualize) can mitigate this effect.

◆ run_task()

bool Element::run_task ( Task *  task)
virtual

Run the element's task.

Returns
true if the task accomplished some meaningful work, false otherwise

The Task(Element *) constructor creates a Task object that calls this method when it fires. Most elements that have tasks use this method.

Note
The default implementation causes an assertion failure.

◆ run_timer()

void Element::run_timer ( Timer *  timer)
virtual

Run the element's timer.

Parameters
timerthe timer object that fired

The Timer(Element *) constructor creates a Timer object that calls this method when it fires. Most elements that have timers use this method.

Note
The default implementation causes an assertion failure.

◆ selected() [1/2]

void Element::selected ( int  fd,
int  mask 
)
virtual

Handle a file descriptor event.

Parameters
fdthe file descriptor
maskrelevant events: bitwise-or of one or more of SELECT_READ, SELECT_WRITE

Click's call to select() indicates that the file descriptor fd is readable, writable, or both. The overriding method should read or write the file descriptor as appropriate. The default implementation causes an assertion failure.

The element must have previously registered interest in fd with add_select().

Note
Only available at user level.
See also
add_select, remove_select

◆ selected() [2/2]

void Element::selected ( int  fd)
virtual

Handle a file descriptor event.

Parameters
fdthe file descriptor
Deprecated:
Elements should define selected(fd, mask) in preference to selected(fd). The default implementation of selected(fd, mask) calls selected(fd) for backwards compatibility.
Note
Only available at user level.
See also
add_select, remove_select

◆ is_fullpush()

bool Element::is_fullpush ( ) const
inline

Tell if the path up to this element is a full push path, always served by the same thread.

Hence, it is not only a matter of having only a push path, as some elements like Pipeliner may be push but lead to thread switch.

Precondition
get_passing_threads() have to be called on this element or any downstream element

If this element is part of a full push path, it means that packets passing through will always be handled by the same thread. They may be shared, in the sense that the usage count could be bigger than one. But then shared only with the same thread. Therefore non-atomic operations can be involved.

◆ checked_output_push()

void Element::checked_output_push ( int  port,
Packet *  p 
) const
inline

Push packet p to output port, or kill it if port is out of range.

Parameters
portoutput port number
ppacket to push

If port is in range (>= 0 and < noutputs()), then push packet p forward using output(port).push(p). Otherwise, kill p with p ->kill().

Note
It is invalid to call checked_output_push() on a pull output port.

◆ checked_input_pull()

Packet * Element::checked_input_pull ( int  port) const
inline

Pull a packet from input port, or return 0 if port is out of range.

Parameters
portinput port number

If port is in range (>= 0 and < ninputs()), then return the result of input(port).pull(). Otherwise, return null.

Note
It is invalid to call checked_input_pull() on a push input port.

◆ class_name()

Element::class_name ( ) const
pure virtual

Return the element's class name.

Each element class must override this function to return its class name.

Click tools extract class names from the source. For Click to find a class name, the function definition must appear inline, on a single line, inside the element class's declaration, and must return a C string constant. It should also have public accessibility. Here's an acceptable class_name() definition:

const char *class_name() const { return "ARPQuerier"; }
virtual const char * class_name() const =0
Return the element's class name.

◆ port_count()

const char * Element::port_count ( ) const
virtual

Return the element's port count specifier.

An element class overrides this virtual function to return a C string describing its port counts. The string gives acceptable input and output ranges, separated by a slash. Examples:

"1/1"
The element has exactly one input port and one output port.
"1-2/0"
One or two input ports and zero output ports.
"1/-6"
One input port and up to six output ports.
"2-/-"
At least two input ports and any number of output ports.
"3"
Exactly three input and output ports. (If no slash appears, the text is used for both input and output ranges.)
"1-/="
At least one input port and the same number of output ports.
"1-/=+"
At least one input port and one more output port than there are input ports.

Port counts are used to determine whether a configuration uses too few or too many ports, and lead to errors such as "'e' has no input 3" and "'e' input 3 unused".

Click extracts port count specifiers from the source for use by tools. For Click to find a port count specifier, the function definition must appear inline, on a single line, inside the element class's declaration, and must return a C string constant (or a name below). It should also have public accessibility. Here's an acceptable port_count() definition:

const char *port_count() const { return "1/1"; }
virtual const char * port_count() const
Return the element's port count specifier.
Definition element.cc:710

The default port_count() method returns "0/0".

The following names are available for common port count specifiers.

  • PORTS_0_0 for "0/0"
  • PORTS_0_1 for "0/1"
  • PORTS_1_0 for "1/0"
  • PORTS_1_1 for "1/1"
  • PORTS_1_1X2 for "1/1-2"

Since port_count() should simply return a C string constant, it shouldn't matter when it's called; nevertheless, it is called before configure().

◆ processing()

const char * Element::processing ( ) const
virtual

Return the element's processing specifier.

An element class overrides this virtual function to return a C string describing which of its ports are push, pull, or agnostic. The string gives acceptable input and output ranges, separated by a slash; the characters "h", "l", and "a" indicate push, pull, and agnostic ports, respectively. Examples:

  • "h/h" All input and output ports are push.
  • "h/l" Push input ports and pull output ports.
  • "a/ah" All input ports are agnostic. The first output port is also agnostic, but the second and subsequent output ports are push.
  • "hl/hlh" Input port 0 and output port 0 are push. Input port 1 and output port 1 are pull. All remaining inputs are pull; all remaining outputs are push.
  • "a" All input and output ports are agnostic. (If no slash appears, the text is used for both input and output ports.)

Thus, each character indicates a single port's processing type, except that the last character in the input section is used for all remaining input ports (and similarly for outputs). It's OK to have more characters than ports; any extra characters are ignored.

Click extracts processing specifiers from the source for use by tools. For Click to find a processing specifier, the function definition must appear inline, on a single line, inside the element class's declaration, and must return a C string constant. It should also have public accessibility. Here's an acceptable processing() definition:

const char *processing() const { return "a/ah"; }
virtual const char * processing() const
Return the element's processing specifier.
Definition element.cc:1139

The default processing() method returns "a/a", which sets all ports to agnostic.

The following names are available for common processing specifiers.

  • AGNOSTIC for "a/a"
  • PUSH for "h/h"
  • PULL for "l/l"
  • PUSH_TO_PULL for "h/l"
  • PULL_TO_PUSH for "l/h"
  • PROCESSING_A_AH for "a/ah"

Since processing() should simply return a C string constant, it shouldn't matter when it's called; nevertheless, it is called before configure().

◆ flow_code()

const char * Element::flow_code ( ) const
virtual

Return the element's internal packet flow specifier (its flow code).

An element class overrides this virtual function to return a C string describing how packets flow within the element. That is, can packets that arrive on input port X be emitted on output port Y? This information helps Click answer questions such as "What Queues are downstream of this element?" and "Should this agnostic port be push or pull?". See below for more.

A flow code string consists of an input specification and an output specification, separated by a slash. Each specification is a sequence of port codes. Packets can travel from an input port to an output port only if the port codes match.

The simplest port code is a single case-sensitive letter. For example, the flow code "x/x" says that packets can travel from the element's input port to its output port, while "x/y" says that packets never travel between ports.

A port code may also be a sequence of letters in brackets, such as [abz]. Two port codes match iff they have at least one letter in common, so [abz] matches a, but [abz] and [cde] do not match. If a caret ^ appears after the open bracket, the port code will match all letters except for those after the caret. Thus, the port code [^bc] is equivalent to [ABC...XYZadef...xyz].

Finally, the # character is also a valid port code, and may be used within brackets. One # matches another # only when they represent the same port number – for example, when one # corresponds to input port 2 and the other to output port 2. # never matches any letter. Thus, for an element with exactly 2 inputs and 2 outputs, the flow code "##/##" behaves like "xy/xy".

The last code in each specification is duplicated as many times as necessary, and any extra codes are ignored. The flow codes "[x#][x#][x#]/x######" and "[x#]/x#" behave identically.

Here are some example flow codes.

"x/x"

Packets may travel from any input port to any output port. Most elements use this flow code.

"xy/x"

Packets arriving on input port 0 may travel to any output port, but those arriving on other input ports will not be emitted on any output. ARPQuerier uses this flow code.

"x/y"

Packets never travel between input and output ports. Idle and Error use this flow code. So does KernelTun, since its input port and output port are decoupled (packets received on its input are sent to the kernel; packets received from the kernel are sent to its output).

"#/#"

Packets arriving on input port K may travel only to output port K. Suppressor uses this flow code.

"#/[^#]"

Packets arriving on input port K may travel to any output port except K. EtherSwitch uses this flow code.

"xy/[xy]x"

Packets arriving on input port 0 may travel to any output port. Packet arriving on any other input port can only travel to output port 0. Bypass uses this flow code.

Click extracts flow codes from the source for use by tools. For Click to find a flow code, the function definition must appear inline, on a single line, inside the element class's declaration, and must return a C string constant. It should also have public accessibility. Here's an acceptable flow_code() definition:

const char *flow_code() const { return "xy/x"; }
virtual const char * flow_code() const
Return the element's internal packet flow specifier (its flow code).
Definition element.cc:946

The default flow_code() method returns "x/x", which indicates that packets may travel from any input to any output. This default is acceptable for the vast majority of elements.

The following name is available for a common flow code.

  • COMPLETE_FLOW for "x/x"

Since flow_code() should simply return a C string constant, it shouldn't matter when it's called; nevertheless, it is called before configure().

Determining an element's flow code

To pick the right flow code for an element, consider how a flow code would affect a simple router.

Given an element E with input port M and output port N, imagine this simple configuration (or a similar configuration):

... -> RED -> [M] E [N] -> Queue -> ...;

Now, should the RED element include the Queue element in its queue length calculation? If so, then the flow code's Mth input port code and Nth output port code should match. If not, they shouldn't.

For example, consider ARPQuerier's second input port. On receiving an ARP response on that input, ARPQuerier may emit a held-over IP packet to its first output. However, a RED element upstream of that second input port probably wouldn't count the downstream Queue in its queue length calculation. After all, the ARP responses are effectively dropped; packets emitted onto the Queue originally came from ARPQuerier's first input port. Therefore, ARPQuerier's flow code, "xy/x", specifies that packets arriving on the second input port are not emitted on any output port.

The ARPResponder element provides a contrasting example. It has one input port, which receives ARP queries, and one output port, which emits the corresponding ARP responses. A RED element upstream of ARPResponder probably would want to include a downstream Queue, since queries received by ARPResponder are effectively transmuted into emitted responses. Thus, ARPResponder's flow code, "x/x" (the default), specifies that packets travel through it, even though the packets it emits are completely different from the packets it receives.

If you find this confusing, don't fret. It is perfectly fine to be conservative when assigning flow codes, and the vast majority of the Click distribution's elements use COMPLETE_FLOW.

◆ flags()

const char * Element::flags ( ) const
virtual

Return the element's flags.

Warning
This interface is not stable.

This virtual function is called to fetch a string describing the element's flags. A flags word includes one or more space-separated flag settings, where a flag setting consists of an uppercase letter optionally followed by a number. The following flags are currently defined.

A

This element requires AlignmentInfo information. The click-align tool only generates AlignmentInfo for A-flagged elements.

S0

This element neither generates nor consumes packets. In other words, every packet received on its inputs will be emitted on its outputs, and every packet emitted on its outputs must have originated from its inputs. Notification uses this flag to discover certain idle paths. For example, packet schedulers (RoundRobinSched, PrioSched) never generate packets and so declare the S0 flag. As a result, degenerate paths like "RoundRobinSched -> ToDevice", where RoundRobinSched has 0 inputs, are idle rather than busy, and waste no CPU time.

◆ flag_value()

int Element::flag_value ( int  flag) const

Return the flag value for flag in flags().

Parameters
flagthe flag

Returns the numeric flag value if flag was specified in flags(), 1 if flag was specified without a numeric flag value, and -1 if flag was not specified.

◆ cast()

void * Element::cast ( const char *  name)
virtual

Attempt to cast the element to a named type.

Parameters
namename of the type being cast to

Click calls this function to see whether this element has a given type, identified by name. Thus, cast() is Click's version of the C++ dynamic_cast operator. (dynamic_cast itself is not available in the Linux kernel, so we rolled our own.) The function should return a pointer to the named object, or a null pointer if this element doesn't have that type. name can name an element class or another type of interface, such as "Storage" or Notifier::EMPTY_NOTIFIER.

The default implementation returns this element if name equals class_name(), and null otherwise.

You should override cast() if your element inherits from another element (and you want to expose that inheritance to Click); the resulting cast() method will check both class names. For example, if element Derived inherited from element Base, Derived::cast() might be defined like this:

void *Derived::cast(const char *name) {
if (strcmp(name, "Derived") == 0)
return (Derived *) this;
else if (strcmp(name, "Base") == 0)
return (Base *) this;
else
return Base::cast(name);
}
String name() const
Return the element's name.
Definition element.cc:555

The recursive call to Base::cast() is useful in case Base itself overrides cast(). The explicit check for the name "Base" is necessary in case Base did not override cast(): the default cast() implementation compares against class_name(), which in this case is "Derived". Always explicitly cast this to the correct type before returning it.

You should also override cast() if your element provides another interface, such as Storage or a Notifier.

See also
port_cast

◆ port_cast()

void * Element::port_cast ( bool  isoutput,
int  port,
const char *  name 
)
virtual

Attempt to cast an element's port to a named type.

Parameters
isoutputfalse for input ports, true for output ports
portport number
namename of the type being cast to

Click calls this function to see whether a port corresponds to an object of the type called name. The function should return a pointer to the named object, or a null pointer if this port doesn't have that type. name can name an element class or another type of interface, such as "Storage" or Notifier::EMPTY_NOTIFIER.

The default implementation returns the result of cast(), ignoring the isoutput and port arguments.

The cast() method suffices for most purposes, but some Click functionality, such as Notifiers, can use the additional precision of port_cast().

See also
cast

◆ configure_phase()

int Element::configure_phase ( ) const
virtual

Return the element's configure phase, which determines the order in which elements are configured and initialized.

Click configures and initializes elements in increasing order of configure_phase(). An element with configure phase 1 will always be configured (have its configure() method called) before an element with configure phase 2. Thus, if two element classes must be configured in a given order, they should define configure_phase() functions to enforce that order. For example, the AddressInfo element defines address abbreviations for other elements to use; it should thus be configured before other elements, and its configure_phase() method returns a low value.

Configure phases should be defined relative to the following constants, which are listed in increasing order.

CONFIGURE_PHASE_FIRST

Configure before other elements. Used by AddressInfo.

CONFIGURE_PHASE_INFO

Configure early. Appropriate for most information elements, such as ScheduleInfo.

CONFIGURE_PHASE_PRIVILEGED

Intended for elements that require root privilege when run at user level, such as FromDevice and ToDevice. The ChangeUID element, which reliquishes root privilege, runs at configure phase CONFIGURE_PHASE_PRIVILEGED + 1.

CONFIGURE_PHASE_DEFAULT

The default implementation returns CONFIGURE_PHASE_DEFAULT, so most elements are configured at this phase. Appropriate for most elements.

CONFIGURE_PHASE_LAST
Configure after other elements.

The body of a configure_phase() method should consist of a single return statement returning some constant. Although it shouldn't matter when it's called, it is called before configure().

◆ configure()

int Element::configure ( Vector< String > &  conf,
ErrorHandler *  errh 
)
virtual

Parse the element's configuration arguments.

Parameters
confconfiguration arguments
errherror handler

The configure() method is passed the element's configuration arguments. It should parse them, report any errors, and initialize the element's internal state.

The conf argument is the element's configuration string, divided into configuration arguments by splitting at commas and removing comments and leading and trailing whitespace (see cp_argvec()). If conf is empty, the element was not supplied with a configuration string (or its configuration string contained only comments and whitespace). It is safe to modify conf; modifications will be thrown away when the function returns.

Any errors, warnings, or messages should be reported to errh. Messages need not specify the element name or type, since this information will be provided as context. errh.nerrors() is initially zero.

configure() should return a negative number if configuration fails. Returning a negative number prevents the router from initializing. The default configure() method succeeds if and only if there are no configuration arguments.

configure() methods are called in order of configure_phase(). All elements' configure() methods are called, even if an early configure() method fails; this is to report all relevant error messages to the user, rather than just the first.

configure() is called early in the initialization process, and cannot check whether a named handler exists. That function must be left for initialize(). Assuming all router connections are valid and all configure() methods succeed, the add_handlers() functions will be called next.

A configure() method should avoid potentially harmful actions, such as truncating files or attaching to devices. These actions should be left for the initialize() method, which is called later. This avoids harm if another element cannot be configured, or if the router is incorrectly connected, since in those cases initialize() will never be called.

Elements that support live reconfiguration (see can_live_reconfigure()) should expect configure() to be called at run time, when a user writes to the element's config handler. In that case, configure() must be careful not to disturb the existing configuration unless the new configuration is error-free.

Note
In previous releases, configure() could not determine whether a port is push or pull or query the router for information about neighboring elements. Those functions had to be left for initialize(). Even in the current release, if any element in a configuration calls the deprecated set_ninputs() or set_noutputs() function from configure(), then all push, pull, and neighbor information is invalidated until initialize() time.
See also
live_reconfigure, args.hh for argument parsing

◆ add_handlers()

void Element::add_handlers ( )
virtual

Install the element's handlers.

The add_handlers() method should install any handlers the element provides by calling add_read_handler(), add_write_handler(), and set_handler(). These functions may also be called from configure(), initialize(), or even later, during router execution. However, it is better in most cases to initialize handlers in configure() or add_handlers(), since elements that depend on other handlers often check in initialize() whether those handlers exist.

add_handlers() is called after configure() and before initialize(). When it runs, it is guaranteed that every configure() method succeeded and that all connections are correct (push and pull match up correctly and there are no unused or badly-connected ports).

Most add_handlers() methods simply call add_read_handler(), add_write_handler(), add_task_handlers(), and possibly set_handler() one or more times. The default add_handlers() method does nothing.

Click automatically provides five handlers for each element: class, name, config, ports, and handlers. There is no need to provide these yourself.

◆ initialize()

int Element::initialize ( ErrorHandler *  errh)
virtual

Initialize the element.

Parameters
errherror handler

The initialize() method is called just before the router is placed on line. It performs any final initialization, and provides the last chance to abort router installation with an error. Any errors, warnings, or messages should be reported to errh. Messages need not specify the element name; this information will be supplied externally. errh.nerrors() is initially zero.

initialize() should return zero if initialization succeeds, or a negative number if it fails. Returning a negative number prevents the router from initializing. The default initialize() method always returns zero (success).

initialize() methods are called in order of configure_phase(), using the same order as for configure(). When an initialize() method fails, router initialization stops immediately, and no more initialize() methods are called. Thus, at most one initialize() method can fail per router configuration.

initialize() is called after add_handlers() and before take_state(). When it runs, it is guaranteed that every configure() method succeeded, that all connections are correct (push and pull match up correctly and there are no unused or badly-connected ports), and that every add_handlers() method has been called.

If every element's initialize() method succeeds, then the router is installed, and will remain installed until another router replaces it. Any errors that occur later than initialize() – during take_state(), push(), or pull(), for example – will not take the router off line.

Strictly speaking, the only task that must go in initialize() is checking whether a handler exists, since that information isn't available at configure() time. It's often convenient, however, to put other functionality in initialize(). For example, opening files for writing fits well in initialize(): if the configuration has errors before the relevant element is initialized, any existing file will be left as is. Common tasks performed in initialize() methods include:

  • Initializing Task objects.
  • Allocating memory.
  • Opening files.
  • Initializing network devices.
Note
initialize() methods may not create or destroy input and output ports, but this functionality is deprecated anyway.
In previous releases, configure() could not determine whether a port was push or pull or query the router for information about neighboring elements, so those tasks were relegated to initialize() methods. In the current release, configure() can perform these tasks too.

◆ take_state()

void Element::take_state ( Element *  old_element,
ErrorHandler *  errh 
)
virtual

Initialize the element for hotswap, where the element should take old_element's state, if possible.

Parameters
old_elementelement in the old configuration; result of hotswap_element()
errherror handler

The take_state() method supports hotswapping, and is the last stage of configuration installation. When a configuration is successfully installed with the hotswap option, the driver (1) stops the old configuration, (2) searches the two configurations for pairs of compatible elements, (3) calls take_state() on the new elements in those pairs to give them a chance to take state from the old elements, and (4) starts the new configuration.

take_state() is called only when a configuration is hotswapped in. The default take_state() implementation does nothing; there's no need to override it unless your element has state you want preserved across hotswaps.

The old_element argument is an element from the old configuration (that is, from router()->hotswap_router()) obtained by calling hotswap_element(). If hotswap_element() returns null, take_state() will not be called. The default hotswap_element() returns an old_element has the same name() as this element. This is often too loose; for instance, old_element might have a completely different class. Thus, most take_state() methods begin by attempting to cast() old_element to a compatible class, and silently returning if the result is null. Alternatively, you can override hotswap_element() and put the check there.

Errors and warnings should be reported to errh, but the router will be installed whether or not there are errors. take_state() should always leave this element in a state that's safe to run, and old_element in a state that's safe to cleanup().

take_state() is called after initialize(). When it runs, it is guaranteed that this element's configuration will shortly be installed. Every configure() and initialize() method succeeded, all connections are correct (push and pull match up correctly and there are no unused or badly-connected ports), and every add_handlers() method has been called. It is also guaranteed that the old configuration (of which old_element is a part) had been successfully installed, but that none of its tasks are running at the moment.

◆ hotswap_element()

Element * Element::hotswap_element ( ) const
virtual

Return a compatible element in the hotswap router.

hotswap_element() searches the hotswap router, router()->hotswap_router(), for an element compatible with this element. It returns that element, if any. If there's no compatible element, or no hotswap router, then it returns 0.

The default implementation searches for an element with the same name as this element. Thus, it returns 0 or an element that satisfies this constraint: hotswap_element()->name() == name().

Generally, this constraint is too loose. A Queue element can't hotswap state from an ARPResponder, even if they do have the same name. Most elements also check that hotswap_element() has the right class, using the cast() function. This check can go either in hotswap_element() or in take_state() itself, whichever is easier; Click doesn't use the result of hotswap_element() except as an argument to take_state().

See also
take_state, Router::hotswap_router

◆ cleanup()

void Element::cleanup ( CleanupStage  stage)
virtual

Clean up the element's state.

Parameters
stagethis element's maximum initialization stage

The cleanup() method should clean up any state allocated by the initialization process. For example, it should close any open files, free up memory, and unhook from network devices. Click calls cleanup() when it determines that an element's state is no longer needed, either because a router configuration is about to be removed or because the router configuration failed to initialize properly. Click will call the cleanup() method exactly once on every element it creates.

The stage parameter is an enumeration constant indicating how far the element made it through the initialization process. Possible values are, in increasing order:

CLEANUP_BEFORE_CONFIGURE

The element's configure() method was not called. This happens when some element's port counts or push/pull processing was wrong.

CLEANUP_CONFIGURE_FAILED

The element's configure() method was called, but it failed.

CLEANUP_CONFIGURED

The element's configure() method was called and succeeded, but its initialize() method was not called (because some other element's configure() method failed, or there was a problem with the configuration's connections).

CLEANUP_INITIALIZE_FAILED

The element's configure() and initialize() methods were both called. configure() succeeded, but initialize() failed.

CLEANUP_INITIALIZED

The element's configure() and initialize() methods were called and succeeded, but its router was never installed (because some other element's initialize() method failed).

CLEANUP_ROUTER_INITIALIZED

The element's configure() and initialize() methods were called and succeeded, and the router of which it is a part was successfully installed.

CLEANUP_MANUAL
Never used by Click. Intended for use when element code calls cleanup() explicitly.

A configuration's cleanup() methods are called in the reverse of the configure_phase() order used for configure() and initialize().

The default cleanup() method does nothing.

cleanup() serves some of the same functions as an element's destructor. However, cleanup() may be called long before an element is destroyed. Elements that are part of an erroneous router are cleaned up, but kept around for debugging purposes until another router is installed.

◆ static_initialize()

void Element::static_initialize ( )
inlinestatic

Initialize static data for this element class.

Place initialization code for an element class's shared global state in the static_initialize() static member function. (For example, the IPFilter element class uses static_initialize() to set up various parsing tables.) Click drivers will call this function when the element code is loaded, before any elements of the class are created.

static_initialize functions are called in an arbitrary and unpredictable order (not, for example, the configure_phase() order). Element authors are responsible for handling static initialization dependencies.

For Click to find a static_initialize declaration, it must appear inside the element class's class declaration on its own line and have the following prototype:

static void static_initialize();
static void static_initialize()
Initialize static data for this element class.
Definition element.hh:481

It must also have public accessibility.

Note
In most cases you should also define a static_cleanup() function to clean up state initialized by static_initialize().
See also
Element::static_cleanup

◆ static_cleanup()

void Element::static_cleanup ( )
inlinestatic

Clean up static data for this element class.

Place cleanup code for an element class's shared global state in the static_cleanup() static member function. Click drivers will call this function before unloading the element code.

static_cleanup functions are called in an arbitrary and unpredictable order (not, for example, the configure_phase() order, and not the reverse of the static_initialize order). Element authors are responsible for handling static cleanup dependencies.

For Click to find a static_cleanup declaration, it must appear inside the element class's class declaration on its own line and have the following prototype:

static void static_cleanup();
static void static_cleanup()
Clean up static data for this element class.
Definition element.hh:509

It must also have public accessibility.

See also
Element::static_initialize

◆ name()

String Element::name ( ) const

Return the element's name.

This is the name used to declare the element in the router configuration, with all compound elements expanded.

◆ declaration()

String Element::declaration ( ) const
virtual

Return a string giving the element's name and class name.

never

The result has the form "name :: class_name". Element classes can override this function to supply additional important information, if desired; for example, FromDump returns a string "name :: class_name(filename)".

◆ router()

Router * Element::router ( ) const
inline

Return the element's router.

◆ eindex() [1/2]

int Element::eindex ( ) const
inline

Return the element's index within its router.

Invariant
this == router()->element(eindex())

◆ eindex() [2/2]

int Element::eindex ( Router *  r) const
inline

Return the element's index within router r.

Returns -1 if r != router().

◆ master()

Master * Element::master ( ) const
inline

Return the element's master.

◆ nports()

int Element::nports ( bool  isoutput) const
inline

Return the number of input or output ports.

Parameters
isoutputfalse for input ports, true for output ports

◆ ninputs()

int Element::ninputs ( ) const
inline

Return the number of input ports.

◆ noutputs()

int Element::noutputs ( ) const
inline

Return the number of output ports.

◆ port()

const Element::Port & Element::port ( bool  isoutput,
int  port 
) const
inline

Return one of the element's ports.

Parameters
isoutputfalse for input ports, true for output ports
portport number

An assertion fails if p is out of range.

◆ input()

const Element::Port & Element::input ( int  port) const
inline

Return one of the element's input ports.

Parameters
portport number

An assertion fails if port is out of range.

See also
Port, port

◆ output()

const Element::Port & Element::output ( int  port) const
inline

Return one of the element's output ports.

Parameters
portport number

An assertion fails if port is out of range.

See also
Port, port

◆ port_active()

bool Element::port_active ( bool  isoutput,
int  port 
) const
inline

Check whether a port is active.

Parameters
isoutputfalse for input ports, true for output ports
portport number

Returns true iff port is in range and port is active. Push outputs and pull inputs are active; pull outputs and push inputs are not.

See also
Element::Port::active

◆ input_is_push()

bool Element::input_is_push ( int  port) const
inline

Check whether input port is push.

Returns true iff input port exists and is push.

◆ input_is_pull()

bool Element::input_is_pull ( int  port) const
inline

Check whether input port is pull.

Returns true iff input port exists and is pull.

See also
port_active

◆ output_is_push()

bool Element::output_is_push ( int  port) const
inline

Check whether output port is push.

Returns true iff output port exists and is push.

See also
port_active

◆ output_is_pull()

bool Element::output_is_pull ( int  port) const
inline

Check whether output port is pull.

Returns true iff output port exists and is pull.

◆ port_flow()

void Element::port_flow ( bool  isoutput,
int  p,
Bitvector *  travels 
) const

Analyze internal packet flow with respect to port p.

Parameters
isoutputfalse for input ports, true for output ports
pport number
[out]travelsthe bitvector to initialize with internal packet flow information

Analyzes the element's flow_code() and determines how packets might travel from the specified port. The travels bitvector is initialized to have one entry per complementary port; thus, if isoutput is true, then travels has ninputs() entries. The entry for port x is set to true iff packets can travel from p to x. Returns all false if p is out of range.

For example, if flow_code() is "xy/xxyx", and the element has 2 inputs and 4 outputs, then:

  • port_flow(false, 0, travels) returns [true, true, false, true]
  • port_flow(false, 1, travels) returns [false, false, true, false]
  • port_flow(true, 0, travels) returns [true, false]

Uses an element's overridden flow code when one is supplied; see Router::flow_code_override().

See also
flow_code

◆ configuration()

String Element::configuration ( ) const

Return the element's current configuration string.

The configuration string is obtained by calling the element's "config" read handler. The default read handler calls Router::econfiguration().

◆ can_live_reconfigure()

bool Element::can_live_reconfigure ( ) const
virtual

Return whether an element supports live reconfiguration.

Returns true iff this element can be reconfigured as the router is running. Click will make the element's "config" handler writable if can_live_reconfigure() returns true; when that handler is written, Click will call the element's live_reconfigure() function. The default implementation returns false.

◆ live_reconfigure()

int Element::live_reconfigure ( Vector< String > &  conf,
ErrorHandler *  errh 
)
virtual

Reconfigure the element while the router is running.

Parameters
confconfiguration arguments
errherror handler

This function should parse the configuration arguments in conf, set the element's state accordingly, and report any error messages or warnings to errh. This resembles configure(). However, live_reconfigure() is called when the element's "config" handler is written, rather than at router initialization time. Thus, the element already has a working configuration. If conf has an error, live_reconfigure() should leave this previous working configuration alone.

can_live_reconfigure() must return true for live_reconfigure() to work.

Return >= 0 on success, < 0 on error. On success, Click will set the element's old configuration arguments to conf, so that later reads of the "config" handler will return conf. (An element can override this by defining its own "config" handler.)

The default implementation simply calls configure(conf, errh). This is OK as long as configure() doesn't change the element's state on error.

See also
can_live_reconfigure

◆ home_thread()

RouterThread * Element::home_thread ( ) const

Return the element's home thread.

◆ get_spawning_threads()

bool Element::get_spawning_threads ( Bitvector &  bmp,
bool  isoutput,
int  port 
)
virtual

Set threads in bitvector than will start pushing or pulling from this element This function implements the expected behaviour, but should be overriden by elements with another behaviour. Default behaviour :

  • If Push to pull : stop traversing, spawn the home thread id if port is output
  • If Pull to push : stop traversing, spawn the home thread id if port is input
  • If no input, and output is push : spawn the home thread id
  • Else : Continue traversing, not spawning anything
    Returns
    false if this element is switching threads, so that the traversing to get all threads on this path should stop here. Queues would return false for example as an element after the queue will only be traversed by the threads of the queue, not the one before.

◆ get_passing_threads()

Bitvector Element::get_passing_threads ( bool  touching = false)

Return the list of threads passing by this element if touching is true (default) it will also return the threads touching the element, such as remote tables, multiple directions elements, handlers etc.

◆ home_thread_id()

int Element::home_thread_id ( ) const

Return the element's home thread id.

◆ trigger_thread_reconfiguration()

void Element::trigger_thread_reconfiguration ( bool  is_up,
std::function< void()>  ready,
Bitvector  threads 
)

Propagate a message to tell that some threads will start pushing or stop pushing packets. This allows further element to prepare for thread migration.

In practice, it will call thread_reconfigure with UP_PRE or DOWN_PRE on downstream elements, execute the ready function, then call UP_POST or DOWN_POST

Parameters
is_upTrue if the threads are being activated, false if deactivated.

◆ add_select()

int Element::add_select ( int  fd,
int  mask 
)

Register interest in mask events on file descriptor fd.

Parameters
fdthe file descriptor
maskrelevant events: bitwise-or of one or more of SELECT_READ, SELECT_WRITE

Click will register interest in readability and/or writability on file descriptor fd. When fd is ready, Click will call this element's selected(fd, mask) method.

add_select(fd, mask) overrides any previous add_select() for the same fd and events in mask. However, different elements may register interest in different events for the same fd.

Note
Only available at user level.
Selecting for writability with SELECT_WRITE normally requires more care than selecting for readability with SELECT_READ. You should add_select(fd, SELECT_WRITE) only when there is data to write to fd. Otherwise, Click will constantly poll your element's selected(fd, mask) method.
See also
remove_select, selected

◆ remove_select()

int Element::remove_select ( int  fd,
int  mask 
)

Remove interest in mask events on file descriptor fd.

Parameters
fdthe file descriptor
maskrelevant events: bitwise-or of one or more of SELECT_READ, SELECT_WRITE

Click will remove any existing add_select() registrations for readability and/or writability on file descriptor fd. The named events on fd will no longer cause a selected() call.

Note
Only available at user level.
See also
add_select, selected

◆ add_read_handler() [1/3]

void Element::add_read_handler ( const String &  name,
ReadHandlerCallback  read_callback,
const void *  user_data = 0,
uint32_t  flags = 0 
)

Register a read handler named name.

Parameters
namehandler name
read_callbackfunction called when handler is read
user_datauser data parameter passed to read_callback
flagsflags to set

Adds a read handler named name for this element. Reading the handler returns the result of the read_callback function, which is called like this:

String result = read_callback(e, user_data);
A string of characters.
Definition string.hh:22

e is this element pointer.

add_read_handler(name) overrides any previous add_read_handler(name) or set_handler(name), but any previous add_write_handler(name) remains in effect.

The added read handler takes no parameters. To create a read handler with parameters, use set_handler() or set_handler_flags().

See also
read_positional_handler, read_keyword_handler: standard read handler callback functions
add_write_handler, set_handler, add_task_handlers

◆ add_read_handler() [2/3]

void Element::add_read_handler ( const String &  name,
ReadHandlerCallback  read_callback,
int  user_data,
uint32_t  flags = 0 
)

Register a read handler named name.

This version of add_read_handler() is useful when user_data is an integer. Note that the read_callback function must still cast its void * argument to intptr_t to obtain the integer value.

◆ add_read_handler() [3/3]

void Element::add_read_handler ( const char *  name,
ReadHandlerCallback  read_callback,
int  user_data = 0,
uint32_t  flags = 0 
)

Register a read handler named name.

This version of add_read_handler() is useful when name is a static constant string. name is passed to String::make_stable. The memory referenced by name must remain valid for as long as the router containing this element.

◆ add_write_handler() [1/3]

void Element::add_write_handler ( const String &  name,
WriteHandlerCallback  write_callback,
const void *  user_data = 0,
uint32_t  flags = 0 
)

Register a write handler named name.

Parameters
namehandler name
write_callbackfunction called when handler is written
user_datauser data parameter passed to write_callback
flagsflags to set

Adds a write handler named name for this element. Writing the handler calls the write_callback function like this:

int r = write_callback(data, e, user_data, errh);

e is this element pointer. The return value r should be negative on error, positive or zero on success. Any messages should be reported to the errh ErrorHandler object.

add_write_handler(name) overrides any previous add_write_handler(name) or set_handler(name), but any previous add_read_handler(name) remains in effect.

See also
reconfigure_positional_handler, reconfigure_keyword_handler: standard write handler callback functions
add_read_handler, set_handler, add_task_handlers

◆ add_write_handler() [2/3]

void Element::add_write_handler ( const String &  name,
WriteHandlerCallback  write_callback,
int  user_data,
uint32_t  flags = 0 
)

Register a write handler named name.

This version of add_write_handler() is useful when user_data is an integer. Note that the write_callback function must still cast its void * argument to intptr_t to obtain the integer value.

◆ add_write_handler() [3/3]

void Element::add_write_handler ( const char *  name,
WriteHandlerCallback  write_callback,
int  user_data = 0,
uint32_t  flags = 0 
)

Register a write handler named name.

This version of add_write_handler() is useful when name is a static constant string. name is passed to String::make_stable. The memory referenced by name must remain valid for as long as the router containing this element.

◆ set_handler() [1/3]

void Element::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.

Parameters
namehandler name
flagshandler flags
callbackfunction called when handler is written
read_user_dataread user data parameter stored in the handler
write_user_datawrite user data parameter stored in the handler

Registers a comprehensive handler named name for this element. The handler handles the operations specified by flags, which can include Handler::f_read, Handler::f_write, Handler::f_read_param, and others. Reading the handler calls the callback function like this:

String data;
int r = callback(Handler::f_read, data, e, h, errh);
@ f_read
Handler supports read operations.
Definition handler.hh:22

Writing the handler calls it like this:

int r = callback(Handler::f_write, data, e, h, errh);
@ f_write
Handler supports write operations.
Definition handler.hh:23

e is this element pointer, and h points to the Handler object for this handler. The data string is an out parameter for reading and an in parameter for writing; when reading with parameters, data has the parameters on input and should be replaced with the result on output. The return value r should be negative on error, positive or zero on success. Any messages should be reported to the errh ErrorHandler object.

set_handler(name) overrides any previous add_read_handler(name), add_write_handler(name), or set_handler(name).

◆ set_handler() [2/3]

void Element::set_handler ( const String &  name,
int  flags,
HandlerCallback  callback,
int  read_user_data,
int  write_user_data = 0 
)

Register a comprehensive handler named name.

This version of set_handler() is useful when user_data is an integer. Note that the Handler::user_data() methods still return void * values.

◆ set_handler() [3/3]

void Element::set_handler ( const char *  name,
int  flags,
HandlerCallback  callback,
int  read_user_data = 0,
int  write_user_data = 0 
)

Register a comprehensive handler named name.

This version of set_handler() is useful when name is a static constant string. name is passed to String::make_stable. The memory referenced by name must remain valid for as long as the router containing this element.

◆ set_handler_flags()

int Element::set_handler_flags ( const String &  name,
int  set_flags,
int  clear_flags = 0 
)

Set flags for the handler named name.

Parameters
namehandler name
set_flagshandler flags to set
clear_flagshandler flags to clear

Sets flags for any handlers named name for this element. Fails if no name handler exists.

◆ add_task_handlers()

void Element::add_task_handlers ( Task *  task,
NotifierSignal *  signal,
int  flags,
const String &  prefix = String() 
)

Register handlers for a task.

Parameters
taskTask object
signaloptional NotifierSignal object
flagsdefines handlers to install
prefixprefix for each handler

Adds a standard set of handlers for the task. They can include:

  • A "scheduled" read handler, which returns true if the task is scheduled and false if not.
  • A "scheduled" write handler, which accepts a Boolean and unschedules or reschedules the task as appropriate.
  • A "tickets" read handler, which returns the task's tickets.
  • A "tickets" write handler to set the task's tickets.
  • A "home_thread" read handler, which returns the task's home thread ID.
  • A "home_thread" write handler, which sets the task's home thread ID.

The flags argument controls which handlers are installed. By default, this is all but the the "scheduled" write handler. Individual flags are:

  • TASKHANDLER_WRITE_SCHEDULED: A "scheduled" write handler.
  • TASKHANDLER_WRITE_TICKETS: A "tickets" write handler.
  • TASKHANDLER_WRITE_HOME_THREAD: A "home_thread" write handler.
  • TASKHANDLER_WRITE_ALL: All available write handlers.
  • TASKHANDLER_DEFAULT: Equals TASKHANDLER_WRITE_TICKETS | TASKHANDLER_WRITE_HOME_THREAD.

Depending on Click's configuration options, some of these handlers might not be available. If Click was configured with schedule debugging, the "scheduled" read handler will additionally report whether an unscheduled task is pending, and a "notifier" read handler will report the state of the signal, if any.

Each handler name is prefixed with the prefix string, so an element with multiple Task objects can register handlers for each of them.

See also
add_read_handler, add_write_handler, set_handler

◆ add_data_handlers() [1/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
uint8_t *  data 
)

Register read and/or write handlers accessing data.

Parameters
namehandler name
flagshandler flags, containing at least one of Handler::f_read and Handler::f_write
datapointer to data

Registers read and/or write handlers named name for this element. If (flags & Handler::f_read), registers a read handler; if (flags & Handler::f_write), registers a write handler. These handlers read or set the data stored at *data, which might, for example, be an element instance variable. This data is unparsed and/or parsed using the expected functions; for example, the bool version uses BoolArg::unparse() and BoolArg::parse(). name is passed to String::make_stable. The memory referenced by name must remain valid for as long as the router containing this element.

Overloaded versions of this function are available for many fundamental data types.

◆ add_data_handlers() [2/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
bool *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [3/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
uint16_t *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [4/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
int *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [5/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
unsigned *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [6/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
atomic_uint32_t *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [7/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
long *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [8/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
unsigned long *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_net_order_data_handlers() [1/2]

void Element::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.

Parameters
namehandler name
flagshandler flags, containing at least one of Handler::f_read and Handler::f_write
datapointer to data

Registers read and/or write handlers named name for this element. If (flags & Handler::f_read), registers a read handler; if (flags & Handler::f_write), registers a write handler. These handlers read or set the data stored at *data, which might, for example, be an element instance variable.

◆ add_net_order_data_handlers() [2/2]

void Element::add_net_order_data_handlers ( const char *  name,
int  flags,
uint32_t *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [9/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
double *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [10/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
String *  data 
)

Register read and/or write handlers accessing data.

This function's read handler returns *data unchanged, and its write handler sets *data to the input string as received, without unquoting or removing leading and trailing whitespace.

◆ add_data_handlers() [11/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
IPAddress *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [12/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
EtherAddress *  data 
)

This is an overloaded member function, provided for convenience. It differs from the above function only in what argument(s) it accepts.

◆ add_data_handlers() [13/13]

void Element::add_data_handlers ( const char *  name,
int  flags,
Timestamp *  data,
bool  is_interval = false 
)

Register read and/or write handlers accessing data.

Parameters
namehandler name
flagshandler flags, containing at least one of Handler::f_read and Handler::f_write
datapointer to data
is_intervalIf true, the read handler unparses *data as an interval.

◆ read_positional_handler()

String Element::read_positional_handler ( Element *  element,
void *  user_data 
)
static

Standard read handler returning a positional argument.

Use this function to define a handler that returns one of an element's positional configuration arguments. The thunk argument is a typecast integer that specifies which one. For instance, to add "first", "second", and "third" read handlers that return the element's first three configuration arguments:

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
static String read_positional_handler(Element *, void *)
Standard read handler returning a positional argument.
Definition element.cc:2949

Returns the empty string if there aren't enough arguments.

Warning
Prefer read_keyword_handler() to read_positional_handler().
See also
configuration: used to obtain the element's current configuration.
read_keyword_handler, reconfigure_positional_handler, add_read_handler

◆ read_keyword_handler()

String Element::read_keyword_handler ( Element *  element,
void *  user_data 
)
static

Standard read handler returning a keyword argument.

Use this function to define a handler that returns one of an element's keyword configuration arguments. The user_data argument is a C string that specifies which one. For instance, to add a "data" read handler that returns the element's "DATA" keyword argument:

static String read_keyword_handler(Element *, void *)
Standard read handler returning a keyword argument.
Definition element.cc:2985

Returns the empty string if the configuration doesn't have the specified keyword.

The keyword might have been passed as a mandatory positional argument. Click will find it anyway if you prefix the keyword name with the mandatory position. For example, this tells reconfigure_keyword_handler to use the first positional argument for "DATA" if the keyword itself is missing:

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
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
See also
configuration: used to obtain the element's current configuration.
read_positional_handler, reconfigure_keyword_handler, add_read_handler

◆ reconfigure_positional_handler()

int Element::reconfigure_positional_handler ( const String &  arg,
Element *  e,
void *  user_data,
ErrorHandler *  errh 
)
static

Standard write handler for reconfiguring an element by changing one of its positional arguments.

Warning
Prefer reconfigure_keyword_handler() to reconfigure_positional_handler().

Use this function to define a handler that, when written, reconfigures an element by changing one of its positional arguments. The user_data argument is a typecast integer that specifies which one. For typecast integer that specifies which one. For instance, to add "first", "second", and "third" write handlers that change the element's first three configuration arguments:

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

When one of these handlers is written, Click will call the element's configuration() method to obtain the element's current configuration, change the relevant argument, and call live_reconfigure() to reconfigure the element.

See also
configuration: used to obtain the element's current configuration.
live_reconfigure: used to reconfigure the element.
reconfigure_keyword_handler, read_positional_handler, add_write_handler

◆ reconfigure_keyword_handler()

int Element::reconfigure_keyword_handler ( const String &  arg,
Element *  e,
void *  user_data,
ErrorHandler *  errh 
)
static

Standard write handler for reconfiguring an element by changing one of its keyword arguments.

Use this function to define a handler that, when written, reconfigures an element by changing one of its keyword arguments. The thunk argument is a C string that specifies which one. For typecast integer that specifies which one. For instance, to add a "data" write handler that changes the element's "DATA" configuration argument:

When this handler is written, Click will obtain the element's current configuration, remove any previous occurrences of the keyword, add the new keyword argument to the end, and call live_reconfigure() to reconfigure the element.

The keyword might have been passed as a mandatory positional argument. Click will find it anyway if you prefix the keyword name with the mandatory position. For example, this tells reconfigure_keyword_handler to use the first positional argument for "DATA" if the keyword itself is missing:

See also
configuration: used to obtain the element's current configuration.
live_reconfigure: used to reconfigure the element.
reconfigure_positional_handler, read_keyword_handler, add_write_handler

◆ llrpc()

int Element::llrpc ( unsigned  command,
void *  data 
)
virtual

Handle a low-level remote procedure call.

Parameters
commandcommand number
[in,out]datapointer to any data for the command
Returns
>= 0 on success, < 0 on failure

Low-level RPCs are a lightweight mechanism for communicating between user-level programs and a Click kernel module, although they're also available in user-level Click. Rather than open a file, write ASCII data to the file, and close it, as for handlers, the user-level program calls ioctl() on an open file. Click intercepts the ioctl and calls the llrpc() method, passing it the ioctl number and the associated data pointer. The llrpc() method should read and write data as appropriate. data may be either a kernel pointer (i.e., directly accessible) or a user pointer (i.e., requires special macros to access), depending on the LLRPC number; see <click/llrpc.h> for more.

A negative return value is interpreted as an error and returned to the user in errno. Overriding implementations should handle commands they understand as appropriate, and call their parents' llrpc() method to handle any other commands. The default implementation simply returns -EINVAL.

Click elements should never call each other's llrpc() methods directly; use local_llrpc() instead.

◆ local_llrpc()

int Element::local_llrpc ( unsigned  command,
void *  data 
)

Execute an LLRPC from within the configuration.

Parameters
commandcommand number
[in,out]datapointer to any data for the command

Call this function to execute an element's LLRPC from within another element's code. It executes any setup code necessary to initialize memory state, then calls llrpc().

Member Data Documentation

◆ in_batch_mode

enum batch_mode Element::in_batch_mode
protected

never


The documentation for this class was generated from the following files: