Lunatik

skbModule

Linux socket buffer interface.

Usage

-- lunatik run -c softirq <script>: raises the priority of the UDP packets the host sends
local netfilter = require("netfilter")
local nf        = require("linux.nf")

local PROTOCOL <const> = 9
local UDP <const>      = 17
local PRIORITY <const> = 6

local function prioritize(skb)
  if skb:data():getuint8(PROTOCOL) == UDP then
    skb:priority(PRIORITY)
  end
  return nf.action.ACCEPT
end

netfilter.register{
  hook     = prioritize,
  pf       = nf.proto.IPV4,
  hooknum  = nf.inet.LOCAL_OUT,
  priority = nf.ip.pri.FILTER,
}

Class skb

skb:__len ()
skb:checksum () Recomputes IP and transport-layer (TCP/UDP) checksums and writes them into the packet.
skb:connmark ([value]) Gets or sets the conntrack mark: with no argument or nil reads it, with value sets it.
skb:copy () Returns an independent copy of the skb with its own data buffer.
skb:data ([layer]) Linearizes the skb and returns a view from where layer starts to the end of the packet: “net” at the network header and “mac” at the MAC header, or, with no layer, at skb->data, where the packet starts as the hook sees it: the network header in an IPv4 or IPv6 netfilter hook and the MAC header in a tc callback.
skb:forward () Transmits a clone of the skb out of skb->dev, the device skb:ifindex() names.
skb:ifindex ()
skb:mark ([value]) Gets or sets the packet mark: with no argument or nil reads it, with value sets it.
skb:priority ([value]) Gets or sets the packet priority: with no argument or nil reads it, with value sets it.
skb:resize (n) Expands (skb_put_zero) or shrinks (pskb_trim_rcsum) the skb data area; the bytes an expansion adds read as zeros, and a shrink keeps the checksum a received skb carries.
skb:vlan ()

Class skb in detail

Represents a socket buffer (sk_buff). This is a userdata object handed to the hooks that receive packets; it is SINGLE, so it cannot be shared with another runtime, and so are the views skb:data() returns.

A netfilter hook callback receives one and tc_ctx:skb() returns one, valid only while that callback runs: once it returns, every method raises skb is not set, and the views that skb:data() returned are cleared too. skb:copy() keeps a packet past the callback.

skb:__len ()

Returns

    integer skb length in bytes
skb:checksum ()
Recomputes IP and transport-layer (TCP/UDP) checksums and writes them into the packet. On IPv4 it recomputes the header checksum and the TCP or UDP checksum; on IPv6, the TCP or UDP checksum when that header follows the fixed one. A packet that is neither IPv4 nor IPv6, an IPv6 packet with extension headers, a packet whose IP header gives a length past its end, or on IPv4 shorter than the header or an IHL below 5, and one too short to hold its TCP or UDP checksum field are left unchanged; resize does not rewrite that length.
skb:connmark ([value])
Gets or sets the conntrack mark: with no argument or nil reads it, with value sets it. Returns the current (or new) mark, or nil if no conntrack is associated. Present only on a kernel built with CONFIG_NF_CONNTRACK_MARK: elsewhere the method is nil, and a script that may run there tests skb.connmark before calling it.

Parameters

  • value integer 32-bit mark to set, from 0 up to U32_MAX (optional)

Returns

    integer 32-bit connmark, or nil if no conntrack is associated

Raises

if value is out of bounds
skb:copy ()
Returns an independent copy of the skb with its own data buffer. The skb is linearized before copying to avoid failures on fragmented skbs (e.g. bridged traffic with paged data). In a tc callback the skb is not linearized, and a non-linear one raises. A view of the copy that data() returns is valid until the copy is collected, and is then cleared as a view of a callback’s skb is when the callback returns.

Returns

    skb

Raises

if skb is FRAGLIST GSO, if the skb is not linear, in a tc callback or after a failed linearization, or if copy allocation fails
skb:data ([layer])
Linearizes the skb and returns a view from where layer starts to the end of the packet: “net” at the network header and “mac” at the MAC header, or, with no layer, at skb->data, where the packet starts as the hook sees it: the network header in an IPv4 or IPv6 netfilter hook and the MAC header in a tc callback. In a tc callback the skb is not linearized, and a non-linear one raises.

The skb keeps one view per start: the view with no layer and the “net” and “mac” views are three objects, and a second call returns the same view, ending at the tail as it is then: a resize alone does not move a view’s end. The skb stays linear once a view is taken, so no later call moves the bytes a view reads. A view is valid until the callback that received the skb returns, or, for a copy, until the copy is collected: afterwards its length is 0 and every access raises “out of bounds”.

Parameters

  • layer string “net” or “mac” (optional)

Returns

    data the view, or nil when the layer’s header is not set or lies past the tail

Raises

if the skb is not linear, in a tc callback or after a failed linearization, or if layer is invalid
skb:forward ()
Transmits a clone of the skb out of skb->dev, the device skb:ifindex() names. The original is untouched and still takes the hook’s verdict, so a callback that forwards a packet returns DROP to not send it twice.

Raises

if skb has no device, MAC header is not set or is past the data, or clone fails
skb:ifindex ()

Returns

    integer network interface index, or nil if not available
skb:mark ([value])
Gets or sets the packet mark: with no argument or nil reads it, with value sets it.

Parameters

  • value integer the new packet mark, from 0 up to U32_MAX (optional)

Returns

    integer the packet mark

Raises

if value is out of bounds
skb:priority ([value])
Gets or sets the packet priority: with no argument or nil reads it, with value sets it.

Parameters

  • value integer the new packet priority, from 0 up to U32_MAX (optional)

Returns

    integer the packet priority

Raises

if value is out of bounds
skb:resize (n)
Expands (skb_put_zero) or shrinks (pskb_trim_rcsum) the skb data area; the bytes an expansion adds read as zeros, and a shrink keeps the checksum a received skb carries. The skb is linearized first, so n is the length of the whole packet, which #skb returns afterwards. In a tc callback the skb is not linearized, and a non-linear one raises.

Parameters

  • n integer desired size in bytes, from 0 up to UINT_MAX

Returns

    boolean true once resized, and false, with the skb as it was, when an expansion does not fit in the tailroom or a shrink would cut the checksum field the stack has yet to fill, as a TCP segment’s on the way out

Raises

if out of bounds, if the skb is not linear, in a tc callback or after a failed linearization
skb:vlan ()

Returns

    integer VLAN tag ID, or nil if not present