1
0
mirror of https://github.com/emmericp/MoonGen synced 2025-10-05 23:52:51 +02:00
Files
MoonGen/lua/crc-ratecontrol.lua
2017-08-20 19:59:00 +02:00

89 lines
2.9 KiB
Lua

local device = require "device"
local pkt = require "packet"
local memory = require "memory"
local ffi = require "ffi"
local log = require "log"
local txQueue = device.__txQueuePrototype
local device = device.__devicePrototype
local C = ffi.C
ffi.cdef[[
void moongen_send_all_packets_with_delay_bad_crc(uint8_t port_id, uint16_t queue_id, struct rte_mbuf** load_pkts, uint16_t num_pkts, struct mempool* pool, uint32_t min_pkt_size);
]]
local mempool
--- Send rate-controlled packets by filling gaps with invalid packets.
-- @param bufs
-- @param targetRate optional, hint to the driver which total rate you are trying to achieve.
-- increases precision at low non-cbr rates
-- @param n optional, number of packets to send (defaults to full bufs)
function txQueue:sendWithDelay(bufs, targetRate, n)
if not self.dev.crcPatch then
log:fatal("Driver does not support disabling the CRC flag. This feature requires a patched driver.")
end
targetRate = targetRate or 14.88
self.used = true
mempool = mempool or memory.createMemPool{
func = function(buf)
-- this is tcp packet because the netfpga/OSNT system we use for testing this
-- cannot handle all-zero packets properly (filters get confused)
-- the actual contents of the packets don't matter since their CRC is invalid anways
local pkt = buf:getTcpPacket()
pkt:fill()
end
}
n = n or bufs.size
local avgPacketSize = 1.25 / (targetRate * 2) * 1000
local minPktSize = self.dev.minPacketSize or 64
local maxPktRate = self.dev.maxPacketRate or 14.88
-- allow smaller packets at low rates
if targetRate < maxPktRate / 2 then
minPktSize = minPktSize + 20
else
minPktSize = math.floor(10 * 10^9 / 10^6 / 8 / maxPktRate)
end
C.moongen_send_all_packets_with_delay_bad_crc(self.id, self.qid, bufs.array, n, mempool, minPktSize)
return bufs.size
end
--- Set the time to wait before the packet is sent for software rate-controlled send methods.
--- @param delay The time to wait before this packet \(in bytes, i.e. 1 == 0.8 nanoseconds on 10 GbE\)
function pkt:setDelay(delay)
self.udata64 = delay
end
--- sets the delay (cf. pkt:setDelay) to match a given packet rate in Mpps
function pkt:setRate(rate)
self.udata64 = 10^10 / 8 / (rate * 10^6) - self.pkt_len - 24
end
ffi.cdef[[
uint64_t moongen_get_bad_pkts_sent(uint8_t port_id);
uint64_t moongen_get_bad_bytes_sent(uint8_t port_id);
]]
local function hookTxStats(dev)
if dev.__txStatsHooked then
return
end
dev.__txStatsHooked = true
local old = dev.getTxStats
if old then
dev.getTxStats = function(self)
local pkts, bytes = old(self)
local badPkts = tonumber(C.moongen_get_bad_pkts_sent(self.id))
local badBytes = tonumber(C.moongen_get_bad_bytes_sent(self.id))
return pkts - badPkts, bytes - badBytes
end
end
end
hookTxStats(device)
for driver, dev in pairs(require("drivers")) do
if tostring(driver):match("^net_") and type(dev) == "table" then
hookTxStats(dev)
end
end