[Click] Adding HEADROOM option to RawSocket and IPFlowRawSockets
Eddie Kohler
kohler at cs.ucla.edu
Sat Apr 8 12:29:41 EDT 2006
Applied, thanks! I was able to simplify the logic a bit using
Packet::DEFAULT_HEADROOM.
E
Michael Gellman wrote:
> I am using Click as an overlay router where I am receiving packets from
> an application using the RawSocket and IPFlowRawSocket elements, then
> adding a reasonably large overlay header, and then re-encapsulating into
> a UDP-in-IP packet before it is sent out again.
>
> In this scenario, I have found that I receive a number of warnings about
> "expensive push operations" due to the fact that the packet received
> from the RawSocket element has the default headroom assigned (currently
> 28 bytes) which isn't enough to accommodate the additional headers.
>
> I've solved my problem using the attached patch, which adds a HEADROOM
> keyword to both elements. Maybe this can be applied upstream?
>
> Michael Gellman
>
>
> ------------------------------------------------------------------------
>
> Index: ipflowrawsockets.cc
> ===================================================================
> RCS file: /cvs/click/release/one/elements/userlevel/ipflowrawsockets.cc,v
> retrieving revision 1.13
> diff -u -r1.13 ipflowrawsockets.cc
> --- ipflowrawsockets.cc 13 Feb 2006 17:32:39 -0000 1.13
> +++ ipflowrawsockets.cc 4 Apr 2006 11:42:52 -0000
> @@ -174,7 +174,7 @@
>
> IPFlowRawSockets::IPFlowRawSockets()
> : _nnoagg(0), _nagg(0), _agg_notifier(0), _task(this),
> - _gc_timer(gc_hook, this)
> + _gc_timer(gc_hook, this), _headroom(0)
> {
> for (int i = 0; i < NFLOWMAP; i++)
> _flowmap[i] = 0;
> @@ -196,6 +196,7 @@
> "NOTIFIER", cpElement, "aggregate deletion notifier", &e,
> "SNAPLEN", cpUnsigned, "maximum packet length", &_snaplen,
> "PCAP", cpBool, "use libpcap", &_usepcap,
> + "HEADROOM", cpUnsigned, "headroom to add to packet", &_headroom,
> cpEnd) < 0)
> return -1;
>
> @@ -322,7 +323,10 @@
> assert(f);
>
> // Read and push() at most one packet.
> - p = Packet::make(_snaplen);
> + if (_headroom)
> + p = Packet::make(_headroom, (unsigned char *)0, _snaplen, 0);
> + else
> + p = Packet::make(_snaplen);
> if (!p)
> return;
> p->take(p->length());
> Index: ipflowrawsockets.hh
> ===================================================================
> RCS file: /cvs/click/release/one/elements/userlevel/ipflowrawsockets.hh,v
> retrieving revision 1.9
> diff -u -r1.9 ipflowrawsockets.hh
> --- ipflowrawsockets.hh 3 Apr 2006 15:53:25 -0000 1.9
> +++ ipflowrawsockets.hh 4 Apr 2006 11:42:52 -0000
> @@ -86,6 +86,13 @@
> Boolean. Whether to use libpcap for packet capture. Libpcap is
> unnecessary for capturing packets on PlanetLab Linux. Default is true.
>
> +=item HEADROOM
> +
> +Unsigned Integer. Amount of headroom to reserve in packets created
> +by this element. This could be useful for encapsulation protocols
> +which add headers to the packet, and can avoid expensive push
> +operations later in the packet's life.
> +
> =back
>
> =n
> @@ -195,6 +202,7 @@
>
> int _snaplen;
> bool _usepcap;
> + unsigned _headroom;
>
> Flow *find_aggregate(uint32_t, const Packet * = 0);
> void end_flow(Flow *, ErrorHandler *);
> Index: rawsocket.cc
> ===================================================================
> RCS file: /cvs/click/release/one/elements/userlevel/rawsocket.cc,v
> retrieving revision 1.4
> diff -u -r1.4 rawsocket.cc
> --- rawsocket.cc 3 Apr 2006 15:44:07 -0000 1.4
> +++ rawsocket.cc 4 Apr 2006 11:42:52 -0000
> @@ -44,7 +44,7 @@
> RawSocket::RawSocket()
> : _task(this), _timer(this),
> _fd(-1), _port(0), _snaplen(2048),
> - _rq(0), _wq(0)
> + _rq(0), _wq(0), _headroom(0)
> {
> }
>
> @@ -58,6 +58,7 @@
> // remove keyword arguments
> if (cp_va_parse_remove_keywords(conf, 1, this, errh,
> "SNAPLEN", cpUnsigned, "maximum packet length", &_snaplen,
> + "HEADROOM", cpUnsigned, "how much header to allocate for the packet", &_headroom,
> cpEnd) < 0)
> return -1;
>
> @@ -171,8 +172,12 @@
>
> if (noutputs()) {
> // read data from socket
> - if (!_rq)
> - _rq = Packet::make(_snaplen);
> + if (!_rq) {
> + if (_headroom)
> + _rq = Packet::make(_headroom, (const unsigned char *)0, _snaplen, 0);
> + else
> + _rq = Packet::make(_snaplen);
> + }
> if (_rq) {
> len = recv(_fd, _rq->data(), _rq->length(), MSG_TRUNC);
> if (len > 0) {
> Index: rawsocket.hh
> ===================================================================
> RCS file: /cvs/click/release/one/elements/userlevel/rawsocket.hh,v
> retrieving revision 1.4
> diff -u -r1.4 rawsocket.hh
> --- rawsocket.hh 17 Feb 2006 21:39:13 -0000 1.4
> +++ rawsocket.hh 4 Apr 2006 11:42:52 -0000
> @@ -39,12 +39,19 @@
> packet source. If the MRU is violated by the peer, i.e. if a packet
> longer than SNAPLEN is sent, the connection may be terminated.
>
> +=item HEADROOM
> +
> +Unsigned Integer. Amount of headroom to reserve in packets created
> +by this element. This could be useful for encapsulation protocols
> +which add headers to the packet, and can avoid expensive push
> +operations later in the packet's life.
> +
> =back
>
> =e
>
> RawSocket(UDP, 53) -> ...
> -
> +
> =a Socket */
>
> class RawSocket : public Element { public:
> @@ -75,6 +82,7 @@
> int _protocol; // IP protocol to bind
> uint16_t _port; // (PlanetLab only) port to bind
> int _snaplen; // maximum received packet length
> + unsigned _headroom; // header length to set aside in the packet
>
> NotifierSignal _signal; // packet is available to pull()
> WritablePacket *_rq; // queue to receive pulled packets
>
>
> ------------------------------------------------------------------------
>
> _______________________________________________
> click mailing list
> click at amsterdam.lcs.mit.edu
> https://amsterdam.lcs.mit.edu/mailman/listinfo/click
More information about the click
mailing list