Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

vita/tunnel: throttle ESP apps to amortize over bursts #81

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 36 additions & 8 deletions src/apps/test/match.lua
Original file line number Diff line number Diff line change
Expand Up @@ -25,19 +25,22 @@ end
function Match:push ()
while not link.empty(self.input.rx) do
local p = link.receive(self.input.rx)
local cmp = link.front(self.input.comparator)
if not cmp then
elseif cmp.length ~= p.length
or C.memcmp(cmp.data, p.data, cmp.length) ~= 0 then
if not self.fuzzy then
for n = 1, link.nreadable(self.input.comparator) do
local cmp = link.front(self.input.comparator)
if p.length == cmp.length and C.memcmp(p, cmp, p.length) == 0 then
self.seen = self.seen + 1
packet.free(link.receive(self.input.comparator))
break
elseif self.fuzzy then
link.transmit(self.input.comparator,
link.receive(self.input.comparator))
else
table.insert(self.errs,
"Mismatch at packet #"..(self.seen+1)..":\n"
..dump(cmp).."\n"
..dump(p))
break
end
else
self.seen = self.seen + 1
packet.free(link.receive(self.input.comparator))
end
packet.free(p)
end
Expand Down Expand Up @@ -88,8 +91,33 @@ function selftest()
assert(#engine.app_table.sink:errors() > 0)

engine.configure(config.new())
local c = config.new()
config.app(c, "sink", Match, {})
config.app(c, "comparator", basic_apps.Source, 8)
config.link(c, "comparator.output -> sink.comparator")
config.app(c, "garbage", basic_apps.Source, 12)
config.link(c, "garbage.output -> sink.rx")
engine.configure(c)
engine.main({duration=0.0001})
assert(#engine.app_table.sink:errors() > 0)

engine.configure(config.new())
local c = config.new()
config.app(c, "sink", Match, {fuzzy=true})
config.app(c, "comparator", basic_apps.Source, 8)
config.link(c, "comparator.output -> sink.comparator")
config.app(c, "garbage", basic_apps.Source, 12)
config.link(c, "garbage.output -> sink.rx")
engine.configure(c)
engine.main({duration=0.0001})
assert(#engine.app_table.sink:errors() > 0)

engine.configure(config.new())
local c = config.new()
config.app(c, "sink", Match, {fuzzy=true})
config.app(c, "comparator", basic_apps.Source, 8)
config.link(c, "comparator.output -> sink.comparator")
config.app(c, "src", basic_apps.Source, 8)
config.app(c, "garbage", basic_apps.Source, 12)
config.app(c, "join", basic_apps.Join)
config.link(c, "src.output -> join.src")
Expand Down
4 changes: 2 additions & 2 deletions src/program/vita/selftest.snabb
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,10 @@ else
"program/vita/selftest-private-out.pcap")
config.app(c, "public_pcap_out", pcap.PcapReader,
"program/vita/selftest-public-out.pcap")
config.app(c, "match_private", match.Match, {})
config.app(c, "match_private", match.Match, {fuzzy=true})
config.link(c, "private_pcap_out.output -> match_private.comparator")
config.link(c, "private_arp.north -> match_private.rx")
config.app(c, "match_public", match.Match, {})
config.app(c, "match_public", match.Match, {fuzzy=true})
config.link(c, "public_pcap_out.output -> match_public.comparator")
config.link(c, "public_out.output -> match_public.rx")
end
Expand Down
4 changes: 2 additions & 2 deletions src/program/vita/selftest6.snabb
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,10 @@ else
"program/vita/selftest6-private-out.pcap")
config.app(c, "public_pcap_out", pcap.PcapReader,
"program/vita/selftest6-public-out.pcap")
config.app(c, "match_private", match.Match, {})
config.app(c, "match_private", match.Match, {fuzzy=true})
config.link(c, "private_pcap_out.output -> match_private.comparator")
config.link(c, "private_arp.north -> match_private.rx")
config.app(c, "match_public", match.Match, {})
config.app(c, "match_public", match.Match, {fuzzy=true})
config.link(c, "public_pcap_out.output -> match_public.comparator")
config.link(c, "public_out.output -> match_public.rx")
end
Expand Down
22 changes: 19 additions & 3 deletions src/program/vita/tunnel.lua
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ local counter = require("core.counter")
local esp = require("lib.ipsec.esp")
local ipv4 = require("lib.protocol.ipv4")
local ipv6 = require("lib.protocol.ipv6")
local lib = require("core.lib")

-- sa := { spi=(SPI), aead=(STRING), key=(KEY), salt=(SALT),
-- [ window_size=(INT),
Expand All @@ -16,6 +17,12 @@ local ipv6 = require("lib.protocol.ipv6")
local NextHeaderIPv4 = 4
local NextHeaderIPv6 = 41

-- Try to process packets in burst sized batches to armortize spinning up the
-- AVX units and loading the caches with AES-GCM contexts, but add no more than
-- 5ms of latency when throughput is low.
local burst = engine.pull_npackets
local throttle = 0.005

Encapsulate = {
name = "Encapsulate",
config = {
Expand All @@ -27,13 +34,17 @@ Encapsulate = {
}

function Encapsulate:new (sa)
return setmetatable({sa = esp.encrypt:new(sa)}, {__index = Encapsulate})
local o = {
sa = esp.encrypt:new(sa),
throttle = lib.throttle(throttle)
}
return setmetatable(o, {__index = Encapsulate})
end

function Encapsulate:push ()
local output, sa = self.output.output, self.sa
local input4, input6 = self.input.input4, self.input.input6
if input4 then
if input4 and (link.nreadable(input4) >= burst or self.throttle()) then
while not link.empty(input4) do
link.transmit(
output,
Expand Down Expand Up @@ -72,12 +83,17 @@ Decapsulate = {
}

function Decapsulate:new (sa)
return setmetatable({sa = esp.decrypt:new(sa)}, {__index = Decapsulate})
local o = {
sa = esp.decrypt:new(sa),
throttle = lib.throttle(throttle)
}
return setmetatable(o, {__index = Decapsulate})
end

function Decapsulate:push ()
local input, sa = self.input.input, self.sa
local output4, output6 = self.output.output4, self.output.output6
if not (link.nreadable(input) >= burst or self.throttle()) then return end
while not link.empty(input) do
local p_enc = link.receive(input)
local p, next_header = sa:decapsulate_tunnel(p_enc)
Expand Down