1 ---------------------------------
 
    3 --- @brief Utility functions 
for packets (rte_mbuf).
 
    5 --- - General functions (timestamping, rate control, ...)
 
    7 --- - Create packet types
 
    8 ---------------------------------
 
   10 local 
ffi = require 
"ffi" 
   14 local dpdkc = require 
"dpdkc" 
   15 local dpdk = require 
"dpdk" 
   17 local 
bor, 
band, 
bnot, rshift, lshift= bit.bor, bit.band, bit.bnot, bit.rshift, bit.lshift
 
   18 local istype = 
ffi.istype
 
   19 local write = io.write
 
   22 -------------------------------------------------------------------------------------------
 
   23 ---- General functions
 
   24 -------------------------------------------------------------------------------------------
 
   26 --- Module 
for packets (rte_mbuf)
 
   30 --- Retrieve the time stamp information.
 
   31 --- @
return The timestamp or nil 
if the packet was not time stamped.
 
   33     if bit.
bor(self.ol_flags, dpdk.PKT_RX_IEEE1588_TMST) ~= 0 then
 
   34         -- TODO: support timestamps that are stored in registers instead of the rx buffer
 
   35         local data = 
ffi.cast("uint32_t* ", self.
pkt.data)
 
   36         -- TODO: this is only tested with the Intel 82580 NIC at the moment
 
   37         -- the datasheet claims that low and high are swapped, but this doesn't seem to be the case
 
   38         -- TODO: check other NICs
 
   41         return high * 2^32 + low
 
   45 --- Check if the PKT_RX_IEEE1588_TMST flag is 
set.
 
   46 --- Turns out that this flag is pretty pointless, it does not indicate
 
   47 --- if the packet was actually timestamped, just that it came from a
 
   48 --- queue/filter with timestamping enabled.
 
   49 --- You probably want to use device:
hasTimestamp() and check the sequence number.
 
   51     return bit.
bor(self.ol_flags, dpdk.PKT_RX_IEEE1588_TMST) ~= 0
 
   54 function 
pkt:getSecFlags()
 
   55     local secp = bit.rshift(bit.
band(self.ol_flags, dpdk.PKT_RX_IPSEC_SECP), 11)
 
   56     local secerr = bit.rshift(bit.
band(self.ol_flags, bit.
bor(dpdk.PKT_RX_SECERR_MSB, dpdk.PKT_RX_SECERR_LSB)), 12)
 
   60 --- Offload VLAN tagging to the NIC for this packet.
 
   62     local tci = vlan + bit.lshift(pcp or 0, 13) + bit.lshift(cfi or 0, 12)
 
   63     self.
pkt.vlan_tci = tci
 
   64     self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_VLAN_PKT)
 
   67 local VLAN_VALID_MASK = bit.
bor(dpdk.PKT_RX_VLAN_PKT, dpdk.PKT_TX_VLAN_PKT)
 
   69 --- Get the VLAN associated with a received packet.
 
   71     if bit.
bor(self.ol_flags, VLAN_VALID_MASK) == 0 then
 
   74     local tci = self.
pkt.vlan_tci
 
   75     return bit.
band(tci, 0xFFF), bit.rshift(tci, 13), bit.
band(bit.rshift(tci, 12), 1)
 
   79 --- Set the time to wait before the packet is sent for software rate-controlled send methods.
 
   80 --- @param delay The time to wait before this packet \(in bytes, i.e. 1 == 0.8 nanoseconds on 10 GbE\)
 
   82     self.
pkt.hash.rss = delay
 
   87     self.
pkt.hash.rss = 10^10 / 8 / (rate * 10^6) - self.
pkt.pkt_len - 24
 
   92     self.
pkt.pkt_len = size
 
   93     self.
pkt.data_len = size
 
   96 --- Returns the packet data cast to the best fitting packet struct. 
 
   97 --- Starting with ethernet header.
 
   98 --- @return packet data as cdata of best fitting packet
 
  103 --- Dumps the packet data cast to the best fitting packet struct.
 
  105 function 
pkt:dump(bytes)
 
  106     self:
get():dump(bytes or self.
pkt.pkt_len)
 
  109 -------------------------------------------------------------------------------------------------------
 
  110 ---- IPSec offloading
 
  111 -------------------------------------------------------------------------------------------------------
 
  113 --- Use IPsec offloading.
 
  114 --- @param idx SA_IDX to use
 
  115 --- @param sec_type IPSec type to use ("esp"/"ah")
 
  116 --- @param esp_mode ESP mode to use encrypt(1) or authenticate(0)
 
  118     local mode = esp_mode or 0
 
  120     if sec_type == "esp" then
 
  122     elseif sec_type == "ah" then
 
  125         error("Wrong IPSec type (esp/ah)")
 
  128     -- Set IPSec offload flag in advanced data transmit descriptor.
 
  129     self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_IPSEC)
 
  132     --if idx < 0 or idx > 1023 then
 
  133     --  error("SA_IDX has to be in 
range 0-2013")
 
  135     --self.ol_ipsec.sec.sa_idx = idx
 
  136     self.ol_ipsec.data = bit.
bor(self.ol_ipsec.data, bit.lshift(bit.
band(idx, 0x3FF), 0))
 
  138     -- Set ESP enc/auth mode
 
  139     --if mode ~= 0 and mode ~= 1 then
 
  140     --  error("Wrong IPSec mode")
 
  142     --self.ol_ipsec.sec.mode = mode
 
  143     self.ol_ipsec.data = bit.
bor(self.ol_ipsec.data, bit.lshift(bit.
band(mode, 0x1), 20))
 
  145     -- Set IPSec ESP/AH type
 
  146     --if sec_type == "esp" then
 
  147     --  self.ol_ipsec.sec.type = 1
 
  148     --elseif sec_type == "ah" then
 
  149     --  self.ol_ipsec.sec.type = 0
 
  151     --  error("Wrong IPSec type (esp/ah)")
 
  153     self.ol_ipsec.data = bit.
bor(self.ol_ipsec.data, bit.lshift(bit.
band(t, 0x1), 19))
 
  156 --- Set the ESP trailer length
 
  157 --- @param len ESP Trailer length in bytes
 
  159     --Disable 
range check for performance reasons
 
  160     --if len < 0 or len > 511 then
 
  161     --  error("ESP trailer length has to be in 
range 0-511")
 
  163     --self.ol_ipsec.sec.esp_len = len -- dont use bitfields
 
  164     self.ol_ipsec.data = bit.
bor(self.ol_ipsec.data, bit.lshift(bit.
band(len, 0x1FF), 10))
 
  167 -------------------------------------------------------------------------------------------------------
 
  168 ---- Checksum offloading
 
  169 -------------------------------------------------------------------------------------------------------
 
  171 --- Instruct the NIC to calculate the IP 
checksum for this packet.
 
  172 --- @param ipv4 Boolean to decide whether the packet uses IPv4 (
set to nil/true) or IPv6 (
set to anything else).
 
  173 ---                In case it is an IPv6 packet, do nothing (the header has no 
checksum).
 
  174 --- @param l2_len Length of the layer 2 header in bytes (default 14 bytes for ethernet).
 
  175 --- @param l3_len Length of the layer 3 header in bytes (default 20 bytes for IPv4).
 
  177     -- NOTE: this method cannot be moved to the udpPacket class because it doesn't (and can't) know the pktbuf it belongs to
 
  178     ipv4 = ipv4 == nil or ipv4
 
  180         l2_len = l2_len or 14
 
  181         l3_len = l3_len or 20
 
  182         self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_IPV4_CSUM)
 
  183         self.
pkt.header_lengths = l2_len * 512 + l3_len
 
  187 --- Instruct the NIC to calculate the IP and UDP 
checksum for this packet.
 
  188 --- @param ipv4 Boolean to decide whether the packet uses IPv4 (
set to nil/true) or IPv6 (
set to anything else).
 
  189 --- @param l2_len Length of the layer 2 header in bytes (default 14 bytes for ethernet).
 
  190 --- @param l3_len Length of the layer 3 header in bytes (default 20 bytes for IPv4, 40 bytes for IPv6).
 
  192     -- NOTE: this method cannot be moved to the udpPacket class because it doesn't (and can't) know the pktbuf it belongs to
 
  193     ipv4 = ipv4 == nil or ipv4
 
  194     l2_len = l2_len or 14
 
  196         l3_len = l3_len or 20
 
  197         self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_IPV4_CSUM, dpdk.PKT_TX_UDP_CKSUM)
 
  198         self.
pkt.header_lengths = l2_len * 512 + l3_len
 
  199         -- calculate pseudo header 
checksum because the NIC doesn't do this...
 
  200         dpdkc.calc_ipv4_pseudo_header_checksum(self.
pkt.data, 20)
 
  202         l3_len = l3_len or 40
 
  203         self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_UDP_CKSUM)
 
  204         self.
pkt.header_lengths = l2_len * 512 + l3_len
 
  205         -- calculate pseudo header 
checksum because the NIC doesn't do this...
 
  206         dpdkc.calc_ipv6_pseudo_header_checksum(self.
pkt.data, 30)
 
  210 --- Instruct the NIC to calculate the IP and TCP 
checksum for this packet.
 
  211 --- @param ipv4 Boolean to decide whether the packet uses IPv4 (
set to nil/true) or IPv6 (
set to anything else).
 
  212 --- @param l2_len Length of the layer 2 header in bytes (default 14 bytes for ethernet).
 
  213 --- @param l3_len Length of the layer 3 header in bytes (default 20 bytes for IPv4, 40 bytes for IPv6).
 
  215     -- NOTE: this method cannot be moved to the udpPacket class because it doesn't (and can't) know the pktbuf it belongs to
 
  216     ipv4 = ipv4 == nil or ipv4
 
  217     l2_len = l2_len or 14
 
  219         l3_len = l3_len or 20
 
  220         self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_IPV4_CSUM, dpdk.PKT_TX_TCP_CKSUM)
 
  221         self.
pkt.header_lengths = l2_len * 512 + l3_len
 
  222         -- calculate pseudo header 
checksum because the NIC doesn't do this...
 
  223         dpdkc.calc_ipv4_pseudo_header_checksum(self.
pkt.data, 25)
 
  225         l3_len = l3_len or 40
 
  226         self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_TCP_CKSUM)
 
  227         self.
pkt.header_lengths = l2_len * 512 + l3_len
 
  228         -- calculate pseudo header 
checksum because the NIC doesn't do this...
 
  229         dpdkc.calc_ipv6_pseudo_header_checksum(self.
pkt.data, 35)
 
  235     self.ol_flags = bit.
bor(self.ol_flags, dpdk.PKT_TX_IEEE1588_TMST)
 
  239 ----------------------------------------------------------------------------------
 
  240 ---- Create 
new packet type
 
  241 ----------------------------------------------------------------------------------
 
  243 -- functions of the packet
 
  253 --- Create struct and functions for a 
new packet.
 
  254 --- For implemented headers (see proto/) these packets are defined in the section 'Packet struct' of each protocol file
 
  255 --- @param args list of keywords (see makeStruct)
 
  256 --- @return returns the constructor/cast function for this packet
 
  262     packet.__index = packet
 
  266     if not packetName then
 
  267         printf("WARNING: Failed to create 
new packet type.")
 
  271     -- functions of the packet
 
  272     packet.getArgs = function() return args end
 
  274     packet.getName = function() return packetName end
 
  288     -- runtime critical function, load specific code during runtime
 
  291     -- functions for manual (not offloaded) 
checksum calculations
 
  292     -- runtime critical function, load specific code during runtime
 
  295     for _, v in ipairs(args) do
 
  297         -- if the header has a 
checksum, 
add a function to calculate it
 
  298         if header == "ip4" or header == "
icmp" then -- FIXME NYI or header == "
udp" or header == "tcp" then
 
  299             local key = 'calculate' .. member:gsub("^.", 
string.upper) .. 'Checksum'
 
  305     -- 
add functions to packet
 
  306     ffi.metatype(packetName, packet)
 
  308     -- return '
get'/'cast' for this kind of packet
 
  309     return function(self) return ctype(self.
pkt.data) end
 
  312 --- Get the name of the header and the name of the respective member of a packet
 
  313 --- @param v Either the name of the header (then the member has the same name), or a table { header, member }
 
  314 --- @
return Name of the header
 
  315 --- @
return Name of the member
 
  317     if type(v) == "table" then
 
  320         -- only the header name
 
  321         -- special alias for ethernet
 
  322         if v == "ethernet" or v == "
eth" then
 
  323             return "ethernet", "
eth"
 
  325             -- otherwise header name = member name
 
  331 --- Get all headers of a packet as list.
 
  332 --- @param self The packet
 
  333 --- @return Table of members of the packet
 
  336     for i, v in ipairs(
self:getArgs()) do 
 
  342 --- Get the specified header of a packet (e.g. self.
eth).
 
  343 --- @param self the packet (cdata)
 
  344 --- @param h header to be returned
 
  345 --- @return The member of the packet
 
  351 --- Print a hex 
dump of a packet.
 
  352 --- @param self the packet
 
  353 --- @param bytes Number of bytes to 
dump. If no size is specified the payload is truncated.
 
  355     bytes = bytes or 
ffi.sizeof(self:getName())
 
  360     -- headers in cleartext
 
  361     for i, v in ipairs(self:getHeaders()) do
 
  363         if i == 1 then write(" " .. str .. "\
n") else print(str) end
 
  370 --- Set all members of all headers.
 
  371 --- Per default, all members are 
set to default values specified in the respective 
set function.
 
  372 --- Optional named arguments can be used to 
set a member to a user-provided value.
 
  373 --- The argument 'pktLength' can be used to automatically calculate and 
set the length member of headers (e.g. 
ip header).
 
  375 --- 
fill() --- only default values
 
  376 --- 
fill{ ethSrc=
"12:23:34:45:56:67", ipTTL=100 } --- all members are 
set to 
default values with the exception of ethSrc and ipTTL
 
  377 --- 
fill{ pktLength=64 } --- only 
default values, length members of the headers are adjusted
 
  379 --- @param 
self The packet
 
  380 --- @param args Table of named arguments. For a list of available arguments see 
"See also" 
  381 --- @note This 
function is slow. If you want to modify members of a header during a time critical section of your script use the respective setters.
 
  383     namedArgs = namedArgs or {}
 
  384     local headers = 
self:getHeaders()
 
  385     local args = self:getArgs()
 
  386     local accumulatedLength = 0
 
  387     for i, v in ipairs(headers) do
 
  392         v:
fill(namedArgs, curMember) 
 
  394         accumulatedLength = accumulatedLength + 
ffi.sizeof(v)
 
  398 --- Retrieve the values of all members as list of named arguments.
 
  399 --- @param self The packet
 
  400 --- @return Table of named arguments. For a list of arguments see "See also".
 
  404     local args = 
self:getArgs()
 
  405     for i, v in ipairs(self:getHeaders()) do 
 
  412 --- Try to find out what the next header in the payload of this packet is.
 
  413 --- This function is only used for buf:
get/buf:
dump 
  414 --- @param self The packet
 
  416     local name = self:getName()
 
  417     local headers = self:getHeaders()
 
  418     local nextHeader = headers[
#headers]:resolveNextHeader() 
  420     -- unable to resolve: either there is no next header, or MoonGen does not support it yet
 
  421     -- either 
case, we 
stop and 
return current type of packet
 
  422     if not nextHeader then
 
  427         -- we know the next header, append it
 
  428         name = name .. 
"__" .. nextHeader .. 
"_" 
  430         -- 
if simple 
struct (headername = membername) already exists we can directly cast
 
  431         nextMember = nextHeader
 
  432         newName = name .. nextMember
 
  434         if not 
pkt.packetStructs[newName] then
 
  435             -- check 
if a similar 
struct with 
this header order exists
 
  438             for k, v in pairs(
pkt.packetStructs) 
do 
  439                 if string.find(k, newName) and not 
string.find(
string.gsub(k, newName, 
""), 
"__") then
 
  440                     -- the type matches and there are no further headers following (which would have been indicated by another 
"__")
 
  449                 -- last resort: 
build new packet type. However, one has to consider that one header 
 
  450                 -- might occur multiple times! In 
this case the member must 
get a 
new (unique!) name.
 
  451                 local args = 
self:getArgs()
 
  454                 local newMember = nextMember
 
  456                 -- 
build new args information and in the meantime check 
for duplicates
 
  457                 for i, v in ipairs(args) do
 
  459                     if member == newMember then
 
  460                         -- found duplicate, increase counter for newMember and keep checking for this one now
 
  461                         counter = counter + 1
 
  462                         newMember = nextMember .. "_" .. counter
 
  463                         -- TODO this assumes that there never will be a <member_X+1> before a <member_X>
 
  468                 -- 
add new header and member
 
  469                 newArgs[
#newArgs + 1] = { nextHeader, newMember } 
  471                 -- create 
new packet. It is unlikely that exactly 
this packet type with 
this made up naming scheme will be used
 
  472                 -- Therefore, we don
't really want to "safe" the cast function 
  473                 pkt.TMP_PACKET = packetCreate(unpack(newArgs)) 
  475                 -- name of the new packet type 
  476                 newName = newName .. newMember 
  480         -- finally, cast the packet to the next better fitting packet type and continue resolving 
  481         return ffi.cast(newName .. "*", self):resolveLastHeader() 
  485 --- Set length for all headers. 
  486 --- Necessary when sending variable sized packets. 
  487 --- @param self The packet 
  488 --- @param length Length of the packet. Value for respective length member of headers get calculated using this value. 
  489 function packetSetLength(args) 
  491     -- build the setLength functions for all the headers in this packet type 
  492     local accumulatedLength = 0 
  493     for _, v in ipairs(args) do 
  494         local header, member = getHeaderMember(v) 
  495         if header == "ip4" or header == "udp" or header == "ptp" then 
  497                 self.]] .. member .. [[:setLength(length - ]] .. accumulatedLength .. [[) 
  499         elseif header == "ip6" then 
  501                 self.]] .. member .. [[:setLength(length - ]] .. accumulatedLength + 40 .. [[) 
  504         accumulatedLength = accumulatedLength + ffi.sizeof("struct " .. header .. "_header") 
  507     -- build complete function 
  509         return function(self, length)]]  
  513     -- load new function and return it 
  514     local func = assert(loadstring(str))() 
  519 --- Calculate all checksums manually (not offloading them). 
  520 --- There also exist functions to calculate the checksum of only one header. 
  521 --- Naming convention: pkt:calculate<member>Checksum() (for all existing packets member = {Ip, Tcp, Udp, Icmp}) 
  522 --- @note Calculating checksums manually is extremely slow compared to offloading this task to the NIC (~65% performance loss at the moment) 
  523 --- @todo Manual calculation of udp and tcp checksums NYI 
  524 function packetCalculateChecksums(args) 
  526     for _, v in ipairs(args) do 
  527         local header, member = getHeaderMember(v) 
  529         -- if the header has a checksum, call the function 
  530         if header == "ip4" or header == "icmp" then -- FIXME NYI or header == "udp" or header == "tcp" then 
  532                 self.]] .. member .. [[:calculateChecksum() 
  537     -- build complete function 
  539         return function(self)]]  
  543     -- load new function and return it 
  544     local func = assert(loadstring(str))() 
  549 --- Table that contains the names and args of all created packet structs 
  550 pkt.packetStructs = {} 
  552 -- List all created packet structs enlisted in packetStructs 
  553 -- Debugging function 
  554 function listPacketStructs() 
  555     printf("All available packet structs:") 
  556     for k, v in pairs(pkt.packetStructs) do 
  561 --- Creates a packet struct (cdata) consisting of different headers. 
  562 --- Simply list the headers in the order you want them to be in a packet. 
  563 --- If you want the member to be named differently, use the following syntax: 
  564 --- normal: <header> ; different membername: { <header>, <member> }. 
  565 --- Supported keywords: eth, arp, ptp, ip, ip6, udp, tcp, icmp 
  567 --- makeStruct('eth', { 'ip4
', 'ip' }, 'udp') --- creates an UDP packet struct 
  568 --- --- the ip4 member of the packet is named 'ip' 
  570 --- The name of the created (internal) struct looks as follows:  
  571 --- struct __HEADER1_MEMBER1__HEADER2_MEMBER2 ...  
  572 --- Only the "__" (double underscore) has the special meaning of "a new header starts with name  
  573 --- <everything until "_" (single underscore)>, followed by the member name <everything after "_"  
  574 --- until next header starts (indicated by next __)>" 
  575 --- @param args list of keywords/tables of keyword-member pairs 
  576 --- @return name name of the struct 
  577 --- @return ctype ctype of the struct 
  578 function packetMakeStruct(...) 
  582     -- add the specified headers and build the name 
  583     for _, v in ipairs(...) do 
  584         local header, member = getHeaderMember(v) 
  588         struct ]] .. header .. '_header 
' .. member .. [[; 
  592         name = name .. "__" .. header .. "_" .. member 
  595     -- add rest of the struct 
  597     struct __attribute__((__packed__)) ]]  
  603         union payload_t payload; 
  607     name = "struct " .. name 
  609     -- check uniqueness of packet type (name of struct) 
  610     if pkt.packetStructs[name] then 
  611         printf("WARNING: Struct with name \"" .. name .. "\" already exists. Skipping.") 
  614         -- add struct definition 
  617         -- add to list of existing structs 
  618         pkt.packetStructs[name] = {...} 
  620         -- return full name and typeof 
  621         return name, ffi.typeof(name .. "*") 
  626 --------------------------------------------------------------------------- 
  628 --------------------------------------------------------------------------- 
  630 ffi.metatype("struct rte_mbuf", pkt) 
param n optional(default=2047)
Create a new memory pool. 
 
local ffi
low-level dpdk wrapper 
 
function pkt setVlan(vlan, pcp, cfi)
Offload VLAN tagging to the NIC for this packet. 
 
function checksum(data, len)
Calculate a 16 bit checksum. 
 
function getTimeMicros()
Retrieve the system time with microseconds accuracy. 
 
function pkt offloadUdpChecksum(ipv4, l2_len, l3_len)
Instruct the NIC to calculate the IP and UDP checksum for this packet. 
 
function mg_filter_5tuple build(numCategories)
Builds the filter with the currently added rules. 
 
function ahHeader setLength(int)
Set the Length. 
 
function packetCreate(...)
Create struct and functions for a new packet. 
 
function ipsecICV getString(doByteSwap)
Get the IPsec string. 
 
pkt getEthernetPacket
Cast the packet to an ethernet packet. 
 
function mod band(mask1, mask2, result)
Bitwise and. 
 
function range(max, start,...)
Return all integerss in the range [start, max]. 
 
function pkt dump(bytes)
Dumps the packet data cast to the best fitting packet struct. 
 
function ipsecICV set(icv)
Set the IPsec ICV. 
 
function pkt enableTimestamps()
 
local udp
Udp protocol constants. 
 
function mod bor(mask1, mask2, result)
Bitwise or. 
 
function pkt setDelay(delay)
Set the time to wait before the packet is sent for software rate-controlled send methods. 
 
function icmpHeader calculateChecksum(len)
Calculate the checksum. 
 
function packetFill(self, namedArgs)
Set all members of all headers. 
 
function pkt get()
Returns the packet data cast to the best fitting packet struct. 
 
function mergeTables(...)
Merge tables. 
 
function getHeaderMember(v)
Get the name of the header and the name of the respective member of a packet. 
 
function printf(str,...)
Print a formatted string. 
 
function ahHeader fill(args, pre)
Set all members of the ah header. 
 
function pkt hasTimestamp()
Check if the PKT_RX_IEEE1588_TMST flag is set. 
 
function pkt setRate(rate)
 
function ip4Addr add(val)
Add a number to an IPv4 address in-place. 
 
function dumpHex(data, bytes)
Print a hex dump of cdata. 
 
function mod stop()
request all tasks to exit 
 
function pkt setESPTrailerLength(len)
Set the ESP trailer length. 
 
function packetDump(self, bytes)
Print a hex dump of a packet. 
 
local eth
Ethernet protocol constants. 
 
function packetMakeStruct(...)
Creates a packet struct (cdata) consisting of different headers. 
 
function pkt offloadTcpChecksum(ipv4, l2_len, l3_len)
Instruct the NIC to calculate the IP and TCP checksum for this packet. 
 
function pkt getTimestamp()
Retrieve the time stamp information. 
 
local ip
IP4 protocol constants. 
 
function packetGetHeader(self, h)
Get the specified header of a packet (e.g. 
 
function packetResolveLastHeader(self)
Try to find out what the next header in the payload of this packet is. 
 
function pkt offloadIPSec(idx, sec_type, esp_mode)
Use IPsec offloading. 
 
function packetCalculateChecksums(args)
Calculate all checksums manually (not offloading them). 
 
local pkt
Module for packets (rte_mbuf) 
 
function mod bnot(mask, result)
Bitwise not. 
 
function pkt getVlan()
Get the VLAN associated with a received packet. 
 
n
Create a new array of memory buffers (initialized to nil). 
 
function ahHeader setDefaultNamedArgs(pre, namedArgs, nextHeader, accumulatedLength)
Change the default values for namedArguments (for fill/get) This can be used to for instance calculat...
 
function packetGet(self)
Retrieve the values of all members as list of named arguments. 
 
function pkt setSize(size)
 
function packetGetHeaders(self)
Get all headers of a packet as list. 
 
local icmp
Icmp4 protocol constants. 
 
function packetSetLength(args)
Set length for all headers. 
 
function pkt offloadIPChecksum(ipv4, l2_len, l3_len)
Instruct the NIC to calculate the IP checksum for this packet.