From a1af15e8222c589b157a9ef806b4fe335682c3c9 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Wed, 31 Aug 2016 16:32:14 +0000 Subject: [PATCH 01/24] Getter/setter ring_buffer_size --- src/apps/intel/intel10g.lua | 13 ++++++++++++- src/apps/intel/loadgen.lua | 6 +++--- src/program/firehose/firehose.lua | 9 +-------- 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/apps/intel/intel10g.lua b/src/apps/intel/intel10g.lua index 5e2ffc564c..0320536f0c 100644 --- a/src/apps/intel/intel10g.lua +++ b/src/apps/intel/intel10g.lua @@ -23,7 +23,18 @@ local timer = require("core.timer") local bits, bitset = lib.bits, lib.bitset local band, bor, lshift = bit.band, bit.bor, bit.lshift -num_descriptors = 1024 +local num_descriptors = 1024 +function ring_buffer_size (arg) + if not arg then return num_descriptors end + local ring_size = assert(tonumber(arg), "bad ring size: " .. arg) + if ring_size > 32*1024 then + error("ring size too large for hardware: " .. ring_size) + end + if math.log(ring_size)/math.log(2) % 1 ~= 0 then + error("ring size is not a power of two: " .. arg) + end + num_descriptors = assert(tonumber(arg)) +end -- Defaults for configurable items local default = { diff --git a/src/apps/intel/loadgen.lua b/src/apps/intel/loadgen.lua index dba5b6363c..874cf63fa7 100644 --- a/src/apps/intel/loadgen.lua +++ b/src/apps/intel/loadgen.lua @@ -31,7 +31,7 @@ function disable_tx_descriptor_writeback (dev) -- Disable writeback of transmit descriptors. -- That way our transmit descriptors stay fresh and reusable. -- Tell hardware write them to this other memory instead. - local bytes = intel10g.num_descriptors * ffi.sizeof(intel10g.rxdesc_t) + local bytes = intel10g.ring_buffer_size() * ffi.sizeof(intel10g.rxdesc_t) local ptr, phy = memory.dma_alloc(bytes) dev.r.TDWBAL(phy % 2^32) dev.r.TDWBAH(phy / 2^32) @@ -40,7 +40,7 @@ end function zero_descriptors (dev) -- Clear unused descriptors local b = memory.dma_alloc(4096) - for i = 0, intel10g.num_descriptors-1 do + for i = 0, intel10g.ring_buffer_size()-1 do -- Make each descriptors point to valid DMA memory but be 0 bytes long. dev.txdesc[i].address = memory.virtual_to_physical(b) dev.txdesc[i].options = bit.lshift(1, 24) -- End of Packet flag @@ -64,7 +64,7 @@ function LoadGen:pull () if dev.tdt == 0 then return end C.full_memory_barrier() if tdh == 0 then - dev.r.TDT(intel10g.num_descriptors) + dev.r.TDT(intel10g.ring_buffer_size()) else dev.r.TDT(tdh - 1) end diff --git a/src/program/firehose/firehose.lua b/src/program/firehose/firehose.lua index 0354f1a0ec..6ee05d8e6a 100644 --- a/src/program/firehose/firehose.lua +++ b/src/program/firehose/firehose.lua @@ -39,13 +39,6 @@ function run (args) end function opt.r (arg) ring_size = tonumber(arg) - if type(ring_size) ~= 'number' then fatal("bad ring size: " .. arg) end - if ring_size > 32*1024 then - fatal("ring size too large for hardware: " .. ring_size) - end - if math.log(ring_size)/math.log(2) % 1 ~= 0 then - fatal("ring size is not a power of two: " .. arg) - end end args = lib.dogetopt(args, opt, "hHet:i:r:", long_opts) if #pciaddresses == 0 then @@ -79,7 +72,7 @@ int firehose_callback_v1(const char *pciaddr, char **packets, void *rxring, local intel10g = require("apps.intel.intel10g") -- Maximum buffers to avoid packet drops - intel10g.num_descriptors = ring_size + intel10g.ring_buffer_size(ring_size) local nic = intel10g.new_sf({pciaddr=pciaddr}) nic:open() From c304027d52f83f77a527975a30ce02d0e7f9cf8b Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 11:35:41 +0000 Subject: [PATCH 02/24] Format packetblaster.lua and removed unused variables --- src/program/packetblaster/packetblaster.lua | 61 ++++++++++----------- 1 file changed, 30 insertions(+), 31 deletions(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index 4b1c11b77f..a75a96bcee 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -4,7 +4,6 @@ module(..., package.seeall) local engine = require("core.app") local timer = require("core.timer") -local intel10g = require("apps.intel.intel10g") local lib = require("core.lib") local pci = require("lib.hardware.pci") local LoadGen = require("apps.intel.loadgen").LoadGen @@ -24,39 +23,39 @@ local function is_device_suitable (pcidev, patterns) end function run_loadgen (c, patterns, duration) - local nics = 0 - pci.scan_devices() - for _,device in ipairs(pci.devices) do - if is_device_suitable(device, patterns) then - nics = nics + 1 - local name = "nic"..nics - config.app(c, name, LoadGen, device.pciaddress) - config.link(c, "source."..tostring(nics).."->"..name..".input") - end - end - assert(nics > 0, " matches no suitable devices.") - engine.busywait = true - engine.configure(c) - local fn = function () - print("Transmissions (last 1 sec):") - engine.report_apps() - end - local t = timer.new("report", fn, 1e9, 'repeating') - timer.activate(t) - if duration then engine.main({duration=duration}) - else engine.main() end + local nics = 0 + pci.scan_devices() + for _,device in ipairs(pci.devices) do + if is_device_suitable(device, patterns) then + nics = nics + 1 + local name = "nic"..nics + config.app(c, name, LoadGen, device.pciaddress) + config.link(c, "source."..tostring(nics).."->"..name..".input") + end + end + assert(nics > 0, " matches no suitable devices.") + engine.busywait = true + engine.configure(c) + local fn = function () + print("Transmissions (last 1 sec):") + engine.report_apps() + end + local t = timer.new("report", fn, 1e9, 'repeating') + timer.activate(t) + if duration then engine.main({duration=duration}) + else engine.main() end end local function show_usage(exit_code) - print(require("program.packetblaster.README_inc")) - main.exit(exit_code) + print(require("program.packetblaster.README_inc")) + main.exit(exit_code) end function run(args) - if #args == 0 then show_usage(1) end - local command = string.gsub(table.remove(args, 1), "-", "_") - local modname = ("program.packetblaster.%s.%s"):format(command, command) - if not lib.have_module(modname) then - show_usage(1) - end - require(modname).run(args) + if #args == 0 then show_usage(1) end + local command = string.gsub(table.remove(args, 1), "-", "_") + local modname = ("program.packetblaster.%s.%s"):format(command, command) + if not lib.have_module(modname) then + show_usage(1) + end + require(modname).run(args) end From f3cc41c016e76b64c5e96f91a3b23f8363c8fd50 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 11:37:59 +0000 Subject: [PATCH 03/24] Check 'packetblaster replay' arguments should be at least 2 --- src/program/packetblaster/replay/replay.lua | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/src/program/packetblaster/replay/replay.lua b/src/program/packetblaster/replay/replay.lua index 53f7715e3b..a2607e098b 100644 --- a/src/program/packetblaster/replay/replay.lua +++ b/src/program/packetblaster/replay/replay.lua @@ -9,26 +9,30 @@ local PcapReader = require("apps.pcap.pcap").PcapReader local lib = require("core.lib") local packetblaster = require("program.packetblaster.packetblaster") -local usage = require("program.packetblaster.replay.README_inc") local long_opts = { duration = "D", help = "h" } +local function show_usage (code) + print(require("program.packetblaster.replay.README_inc")) + main.exit(code) +end + function run (args) local opt = {} local duration local c = config.new() - function opt.D (arg) - duration = assert(tonumber(arg), "duration is not a number!") + function opt.D (arg) + duration = assert(tonumber(arg), "duration is not a number!") end - function opt.h (arg) - print(usage) - main.exit(1) + function opt.h () + show_usage(0) end args = lib.dogetopt(args, opt, "hD:", long_opts) + if #args < 2 then show_usage(1) end local filename = table.remove(args, 1) print (string.format("filename=%s", filename)) config.app(c, "pcap", PcapReader, filename) From fb32e41b74d91e01c611332b4f24da5a2aaa3eaf Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 12:10:31 +0000 Subject: [PATCH 04/24] Refactor 'packetblaster synth' --- src/program/packetblaster/synth/synth.lua | 26 +++++++++++++---------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/src/program/packetblaster/synth/synth.lua b/src/program/packetblaster/synth/synth.lua index d657d5b654..2ef6638788 100644 --- a/src/program/packetblaster/synth/synth.lua +++ b/src/program/packetblaster/synth/synth.lua @@ -8,7 +8,6 @@ local Synth = require("apps.test.synth").Synth local lib = require("core.lib") local packetblaster = require("program.packetblaster.packetblaster") -local usage = require("program.packetblaster.synth.README_inc") local long_opts = { duration = "D", @@ -18,16 +17,20 @@ local long_opts = { sizes = "S" } +local function show_usage (code) + print(require("program.packetblaster.synth.README_inc")) + main.exit(code) +end + function run (args) local opt = {} local duration local c = config.new() - function opt.D (arg) - duration = assert(tonumber(arg), "duration is not a number!") + function opt.D (arg) + duration = assert(tonumber(arg), "duration is not a number!") end - function opt.h (arg) - print(usage) - main.exit(1) + function opt.h () + show_usage(0) end local source @@ -36,14 +39,15 @@ function run (args) function opt.s (arg) source = arg end function opt.d (arg) destination = arg end function opt.S (arg) - sizes = {} - for size in string.gmatch(arg, "%d+") do - sizes[#sizes+1] = tonumber(size) - end + sizes = {} + for size in string.gmatch(arg, "%d+") do + sizes[#sizes+1] = tonumber(size) + end end args = lib.dogetopt(args, opt, "hD:s:d:S:", long_opts) + if not (sizes or source or destination) then show_usage(1) end config.app(c, "source", Synth, { sizes = sizes, - src = source, dst = destination }) + src = source, dst = destination }) packetblaster.run_loadgen(c, args, duration) end From e58e1248e828f4b15e86231c865c2d117a269193 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 11:43:31 +0000 Subject: [PATCH 05/24] Pass array of options instead of duration --- src/program/packetblaster/packetblaster.lua | 4 ++-- src/program/packetblaster/replay/replay.lua | 13 +++++++------ src/program/packetblaster/synth/synth.lua | 20 ++++++++++---------- 3 files changed, 19 insertions(+), 18 deletions(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index a75a96bcee..e155eb7d3a 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -22,7 +22,7 @@ local function is_device_suitable (pcidev, patterns) end end -function run_loadgen (c, patterns, duration) +function run_loadgen (c, patterns, opts) local nics = 0 pci.scan_devices() for _,device in ipairs(pci.devices) do @@ -42,7 +42,7 @@ function run_loadgen (c, patterns, duration) end local t = timer.new("report", fn, 1e9, 'repeating') timer.activate(t) - if duration then engine.main({duration=duration}) + if opts.duration then engine.main({duration=opts.duration}) else engine.main() end end local function show_usage(exit_code) diff --git a/src/program/packetblaster/replay/replay.lua b/src/program/packetblaster/replay/replay.lua index a2607e098b..eaa411e2e0 100644 --- a/src/program/packetblaster/replay/replay.lua +++ b/src/program/packetblaster/replay/replay.lua @@ -21,17 +21,18 @@ local function show_usage (code) end function run (args) - local opt = {} + local handlers = {} + local opts = {} local duration local c = config.new() - function opt.D (arg) - duration = assert(tonumber(arg), "duration is not a number!") + function handlers.D (arg) + opts.duration = assert(tonumber(arg), "duration is not a number!") end - function opt.h () + function handlers.h () show_usage(0) end - args = lib.dogetopt(args, opt, "hD:", long_opts) + args = lib.dogetopt(args, handlers, "hD:", long_opts) if #args < 2 then show_usage(1) end local filename = table.remove(args, 1) print (string.format("filename=%s", filename)) @@ -40,5 +41,5 @@ function run (args) config.app(c, "source", basic_apps.Tee) config.link(c, "pcap.output -> loop.input") config.link(c, "loop.output -> source.input") - packetblaster.run_loadgen(c, args, duration) + packetblaster.run_loadgen(c, args, opts) end diff --git a/src/program/packetblaster/synth/synth.lua b/src/program/packetblaster/synth/synth.lua index 2ef6638788..1cacb1df33 100644 --- a/src/program/packetblaster/synth/synth.lua +++ b/src/program/packetblaster/synth/synth.lua @@ -23,31 +23,31 @@ local function show_usage (code) end function run (args) - local opt = {} - local duration + local handlers = {} + local opts = {} local c = config.new() - function opt.D (arg) - duration = assert(tonumber(arg), "duration is not a number!") + function handlers.D (arg) + opts.duration = assert(tonumber(arg), "duration is not a number!") end - function opt.h () + function handlers.h () show_usage(0) end local source local destination local sizes - function opt.s (arg) source = arg end - function opt.d (arg) destination = arg end - function opt.S (arg) + function handlers.s (arg) source = arg end + function handlers.d (arg) destination = arg end + function handlers.S (arg) sizes = {} for size in string.gmatch(arg, "%d+") do sizes[#sizes+1] = tonumber(size) end end - args = lib.dogetopt(args, opt, "hD:s:d:S:", long_opts) + args = lib.dogetopt(args, handlers, "hD:s:d:S:", long_opts) if not (sizes or source or destination) then show_usage(1) end config.app(c, "source", Synth, { sizes = sizes, src = source, dst = destination }) - packetblaster.run_loadgen(c, args, duration) + packetblaster.run_loadgen(c, args, opts) end From 4de74b149eeff351464f70fef707d2a4e1e35756 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 12:07:46 +0000 Subject: [PATCH 06/24] Add switch 'no-loop' to 'packetblaster replay' --- src/program/packetblaster/packetblaster.lua | 26 +++++++++++++++------ src/program/packetblaster/replay/README | 3 +++ src/program/packetblaster/replay/replay.lua | 17 ++++++++++---- 3 files changed, 35 insertions(+), 11 deletions(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index e155eb7d3a..129af9da65 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -7,6 +7,7 @@ local timer = require("core.timer") local lib = require("core.lib") local pci = require("lib.hardware.pci") local LoadGen = require("apps.intel.loadgen").LoadGen +local Intel82599 = require("apps.intel.intel_app").Intel82599 local function is_device_suitable (pcidev, patterns) if not pcidev.usable or pcidev.driver ~= 'apps.intel.intel_app' then @@ -23,28 +24,39 @@ local function is_device_suitable (pcidev, patterns) end function run_loadgen (c, patterns, opts) + if opts.loop == nil then opts.loop = true end local nics = 0 pci.scan_devices() for _,device in ipairs(pci.devices) do if is_device_suitable(device, patterns) then nics = nics + 1 local name = "nic"..nics - config.app(c, name, LoadGen, device.pciaddress) + if opts.loop then + config.app(c, name, LoadGen, device.pciaddress) + else + config.app(c, name, Intel82599, {pciaddr = device.pciaddress}) + end config.link(c, "source."..tostring(nics).."->"..name..".input") end end assert(nics > 0, " matches no suitable devices.") engine.busywait = true engine.configure(c) - local fn = function () - print("Transmissions (last 1 sec):") - engine.report_apps() + + if opts.loop then + local fn = function () + print("Transmissions (last 1 sec):") + engine.report_apps() + end + local t = timer.new("report", fn, 1e9, 'repeating') + timer.activate(t) end - local t = timer.new("report", fn, 1e9, 'repeating') - timer.activate(t) - if opts.duration then engine.main({duration=opts.duration}) + + local report = not opts.loop and {showlinks = true} or {} + if opts.duration then engine.main({duration=opts.duration, report=report}) else engine.main() end end + local function show_usage(exit_code) print(require("program.packetblaster.README_inc")) main.exit(exit_code) diff --git a/src/program/packetblaster/replay/README b/src/program/packetblaster/replay/README index 4bc2a3fe40..7583e1c525 100644 --- a/src/program/packetblaster/replay/README +++ b/src/program/packetblaster/replay/README @@ -6,6 +6,9 @@ Usage: packetblaster replay [OPTIONS] ... -h, --help Print usage information. + --no-loop Do not loop through . + Duration is one second if not set. + packetblaster transmits packets continuously to one or more network adapters. The PCI arguments are Lua pattern strings that are used to match the network adapters to use. The packets are extracted from PCAPFILE. diff --git a/src/program/packetblaster/replay/replay.lua b/src/program/packetblaster/replay/replay.lua index eaa411e2e0..b54b25682d 100644 --- a/src/program/packetblaster/replay/replay.lua +++ b/src/program/packetblaster/replay/replay.lua @@ -12,7 +12,8 @@ local packetblaster = require("program.packetblaster.packetblaster") local long_opts = { duration = "D", - help = "h" + help = "h", + ["no-loop"] = 0, } local function show_usage (code) @@ -31,15 +32,23 @@ function run (args) function handlers.h () show_usage(0) end + handlers["no-loop"] = function () + opts.loop = false + end args = lib.dogetopt(args, handlers, "hD:", long_opts) if #args < 2 then show_usage(1) end local filename = table.remove(args, 1) print (string.format("filename=%s", filename)) config.app(c, "pcap", PcapReader, filename) - config.app(c, "loop", basic_apps.Repeater) config.app(c, "source", basic_apps.Tee) - config.link(c, "pcap.output -> loop.input") - config.link(c, "loop.output -> source.input") + if opts.loop then + config.app(c, "loop", basic_apps.Repeater) + config.link(c, "pcap.output -> loop.input") + config.link(c, "loop.output -> source.input") + else + config.link(c, "pcap.output -> source.input") + if not opts.duration then opts.duration = 1 end + end packetblaster.run_loadgen(c, args, opts) end From 7429a78a6c18ac8fcb4fb03ede8447c3d272fa5d Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 15:21:48 +0000 Subject: [PATCH 07/24] Initialize loop flag in subprogram --- src/program/packetblaster/packetblaster.lua | 2 +- src/program/packetblaster/replay/replay.lua | 5 ++--- src/program/packetblaster/synth/synth.lua | 4 ++-- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index 129af9da65..7a0b4a3aa7 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -24,7 +24,7 @@ local function is_device_suitable (pcidev, patterns) end function run_loadgen (c, patterns, opts) - if opts.loop == nil then opts.loop = true end + assert(type(opts) == "table") local nics = 0 pci.scan_devices() for _,device in ipairs(pci.devices) do diff --git a/src/program/packetblaster/replay/replay.lua b/src/program/packetblaster/replay/replay.lua index b54b25682d..150e654152 100644 --- a/src/program/packetblaster/replay/replay.lua +++ b/src/program/packetblaster/replay/replay.lua @@ -22,10 +22,9 @@ local function show_usage (code) end function run (args) - local handlers = {} - local opts = {} - local duration local c = config.new() + local handlers = {} + local opts = { loop = true } function handlers.D (arg) opts.duration = assert(tonumber(arg), "duration is not a number!") end diff --git a/src/program/packetblaster/synth/synth.lua b/src/program/packetblaster/synth/synth.lua index 1cacb1df33..604e4a4f78 100644 --- a/src/program/packetblaster/synth/synth.lua +++ b/src/program/packetblaster/synth/synth.lua @@ -23,9 +23,9 @@ local function show_usage (code) end function run (args) - local handlers = {} - local opts = {} local c = config.new() + local handlers = {} + local opts = {loop = true} function handlers.D (arg) opts.duration = assert(tonumber(arg), "duration is not a number!") end From 0b035aebd6c44080ed30cc78be5f83af3c4db8ba Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 15:27:38 +0000 Subject: [PATCH 08/24] Add --no-loop to 'packetblaster synth' --- src/program/packetblaster/synth/synth.lua | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/program/packetblaster/synth/synth.lua b/src/program/packetblaster/synth/synth.lua index 604e4a4f78..4363c80433 100644 --- a/src/program/packetblaster/synth/synth.lua +++ b/src/program/packetblaster/synth/synth.lua @@ -14,7 +14,8 @@ local long_opts = { help = "h", src = "s", dst = "d", - sizes = "S" + sizes = "S", + ["no-loop"] = 0, } local function show_usage (code) @@ -32,6 +33,9 @@ function run (args) function handlers.h () show_usage(0) end + handlers["no-loop"] = function () + opts.loop = false + end local source local destination From bbdd18276028b1dbed8bd016d344aeb62931147a Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 2 Sep 2016 15:28:44 +0000 Subject: [PATCH 09/24] Update 'replay' and 'synth' README * Add info '--no-loop' switch. * Removed tabs. --- src/program/packetblaster/replay/README | 7 +++---- src/program/packetblaster/synth/README | 8 +++++--- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/program/packetblaster/replay/README b/src/program/packetblaster/replay/README index 7583e1c525..64d64da1a2 100644 --- a/src/program/packetblaster/replay/README +++ b/src/program/packetblaster/replay/README @@ -2,12 +2,11 @@ Usage: packetblaster replay [OPTIONS] ... -D DURATION, --duration DURATION Run for DURATION seconds. - Default: unlimited - -h, --help - Print usage information. - + Default: unlimited --no-loop Do not loop through . Duration is one second if not set. + -h, --help + Print usage information. packetblaster transmits packets continuously to one or more network adapters. The PCI arguments are Lua pattern strings that are used to match the network diff --git a/src/program/packetblaster/synth/README b/src/program/packetblaster/synth/README index 77630edd71..91b20ccdb1 100644 --- a/src/program/packetblaster/synth/README +++ b/src/program/packetblaster/synth/README @@ -2,17 +2,19 @@ Usage: packetblaster synth [OPTIONS] ... -s SOURCE, --src SOURCE Source MAC-Address. - Default: 00:00:00:00:00:00 + Default: 00:00:00:00:00:00 -d DESTINATION, --dst DESTINATION Destination MAC-Address. - Default: 00:00:00:00:00:00 + Default: 00:00:00:00:00:00 -S SIZES, --sizes SIZES A comma separated list of numbers. Send packets of SIZES bytes. Default: 64 -D DURATION, --duration DURATION Run for DURATION seconds. - Default: unlimited + Default: unlimited + --no-loop Do not loop through . + Duration is one second if not set. -h, --help Print usage information. From da860a663c69768235efc9a6d79102c7a219094a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Domen=20Ko=C5=BEar?= Date: Mon, 5 Sep 2016 10:43:31 +0200 Subject: [PATCH 10/24] manual: support NixOS 16.03 and 16.09 texlive package sets --- src/doc/default.nix | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/default.nix b/src/doc/default.nix index 673d319931..216ab49790 100644 --- a/src/doc/default.nix +++ b/src/doc/default.nix @@ -13,8 +13,8 @@ stdenv.mkDerivation rec { buildInputs = [ ditaa pandoc git (texlive.combine { - inherit (texlive) scheme-small luatex luatexbase sectsty titlesec cprotect bigfoot titling droid; - }) + inherit (texlive) scheme-small luatex luatexbase sectsty titlesec cprotect bigfoot titling droid collection-luatex; + }) ]; patchPhase = '' From 81d1d6a9c2fa11bd8bd96f5dc06668efe4b1a61e Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Mon, 5 Sep 2016 22:27:06 +0000 Subject: [PATCH 11/24] Remove --no-loop flag in synth * Removed not required checks too. --- src/program/packetblaster/packetblaster.lua | 3 ++- src/program/packetblaster/synth/README | 2 -- src/program/packetblaster/synth/synth.lua | 7 +------ 3 files changed, 3 insertions(+), 9 deletions(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index 7a0b4a3aa7..0dd051a79f 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -25,13 +25,14 @@ end function run_loadgen (c, patterns, opts) assert(type(opts) == "table") + local use_loadgen = opts.loop == nil or opts.loop local nics = 0 pci.scan_devices() for _,device in ipairs(pci.devices) do if is_device_suitable(device, patterns) then nics = nics + 1 local name = "nic"..nics - if opts.loop then + if use_loadgen then config.app(c, name, LoadGen, device.pciaddress) else config.app(c, name, Intel82599, {pciaddr = device.pciaddress}) diff --git a/src/program/packetblaster/synth/README b/src/program/packetblaster/synth/README index 91b20ccdb1..7109fc09b4 100644 --- a/src/program/packetblaster/synth/README +++ b/src/program/packetblaster/synth/README @@ -13,8 +13,6 @@ Usage: packetblaster synth [OPTIONS] ... -D DURATION, --duration DURATION Run for DURATION seconds. Default: unlimited - --no-loop Do not loop through . - Duration is one second if not set. -h, --help Print usage information. diff --git a/src/program/packetblaster/synth/synth.lua b/src/program/packetblaster/synth/synth.lua index 4363c80433..e820c8ce49 100644 --- a/src/program/packetblaster/synth/synth.lua +++ b/src/program/packetblaster/synth/synth.lua @@ -15,7 +15,6 @@ local long_opts = { src = "s", dst = "d", sizes = "S", - ["no-loop"] = 0, } local function show_usage (code) @@ -26,16 +25,13 @@ end function run (args) local c = config.new() local handlers = {} - local opts = {loop = true} + local opts = {} function handlers.D (arg) opts.duration = assert(tonumber(arg), "duration is not a number!") end function handlers.h () show_usage(0) end - handlers["no-loop"] = function () - opts.loop = false - end local source local destination @@ -50,7 +46,6 @@ function run (args) end args = lib.dogetopt(args, handlers, "hD:s:d:S:", long_opts) - if not (sizes or source or destination) then show_usage(1) end config.app(c, "source", Synth, { sizes = sizes, src = source, dst = destination }) packetblaster.run_loadgen(c, args, opts) From c547d906c340f4d9612051f6cd0b852cdd9aa29a Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Mon, 5 Sep 2016 22:34:55 +0000 Subject: [PATCH 12/24] Properly configure link for Intel82599 --- src/program/packetblaster/packetblaster.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index 0dd051a79f..4977a7e9da 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -34,10 +34,11 @@ function run_loadgen (c, patterns, opts) local name = "nic"..nics if use_loadgen then config.app(c, name, LoadGen, device.pciaddress) + config.link(c, "source."..tostring(nics).."->"..name..".input") else config.app(c, name, Intel82599, {pciaddr = device.pciaddress}) + config.link(c, "source."..tostring(nics).."->"..name..".rx") end - config.link(c, "source."..tostring(nics).."->"..name..".input") end end assert(nics > 0, " matches no suitable devices.") From b73f488e70d2b68fa35bcd22fd4427030b62c64f Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Tue, 6 Sep 2016 06:14:37 +0000 Subject: [PATCH 13/24] Report LoadGen results in synth.lua --- src/program/packetblaster/packetblaster.lua | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/program/packetblaster/packetblaster.lua b/src/program/packetblaster/packetblaster.lua index 4977a7e9da..22d1ea4071 100644 --- a/src/program/packetblaster/packetblaster.lua +++ b/src/program/packetblaster/packetblaster.lua @@ -45,16 +45,18 @@ function run_loadgen (c, patterns, opts) engine.busywait = true engine.configure(c) - if opts.loop then + local report = {} + if use_loadgen then local fn = function () print("Transmissions (last 1 sec):") engine.report_apps() end local t = timer.new("report", fn, 1e9, 'repeating') timer.activate(t) + else + report = {showlinks = true} end - local report = not opts.loop and {showlinks = true} or {} if opts.duration then engine.main({duration=opts.duration, report=report}) else engine.main() end end From d65e9dc7919b423b86bee131eab392455ac2888a Mon Sep 17 00:00:00 2001 From: Pete Bristow Date: Wed, 7 Sep 2016 12:33:42 +0100 Subject: [PATCH 14/24] avoid allocating a packet on every breath --- src/apps/tap/tap.lua | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/apps/tap/tap.lua b/src/apps/tap/tap.lua index f0fb97bc98..5fc37f83da 100644 --- a/src/apps/tap/tap.lua +++ b/src/apps/tap/tap.lua @@ -31,6 +31,7 @@ function Tap:new (name) end return setmetatable({sock = sock, name = name, + pkt = packet.allocate(), shm = { rxbytes = {counter}, rxpackets = {counter}, rxmcast = {counter}, @@ -45,17 +46,15 @@ end function Tap:pull () local l = self.output.output if l == nil then return end + local p = self.pkt for i=1,engine.pull_npackets do - local p = packet.allocate() local len, err = S.read(self.sock, p.data, C.PACKET_PAYLOAD_SIZE) -- errno == EAGAIN indicates that the read would of blocked as there is no -- packet waiting. It is not a failure. if not len and err.errno == const.E.AGAIN then - packet.free(p) return end if not len then - packet.free(p) error("Failed read on " .. self.name .. ": " .. tostring(err)) end p.length = len @@ -68,7 +67,9 @@ function Tap:pull () if ethernet:is_bcast(p.data) then counter.add(self.shm.rxbcast) end + p = packet.allocate() end + self.pkt = p end function Tap:push () From f06c88f49930e257845e5824f4035e0ef17bf101 Mon Sep 17 00:00:00 2001 From: Pete Bristow Date: Wed, 7 Sep 2016 22:06:50 +0100 Subject: [PATCH 15/24] Use output rather than out as Joins only output --- src/apps/basic/basic_apps.lua | 2 +- src/apps/intel/intel_app.lua | 18 +++++++++--------- src/apps/test/match.lua | 2 +- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/src/apps/basic/basic_apps.lua b/src/apps/basic/basic_apps.lua index 94eb669272..e98956331e 100644 --- a/src/apps/basic/basic_apps.lua +++ b/src/apps/basic/basic_apps.lua @@ -42,7 +42,7 @@ end function Join:push () for _, inport in ipairs(self.input) do while not link.empty(inport) do - transmit(self.output.out, receive(inport)) + transmit(self.output.output, receive(inport)) end end end diff --git a/src/apps/intel/intel_app.lua b/src/apps/intel/intel_app.lua index f88ac272f9..af7ddc9e22 100644 --- a/src/apps/intel/intel_app.lua +++ b/src/apps/intel/intel_app.lua @@ -376,14 +376,14 @@ function mq_sq(pcidevA, pcidevB) print("Send traffic from a nicA (SF) to nicB (two VFs)") print("The packets should arrive evenly split between the VFs") config.app(c, 'sink_ms', basic_apps.Sink) - config.link(c, 'source_ms.out -> repeater_ms.input') + config.link(c, 'source_ms.output -> repeater_ms.input') config.link(c, 'repeater_ms.output -> nicAs.rx') config.link(c, 'nicAs.tx -> sink_ms.in1') config.link(c, 'nicBm0.tx -> sink_ms.in2') config.link(c, 'nicBm1.tx -> sink_ms.in3') engine.configure(c) - link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d1)) - link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d2)) + link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d1)) + link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d2)) end -- one multiqueue driver with two apps and do switch stuff @@ -424,13 +424,13 @@ function mq_sw(pcidevA) print ("Send a bunch of packets from Am0") print ("half of them go to nicAm1 and half go nowhere") config.app(c, 'sink_ms', basic_apps.Sink) - config.link(c, 'source_ms.out -> repeater_ms.input') + config.link(c, 'source_ms.output -> repeater_ms.input') config.link(c, 'repeater_ms.output -> nicAm0.rx') config.link(c, 'nicAm0.tx -> sink_ms.in1') config.link(c, 'nicAm1.tx -> sink_ms.in2') engine.configure(c) - link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d1)) - link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d2)) + link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d1)) + link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d2)) end function manyreconf(pcidevA, pcidevB, n, do_pf) @@ -476,14 +476,14 @@ function manyreconf(pcidevA, pcidevB, n, do_pf) vlan = 100+i, }) config.app(c, 'sink_ms', basic_apps.Sink) - config.link(c, 'source_ms.out -> repeater_ms.input') + config.link(c, 'source_ms.output -> repeater_ms.input') config.link(c, 'repeater_ms.output -> nicAm0.rx') config.link(c, 'nicAm0.tx -> sink_ms.in1') config.link(c, 'nicAm1.tx -> sink_ms.in2') if do_pf then engine.configure(config.new()) end engine.configure(c) - link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d1)) - link.transmit(engine.app_table.source_ms.output.out, packet.from_string(d2)) + link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d1)) + link.transmit(engine.app_table.source_ms.output.output, packet.from_string(d2)) engine.main({duration = 0.1, no_report=true}) cycles = cycles + 1 redos = redos + engine.app_table.nicAm1.dev.pf.redos diff --git a/src/apps/test/match.lua b/src/apps/test/match.lua index 649bc4803f..3556d7ecee 100644 --- a/src/apps/test/match.lua +++ b/src/apps/test/match.lua @@ -88,7 +88,7 @@ function selftest() config.app(c, "join", basic_apps.Join) config.link(c, "src.output -> join.src") config.link(c, "garbage.output -> join.garbage") - config.link(c, "join.out -> sink.rx") + config.link(c, "join.output -> sink.rx") engine.configure(c) engine.main({duration=0.0001}) assert(#engine.app_table.sink:errors() == 0) From 598c5d01fc8ad54383a619f4de711734f5fe4cd3 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Wed, 7 Sep 2016 14:18:49 +0200 Subject: [PATCH 16/24] core.main: check the return value of fork. --- src/core/main.lua | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/core/main.lua b/src/core/main.lua index 5930142313..9e2348053f 100644 --- a/src/core/main.lua +++ b/src/core/main.lua @@ -164,7 +164,8 @@ function selftest () end -- Fork into worker process and supervisor -local worker_pid = S.fork() +local worker_pid, err = S.fork() +assert(worker_pid, tostring(err)) if worker_pid == 0 then -- Worker: Use prctl to ensure we are killed (SIGHUP) when our parent quits -- and run main. From eabe7bf0e738a806c930afbaa546a265e0403b88 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Wed, 7 Sep 2016 15:04:01 +0200 Subject: [PATCH 17/24] Provide global assert implementation that plays nicely with ljsyscall. --- src/apps/socket/raw.lua | 7 ------- src/apps/socket/unix.lua | 7 ------- src/core/lib.lua | 7 +++++++ src/core/main.lua | 5 +++-- src/program/lisper/lisper.lua | 5 ----- 5 files changed, 10 insertions(+), 21 deletions(-) diff --git a/src/apps/socket/raw.lua b/src/apps/socket/raw.lua index 13ecb8d635..d668248072 100644 --- a/src/apps/socket/raw.lua +++ b/src/apps/socket/raw.lua @@ -12,13 +12,6 @@ local ethernet = require("lib.protocol.ethernet") local ffi = require("ffi") local C = ffi.C ---ljsyscall returns error as a a cdata instead of a string, ---and the standard assert() doesn't use tostring() on it. -local function assert(v, ...) - if not v then error(tostring(... or 'assertion failed'), 2) end - return v, ... -end - local c, t = S.c, S.types.t RawSocket = {} diff --git a/src/apps/socket/unix.lua b/src/apps/socket/unix.lua index 57d29f2b92..00216b9c3a 100644 --- a/src/apps/socket/unix.lua +++ b/src/apps/socket/unix.lua @@ -9,13 +9,6 @@ local link = require("core.link") local packet = require("core.packet") local S = require("syscall") ---ljsyscall returns error as a a cdata instead of a string, ---and the standard assert() doesn't use tostring() on it. -local function assert(v, ...) - if not v then error(tostring(... or 'assertion failed'), 2) end - return v, ... -end - UnixSocket = {} UnixSocket.__index = UnixSocket diff --git a/src/core/lib.lua b/src/core/lib.lua index 6e37a90964..c348ad39b9 100644 --- a/src/core/lib.lua +++ b/src/core/lib.lua @@ -11,6 +11,13 @@ local bit = require("bit") local band, bor, bnot, lshift, rshift, bswap = bit.band, bit.bor, bit.bnot, bit.lshift, bit.rshift, bit.bswap +-- Alternate version of assert that calls tostring on it second argument. Very +-- useful for working with ljsyscall. +function assert (v, ...) + if v then return v, ... end + error(tostring(... or "assertion failed!")) +end + -- Returns true if x and y are structurally similar (isomorphic). function equal (x, y) if type(x) ~= type(y) then return false end diff --git a/src/core/main.lua b/src/core/main.lua index 9e2348053f..d206351072 100644 --- a/src/core/main.lua +++ b/src/core/main.lua @@ -112,10 +112,11 @@ end --- Globally initialize some things. Module can depend on this being done. function initialize () - require("core.lib") + -- Global API + _G.lib = require("core.lib") + _G.assert = _G.lib.assert require("core.clib_h") require("core.lib_h") - -- Global API _G.config = require("core.config") _G.engine = require("core.app") _G.memory = require("core.memory") diff --git a/src/program/lisper/lisper.lua b/src/program/lisper/lisper.lua index 0f43e4c181..258425db7b 100644 --- a/src/program/lisper/lisper.lua +++ b/src/program/lisper/lisper.lua @@ -28,11 +28,6 @@ local ntohl = lib.ntohl local getenv = lib.getenv local hexdump = lib.hexdump -local function assert(v, ...) --assert overload because - if v then return v, ... end - error(tostring((...) or "Assertion failed"), 2) -end - local function parsehex(s) return (s:gsub("[0-9a-fA-F][0-9a-fA-F]", function(cc) return string.char(tonumber(cc, 16)) From 9daa25c57055fb2c639ca14168c493c74be1e828 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Wed, 7 Sep 2016 15:05:50 +0200 Subject: [PATCH 18/24] Make use of new assert implementation. --- src/core/main.lua | 11 ++++------- src/core/memory.lua | 3 +-- src/lib/hardware/pci.lua | 12 ++++-------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/src/core/main.lua b/src/core/main.lua index d206351072..af456dca62 100644 --- a/src/core/main.lua +++ b/src/core/main.lua @@ -165,8 +165,7 @@ function selftest () end -- Fork into worker process and supervisor -local worker_pid, err = S.fork() -assert(worker_pid, tostring(err)) +local worker_pid = assert(S.fork()) if worker_pid == 0 then -- Worker: Use prctl to ensure we are killed (SIGHUP) when our parent quits -- and run main. @@ -181,16 +180,14 @@ else while true do -- Read signals from signalfd. Only process the first signal because any -- signal causes shutdown. - local signals, err = S.util.signalfd_read(signalfd) - assert(signals, tostring(err)) + local signals = assert(S.util.signalfd_read(signalfd)) for i = 1, #signals do local exit_status if signals[i].chld then -- SIGCHILD means worker state changed: retrieve its status using -- waitpid and set exit status accordingly. - local status, err, worker = - S.waitpid(worker_pid, "stopped,continued") - assert(status, tostring(err)) + local status, _, worker = + assert(S.waitpid(worker_pid, "stopped,continued")) if worker.WIFEXITED then exit_status = worker.EXITSTATUS elseif worker.WIFSIGNALED then exit_status = 128 + worker.WTERMSIG -- WIFSTOPPED and WIFCONTINUED are ignored. diff --git a/src/core/memory.lua b/src/core/memory.lua index ecfba556e1..30f8cc49e9 100644 --- a/src/core/memory.lua +++ b/src/core/memory.lua @@ -57,8 +57,7 @@ end --- ### HugeTLB: Allocate contiguous memory in bulk from Linux function allocate_hugetlb_chunk () - local fd, err = syscall.open("/proc/sys/vm/nr_hugepages","rdonly") - assert(fd, tostring(err)) + local fd = assert(syscall.open("/proc/sys/vm/nr_hugepages","rdonly")) fd:flock("ex") for i =1, 3 do local page = C.allocate_huge_page(huge_page_size) diff --git a/src/lib/hardware/pci.lua b/src/lib/hardware/pci.lua index de34a4d5d7..3c3fdf0c09 100644 --- a/src/lib/hardware/pci.lua +++ b/src/lib/hardware/pci.lua @@ -142,15 +142,12 @@ function map_pci_memory (device, n, lock) if lock then assert(f:flock("ex, nb"), "failed to lock " .. filepath) end - local st, err = f:stat() - assert(st, tostring(err)) - local mem, err = f:mmap(nil, st.size, "read, write", "shared", 0) - assert(mem, tostring(err)) + local st = assert(f:stat()) + local mem = assert(f:mmap(nil, st.size, "read, write", "shared", 0)) return ffi.cast("uint32_t *", mem), f end function close_pci_resource (fd, base) - local st, err = fd:stat() - assert(st, tostring(err)) + local st = assert(fd:stat()) S.munmap(base, st.size) fd:close() end @@ -159,8 +156,7 @@ end --- mastering is enabled. function set_bus_master (device, enable) root_check() - local f,err = S.open(path(device).."/config", "rdwr") - assert(f, tostring(err)) + local f = assert(S.open(path(device).."/config", "rdwr")) local fd = f:getfd() local value = ffi.new("uint16_t[1]") From 82eecef77502d1d00529492f18a51a33a9d1c8b8 Mon Sep 17 00:00:00 2001 From: Pete Bristow Date: Thu, 8 Sep 2016 19:07:17 +0100 Subject: [PATCH 19/24] The last fix for allocating on every breath actually broke under load, this one does not --- src/apps/tap/tap.lua | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/src/apps/tap/tap.lua b/src/apps/tap/tap.lua index 5fc37f83da..2218897031 100644 --- a/src/apps/tap/tap.lua +++ b/src/apps/tap/tap.lua @@ -46,9 +46,8 @@ end function Tap:pull () local l = self.output.output if l == nil then return end - local p = self.pkt for i=1,engine.pull_npackets do - local len, err = S.read(self.sock, p.data, C.PACKET_PAYLOAD_SIZE) + local len, err = S.read(self.sock, self.pkt.data, C.PACKET_PAYLOAD_SIZE) -- errno == EAGAIN indicates that the read would of blocked as there is no -- packet waiting. It is not a failure. if not len and err.errno == const.E.AGAIN then @@ -57,19 +56,18 @@ function Tap:pull () if not len then error("Failed read on " .. self.name .. ": " .. tostring(err)) end - p.length = len - link.transmit(l, p) + self.pkt.length = len + link.transmit(l, self.pkt) counter.add(self.shm.rxbytes, len) counter.add(self.shm.rxpackets) - if ethernet:is_mcast(p.data) then + if ethernet:is_mcast(self.pkt.data) then counter.add(self.shm.rxmcast) end - if ethernet:is_bcast(p.data) then + if ethernet:is_bcast(self.pkt.data) then counter.add(self.shm.rxbcast) end - p = packet.allocate() + self.pkt = packet.allocate() end - self.pkt = p end function Tap:push () From 4411ad3498107af1a6e8fab85d69472d0932eeba Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Fri, 9 Sep 2016 14:36:12 +0200 Subject: [PATCH 20/24] Move lib.assert to core.main, fixing global name space breakage. --- src/core/lib.lua | 7 ------- src/core/main.lua | 12 +++++++++--- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/core/lib.lua b/src/core/lib.lua index c348ad39b9..6e37a90964 100644 --- a/src/core/lib.lua +++ b/src/core/lib.lua @@ -11,13 +11,6 @@ local bit = require("bit") local band, bor, bnot, lshift, rshift, bswap = bit.band, bit.bor, bit.bnot, bit.lshift, bit.rshift, bit.bswap --- Alternate version of assert that calls tostring on it second argument. Very --- useful for working with ljsyscall. -function assert (v, ...) - if v then return v, ... end - error(tostring(... or "assertion failed!")) -end - -- Returns true if x and y are structurally similar (isomorphic). function equal (x, y) if type(x) ~= type(y) then return false end diff --git a/src/core/main.lua b/src/core/main.lua index af456dca62..611f167152 100644 --- a/src/core/main.lua +++ b/src/core/main.lua @@ -19,6 +19,13 @@ local S = require("syscall") require("lib.lua.strict") require("lib.lua.class") +-- ljsyscall returns error as a cdata instead of a string, and the standard +-- assert doesn't use tostring on it. +_G.assert = function (v, ...) + if v then return v, ... end + error(tostring(... or "assertion failed!")) +end + -- Reserve names that we want to use for global module. -- (This way we avoid errors from the 'strict' module.) _G.config, _G.engine, _G.memory, _G.link, _G.packet, _G.timer, @@ -112,11 +119,10 @@ end --- Globally initialize some things. Module can depend on this being done. function initialize () - -- Global API - _G.lib = require("core.lib") - _G.assert = _G.lib.assert + require("core.lib") require("core.clib_h") require("core.lib_h") + -- Global API _G.config = require("core.config") _G.engine = require("core.app") _G.memory = require("core.memory") From 65cdc1c7f22ebf4390ef95e88e84ac35662c8aa0 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 23 Sep 2016 08:01:05 +0000 Subject: [PATCH 21/24] Cast VLAN tags as int32 --- src/apps/vlan/vlan.lua | 31 ++++++++++++++++++++++++++++--- 1 file changed, 28 insertions(+), 3 deletions(-) diff --git a/src/apps/vlan/vlan.lua b/src/apps/vlan/vlan.lua index 2024e72624..13fc6b5b8b 100644 --- a/src/apps/vlan/vlan.lua +++ b/src/apps/vlan/vlan.lua @@ -17,7 +17,7 @@ Untagger = {} -- 802.1q local dot1q_tpid = 0x8100 local o_ethernet_ethertype = 12 -local uint32_ptr_t = ffi.typeof('uint32_t*') +local int32_ptr_t = ffi.typeof('int32_t*') -- build a VLAN tag consisting of 2 bytes of TPID set to 0x8100 followed by the @@ -41,7 +41,7 @@ function push_tag(pkt, tag) local length = pkt.length pkt.length = length + 4 C.memmove(payload + 4, payload, length - o_ethernet_ethertype) - cast(uint32_ptr_t, payload)[0] = tag + cast(int32_ptr_t, payload)[0] = tag end -- extract TCI (2 bytes) from packet, no check is performed to verify that the @@ -85,7 +85,7 @@ function Untagger:push () for _=1,link.nreadable(input) do local pkt = receive(input) local payload = pkt.data + o_ethernet_ethertype - if cast(uint32_ptr_t, payload)[0] ~= tag then + if cast(int32_ptr_t, payload)[0] ~= tag then -- Incorrect VLAN tag; drop. packet.free(pkt) else @@ -147,6 +147,29 @@ function VlanMux:transmit(o, pkt) end end +function test_tag_untag () + local pkt = packet.from_string(lib.hexundump([[ + 02:aa:aa:aa:aa:aa 02:99:99:99:99:99 08 00 45 00 + 00 54 43 58 40 00 40 01 7c 5c c0 a8 0d 28 ac 14 + 01 10 08 00 9c d4 07 c0 00 01 bc fa e3 57 00 00 + 00 00 f3 44 01 00 00 00 00 00 10 11 12 13 14 15 + 16 17 18 19 1a 1b 1c 1d 1e 1f 20 21 22 23 24 25 + 26 27 28 29 2a 2b 2c 2d 2e 2f 30 31 32 33 34 35 + 36 37 + ]], 82)) + local payload = pkt.data + o_ethernet_ethertype + local vid = 0 + for i=0,15 do + for j=0,255 do + local tag = build_tag(vid) + push_tag(pkt, tag) + assert(cast(int32_ptr_t, payload)[0] == tag) + vid = vid + 1 + end + end + assert(vid == 4096) + print("Sucessfully tagged/untagged all potential VLAN tags (0-4095)") +end function selftest() local app = require("core.app") @@ -164,4 +187,6 @@ function selftest() print("source sent: " .. link.stats(app.app_table.source.output.output).txpackets) print("sink received: " .. link.stats(app.app_table.sink.input.input).rxpackets) + + test_tag_untag() end From 83a4216726fdc4d7f47fda826ad56b5398f7f9cb Mon Sep 17 00:00:00 2001 From: Katerina Barone-Adesi Date: Sat, 24 Sep 2016 11:45:06 +0200 Subject: [PATCH 22/24] Make ntohl/htonl unsigned This is the behavior in C, and which most code expects. This also documents that ntohl/htonl are unsigned. There should be no performance impact; the assembly code has the same number of the essentially the same instructions as before. --- src/README.md | 4 ++-- src/core/lib.lua | 5 ++++- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/src/README.md b/src/README.md index 6dcbb3955e..5a507ea5ed 100644 --- a/src/README.md +++ b/src/README.md @@ -871,14 +871,14 @@ Returns a copy of *array*. *Array* must not be a "sparse array". — Function **lib.htons** *n* Host to network byte order conversion functions for 32 and 16 bit -integers *n* respectively. +integers *n* respectively. Unsigned. — Function **lib.ntohl** *n* — Function **lib.ntohs** *n* Network to host byte order conversion functions for 32 and 16 bit -integers *n* respectively. +integers *n* respectively. Unsigned. diff --git a/src/core/lib.lua b/src/core/lib.lua index 6e37a90964..30f9b8857c 100644 --- a/src/core/lib.lua +++ b/src/core/lib.lua @@ -10,6 +10,8 @@ require("core.clib_h") local bit = require("bit") local band, bor, bnot, lshift, rshift, bswap = bit.band, bit.bor, bit.bnot, bit.lshift, bit.rshift, bit.bswap +local tonumber = tonumber -- Yes, this makes a performance difference. +local cast = ffi.cast -- Returns true if x and y are structurally similar (isomorphic). function equal (x, y) @@ -373,7 +375,8 @@ if ffi.abi("be") then function htonl(b) return b end function htons(b) return b end else - function htonl(b) return bswap(b) end + -- htonl is unsigned, matching the C version and expectations. + function htonl(b) return tonumber(cast('uint32_t', bswap(b))) end function htons(b) return rshift(bswap(b), 16) end end ntohl = htonl From f0a9bb091915d6f8e75772ab224455a57c1dcaa1 Mon Sep 17 00:00:00 2001 From: Max Rottenkolber Date: Mon, 26 Sep 2016 15:01:40 +0200 Subject: [PATCH 23/24] Revert "Cast VLAN tags as int32" in favor of #1024, keep test case This reverts commit 65cdc1c7f22ebf4390ef95e88e84ac35662c8aa0. --- src/apps/vlan/vlan.lua | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/apps/vlan/vlan.lua b/src/apps/vlan/vlan.lua index 13fc6b5b8b..e5b38ad306 100644 --- a/src/apps/vlan/vlan.lua +++ b/src/apps/vlan/vlan.lua @@ -17,7 +17,7 @@ Untagger = {} -- 802.1q local dot1q_tpid = 0x8100 local o_ethernet_ethertype = 12 -local int32_ptr_t = ffi.typeof('int32_t*') +local uint32_ptr_t = ffi.typeof('uint32_t*') -- build a VLAN tag consisting of 2 bytes of TPID set to 0x8100 followed by the @@ -41,7 +41,7 @@ function push_tag(pkt, tag) local length = pkt.length pkt.length = length + 4 C.memmove(payload + 4, payload, length - o_ethernet_ethertype) - cast(int32_ptr_t, payload)[0] = tag + cast(uint32_ptr_t, payload)[0] = tag end -- extract TCI (2 bytes) from packet, no check is performed to verify that the @@ -85,7 +85,7 @@ function Untagger:push () for _=1,link.nreadable(input) do local pkt = receive(input) local payload = pkt.data + o_ethernet_ethertype - if cast(int32_ptr_t, payload)[0] ~= tag then + if cast(uint32_ptr_t, payload)[0] ~= tag then -- Incorrect VLAN tag; drop. packet.free(pkt) else @@ -163,7 +163,7 @@ function test_tag_untag () for j=0,255 do local tag = build_tag(vid) push_tag(pkt, tag) - assert(cast(int32_ptr_t, payload)[0] == tag) + assert(cast(uint32_ptr_t, payload)[0] == tag) vid = vid + 1 end end From 2194fa5ae65cb52b597c03ec20562521845ac83a Mon Sep 17 00:00:00 2001 From: Katerina Barone-Adesi Date: Mon, 26 Sep 2016 16:32:27 +0200 Subject: [PATCH 24/24] Added ntohl selftest sanity checks --- src/core/lib.lua | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/core/lib.lua b/src/core/lib.lua index 6e37a90964..970ee59626 100644 --- a/src/core/lib.lua +++ b/src/core/lib.lua @@ -739,4 +739,9 @@ function selftest () :match('^45.00.B6.7D.00.FA.40.00.40.11$'), "wrong hex dump") assert(hexundump('4500 B67D 00FA400040 11', 10) =='\x45\x00\xb6\x7d\x00\xFA\x40\x00\x40\x11', "wrong hex undump") + print("Testing ntohl") + local raw_val = 0xf0d0b0f0 + assert(ntohl(raw_val) > 0, "ntohl must be unsigned") + assert(ntohl(ntohl(raw_val)) == raw_val, + "calling ntohl twice must return the original value") end