[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