// -*- c-basic-offset: 4 -*-
#ifndef CLICK_FROMDEVICE_HH
#define CLICK_FROMDEVICE_HH
/*
=c
FromDevice(DEVNAME [, PROMISC, BURST, I<KEYWORDS>])
=s netdevices
reads packets from network device (Linux kernel)
=d
This manual page describes the Linux kernel module version of the FromDevice
element. For the user-level element, read the FromDevice.u manual page.
Intercepts all packets received by the Linux network interface named DEVNAME
and pushes them out output 0. The packets include the link-level header.
DEVNAME may also be an Ethernet address, in which case FromDevice searches for
a device with that address.
FromDevice receives packets at interrupt time. As this happens, FromDevice
simply stores the packets in an internal queue. Later, in the Click kernel
thread -- that is, not at interrupt time -- FromDevice emits packets from that
queue as it is scheduled by the driver. It emits at most BURST packets per
scheduling; BURST is 8 by default.
If PROMISC is set (by default, it is not), then the device is put into
promiscuous mode while FromDevice is active.
Keyword arguments are:
=over 8
=item PROMISC
Boolean. Same as the PROMISC argument.
=item BURST
Unsigned integer. Same as the BURST argument.
=item ALLOW_NONEXISTENT
Allow nonexistent devices. If true, and no device named DEVNAME exists when
the router is initialized, then FromDevice will report a warning (rather than
an error). Later, while the router is running, if a device named DEVNAME
appears, FromDevice will seamlessly begin outputing its packets. Default is
false.
=back
=n
Linux won't see any packets from the device. If you want Linux to process
packets, you should hand them to ToHost.
FromDevice accesses packets the same way Linux does: through interrupts.
This is bad for performance. If you care about performance and have a
polling-capable device, use PollDevice instead.
Linux device drivers, and thus FromDevice, should set packets' timestamp,
packet-type, and device annotations.
=a PollDevice, ToDevice, FromHost, ToHost, FromDevice.u */
#include "elements/linuxmodule/anydevice.hh"
#include <click/standard/storage.hh>
class FromDevice : public AnyTaskDevice, public Storage { public:
FromDevice();
~FromDevice();
static void static_initialize();
static void static_cleanup();
const char *class_name() const { return "FromDevice"; }
const char *port_count() const { return PORTS_0_1; }
const char *processing() const { return PUSH; }
void *cast(const char *);
int configure(Vector<String> &, ErrorHandler *);
int initialize(ErrorHandler *);
void cleanup(CleanupStage);
void add_handlers();
void take_state(Element *, ErrorHandler *);
void change_device(net_device *);
/* process a packet. return 0 if not wanted after all. */
int got_skb(struct sk_buff *);
bool run_task();
void reset_counts();
unsigned drops() { return _drops; }
unsigned runs() { return _runs; }
unsigned empty_runs() { return _empty_runs; }
unsigned pushes() { return _pushes; }
private:
unsigned _burst;
unsigned _drops;
unsigned _runs;
unsigned _empty_runs;
unsigned _pushes;
enum { QSIZE = 511 };
Packet *_queue[QSIZE+1];
#if CLICK_DEBUG_SCHEDULING
struct Schinfo {
struct timeval enq_time;
char enq_state;
char enq_woke_process;
char enq_task_scheduled;
uint32_t enq_epoch;
uint32_t enq_task_epoch;
};
Schinfo _schinfo[QSIZE+1];
void emission_report(int);
#endif
};
#endif
syntax highlighted by Code2HTML, v. 0.9.1