From 2ad68178323e961b03297c5c2d7c4b54fd6ddff2 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Mon, 11 Jun 2018 17:42:16 +0200 Subject: [PATCH 01/35] ipv6.reassembly: avoid packet cloning --- src/apps/ipv6/reassemble.lua | 20 ++++++++++--------- .../tests/data/counters/arp-for-next-hop.lua | 2 +- .../lwaftr/tests/data/counters/empty.lua | 2 +- ...pv4-in-binding-big-packet-df-set-allow.lua | 2 +- ...ipv4-in-binding-big-packet-df-set-drop.lua | 2 +- .../counters/from-to-b4-ipv6-hairpin-n64.lua | 2 +- .../data/counters/from-to-b4-ipv6-hairpin.lua | 2 +- ...4-tunneled-icmpv4-ping-hairpin-unbound.lua | 2 +- ...rom-to-b4-tunneled-icmpv4-ping-hairpin.lua | 2 +- .../data/counters/icmpv6-ping-and-reply.lua | 2 +- ...1p-ipv4-infrags-out-1p-ipv6-6-outfrags.lua | 2 +- .../data/counters/in-1p-ipv4-out-0p-drop.lua | 2 +- .../counters/in-1p-ipv4-out-1p-icmpv4.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-1.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-2.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-3.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-4.lua | 2 +- .../in-1p-ipv4-out-1p-ipv6-6-outfrags.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-6.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-7.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-8.lua | 2 +- .../counters/in-1p-ipv4-out-1p-ipv6-echo.lua | 2 +- .../data/counters/in-1p-ipv4-out-none-1.lua | 2 +- .../data/counters/in-1p-ipv4-out-none-2.lua | 2 +- .../data/counters/in-1p-ipv4-out-none-3.lua | 2 +- .../data/counters/in-1p-ipv4-out-none-4.lua | 2 +- .../data/counters/in-1p-ipv6-out-0p-ipv4.lua | 2 +- .../counters/in-1p-ipv6-out-1p-icmpv4-1.lua | 2 +- .../counters/in-1p-ipv6-out-1p-icmpv6-1.lua | 2 +- .../counters/in-1p-ipv6-out-1p-icmpv6-2.lua | 2 +- .../counters/in-1p-ipv6-out-1p-ipv4-1.lua | 2 +- .../counters/in-1p-ipv6-out-1p-ipv4-2.lua | 2 +- .../counters/in-1p-ipv6-out-1p-ipv4-3.lua | 2 +- .../in-1p-ipv6-out-1p-ipv4-4-and-echo.lua | 2 +- .../counters/in-1p-ipv6-out-1p-ipv4-4.lua | 2 +- .../in-1p-ipv6-out-1p-ipv4-5-frags.lua | 2 +- .../counters/in-1p-ipv6-out-1p-ipv4-5.lua | 2 +- .../in-1p-ipv6-out-1p-ipv4-hoplimhair.lua | 2 +- .../data/counters/in-1p-ipv6-out-none-1.lua | 2 +- .../data/counters/in-1p-ipv6-out-none-2.lua | 2 +- ...v4-ipv6-out-icmpv4-ipv6-hairpin-1-drop.lua | 2 +- ...in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1.lua | 2 +- .../ndp-no-na-next-hop6-mac-not-set-2pkts.lua | 2 +- .../ndp-no-na-next-hop6-mac-not-set-3pkts.lua | 2 +- .../data/counters/ndp-ns-for-next-hop.lua | 2 +- .../tests/data/counters/ndp-secondary.lua | 2 +- .../lwaftr/tests/data/counters/nofrag4.lua | 2 +- .../tests/data/counters/nofrag6-sol.lua | 2 +- .../lwaftr/tests/data/counters/nofrag6.lua | 2 +- .../non-ipv4-traffic-to-ipv4-interface.lua | 2 +- .../non-ipv6-traffic-to-ipv6-interface.lua | 2 +- .../data/counters/regressiontest-endaddr.lua | 2 +- ...ressiontest-signedntohl-frags-counters.lua | 2 +- .../data/counters/tcp-frominet-bound-ttl1.lua | 2 +- 54 files changed, 64 insertions(+), 62 deletions(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 3d86fd9146..7b108e30ba 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -153,7 +153,7 @@ function Reassembler:new(conf) uint16_t final_start; uint16_t reassembly_base; uint32_t running_length; // bytes copied so far - struct packet packet; + struct packet *packet; } __attribute((packed))]], o.max_fragments_per_reassembly, o.max_fragments_per_reassembly), @@ -193,13 +193,14 @@ function Reassembler:record_eviction() counter.add(self.shm["drop-ipv6-frag-random-evicted"]) end -function Reassembler:reassembly_success(entry, pkt) - self.ctab:remove_ptr(entry) +function Reassembler:reassembly_success(entry) counter.add(self.shm["in-ipv6-frag-reassembled"]) - link.transmit(self.output.output, pkt) + link.transmit(self.output.output, entry.value.packet) + self.ctab:remove_ptr(entry) end function Reassembler:reassembly_error(entry, icmp_error) + packet.free(entry.value.packet) self.ctab:remove_ptr(entry) counter.add(self.shm["drop-ipv6-frag-invalid-reassembly"]) if icmp_error then -- This is an ICMP packet @@ -218,8 +219,10 @@ function Reassembler:lookup_reassembly(src_ip, dst_ip, fragment_id) ffi.fill(reassembly, ffi.sizeof(reassembly)) reassembly.reassembly_base = ether_ipv6_header_len reassembly.running_length = ether_ipv6_header_len + + reassembly.packet = packet.allocate() -- Fragment 0 will fill in the contents of this data. - packet.length = ether_ipv6_header_len + reassembly.packet.length = ether_ipv6_header_len local did_evict = false entry, did_evict = self.ctab:add(key, reassembly, false) @@ -292,10 +295,9 @@ function Reassembler:handle_fragment(h) elseif not verify_valid_offsets(reassembly) then return self:reassembly_error(entry) else - local out = packet.clone(reassembly.packet) - local header = ffi.cast(ether_ipv6_header_ptr_t, out.data) - header.ipv6.payload_length = htons(out.length - ether_ipv6_header_len) - return self:reassembly_success(entry, out) + local header = ffi.cast(ether_ipv6_header_ptr_t, reassembly.packet.data) + header.ipv6.payload_length = htons(reassembly.packet.length - ether_ipv6_header_len) + return self:reassembly_success(entry) end end diff --git a/src/program/lwaftr/tests/data/counters/arp-for-next-hop.lua b/src/program/lwaftr/tests/data/counters/arp-for-next-hop.lua index b9ab1dc980..c692e9d73e 100644 --- a/src/program/lwaftr/tests/data/counters/arp-for-next-hop.lua +++ b/src/program/lwaftr/tests/data/counters/arp-for-next-hop.lua @@ -1,5 +1,5 @@ return { ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-frag-not"] = 1, } diff --git a/src/program/lwaftr/tests/data/counters/empty.lua b/src/program/lwaftr/tests/data/counters/empty.lua index 66cfe280fe..9365f0589b 100644 --- a/src/program/lwaftr/tests/data/counters/empty.lua +++ b/src/program/lwaftr/tests/data/counters/empty.lua @@ -1,4 +1,4 @@ return { ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-allow.lua b/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-allow.lua index 3c4a0491f8..bd28c5fd2a 100644 --- a/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-allow.lua +++ b/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-allow.lua @@ -7,7 +7,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv4-bytes"] = 590, ["out-icmpv4-packets"] = 1, ["out-ipv4-bytes"] = 590, diff --git a/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-drop.lua b/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-drop.lua index 1ac4f06174..d524239baa 100644 --- a/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-drop.lua +++ b/src/program/lwaftr/tests/data/counters/from-inet-ipv4-in-binding-big-packet-df-set-drop.lua @@ -8,5 +8,5 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin-n64.lua b/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin-n64.lua index 26667c7f95..a42a9b9c82 100644 --- a/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin-n64.lua +++ b/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin-n64.lua @@ -5,7 +5,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 64, ["in-ipv6-packets"] = 64, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 6784, ["out-ipv6-frag-not"] = 64, ["out-ipv6-packets"] = 64, diff --git a/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin.lua b/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin.lua index d69b852870..80c25392ad 100644 --- a/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin.lua +++ b/src/program/lwaftr/tests/data/counters/from-to-b4-ipv6-hairpin.lua @@ -5,7 +5,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 106, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin-unbound.lua b/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin-unbound.lua index 0222985aa2..7f010f52cf 100644 --- a/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin-unbound.lua +++ b/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin-unbound.lua @@ -11,5 +11,5 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin.lua b/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin.lua index ce38659ba7..2cd6e7c58e 100644 --- a/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin.lua +++ b/src/program/lwaftr/tests/data/counters/from-to-b4-tunneled-icmpv4-ping-hairpin.lua @@ -5,7 +5,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 138, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/icmpv6-ping-and-reply.lua b/src/program/lwaftr/tests/data/counters/icmpv6-ping-and-reply.lua index 3c274602e3..2e6a730d5a 100644 --- a/src/program/lwaftr/tests/data/counters/icmpv6-ping-and-reply.lua +++ b/src/program/lwaftr/tests/data/counters/icmpv6-ping-and-reply.lua @@ -1,6 +1,6 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-frag-not"] = 1, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-infrags-out-1p-ipv6-6-outfrags.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-infrags-out-1p-ipv6-6-outfrags.lua index 733546771d..4a23766605 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-infrags-out-1p-ipv6-6-outfrags.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-infrags-out-1p-ipv6-6-outfrags.lua @@ -4,7 +4,7 @@ return { ["in-ipv4-frag-reassembled"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 1514, ["out-ipv6-frag"] = 2, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-0p-drop.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-0p-drop.lua index f54a875a73..f45d7746aa 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-0p-drop.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-0p-drop.lua @@ -1,5 +1,5 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-icmpv4.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-icmpv4.lua index eecdde9a1f..39a5560d16 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-icmpv4.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-icmpv4.lua @@ -7,7 +7,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv4-bytes"] = 94, ["out-icmpv4-packets"] = 1, ["out-ipv4-bytes"] = 94, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-1.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-1.lua index 0f66323da5..d38aeb36ca 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-1.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 106, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-2.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-2.lua index 86b076482a..aa1d77398d 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-2.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-2.lua @@ -4,7 +4,7 @@ return { ["in-ipv4-frag-reassembled"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 1500, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-3.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-3.lua index 01418d89dd..9c8280e9b3 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-3.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-3.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 1534, ["out-ipv6-frag"] = 2, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-4.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-4.lua index 4457e0be24..700700db26 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-4.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-4.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 2774, ["out-ipv6-frag"] = 3, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6-outfrags.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6-outfrags.lua index ba05aee0c6..279737d88f 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6-outfrags.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6-outfrags.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 1514, ["out-ipv6-frag"] = 2, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6.lua index 38d2e263bb..a936340068 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-6.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 1514, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-7.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-7.lua index 28e02ebb0e..eb589191e3 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-7.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-7.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 138, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-8.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-8.lua index 1647ce627d..f30001771f 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-8.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-8.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 110, ["out-ipv6-frag-not"] = 1, ["out-ipv6-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-echo.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-echo.lua index fe3f6fc983..418eba156c 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-echo.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-1p-ipv6-echo.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 2, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-frag-not"] = 1, ["out-ipv6-bytes"] = 106, ["out-ipv6-frag-not"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-1.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-1.lua index 226c58c2fb..df96ea5c17 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-1.lua @@ -8,5 +8,5 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-2.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-2.lua index df93b0739a..ce15d02de7 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-2.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-2.lua @@ -7,5 +7,5 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-3.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-3.lua index 8a70c2c4eb..cc19af49d7 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-3.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-3.lua @@ -7,5 +7,5 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-4.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-4.lua index e98f2e3c79..d825e21eb5 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-4.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv4-out-none-4.lua @@ -9,5 +9,5 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua index 93ac662da1..397cea054c 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua @@ -2,5 +2,5 @@ return { ["drop-ipv6-frag-invalid-reassembly"] = 1, ["in-ipv6-frag-needs-reassembly"] = 2, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 393216, + ["memuse-ipv6-frag-reassembly-buffer"] = 1536, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv4-1.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv4-1.lua index a38097dfd6..c9191edd5b 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv4-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv4-1.lua @@ -3,7 +3,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv4-bytes"] = 94, ["out-icmpv4-packets"] = 1, ["out-ipv4-bytes"] = 94, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-1.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-1.lua index 283801a033..16190036a3 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-1.lua @@ -7,7 +7,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv6-bytes"] = 154, ["out-icmpv6-packets"] = 1, ["out-ipv6-bytes"] = 154, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-2.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-2.lua index aad8233063..2c41896cac 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-2.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-icmpv6-2.lua @@ -7,7 +7,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv6-bytes"] = 186, ["out-icmpv6-packets"] = 1, ["out-ipv6-bytes"] = 186, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-1.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-1.lua index ed3bcb69c5..7c746949d4 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-1.lua @@ -3,7 +3,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 1006, ["out-ipv4-frag"] = 2, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-2.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-2.lua index 3fecd1a4f1..0b9dc241ff 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-2.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-2.lua @@ -3,7 +3,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 1460, ["out-ipv4-frag"] = 3, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-3.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-3.lua index ead36e485c..cbfc4d08c2 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-3.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-3.lua @@ -4,7 +4,7 @@ return { ["in-ipv6-frag-reassembled"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 1494, ["out-ipv4-frag-not"] = 1, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4-and-echo.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4-and-echo.lua index acef37d165..b567ab93b3 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4-and-echo.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4-and-echo.lua @@ -3,7 +3,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 2, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 66, ["out-ipv4-frag-not"] = 1, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4.lua index 6d30616d58..1e0519c852 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-4.lua @@ -3,7 +3,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 66, ["out-ipv4-frag-not"] = 1, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5-frags.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5-frags.lua index 254e2043d4..b33e646296 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5-frags.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5-frags.lua @@ -4,7 +4,7 @@ return { ["in-ipv6-frag-reassembled"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 1474, ["out-ipv4-frag-not"] = 1, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5.lua index 0f4ce4be24..6ffc5b7521 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-5.lua @@ -4,7 +4,7 @@ return { ["in-ipv6-frag-reassembled"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 1474, ["out-ipv4-frag"] = 3, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-hoplimhair.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-hoplimhair.lua index 92898bb9fd..de987128b6 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-hoplimhair.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-1p-ipv4-hoplimhair.lua @@ -3,7 +3,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv4-bytes"] = 94, ["out-icmpv4-packets"] = 1, ["out-ipv6-bytes"] = 134, diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-1.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-1.lua index 14976104ef..5c41b206c8 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-1.lua @@ -8,5 +8,5 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-2.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-2.lua index 4255a873a9..163e5358e9 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-2.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-none-2.lua @@ -7,5 +7,5 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1-drop.lua b/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1-drop.lua index 8719803782..8636ee5cc1 100644 --- a/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1-drop.lua +++ b/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1-drop.lua @@ -10,5 +10,5 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1.lua b/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1.lua index 405de1a44a..c1da09ef34 100644 --- a/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1.lua +++ b/src/program/lwaftr/tests/data/counters/in-ipv4-ipv6-out-icmpv4-ipv6-hairpin-1.lua @@ -9,7 +9,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["in-ipv6-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv4-bytes"] = 94, ["out-icmpv4-packets"] = 1, ["out-ipv6-bytes"] = 134, diff --git a/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-2pkts.lua b/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-2pkts.lua index ae923e4410..0bfb63a5fd 100644 --- a/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-2pkts.lua +++ b/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-2pkts.lua @@ -5,7 +5,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 2, ["in-ipv6-packets"] = 2, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 66, ["out-ipv4-frag-not"] = 1, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-3pkts.lua b/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-3pkts.lua index 8c074bb911..b85c3e5ded 100644 --- a/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-3pkts.lua +++ b/src/program/lwaftr/tests/data/counters/ndp-no-na-next-hop6-mac-not-set-3pkts.lua @@ -5,7 +5,7 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 3, ["in-ipv6-packets"] = 2, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-bytes"] = 66, ["out-ipv4-frag-not"] = 1, ["out-ipv4-packets"] = 1, diff --git a/src/program/lwaftr/tests/data/counters/ndp-ns-for-next-hop.lua b/src/program/lwaftr/tests/data/counters/ndp-ns-for-next-hop.lua index b2c38d02ce..2a8197e9c0 100644 --- a/src/program/lwaftr/tests/data/counters/ndp-ns-for-next-hop.lua +++ b/src/program/lwaftr/tests/data/counters/ndp-ns-for-next-hop.lua @@ -1,5 +1,5 @@ return { ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-frag-not"] = 1, } diff --git a/src/program/lwaftr/tests/data/counters/ndp-secondary.lua b/src/program/lwaftr/tests/data/counters/ndp-secondary.lua index 162edb11a9..3ce9e1bc91 100644 --- a/src/program/lwaftr/tests/data/counters/ndp-secondary.lua +++ b/src/program/lwaftr/tests/data/counters/ndp-secondary.lua @@ -1,5 +1,5 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/nofrag4.lua b/src/program/lwaftr/tests/data/counters/nofrag4.lua index 045cbb95f2..6e95815eba 100644 --- a/src/program/lwaftr/tests/data/counters/nofrag4.lua +++ b/src/program/lwaftr/tests/data/counters/nofrag4.lua @@ -1,6 +1,6 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv4-frag-not"] = 1, } diff --git a/src/program/lwaftr/tests/data/counters/nofrag6-sol.lua b/src/program/lwaftr/tests/data/counters/nofrag6-sol.lua index 3c274602e3..2e6a730d5a 100644 --- a/src/program/lwaftr/tests/data/counters/nofrag6-sol.lua +++ b/src/program/lwaftr/tests/data/counters/nofrag6-sol.lua @@ -1,6 +1,6 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-frag-not"] = 1, } diff --git a/src/program/lwaftr/tests/data/counters/nofrag6.lua b/src/program/lwaftr/tests/data/counters/nofrag6.lua index 162edb11a9..3ce9e1bc91 100644 --- a/src/program/lwaftr/tests/data/counters/nofrag6.lua +++ b/src/program/lwaftr/tests/data/counters/nofrag6.lua @@ -1,5 +1,5 @@ return { ["in-ipv6-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/non-ipv4-traffic-to-ipv4-interface.lua b/src/program/lwaftr/tests/data/counters/non-ipv4-traffic-to-ipv4-interface.lua index bb3eb92a4c..6f743b6594 100644 --- a/src/program/lwaftr/tests/data/counters/non-ipv4-traffic-to-ipv4-interface.lua +++ b/src/program/lwaftr/tests/data/counters/non-ipv4-traffic-to-ipv4-interface.lua @@ -5,5 +5,5 @@ return { ["drop-misplaced-not-ipv6-packets"] = 1, ["in-ipv6-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/non-ipv6-traffic-to-ipv6-interface.lua b/src/program/lwaftr/tests/data/counters/non-ipv6-traffic-to-ipv6-interface.lua index 8404387f4f..cca5d19476 100644 --- a/src/program/lwaftr/tests/data/counters/non-ipv6-traffic-to-ipv6-interface.lua +++ b/src/program/lwaftr/tests/data/counters/non-ipv6-traffic-to-ipv6-interface.lua @@ -5,5 +5,5 @@ return { ["drop-misplaced-not-ipv4-packets"] = 1, ["in-ipv4-frag-reassembly-unneeded"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/regressiontest-endaddr.lua b/src/program/lwaftr/tests/data/counters/regressiontest-endaddr.lua index be5c83e3b7..43c7fe07cf 100644 --- a/src/program/lwaftr/tests/data/counters/regressiontest-endaddr.lua +++ b/src/program/lwaftr/tests/data/counters/regressiontest-endaddr.lua @@ -3,7 +3,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 4, ["in-ipv4-packets"] = 4, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-ipv6-bytes"] = 6136, ["out-ipv6-frag-not"] = 4, ["out-ipv6-packets"] = 4, diff --git a/src/program/lwaftr/tests/data/counters/regressiontest-signedntohl-frags-counters.lua b/src/program/lwaftr/tests/data/counters/regressiontest-signedntohl-frags-counters.lua index e8089d368b..6106d8f651 100644 --- a/src/program/lwaftr/tests/data/counters/regressiontest-signedntohl-frags-counters.lua +++ b/src/program/lwaftr/tests/data/counters/regressiontest-signedntohl-frags-counters.lua @@ -9,5 +9,5 @@ return { ["in-ipv6-frag-reassembled"] = 5, ["in-ipv6-packets"] = 5, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, } diff --git a/src/program/lwaftr/tests/data/counters/tcp-frominet-bound-ttl1.lua b/src/program/lwaftr/tests/data/counters/tcp-frominet-bound-ttl1.lua index f22dc4491a..55ea25db4b 100644 --- a/src/program/lwaftr/tests/data/counters/tcp-frominet-bound-ttl1.lua +++ b/src/program/lwaftr/tests/data/counters/tcp-frominet-bound-ttl1.lua @@ -7,7 +7,7 @@ return { ["in-ipv4-frag-reassembly-unneeded"] = 1, ["in-ipv4-packets"] = 1, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 728203264, + ["memuse-ipv6-frag-reassembly-buffer"] = 11378176, ["out-icmpv4-bytes"] = 94, ["out-icmpv4-packets"] = 1, ["out-ipv4-bytes"] = 94, From 0463915d53726dc23d197c0f78b5b98ec846a339 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Thu, 14 Jun 2018 11:06:18 +0200 Subject: [PATCH 02/35] ipv6.reassembly: expire stale reassembly buffers --- src/apps/ipv6/reassemble.lua | 39 ++++++++++++++++++- .../data/counters/in-1p-ipv6-out-0p-ipv4.lua | 2 +- 2 files changed, 39 insertions(+), 2 deletions(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 7b108e30ba..7af64ccb63 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -24,6 +24,8 @@ local link = require("core.link") local ipsum = require("lib.checksum").ipsum local ctable = require('lib.ctable') local ctablew = require('apps.lwaftr.ctable_wrapper') +local token_bucket = require('lib.token_bucket') +local tsc = require('lib.tsc') local alarms = require('lib.yang.alarms') local S = require('syscall') @@ -132,6 +134,8 @@ local reassembler_config_params = { max_concurrent_reassemblies = { default=20000 }, -- Maximum number of fragments to reassemble. max_fragments_per_reassembly = { default=40 }, + -- Maximum number of seconds to keep a partially reassembled packet + reassembly_timeout = { default = 60 }, } function Reassembler:new(conf) @@ -153,6 +157,7 @@ function Reassembler:new(conf) uint16_t final_start; uint16_t reassembly_base; uint32_t running_length; // bytes copied so far + uint64_t tstamp; // creation time in TSC ticks struct packet *packet; } __attribute((packed))]], o.max_fragments_per_reassembly, @@ -165,6 +170,16 @@ function Reassembler:new(conf) o.scratch_reassembly = params.value_type() o.next_counter_update = -1 + local scan_time = o.reassembly_timeout / 2 + local scan_chunks = 100 + o.scan_tb = token_bucket.new({ rate = math.ceil(o.ctab.size / scan_time), + burst_size = o.ctab.size / scan_chunks}) + o.tsc = tsc.new() + o.ticks_per_timeout = o.tsc:tps() * o.reassembly_timeout + o.scan_cursor = 0 + o.scan_tstamp = o.tsc:stamp() + o.scan_interval = o.tsc:tps() * scan_time / scan_chunks + 0ULL + alarms.add_to_inventory { [{alarm_type_id='incoming-ipv6-fragments'}] = { resource=tostring(S.getpid()), @@ -219,7 +234,7 @@ function Reassembler:lookup_reassembly(src_ip, dst_ip, fragment_id) ffi.fill(reassembly, ffi.sizeof(reassembly)) reassembly.reassembly_base = ether_ipv6_header_len reassembly.running_length = ether_ipv6_header_len - + reassembly.tstamp = self.tsc:stamp() reassembly.packet = packet.allocate() -- Fragment 0 will fill in the contents of this data. reassembly.packet.length = ether_ipv6_header_len @@ -301,11 +316,33 @@ function Reassembler:handle_fragment(h) end end +function Reassembler:expire (now) + local cursor = self.scan_cursor + for i = 1, self.scan_tb:take_burst() do + local entry + cursor, entry = self.ctab:next_entry(cursor, cursor + 1) + if entry then + if now - entry.value.tstamp > self.ticks_per_timeout then + self:reassembly_error(entry) + else + cursor = cursor + 1 + end + end + end + self.scan_cursor = cursor + self.scan_tstamp = now +end + function Reassembler:push () local input, output = self.input.input, self.output.output self.incoming_ipv6_fragments_alarm:check() + local now = self.tsc:stamp() + if now - self.scan_tstamp > self.scan_interval then + self:expire(now) + end + for _ = 1, link.nreadable(input) do local pkt = link.receive(input) local h = ffi.cast(ether_ipv6_header_ptr_t, pkt.data) diff --git a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua index 397cea054c..ae1587c48a 100644 --- a/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua +++ b/src/program/lwaftr/tests/data/counters/in-1p-ipv6-out-0p-ipv4.lua @@ -2,5 +2,5 @@ return { ["drop-ipv6-frag-invalid-reassembly"] = 1, ["in-ipv6-frag-needs-reassembly"] = 2, ["memuse-ipv4-frag-reassembly-buffer"] = 728203264, - ["memuse-ipv6-frag-reassembly-buffer"] = 1536, + ["memuse-ipv6-frag-reassembly-buffer"] = 3072, } From ffd584c3647f7951b4b5794c64784ea7858336c6 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Wed, 20 Jun 2018 10:23:06 +0200 Subject: [PATCH 03/35] ipv6.reassembly: reduce scope of local variables in handle_fragment() Frequent trace aborts due to "register coalescing too complex" have been observed within handle_fragment(). This commit attempts to mitigate this by limiting the scope of local variables, either by explicit scoping with do/end or by placing variable declarations after function calls that don't need them. --- src/apps/ipv6/reassemble.lua | 49 ++++++++++++++++++++++-------------- 1 file changed, 30 insertions(+), 19 deletions(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 7af64ccb63..32543c832e 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -223,9 +223,10 @@ function Reassembler:reassembly_error(entry, icmp_error) end end -function Reassembler:lookup_reassembly(src_ip, dst_ip, fragment_id) +function Reassembler:lookup_reassembly(h, fragment_id) local key = self.scratch_fragment_key - key.src_addr, key.dst_addr, key.fragment_id = src_ip, dst_ip, fragment_id + key.src_addr, key.dst_addr, key.fragment_id = + h.ipv6.src_ip, h.ipv6.dst_ip, fragment_id local entry = self.ctab:lookup_ptr(key) if entry then return entry end @@ -247,13 +248,15 @@ end function Reassembler:handle_fragment(h) local fragment = ffi.cast(fragment_header_ptr_t, h.ipv6.payload) + -- Note: keep the number of local variables to a minimum when + -- calling lookup_reassembly to avoid "register coalescing too + -- complex" trace aborts in ctable. + local entry = self:lookup_reassembly(h, ntohl(fragment.id)) + local reassembly = entry.value local fragment_offset_and_flags = ntohs(fragment.fragment_offset_and_flags) local frag_start = bit.band(fragment_offset_and_flags, fragment_offset_mask) local frag_size = ntohs(h.ipv6.payload_length) - fragment_header_len - local entry = self:lookup_reassembly(h.ipv6.src_ip, h.ipv6.dst_ip, - ntohl(fragment.id)) - local reassembly = entry.value -- Header comes from unfragmentable part of packet 0. if frag_start == 0 then @@ -290,16 +293,19 @@ function Reassembler:handle_fragment(h) return self:reassembly_error(entry) end - local max_data_offset = ether_ipv6_header_len + frag_start + frag_size - if max_data_offset > ffi.sizeof(reassembly.packet.data) then - -- Snabb packets have a maximum size of 10240 bytes. - return self:reassembly_error(entry) + -- Limit the scope of max_data_offset + do + local max_data_offset = ether_ipv6_header_len + frag_start + frag_size + if max_data_offset > ffi.sizeof(reassembly.packet.data) then + -- Snabb packets have a maximum size of 10240 bytes. + return self:reassembly_error(entry) + end + ffi.copy(reassembly.packet.data + reassembly.reassembly_base + frag_start, + fragment.payload, frag_size) + reassembly.packet.length = math.max(reassembly.packet.length, + max_data_offset) + reassembly.running_length = reassembly.running_length + frag_size end - ffi.copy(reassembly.packet.data + reassembly.reassembly_base + frag_start, - fragment.payload, frag_size) - reassembly.packet.length = math.max(reassembly.packet.length, - max_data_offset) - reassembly.running_length = reassembly.running_length + frag_size if reassembly.final_start == 0 then -- Still reassembling. @@ -310,8 +316,11 @@ function Reassembler:handle_fragment(h) elseif not verify_valid_offsets(reassembly) then return self:reassembly_error(entry) else - local header = ffi.cast(ether_ipv6_header_ptr_t, reassembly.packet.data) - header.ipv6.payload_length = htons(reassembly.packet.length - ether_ipv6_header_len) + -- Limit the scope of header + do + local header = ffi.cast(ether_ipv6_header_ptr_t, reassembly.packet.data) + header.ipv6.payload_length = htons(reassembly.packet.length - ether_ipv6_header_len) + end return self:reassembly_success(entry) end end @@ -338,9 +347,11 @@ function Reassembler:push () self.incoming_ipv6_fragments_alarm:check() - local now = self.tsc:stamp() - if now - self.scan_tstamp > self.scan_interval then - self:expire(now) + do + local now = self.tsc:stamp() + if now - self.scan_tstamp > self.scan_interval then + self:expire(now) + end end for _ = 1, link.nreadable(input) do From 66a7575223baf9d71ace816d5c96291190c5a988 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Fri, 15 Jun 2018 13:54:26 +0200 Subject: [PATCH 04/35] Add PMTUD to apps.ipv6.fragment --- src/apps/ipv6/README.md | 75 +++++++++++++++- src/apps/ipv6/fragment.lua | 171 ++++++++++++++++++++++++++++++++++--- 2 files changed, 230 insertions(+), 16 deletions(-) diff --git a/src/apps/ipv6/README.md b/src/apps/ipv6/README.md index df1636fc90..4e7a73d917 100644 --- a/src/apps/ipv6/README.md +++ b/src/apps/ipv6/README.md @@ -178,8 +178,15 @@ Ingress packets dropped due to wrong local IPv6 endpoint address. ## Fragmenter (apps.ipv6.fragment) -The `Fragmenter` app that will fragment any IPv6 packets larger than a -configured maximum transmission unit (MTU). +The `Fragmenter` app will fragment any IPv6 packets larger than a +configured maximum transmission unit (MTU) or the dynamically +discovered MTU on the network path (PMTU) towards a specific +destination, depending on the setting of the **pmtud** configuration +option. + +If path MTU discovery (PMTUD) is disabled, the app expects to receive +packets on its `input` link and sends (possibly fragmented) packets to +its `output` link DIAGRAM: IPv6Fragmenter +-----------+ @@ -188,16 +195,78 @@ configured maximum transmission unit (MTU). | | +-----------+ +If PMTUD is enabled, the app also expects to process packets in the +reverse direction in order to be able to intercept and interpret ICMP +packets of type 2, code 0. Those packets, known as "Packet Too Big" +(PTB) messages, contain reports from nodes on the path towards a +particular destination, which indicate that a previously sent packet +could not be forwarded due to a MTU bottleneck. The message contains +the MTU in question as well as at least the header of the original +packet that triggered the PTB message. The `Fragmenter` app extracts +the destination address from the original packet and stores the MTU in +a per-destination cache as the PMTU for that address. + +Apart from checking the integrity of the ICMP message, the app can +optionally also verify whether the message is actually intended for +consumption by this instance of the `Fragmenter` app. For that +purpose, the app can be configured with an exhaustive list of IPv6 +addresses that are designated to be local to the system. When a PTB +message is received, it is checked whether the destination address of +the ICMP message as well as the source address of the embedded +original packet are contained in this list. The message is discarded +if this condition is not met. No such checking is performed if the +list is empty. + +When the `Fragmenter` receives a packet on the `input` link, it first +consults the per-destination cache. In case of a hit, the PMTU from +the cache takes precedence over the statically configured MTU. + +A PMTU is removed from the cache after a configurable timeout to allow +the system to discover a larger PMTU, e.g. after a change in network +topology. + +With PMTUD enabled, the app has two additional links, called `north` +and `south` + + + DIAGRAM: IPv6Fragmenter_PMTUD + +-----------+ + | | + input ---->*Fragmenter *----> output + north <----* *<---- south + | | + +-----------+ + +All packets received on the `south` link which are not ICMP packets of +type 2, code 0 are passed on unmodified on the `north` link. + ### Configuration The `Fragmenter` app accepts a table as its configuration argument. The -following key is defined: +following keys are defined: — Key **mtu** *Required*. The maximum transmission unit, in bytes, not including the Ethernet header. +— Key **pmtud** + +*Optional*. If set to `true`, dynamic path MTU discovery (PMTUD) is +enabled. The default is `false`. + +— Key **pmtu_timeout** + +*Optional*. The amount of time in seconds after which a PMTU is + removed from the cache. The default is 600. This key is ignored + unless **pmtud** is `true`. + +— Key **pmtu_local_addresses** + +*Optional*. A table of IPv6 addresses in human readable representation +for which the app will accept PTB messages. The default is an empty +table, which disables the check for local addresses. + ## ICMP Echo responder (apps.ipv6.echo) The `ICMPEcho` app responds to ICMP echo requests ("pings") to a given diff --git a/src/apps/ipv6/fragment.lua b/src/apps/ipv6/fragment.lua index ff0cf1be2b..275bf1fd8f 100644 --- a/src/apps/ipv6/fragment.lua +++ b/src/apps/ipv6/fragment.lua @@ -11,6 +11,13 @@ local packet = require("core.packet") local counter = require("core.counter") local link = require("core.link") local alarms = require('lib.yang.alarms') +local ctable = require('lib.ctable') +local filter = require('lib.pcap.filter') +local datagram = require('lib.protocol.datagram') +local ethernet = require('lib.protocol.ethernet') +local ipv6_hdr = require('lib.protocol.ipv6') +local ptb = require('lib.protocol.icmp.ptb') +local tsc = require('lib.tsc') local S = require('syscall') local CounterAlarm = alarms.CounterAlarm @@ -61,6 +68,7 @@ local fragment_flag_more_fragments = 0x1 -- offset is non-zero, it is a fragment. local fragment_proto = 44 +local ipv6_header_ptr_t = ffi.typeof('$*', ipv6_header_t) local ether_ipv6_header_t = ffi.typeof( 'struct { $ ether; $ ipv6; uint8_t payload[0]; } __attribute__((packed))', ether_header_t, ipv6_header_t) @@ -79,12 +87,19 @@ end Fragmenter = {} Fragmenter.shm = { ["out-ipv6-frag"] = {counter}, - ["out-ipv6-frag-not"] = {counter} + ["out-ipv6-frag-not"] = {counter}, + ["ipv6-pmtud-ptb-received"] = {counter}, + ["ipv6-pmtud-ptb-valid"] = {counter}, + ["ipv6-pmtud-ptb-invalid-csum"] = {counter}, + ["ipv6-pmtud-ptb-invalid"] = {counter} } local fragmenter_config_params = { -- Maximum transmission unit, in bytes, not including the ethernet -- header. - mtu = { mandatory=true } + mtu = { mandatory=true }, + pmtud = { default=false }, + pmtu_timeout = { default = 600 }, + pmtu_local_addresses = { default = {} }, } deterministic_first_fragment_id = false @@ -99,6 +114,53 @@ function Fragmenter:new(conf) o.next_fragment_id = deterministic_first_fragment_id or math.random(0, 0xffffffff) + if o.pmtud then + -- Path MTU Discovery is supported by listening to ICMP + -- Packet-Too-Big messages and recording path MTUs in a + -- per-destination cache. Cache entries are removed after 10 + -- minutes by default as recommended by RFC 1981 §5.3. + local max_occupy = 0.4 + local initial_size = 128 + local params = { + key_type = ffi.typeof("uint8_t [16]"), + value_type = ffi.typeof[[ + struct { + uint16_t mtu; + uint64_t tstamp; + } __attribute((packed))]], + initial_size = initial_size, + max_occupancy_rate = max_occupy, + resize_callback = function(table, old_size) + if old_size > 0 then + require('jit').flush() + end + end, + } + o.dcache = ctable.new(params) + o.scratch_dcache_value = params.value_type() + o.tsc = tsc.new() + o.pmtu_timeout_ticks = o.tsc:tps() * o.pmtu_timeout + o.pmtu_timer = lib.throttle(o.pmtu_timeout/10) + -- ICMP6 Packet Too Big (Type 2) + o.ptb_filter = filter:new("icmp6 and ip6[40] = 2") + o.dgram = datagram:new() + packet.free(o.dgram:packet()) + + -- List of local addresses for which to perform PMTUD. PTB + -- messages not targeted at any of these addresses are ignored + o.pmtu_local_address_table = ctable.new( + { + key_type = ffi.typeof("uint8_t [16]"), + value_type = ffi.typeof("uint8_t"), -- dummy + initial_size = #o.pmtu_local_addresses, + max_occupancy_rate = 1, + }) + for _, addr in ipairs(o.pmtu_local_addresses) do + o.pmtu_local_address_table:add(ipv6_hdr:pton(addr), 0) + end + o.ipv6_hdr = ipv6_hdr:new({}) + end + alarms.add_to_inventory { [{alarm_type_id='outgoing-ipv6-fragments'}] = { resource=tostring(S.getpid()), @@ -134,8 +196,8 @@ function Fragmenter:unfragmentable_packet(p) -- TODO: Send an error packet. end -function Fragmenter:fragment_and_transmit(in_h, in_pkt) - local mtu_with_l2 = self.mtu + ether_header_len +function Fragmenter:fragment_and_transmit(in_next_header, in_pkt, mtu) + local mtu_with_l2 = mtu + ether_header_len local total_payload_size = in_pkt.length - ether_ipv6_header_len local offset, id = 0, self:fresh_fragment_id() @@ -158,7 +220,7 @@ function Fragmenter:fragment_and_transmit(in_h, in_pkt) out_h.ipv6.next_header = fragment_proto out_h.ipv6.payload_length = htons(out_pkt.length - ether_ipv6_header_len) - fragment_h.next_header = in_h.ipv6.next_header + fragment_h.next_header = in_next_header fragment_h.reserved = 0 fragment_h.id = htonl(id) fragment_h.fragment_offset_and_flags = htons(bit.bor(offset, flags)) @@ -168,9 +230,62 @@ function Fragmenter:fragment_and_transmit(in_h, in_pkt) end end +function Fragmenter:process_ptb (pkt) + counter.add(self.shm["ipv6-pmtud-ptb-received"]) + local dgram = self.dgram:new(pkt, ethernet) + dgram:parse_n(3) + local _, ipv6, icmp = unpack(dgram:stack()) + local payload, length = dgram:payload() + + if (#self.pmtu_local_addresses > 0 and + not self.pmtu_local_address_table:lookup_ptr(ipv6:dst())) then + -- PTB not addressed to us + return false + end + + if icmp:checksum_check(payload, length, ipv6) then + local ptb = dgram:parse() + local mtu = ptb:mtu() + local payload, length = dgram:payload() + local orig_hdr = self.ipv6_hdr:new_from_mem(payload, length) + if (length >= ipv6_hdr:sizeof() and + (#self.pmtu_local_addresses == 0 or + self.pmtu_local_address_table:lookup_ptr(orig_hdr:src()))) then + counter.add(self.shm["ipv6-pmtud-ptb-valid"]) + local value = self.scratch_dcache_value + value.mtu = mtu + value.tstamp = self.tsc:stamp() + self.dcache:add(orig_hdr:dst(), value, 'update_allowed') + else + counter.add(self.shm["ipv6-pmtud-ptb-invalid"]) + end + else + counter.add(self.shm["ipv6-pmtud-ptb-invalid-csum"]) + end + return true +end + +-- The destination cache is expected to be fairly small so it should +-- be ok to make a full scan. +function Fragmenter:expire_pmtu () + local now = self.tsc:stamp() + local cursor = 0 + repeat + local entry + cursor, entry = self.dcache:next_entry(cursor, cursor + 1) + if entry then + if now - entry.value.tstamp > self.pmtu_timeout_ticks then + self.dcache:remove_ptr(entry) + else + cursor = cursor + 1 + end + end + until cursor == 0 +end + function Fragmenter:push () local input, output = self.input.input, self.output.output - local max_length = self.mtu + ether_header_len + local south, north = self.input.south, self.output.north self.outgoing_ipv6_fragments_alarm:check() @@ -186,14 +301,43 @@ function Fragmenter:push () -- IPv6 packet has invalid length; drop. FIXME: Should add a -- counter here. packet.free(pkt) - elseif pkt.length <= max_length then - -- No need to fragment; forward it on. - counter.add(self.shm["out-ipv6-frag-not"]) - link.transmit(output, pkt) else - -- Packet doesn't fit into MTU; need to fragment. - self:fragment_and_transmit(h, pkt) - packet.free(pkt) + local mtu = self.mtu + if self.pmtud then + local entry = self.dcache:lookup_ptr(h.ipv6.dst_ip) + if entry then + mtu = entry.value.mtu + end + end + if pkt.length <= mtu + ether_header_len then + -- No need to fragment; forward it on. + counter.add(self.shm["out-ipv6-frag-not"]) + link.transmit(output, pkt) + else + -- Packet doesn't fit into MTU; need to fragment. + self:fragment_and_transmit(h.ipv6.next_header, pkt, mtu) + packet.free(pkt) + end + end + end + + if self.pmtud then + for _ = 1, link.nreadable(south) do + local pkt = link.receive(south) + if self.ptb_filter:match(pkt.data, pkt.length) then + if self:process_ptb(pkt) then + packet.free(pkt) + else + -- Packet was not addressed to us + link.transmit(north, pkt) + end + else + link.transmit(north, pkt) + end + end + + if self.pmtu_timer() then + self:expire_pmtu() end end end @@ -272,5 +416,6 @@ function selftest() link.free(input, 'fragment input') link.free(output, 'fragment output') + -- FIXME: add test case for PMTUD print("selftest: ok") end From a9a4b72961f786e46ef455e5eb6434e2df31f739 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Mon, 2 Jul 2018 15:45:23 +0200 Subject: [PATCH 05/35] ipv6.fragment: improve performance, reduce garbage The main processing loop is split into three separate loops to reduce the effect of unbiased branches due to workloads with either mixed fragmented/unfragmented packets or a shift from mainly fragmented to mainly unfragmented packets on the selection of traces. All packets needing fragmentation are processed in a separate loop. The fragmentation itself contains another loop which might get compiled first. In that case, the pointers passed to fragment_and_transmit() would require dynamic boxing on the Lua stack, which cause GC activity. Explicit boxing is used to avoid this. --- src/apps/ipv6/fragment.lua | 56 ++++++++++++++++++++++++++------------ 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/src/apps/ipv6/fragment.lua b/src/apps/ipv6/fragment.lua index 275bf1fd8f..e588118a01 100644 --- a/src/apps/ipv6/fragment.lua +++ b/src/apps/ipv6/fragment.lua @@ -196,12 +196,15 @@ function Fragmenter:unfragmentable_packet(p) -- TODO: Send an error packet. end -function Fragmenter:fragment_and_transmit(in_next_header, in_pkt, mtu) +function Fragmenter:fragment_and_transmit(in_next_header, in_pkt_box, mtu) local mtu_with_l2 = mtu + ether_header_len - local total_payload_size = in_pkt.length - ether_ipv6_header_len + local total_payload_size = in_pkt_box[0].length - ether_ipv6_header_len local offset, id = 0, self:fresh_fragment_id() + -- Use explicit boxing to avoid garbage when passing the header and + -- packet pointers in case this loop gets compiled first. while offset < total_payload_size do + local in_pkt = in_pkt_box[0] local out_pkt = packet.allocate() packet.append(out_pkt, in_pkt.data, ether_ipv6_header_len) local out_h = ffi.cast(ether_ipv6_header_ptr_t, out_pkt.data) @@ -283,6 +286,7 @@ function Fragmenter:expire_pmtu () until cursor == 0 end +local pkt_box = ffi.new("struct packet *[1]") function Fragmenter:push () local input, output = self.input.input, self.output.output local south, north = self.input.south, self.output.north @@ -302,23 +306,41 @@ function Fragmenter:push () -- counter here. packet.free(pkt) else - local mtu = self.mtu - if self.pmtud then - local entry = self.dcache:lookup_ptr(h.ipv6.dst_ip) - if entry then - mtu = entry.value.mtu - end - end - if pkt.length <= mtu + ether_header_len then - -- No need to fragment; forward it on. - counter.add(self.shm["out-ipv6-frag-not"]) - link.transmit(output, pkt) - else - -- Packet doesn't fit into MTU; need to fragment. - self:fragment_and_transmit(h.ipv6.next_header, pkt, mtu) - packet.free(pkt) + link.transmit(input, pkt) + end + end + + for _ = 1, link.nreadable(input) do + local pkt = link.receive(input) + local mtu = self.mtu + if self.pmtud then + local h = ffi.cast(ether_ipv6_header_ptr_t, pkt.data) + local entry = self.dcache:lookup_ptr(h.ipv6.dst_ip) + if entry then + mtu = entry.value.mtu end end + -- FIXME: assumes that there is always room to store the MTU at + -- the end of the payload. + ffi.cast("uint16_t *", pkt.data + pkt.length)[0] = mtu + if pkt.length <= mtu + ether_header_len then + -- No need to fragment; forward it on. + counter.add(self.shm["out-ipv6-frag-not"]) + link.transmit(output, pkt) + else + -- Packet doesn't fit into MTU; need to fragment. + link.transmit(input, pkt) + end + end + + for _ = 1, link.nreadable(input) do + local pkt = link.receive(input) + local mtu = ffi.cast("uint16_t *", pkt.data + pkt.length)[0] + local next_header = + ffi.cast(ether_ipv6_header_ptr_t, pkt.data).ipv6.next_header + pkt_box[0] = pkt + self:fragment_and_transmit(next_header, pkt_box, mtu) + packet.free(pkt_box[0]) end if self.pmtud then From 7f0703ada3f5c9db66ae59529b6f4f910a66d079 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Thu, 28 Jun 2018 14:41:16 +0200 Subject: [PATCH 06/35] ipv6.reassembly: perform reassembly in separate loop The amount of work being done in the main push() loop is reduced by moving fragments to a separate queue. This is beneficial if the workload is unbiased with respect to fragmentation or if the workload shifts from mainly fragmented to mainly unfragmented packets. All packets needing reassembly are processed in a separate loop. --- src/apps/ipv6/reassemble.lua | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 32543c832e..9aad6025e4 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -246,7 +246,8 @@ function Reassembler:lookup_reassembly(h, fragment_id) return entry end -function Reassembler:handle_fragment(h) +function Reassembler:handle_fragment(pkt) + local h = ffi.cast(ether_ipv6_header_ptr_t, pkt.data) local fragment = ffi.cast(fragment_header_ptr_t, h.ipv6.payload) -- Note: keep the number of local variables to a minimum when -- calling lookup_reassembly to avoid "register coalescing too @@ -369,8 +370,7 @@ function Reassembler:push () elseif h.ipv6.next_header == fragment_proto then -- A fragment; try to reassemble. counter.add(self.shm["in-ipv6-frag-needs-reassembly"]) - self:handle_fragment(h) - packet.free(pkt) + link.transmit(input, pkt) else -- Not fragmented; forward it on. counter.add(self.shm["in-ipv6-frag-reassembly-unneeded"]) @@ -378,6 +378,12 @@ function Reassembler:push () end end + for _ = 1, link.nreadable(input) do + local pkt = link.receive(input) + self:handle_fragment(pkt) + packet.free(pkt) + end + if self.next_counter_update < engine.now() then -- Update counters every second, but add a bit of jitter to smooth -- things out. From f2bd95dcd8462063ff9d1b6209144d01197d9a81 Mon Sep 17 00:00:00 2001 From: aouinizied Date: Fri, 6 Jul 2018 01:18:09 +0200 Subject: [PATCH 07/35] Implement nDPI2.x snabb compatibility --- lib/ljndpi/ndpi/c.lua | 8 +- lib/ljndpi/ndpi/protocol_ids_2_0.lua | 465 +++++++++++++++++++++++++ lib/ljndpi/ndpi/protocol_ids_2_2.lua | 497 ++++++++++++++++++++++++++ lib/ljndpi/ndpi/protocol_ids_2_3.lua | 501 +++++++++++++++++++++++++++ 4 files changed, 1467 insertions(+), 4 deletions(-) create mode 100644 lib/ljndpi/ndpi/protocol_ids_2_0.lua create mode 100644 lib/ljndpi/ndpi/protocol_ids_2_2.lua create mode 100644 lib/ljndpi/ndpi/protocol_ids_2_3.lua diff --git a/lib/ljndpi/ndpi/c.lua b/lib/ljndpi/ndpi/c.lua index c4ecfcb108..d6ff12c1e3 100644 --- a/lib/ljndpi/ndpi/c.lua +++ b/lib/ljndpi/ndpi/c.lua @@ -85,11 +85,11 @@ local lib_version = (function () end)() -- Only nDPI 1.x versions above 1.7 are supported. -if lib_version.major ~= 1 or lib_version.minor < 7 then +if lib_version.major == 1 and lib_version.minor < 7 then error("Unsupported nDPI version: " .. tostring(lib_version)) end -if lib_version.minor == 7 then +if lib_version.major == 1 and lib_version.minor == 7 then -- nDPI 1.7 ffi.cdef [[ ndpi_detection_module_t* ndpi_init_detection_module (uint32_t ticks_per_second, @@ -105,8 +105,8 @@ if lib_version.minor == 7 then uint32_t src_host, uint16_t src_port, uint32_t dst_host, uint32_t dst_port); ]] -elseif lib_version.minor == 8 then - -- nDPI 1.8 +else + -- nDPI 1.8 and later ffi.cdef [[ ndpi_detection_module_t* ndpi_init_detection_module (void); diff --git a/lib/ljndpi/ndpi/protocol_ids_2_0.lua b/lib/ljndpi/ndpi/protocol_ids_2_0.lua new file mode 100644 index 0000000000..1c0589fdfd --- /dev/null +++ b/lib/ljndpi/ndpi/protocol_ids_2_0.lua @@ -0,0 +1,465 @@ +-- Generated by ljdnpi's tools/update-protocol-ids script +local T = { + [0] = "PROTOCOL_UNKNOWN", + [0] = "PROTOCOL_UNKNOWN", + [1] = "PROTOCOL_FTP_CONTROL", + [2] = "PROTOCOL_SIZE", + [2] = "PROTOCOL_MAIL_POP", + [3] = "PROTOCOL_MAIL_SMTP", + [4] = "PROTOCOL_MAIL_IMAP", + [5] = "PROTOCOL_DNS", + [6] = "PROTOCOL_IPP", + [7] = "PROTOCOL_HTTP", + [8] = "PROTOCOL_MDNS", + [9] = "PROTOCOL_NTP", + [10] = "PROTOCOL_NETBIOS", + [11] = "PROTOCOL_NFS", + [12] = "PROTOCOL_SSDP", + [13] = "PROTOCOL_BGP", + [14] = "PROTOCOL_SNMP", + [15] = "PROTOCOL_XDMCP", + [16] = "PROTOCOL_SMB", + [17] = "PROTOCOL_SYSLOG", + [18] = "PROTOCOL_DHCP", + [19] = "PROTOCOL_POSTGRES", + [20] = "PROTOCOL_MYSQL", + [21] = "PROTOCOL_HOTMAIL", + [22] = "PROTOCOL_DIRECT_DOWNLOAD_LINK", + [23] = "PROTOCOL_MAIL_POPS", + [24] = "PROTOCOL_APPLEJUICE", + [25] = "PROTOCOL_DIRECTCONNECT", + [26] = "PROTOCOL_SOCRATES", + [27] = "PROTOCOL_COAP", + [28] = "PROTOCOL_VMWARE", + [29] = "PROTOCOL_MAIL_SMTPS", + [30] = "PROTOCOL_FILETOPIA", + [31] = "PROTOCOL_UBNTAC2", + [32] = "PROTOCOL_KONTIKI", + [33] = "PROTOCOL_OPENFT", + [34] = "PROTOCOL_FASTTRACK", + [35] = "PROTOCOL_GNUTELLA", + [36] = "PROTOCOL_EDONKEY", + [37] = "PROTOCOL_BITTORRENT", + [38] = "PROTOCOL_EPP", + [39] = "CONTENT_AVI", + [40] = "CONTENT_FLASH", + [41] = "CONTENT_OGG", + [42] = "CONTENT_MPEG", + [43] = "CONTENT_QUICKTIME", + [44] = "CONTENT_REALMEDIA", + [45] = "CONTENT_WINDOWSMEDIA", + [46] = "CONTENT_MMS", + [47] = "PROTOCOL_XBOX", + [48] = "PROTOCOL_QQ", + [49] = "PROTOCOL_MOVE", + [50] = "PROTOCOL_RTSP", + [51] = "PROTOCOL_MAIL_IMAPS", + [52] = "PROTOCOL_ICECAST", + [53] = "PROTOCOL_PPLIVE", + [54] = "PROTOCOL_PPSTREAM", + [55] = "PROTOCOL_ZATTOO", + [56] = "PROTOCOL_SHOUTCAST", + [57] = "PROTOCOL_SOPCAST", + [58] = "PROTOCOL_TVANTS", + [59] = "PROTOCOL_TVUPLAYER", + [60] = "PROTOCOL_HTTP_DOWNLOAD", + [61] = "PROTOCOL_QQLIVE", + [62] = "PROTOCOL_THUNDER", + [63] = "PROTOCOL_SOULSEEK", + [64] = "PROTOCOL_SSL_NO_CERT", + [65] = "PROTOCOL_IRC", + [66] = "PROTOCOL_AYIYA", + [67] = "PROTOCOL_UNENCRYPTED_JABBER", + [68] = "PROTOCOL_MSN", + [69] = "PROTOCOL_OSCAR", + [70] = "PROTOCOL_YAHOO", + [71] = "PROTOCOL_BATTLEFIELD", + [72] = "PROTOCOL_QUAKE", + [73] = "PROTOCOL_IP_VRRP", + [74] = "PROTOCOL_STEAM", + [75] = "PROTOCOL_HALFLIFE2", + [76] = "PROTOCOL_WORLDOFWARCRAFT", + [77] = "PROTOCOL_TELNET", + [78] = "PROTOCOL_STUN", + [79] = "PROTOCOL_IP_IPSEC", + [80] = "PROTOCOL_IP_GRE", + [81] = "PROTOCOL_IP_ICMP", + [82] = "PROTOCOL_IP_IGMP", + [83] = "PROTOCOL_IP_EGP", + [84] = "PROTOCOL_IP_SCTP", + [85] = "PROTOCOL_IP_OSPF", + [86] = "PROTOCOL_IP_IP_IN_IP", + [87] = "PROTOCOL_RTP", + [88] = "PROTOCOL_RDP", + [89] = "PROTOCOL_VNC", + [90] = "PROTOCOL_PCANYWHERE", + [91] = "PROTOCOL_SSL", + [92] = "PROTOCOL_SSH", + [93] = "PROTOCOL_USENET", + [94] = "PROTOCOL_MGCP", + [95] = "PROTOCOL_IAX", + [96] = "PROTOCOL_TFTP", + [97] = "PROTOCOL_AFP", + [98] = "PROTOCOL_STEALTHNET", + [99] = "PROTOCOL_AIMINI", + [100] = "PROTOCOL_SIP", + [101] = "PROTOCOL_TRUPHONE", + [102] = "PROTOCOL_IP_ICMPV6", + [103] = "PROTOCOL_DHCPV6", + [104] = "PROTOCOL_ARMAGETRON", + [105] = "PROTOCOL_CROSSFIRE", + [106] = "PROTOCOL_DOFUS", + [107] = "PROTOCOL_FIESTA", + [108] = "PROTOCOL_FLORENSIA", + [109] = "PROTOCOL_GUILDWARS", + [110] = "PROTOCOL_HTTP_APPLICATION_ACTIVESYNC", + [111] = "PROTOCOL_KERBEROS", + [112] = "PROTOCOL_LDAP", + [113] = "PROTOCOL_MAPLESTORY", + [114] = "PROTOCOL_MSSQL_TDS", + [115] = "PROTOCOL_PPTP", + [116] = "PROTOCOL_WARCRAFT3", + [117] = "PROTOCOL_WORLD_OF_KUNG_FU", + [118] = "PROTOCOL_SLACK", + [119] = "PROTOCOL_FACEBOOK", + [120] = "PROTOCOL_TWITTER", + [121] = "PROTOCOL_DROPBOX", + [122] = "PROTOCOL_GMAIL", + [123] = "PROTOCOL_GOOGLE_MAPS", + [124] = "PROTOCOL_YOUTUBE", + [125] = "PROTOCOL_SKYPE", + [126] = "PROTOCOL_GOOGLE", + [127] = "PROTOCOL_DCERPC", + [128] = "PROTOCOL_NETFLOW", + [129] = "PROTOCOL_SFLOW", + [130] = "PROTOCOL_HTTP_CONNECT", + [131] = "PROTOCOL_HTTP_PROXY", + [132] = "PROTOCOL_CITRIX", + [133] = "PROTOCOL_NETFLIX", + [134] = "PROTOCOL_LASTFM", + [135] = "PROTOCOL_WAZE", + [136] = "PROTOCOL_SKYFILE_PREPAID", + [137] = "PROTOCOL_SKYFILE_RUDICS", + [138] = "PROTOCOL_SKYFILE_POSTPAID", + [139] = "PROTOCOL_CITRIX_ONLINE", + [140] = "PROTOCOL_APPLE", + [141] = "PROTOCOL_WEBEX", + [142] = "PROTOCOL_WHATSAPP", + [143] = "PROTOCOL_APPLE_ICLOUD", + [144] = "PROTOCOL_VIBER", + [145] = "PROTOCOL_APPLE_ITUNES", + [146] = "PROTOCOL_RADIUS", + [147] = "PROTOCOL_WINDOWS_UPDATE", + [148] = "PROTOCOL_TEAMVIEWER", + [149] = "PROTOCOL_TUENTI", + [150] = "PROTOCOL_LOTUS_NOTES", + [151] = "PROTOCOL_SAP", + [152] = "PROTOCOL_GTP", + [153] = "PROTOCOL_UPNP", + [154] = "PROTOCOL_LLMNR", + [155] = "PROTOCOL_REMOTE_SCAN", + [156] = "PROTOCOL_SPOTIFY", + [157] = "CONTENT_WEBM", + [158] = "PROTOCOL_H323", + [159] = "PROTOCOL_OPENVPN", + [160] = "PROTOCOL_NOE", + [161] = "PROTOCOL_CISCOVPN", + [162] = "PROTOCOL_TEAMSPEAK", + [163] = "PROTOCOL_TOR", + [164] = "PROTOCOL_SKINNY", + [165] = "PROTOCOL_RTCP", + [166] = "PROTOCOL_RSYNC", + [167] = "PROTOCOL_ORACLE", + [168] = "PROTOCOL_CORBA", + [169] = "PROTOCOL_UBUNTUONE", + [170] = "PROTOCOL_WHOIS_DAS", + [171] = "PROTOCOL_COLLECTD", + [172] = "PROTOCOL_SOCKS", + [173] = "PROTOCOL_MS_LYNC", + [174] = "PROTOCOL_RTMP", + [175] = "PROTOCOL_FTP_DATA", + [176] = "PROTOCOL_WIKIPEDIA", + [177] = "PROTOCOL_ZMQ", + [178] = "PROTOCOL_AMAZON", + [179] = "PROTOCOL_EBAY", + [180] = "PROTOCOL_CNN", + [181] = "PROTOCOL_MEGACO", + [182] = "PROTOCOL_REDIS", + [183] = "PROTOCOL_PANDO", + [184] = "PROTOCOL_VHUA", + [185] = "PROTOCOL_TELEGRAM", + [186] = "PROTOCOL_VEVO", + [187] = "PROTOCOL_PANDORA", + [188] = "PROTOCOL_QUIC", + [189] = "PROTOCOL_WHATSAPP_VOICE", + [190] = "PROTOCOL_EAQ", + [191] = "PROTOCOL_OOKLA", + [192] = "PROTOCOL_AMQP", + [193] = "PROTOCOL_KAKAOTALK", + [194] = "PROTOCOL_KAKAOTALK_VOICE", + [195] = "PROTOCOL_TWITCH", + [196] = "PROTOCOL_QUICKPLAY", + [197] = "PROTOCOL_WECHAT", + [198] = "PROTOCOL_MPEGTS", + [199] = "PROTOCOL_SNAPCHAT", + [200] = "PROTOCOL_SINA", + [201] = "PROTOCOL_HANGOUT", + [202] = "PROTOCOL_IFLIX", + [203] = "PROTOCOL_GITHUB", + [204] = "PROTOCOL_BJNP", + [205] = "PROTOCOL_1KXUN", + [206] = "PROTOCOL_IQIYI", + [207] = "PROTOCOL_SMPP", + [208] = "PROTOCOL_DNSCRYPT", + [209] = "PROTOCOL_FREE_209", + [210] = "PROTOCOL_DEEZER", + [211] = "PROTOCOL_INSTAGRAM", + [212] = "PROTOCOL_MICROSOFT", + [213] = "PROTOCOL_STARCRAFT", + [214] = "PROTOCOL_TEREDO", + [215] = "PROTOCOL_HOTSPOT_SHIELD", + [216] = "PROTOCOL_HEP", + [217] = "PROTOCOL_FREE_217", + [218] = "PROTOCOL_OCS", + [219] = "PROTOCOL_OFFICE_365", + [220] = "PROTOCOL_CLOUDFLARE", + [221] = "PROTOCOL_MS_ONE_DRIVE", + [222] = "PROTOCOL_MQTT", + [223] = "PROTOCOL_RX", + [224] = "PROTOCOL_FREE_224", + [225] = "PROTOCOL_OPENDNS", + [226] = "PROTOCOL_GIT", + [227] = "PROTOCOL_DRDA", + PROTOCOL_UNKNOWN = 0, + PROTOCOL_UNKNOWN = 0, + PROTOCOL_FTP_CONTROL = 1, + PROTOCOL_SIZE = 2, + PROTOCOL_MAIL_POP = 2, + PROTOCOL_MAIL_SMTP = 3, + PROTOCOL_MAIL_IMAP = 4, + PROTOCOL_DNS = 5, + PROTOCOL_IPP = 6, + PROTOCOL_HTTP = 7, + PROTOCOL_MDNS = 8, + PROTOCOL_NTP = 9, + PROTOCOL_NETBIOS = 10, + PROTOCOL_NFS = 11, + PROTOCOL_SSDP = 12, + PROTOCOL_BGP = 13, + PROTOCOL_SNMP = 14, + PROTOCOL_XDMCP = 15, + PROTOCOL_SMB = 16, + PROTOCOL_SYSLOG = 17, + PROTOCOL_DHCP = 18, + PROTOCOL_POSTGRES = 19, + PROTOCOL_MYSQL = 20, + PROTOCOL_HOTMAIL = 21, + PROTOCOL_DIRECT_DOWNLOAD_LINK = 22, + PROTOCOL_MAIL_POPS = 23, + PROTOCOL_APPLEJUICE = 24, + PROTOCOL_DIRECTCONNECT = 25, + PROTOCOL_SOCRATES = 26, + PROTOCOL_COAP = 27, + PROTOCOL_VMWARE = 28, + PROTOCOL_MAIL_SMTPS = 29, + PROTOCOL_FILETOPIA = 30, + PROTOCOL_UBNTAC2 = 31, + PROTOCOL_KONTIKI = 32, + PROTOCOL_OPENFT = 33, + PROTOCOL_FASTTRACK = 34, + PROTOCOL_GNUTELLA = 35, + PROTOCOL_EDONKEY = 36, + PROTOCOL_BITTORRENT = 37, + PROTOCOL_EPP = 38, + CONTENT_AVI = 39, + CONTENT_FLASH = 40, + CONTENT_OGG = 41, + CONTENT_MPEG = 42, + CONTENT_QUICKTIME = 43, + CONTENT_REALMEDIA = 44, + CONTENT_WINDOWSMEDIA = 45, + CONTENT_MMS = 46, + PROTOCOL_XBOX = 47, + PROTOCOL_QQ = 48, + PROTOCOL_MOVE = 49, + PROTOCOL_RTSP = 50, + PROTOCOL_MAIL_IMAPS = 51, + PROTOCOL_ICECAST = 52, + PROTOCOL_PPLIVE = 53, + PROTOCOL_PPSTREAM = 54, + PROTOCOL_ZATTOO = 55, + PROTOCOL_SHOUTCAST = 56, + PROTOCOL_SOPCAST = 57, + PROTOCOL_TVANTS = 58, + PROTOCOL_TVUPLAYER = 59, + PROTOCOL_HTTP_DOWNLOAD = 60, + PROTOCOL_QQLIVE = 61, + PROTOCOL_THUNDER = 62, + PROTOCOL_SOULSEEK = 63, + PROTOCOL_SSL_NO_CERT = 64, + PROTOCOL_IRC = 65, + PROTOCOL_AYIYA = 66, + PROTOCOL_UNENCRYPTED_JABBER = 67, + PROTOCOL_MSN = 68, + PROTOCOL_OSCAR = 69, + PROTOCOL_YAHOO = 70, + PROTOCOL_BATTLEFIELD = 71, + PROTOCOL_QUAKE = 72, + PROTOCOL_IP_VRRP = 73, + PROTOCOL_STEAM = 74, + PROTOCOL_HALFLIFE2 = 75, + PROTOCOL_WORLDOFWARCRAFT = 76, + PROTOCOL_TELNET = 77, + PROTOCOL_STUN = 78, + PROTOCOL_IP_IPSEC = 79, + PROTOCOL_IP_GRE = 80, + PROTOCOL_IP_ICMP = 81, + PROTOCOL_IP_IGMP = 82, + PROTOCOL_IP_EGP = 83, + PROTOCOL_IP_SCTP = 84, + PROTOCOL_IP_OSPF = 85, + PROTOCOL_IP_IP_IN_IP = 86, + PROTOCOL_RTP = 87, + PROTOCOL_RDP = 88, + PROTOCOL_VNC = 89, + PROTOCOL_PCANYWHERE = 90, + PROTOCOL_SSL = 91, + PROTOCOL_SSH = 92, + PROTOCOL_USENET = 93, + PROTOCOL_MGCP = 94, + PROTOCOL_IAX = 95, + PROTOCOL_TFTP = 96, + PROTOCOL_AFP = 97, + PROTOCOL_STEALTHNET = 98, + PROTOCOL_AIMINI = 99, + PROTOCOL_SIP = 100, + PROTOCOL_TRUPHONE = 101, + PROTOCOL_IP_ICMPV6 = 102, + PROTOCOL_DHCPV6 = 103, + PROTOCOL_ARMAGETRON = 104, + PROTOCOL_CROSSFIRE = 105, + PROTOCOL_DOFUS = 106, + PROTOCOL_FIESTA = 107, + PROTOCOL_FLORENSIA = 108, + PROTOCOL_GUILDWARS = 109, + PROTOCOL_HTTP_APPLICATION_ACTIVESYNC = 110, + PROTOCOL_KERBEROS = 111, + PROTOCOL_LDAP = 112, + PROTOCOL_MAPLESTORY = 113, + PROTOCOL_MSSQL_TDS = 114, + PROTOCOL_PPTP = 115, + PROTOCOL_WARCRAFT3 = 116, + PROTOCOL_WORLD_OF_KUNG_FU = 117, + PROTOCOL_SLACK = 118, + PROTOCOL_FACEBOOK = 119, + PROTOCOL_TWITTER = 120, + PROTOCOL_DROPBOX = 121, + PROTOCOL_GMAIL = 122, + PROTOCOL_GOOGLE_MAPS = 123, + PROTOCOL_YOUTUBE = 124, + PROTOCOL_SKYPE = 125, + PROTOCOL_GOOGLE = 126, + PROTOCOL_DCERPC = 127, + PROTOCOL_NETFLOW = 128, + PROTOCOL_SFLOW = 129, + PROTOCOL_HTTP_CONNECT = 130, + PROTOCOL_HTTP_PROXY = 131, + PROTOCOL_CITRIX = 132, + PROTOCOL_NETFLIX = 133, + PROTOCOL_LASTFM = 134, + PROTOCOL_WAZE = 135, + PROTOCOL_SKYFILE_PREPAID = 136, + PROTOCOL_SKYFILE_RUDICS = 137, + PROTOCOL_SKYFILE_POSTPAID = 138, + PROTOCOL_CITRIX_ONLINE = 139, + PROTOCOL_APPLE = 140, + PROTOCOL_WEBEX = 141, + PROTOCOL_WHATSAPP = 142, + PROTOCOL_APPLE_ICLOUD = 143, + PROTOCOL_VIBER = 144, + PROTOCOL_APPLE_ITUNES = 145, + PROTOCOL_RADIUS = 146, + PROTOCOL_WINDOWS_UPDATE = 147, + PROTOCOL_TEAMVIEWER = 148, + PROTOCOL_TUENTI = 149, + PROTOCOL_LOTUS_NOTES = 150, + PROTOCOL_SAP = 151, + PROTOCOL_GTP = 152, + PROTOCOL_UPNP = 153, + PROTOCOL_LLMNR = 154, + PROTOCOL_REMOTE_SCAN = 155, + PROTOCOL_SPOTIFY = 156, + CONTENT_WEBM = 157, + PROTOCOL_H323 = 158, + PROTOCOL_OPENVPN = 159, + PROTOCOL_NOE = 160, + PROTOCOL_CISCOVPN = 161, + PROTOCOL_TEAMSPEAK = 162, + PROTOCOL_TOR = 163, + PROTOCOL_SKINNY = 164, + PROTOCOL_RTCP = 165, + PROTOCOL_RSYNC = 166, + PROTOCOL_ORACLE = 167, + PROTOCOL_CORBA = 168, + PROTOCOL_UBUNTUONE = 169, + PROTOCOL_WHOIS_DAS = 170, + PROTOCOL_COLLECTD = 171, + PROTOCOL_SOCKS = 172, + PROTOCOL_MS_LYNC = 173, + PROTOCOL_RTMP = 174, + PROTOCOL_FTP_DATA = 175, + PROTOCOL_WIKIPEDIA = 176, + PROTOCOL_ZMQ = 177, + PROTOCOL_AMAZON = 178, + PROTOCOL_EBAY = 179, + PROTOCOL_CNN = 180, + PROTOCOL_MEGACO = 181, + PROTOCOL_REDIS = 182, + PROTOCOL_PANDO = 183, + PROTOCOL_VHUA = 184, + PROTOCOL_TELEGRAM = 185, + PROTOCOL_VEVO = 186, + PROTOCOL_PANDORA = 187, + PROTOCOL_QUIC = 188, + PROTOCOL_WHATSAPP_VOICE = 189, + PROTOCOL_EAQ = 190, + PROTOCOL_OOKLA = 191, + PROTOCOL_AMQP = 192, + PROTOCOL_KAKAOTALK = 193, + PROTOCOL_KAKAOTALK_VOICE = 194, + PROTOCOL_TWITCH = 195, + PROTOCOL_QUICKPLAY = 196, + PROTOCOL_WECHAT = 197, + PROTOCOL_MPEGTS = 198, + PROTOCOL_SNAPCHAT = 199, + PROTOCOL_SINA = 200, + PROTOCOL_HANGOUT = 201, + PROTOCOL_IFLIX = 202, + PROTOCOL_GITHUB = 203, + PROTOCOL_BJNP = 204, + PROTOCOL_1KXUN = 205, + PROTOCOL_IQIYI = 206, + PROTOCOL_SMPP = 207, + PROTOCOL_DNSCRYPT = 208, + PROTOCOL_FREE_209 = 209, + PROTOCOL_DEEZER = 210, + PROTOCOL_INSTAGRAM = 211, + PROTOCOL_MICROSOFT = 212, + PROTOCOL_STARCRAFT = 213, + PROTOCOL_TEREDO = 214, + PROTOCOL_HOTSPOT_SHIELD = 215, + PROTOCOL_HEP = 216, + PROTOCOL_FREE_217 = 217, + PROTOCOL_OCS = 218, + PROTOCOL_OFFICE_365 = 219, + PROTOCOL_CLOUDFLARE = 220, + PROTOCOL_MS_ONE_DRIVE = 221, + PROTOCOL_MQTT = 222, + PROTOCOL_RX = 223, + PROTOCOL_FREE_224 = 224, + PROTOCOL_OPENDNS = 225, + PROTOCOL_GIT = 226, + PROTOCOL_DRDA = 227, +} +T.PROTOCOL_NO_MASTER_PROTO = T.PROTOCOL_UNKNOWN +return T \ No newline at end of file diff --git a/lib/ljndpi/ndpi/protocol_ids_2_2.lua b/lib/ljndpi/ndpi/protocol_ids_2_2.lua new file mode 100644 index 0000000000..68f1b4b7ea --- /dev/null +++ b/lib/ljndpi/ndpi/protocol_ids_2_2.lua @@ -0,0 +1,497 @@ +-- Generated by ljdnpi's tools/update-protocol-ids script +local T = { + [0] = "PROTOCOL_UNKNOWN", + [0] = "PROTOCOL_UNKNOWN", + [1] = "PROTOCOL_FTP_CONTROL", + [2] = "PROTOCOL_SIZE", + [2] = "PROTOCOL_MAIL_POP", + [3] = "PROTOCOL_MAIL_SMTP", + [4] = "PROTOCOL_MAIL_IMAP", + [5] = "PROTOCOL_DNS", + [6] = "PROTOCOL_IPP", + [7] = "PROTOCOL_HTTP", + [8] = "PROTOCOL_MDNS", + [9] = "PROTOCOL_NTP", + [10] = "PROTOCOL_NETBIOS", + [11] = "PROTOCOL_NFS", + [12] = "PROTOCOL_SSDP", + [13] = "PROTOCOL_BGP", + [14] = "PROTOCOL_SNMP", + [15] = "PROTOCOL_XDMCP", + [16] = "PROTOCOL_SMB", + [17] = "PROTOCOL_SYSLOG", + [18] = "PROTOCOL_DHCP", + [19] = "PROTOCOL_POSTGRES", + [20] = "PROTOCOL_MYSQL", + [21] = "PROTOCOL_HOTMAIL", + [22] = "PROTOCOL_DIRECT_DOWNLOAD_LINK", + [23] = "PROTOCOL_MAIL_POPS", + [24] = "PROTOCOL_APPLEJUICE", + [25] = "PROTOCOL_DIRECTCONNECT", + [26] = "PROTOCOL_SOCRATES", + [27] = "PROTOCOL_COAP", + [28] = "PROTOCOL_VMWARE", + [29] = "PROTOCOL_MAIL_SMTPS", + [30] = "PROTOCOL_FILETOPIA", + [31] = "PROTOCOL_UBNTAC2", + [32] = "PROTOCOL_KONTIKI", + [33] = "PROTOCOL_OPENFT", + [34] = "PROTOCOL_FASTTRACK", + [35] = "PROTOCOL_GNUTELLA", + [36] = "PROTOCOL_EDONKEY", + [37] = "PROTOCOL_BITTORRENT", + [38] = "PROTOCOL_EPP", + [39] = "CONTENT_AVI", + [40] = "CONTENT_FLASH", + [41] = "CONTENT_OGG", + [42] = "CONTENT_MPEG", + [43] = "CONTENT_QUICKTIME", + [44] = "CONTENT_REALMEDIA", + [45] = "CONTENT_WINDOWSMEDIA", + [46] = "CONTENT_MMS", + [47] = "PROTOCOL_XBOX", + [48] = "PROTOCOL_QQ", + [49] = "PROTOCOL_FREE_A", + [50] = "PROTOCOL_RTSP", + [51] = "PROTOCOL_MAIL_IMAPS", + [52] = "PROTOCOL_ICECAST", + [53] = "PROTOCOL_PPLIVE", + [54] = "PROTOCOL_PPSTREAM", + [55] = "PROTOCOL_ZATTOO", + [56] = "PROTOCOL_SHOUTCAST", + [57] = "PROTOCOL_SOPCAST", + [58] = "PROTOCOL_TVANTS", + [59] = "PROTOCOL_TVUPLAYER", + [60] = "PROTOCOL_HTTP_DOWNLOAD", + [61] = "PROTOCOL_QQLIVE", + [62] = "PROTOCOL_THUNDER", + [63] = "PROTOCOL_SOULSEEK", + [64] = "PROTOCOL_SSL_NO_CERT", + [65] = "PROTOCOL_IRC", + [66] = "PROTOCOL_AYIYA", + [67] = "PROTOCOL_UNENCRYPTED_JABBER", + [68] = "PROTOCOL_MSN", + [69] = "PROTOCOL_OSCAR", + [70] = "PROTOCOL_YAHOO", + [71] = "PROTOCOL_BATTLEFIELD", + [72] = "PROTOCOL_GOOGLE_PLUS", + [73] = "PROTOCOL_IP_VRRP", + [74] = "PROTOCOL_STEAM", + [75] = "PROTOCOL_HALFLIFE2", + [76] = "PROTOCOL_WORLDOFWARCRAFT", + [77] = "PROTOCOL_TELNET", + [78] = "PROTOCOL_STUN", + [79] = "PROTOCOL_IP_IPSEC", + [80] = "PROTOCOL_IP_GRE", + [81] = "PROTOCOL_IP_ICMP", + [82] = "PROTOCOL_IP_IGMP", + [83] = "PROTOCOL_IP_EGP", + [84] = "PROTOCOL_IP_SCTP", + [85] = "PROTOCOL_IP_OSPF", + [86] = "PROTOCOL_IP_IP_IN_IP", + [87] = "PROTOCOL_RTP", + [88] = "PROTOCOL_RDP", + [89] = "PROTOCOL_VNC", + [90] = "PROTOCOL_PCANYWHERE", + [91] = "PROTOCOL_SSL", + [92] = "PROTOCOL_SSH", + [93] = "PROTOCOL_USENET", + [94] = "PROTOCOL_MGCP", + [95] = "PROTOCOL_IAX", + [96] = "PROTOCOL_TFTP", + [97] = "PROTOCOL_AFP", + [98] = "PROTOCOL_STEALTHNET", + [99] = "PROTOCOL_AIMINI", + [100] = "PROTOCOL_SIP", + [101] = "PROTOCOL_TRUPHONE", + [102] = "PROTOCOL_IP_ICMPV6", + [103] = "PROTOCOL_DHCPV6", + [104] = "PROTOCOL_ARMAGETRON", + [105] = "PROTOCOL_CROSSFIRE", + [106] = "PROTOCOL_DOFUS", + [107] = "PROTOCOL_FIESTA", + [108] = "PROTOCOL_FLORENSIA", + [109] = "PROTOCOL_GUILDWARS", + [110] = "PROTOCOL_HTTP_APPLICATION_ACTIVESYNC", + [111] = "PROTOCOL_KERBEROS", + [112] = "PROTOCOL_LDAP", + [113] = "PROTOCOL_MAPLESTORY", + [114] = "PROTOCOL_MSSQL_TDS", + [115] = "PROTOCOL_PPTP", + [116] = "PROTOCOL_WARCRAFT3", + [117] = "PROTOCOL_WORLD_OF_KUNG_FU", + [118] = "PROTOCOL_SLACK", + [119] = "PROTOCOL_FACEBOOK", + [120] = "PROTOCOL_TWITTER", + [121] = "PROTOCOL_DROPBOX", + [122] = "PROTOCOL_GMAIL", + [123] = "PROTOCOL_GOOGLE_MAPS", + [124] = "PROTOCOL_YOUTUBE", + [125] = "PROTOCOL_SKYPE", + [126] = "PROTOCOL_GOOGLE", + [127] = "PROTOCOL_DCERPC", + [128] = "PROTOCOL_NETFLOW", + [129] = "PROTOCOL_SFLOW", + [130] = "PROTOCOL_HTTP_CONNECT", + [131] = "PROTOCOL_HTTP_PROXY", + [132] = "PROTOCOL_CITRIX", + [133] = "PROTOCOL_NETFLIX", + [134] = "PROTOCOL_LASTFM", + [135] = "PROTOCOL_WAZE", + [136] = "PROTOCOL_YOUTUBE_UPLOAD", + [137] = "PROTOCOL_ICQ", + [138] = "PROTOCOL_CHECKMK", + [139] = "PROTOCOL_FREE_B", + [140] = "PROTOCOL_APPLE", + [141] = "PROTOCOL_WEBEX", + [142] = "PROTOCOL_WHATSAPP", + [143] = "PROTOCOL_APPLE_ICLOUD", + [144] = "PROTOCOL_VIBER", + [145] = "PROTOCOL_APPLE_ITUNES", + [146] = "PROTOCOL_RADIUS", + [147] = "PROTOCOL_WINDOWS_UPDATE", + [148] = "PROTOCOL_TEAMVIEWER", + [149] = "PROTOCOL_TUENTI", + [150] = "PROTOCOL_LOTUS_NOTES", + [151] = "PROTOCOL_SAP", + [152] = "PROTOCOL_GTP", + [153] = "PROTOCOL_UPNP", + [154] = "PROTOCOL_LLMNR", + [155] = "PROTOCOL_REMOTE_SCAN", + [156] = "PROTOCOL_SPOTIFY", + [157] = "CONTENT_WEBM", + [158] = "PROTOCOL_H323", + [159] = "PROTOCOL_OPENVPN", + [160] = "PROTOCOL_NOE", + [161] = "PROTOCOL_CISCOVPN", + [162] = "PROTOCOL_TEAMSPEAK", + [163] = "PROTOCOL_TOR", + [164] = "PROTOCOL_SKINNY", + [165] = "PROTOCOL_RTCP", + [166] = "PROTOCOL_RSYNC", + [167] = "PROTOCOL_ORACLE", + [168] = "PROTOCOL_CORBA", + [169] = "PROTOCOL_UBUNTUONE", + [170] = "PROTOCOL_WHOIS_DAS", + [171] = "PROTOCOL_COLLECTD", + [172] = "PROTOCOL_SOCKS", + [173] = "PROTOCOL_NINTENDO", + [174] = "PROTOCOL_RTMP", + [175] = "PROTOCOL_FTP_DATA", + [176] = "PROTOCOL_WIKIPEDIA", + [177] = "PROTOCOL_ZMQ", + [178] = "PROTOCOL_AMAZON", + [179] = "PROTOCOL_EBAY", + [180] = "PROTOCOL_CNN", + [181] = "PROTOCOL_MEGACO", + [182] = "PROTOCOL_REDIS", + [183] = "PROTOCOL_PANDO", + [184] = "PROTOCOL_VHUA", + [185] = "PROTOCOL_TELEGRAM", + [186] = "PROTOCOL_VEVO", + [187] = "PROTOCOL_PANDORA", + [188] = "PROTOCOL_QUIC", + [189] = "PROTOCOL_WHATSAPP_VOICE", + [190] = "PROTOCOL_EAQ", + [191] = "PROTOCOL_OOKLA", + [192] = "PROTOCOL_AMQP", + [193] = "PROTOCOL_KAKAOTALK", + [194] = "PROTOCOL_KAKAOTALK_VOICE", + [195] = "PROTOCOL_TWITCH", + [196] = "PROTOCOL_QUICKPLAY", + [197] = "PROTOCOL_WECHAT", + [198] = "PROTOCOL_MPEGTS", + [199] = "PROTOCOL_SNAPCHAT", + [200] = "PROTOCOL_SINA", + [201] = "PROTOCOL_HANGOUT", + [202] = "PROTOCOL_IFLIX", + [203] = "PROTOCOL_GITHUB", + [204] = "PROTOCOL_BJNP", + [205] = "PROTOCOL_1KXUN", + [206] = "PROTOCOL_IQIYI", + [207] = "PROTOCOL_SMPP", + [208] = "PROTOCOL_DNSCRYPT", + [209] = "PROTOCOL_TINC", + [210] = "PROTOCOL_DEEZER", + [211] = "PROTOCOL_INSTAGRAM", + [212] = "PROTOCOL_MICROSOFT", + [213] = "PROTOCOL_STARCRAFT", + [214] = "PROTOCOL_TEREDO", + [215] = "PROTOCOL_HOTSPOT_SHIELD", + [216] = "PROTOCOL_HEP", + [217] = "PROTOCOL_GOOGLE_DRIVE", + [218] = "PROTOCOL_OCS", + [219] = "PROTOCOL_OFFICE_365", + [220] = "PROTOCOL_CLOUDFLARE", + [221] = "PROTOCOL_MS_ONE_DRIVE", + [222] = "PROTOCOL_MQTT", + [223] = "PROTOCOL_RX", + [224] = "PROTOCOL_APPLESTORE", + [225] = "PROTOCOL_OPENDNS", + [226] = "PROTOCOL_GIT", + [227] = "PROTOCOL_DRDA", + [228] = "PROTOCOL_PLAYSTORE", + [229] = "PROTOCOL_SOMEIP", + [230] = "PROTOCOL_FIX", + [231] = "PROTOCOL_PLAYSTATION", + [232] = "PROTOCOL_PASTEBIN", + [233] = "PROTOCOL_LINKEDIN", + [234] = "PROTOCOL_SOUNDCLOUD", + [235] = "PROTOCOL_CSGO", + [236] = "PROTOCOL_LISP", + [237] = "PROTOCOL_DIAMETER", + [238] = "PROTOCOL_APPLE_PUSH", + [239] = "PROTOCOL_GOOGLE_SERVICES", + [240] = "PROTOCOL_AMAZON_VIDEO", + [241] = "PROTOCOL_GOOGLE_DOCS", + [242] = "PROTOCOL_WHATSAPP_FILES", + PROTOCOL_UNKNOWN = 0, + PROTOCOL_UNKNOWN = 0, + PROTOCOL_FTP_CONTROL = 1, + PROTOCOL_SIZE = 2, + PROTOCOL_MAIL_POP = 2, + PROTOCOL_MAIL_SMTP = 3, + PROTOCOL_MAIL_IMAP = 4, + PROTOCOL_DNS = 5, + PROTOCOL_IPP = 6, + PROTOCOL_HTTP = 7, + PROTOCOL_MDNS = 8, + PROTOCOL_NTP = 9, + PROTOCOL_NETBIOS = 10, + PROTOCOL_NFS = 11, + PROTOCOL_SSDP = 12, + PROTOCOL_BGP = 13, + PROTOCOL_SNMP = 14, + PROTOCOL_XDMCP = 15, + PROTOCOL_SMB = 16, + PROTOCOL_SYSLOG = 17, + PROTOCOL_DHCP = 18, + PROTOCOL_POSTGRES = 19, + PROTOCOL_MYSQL = 20, + PROTOCOL_HOTMAIL = 21, + PROTOCOL_DIRECT_DOWNLOAD_LINK = 22, + PROTOCOL_MAIL_POPS = 23, + PROTOCOL_APPLEJUICE = 24, + PROTOCOL_DIRECTCONNECT = 25, + PROTOCOL_SOCRATES = 26, + PROTOCOL_COAP = 27, + PROTOCOL_VMWARE = 28, + PROTOCOL_MAIL_SMTPS = 29, + PROTOCOL_FILETOPIA = 30, + PROTOCOL_UBNTAC2 = 31, + PROTOCOL_KONTIKI = 32, + PROTOCOL_OPENFT = 33, + PROTOCOL_FASTTRACK = 34, + PROTOCOL_GNUTELLA = 35, + PROTOCOL_EDONKEY = 36, + PROTOCOL_BITTORRENT = 37, + PROTOCOL_EPP = 38, + CONTENT_AVI = 39, + CONTENT_FLASH = 40, + CONTENT_OGG = 41, + CONTENT_MPEG = 42, + CONTENT_QUICKTIME = 43, + CONTENT_REALMEDIA = 44, + CONTENT_WINDOWSMEDIA = 45, + CONTENT_MMS = 46, + PROTOCOL_XBOX = 47, + PROTOCOL_QQ = 48, + PROTOCOL_FREE_A = 49, + PROTOCOL_RTSP = 50, + PROTOCOL_MAIL_IMAPS = 51, + PROTOCOL_ICECAST = 52, + PROTOCOL_PPLIVE = 53, + PROTOCOL_PPSTREAM = 54, + PROTOCOL_ZATTOO = 55, + PROTOCOL_SHOUTCAST = 56, + PROTOCOL_SOPCAST = 57, + PROTOCOL_TVANTS = 58, + PROTOCOL_TVUPLAYER = 59, + PROTOCOL_HTTP_DOWNLOAD = 60, + PROTOCOL_QQLIVE = 61, + PROTOCOL_THUNDER = 62, + PROTOCOL_SOULSEEK = 63, + PROTOCOL_SSL_NO_CERT = 64, + PROTOCOL_IRC = 65, + PROTOCOL_AYIYA = 66, + PROTOCOL_UNENCRYPTED_JABBER = 67, + PROTOCOL_MSN = 68, + PROTOCOL_OSCAR = 69, + PROTOCOL_YAHOO = 70, + PROTOCOL_BATTLEFIELD = 71, + PROTOCOL_GOOGLE_PLUS = 72, + PROTOCOL_IP_VRRP = 73, + PROTOCOL_STEAM = 74, + PROTOCOL_HALFLIFE2 = 75, + PROTOCOL_WORLDOFWARCRAFT = 76, + PROTOCOL_TELNET = 77, + PROTOCOL_STUN = 78, + PROTOCOL_IP_IPSEC = 79, + PROTOCOL_IP_GRE = 80, + PROTOCOL_IP_ICMP = 81, + PROTOCOL_IP_IGMP = 82, + PROTOCOL_IP_EGP = 83, + PROTOCOL_IP_SCTP = 84, + PROTOCOL_IP_OSPF = 85, + PROTOCOL_IP_IP_IN_IP = 86, + PROTOCOL_RTP = 87, + PROTOCOL_RDP = 88, + PROTOCOL_VNC = 89, + PROTOCOL_PCANYWHERE = 90, + PROTOCOL_SSL = 91, + PROTOCOL_SSH = 92, + PROTOCOL_USENET = 93, + PROTOCOL_MGCP = 94, + PROTOCOL_IAX = 95, + PROTOCOL_TFTP = 96, + PROTOCOL_AFP = 97, + PROTOCOL_STEALTHNET = 98, + PROTOCOL_AIMINI = 99, + PROTOCOL_SIP = 100, + PROTOCOL_TRUPHONE = 101, + PROTOCOL_IP_ICMPV6 = 102, + PROTOCOL_DHCPV6 = 103, + PROTOCOL_ARMAGETRON = 104, + PROTOCOL_CROSSFIRE = 105, + PROTOCOL_DOFUS = 106, + PROTOCOL_FIESTA = 107, + PROTOCOL_FLORENSIA = 108, + PROTOCOL_GUILDWARS = 109, + PROTOCOL_HTTP_APPLICATION_ACTIVESYNC = 110, + PROTOCOL_KERBEROS = 111, + PROTOCOL_LDAP = 112, + PROTOCOL_MAPLESTORY = 113, + PROTOCOL_MSSQL_TDS = 114, + PROTOCOL_PPTP = 115, + PROTOCOL_WARCRAFT3 = 116, + PROTOCOL_WORLD_OF_KUNG_FU = 117, + PROTOCOL_SLACK = 118, + PROTOCOL_FACEBOOK = 119, + PROTOCOL_TWITTER = 120, + PROTOCOL_DROPBOX = 121, + PROTOCOL_GMAIL = 122, + PROTOCOL_GOOGLE_MAPS = 123, + PROTOCOL_YOUTUBE = 124, + PROTOCOL_SKYPE = 125, + PROTOCOL_GOOGLE = 126, + PROTOCOL_DCERPC = 127, + PROTOCOL_NETFLOW = 128, + PROTOCOL_SFLOW = 129, + PROTOCOL_HTTP_CONNECT = 130, + PROTOCOL_HTTP_PROXY = 131, + PROTOCOL_CITRIX = 132, + PROTOCOL_NETFLIX = 133, + PROTOCOL_LASTFM = 134, + PROTOCOL_WAZE = 135, + PROTOCOL_YOUTUBE_UPLOAD = 136, + PROTOCOL_ICQ = 137, + PROTOCOL_CHECKMK = 138, + PROTOCOL_FREE_B = 139, + PROTOCOL_APPLE = 140, + PROTOCOL_WEBEX = 141, + PROTOCOL_WHATSAPP = 142, + PROTOCOL_APPLE_ICLOUD = 143, + PROTOCOL_VIBER = 144, + PROTOCOL_APPLE_ITUNES = 145, + PROTOCOL_RADIUS = 146, + PROTOCOL_WINDOWS_UPDATE = 147, + PROTOCOL_TEAMVIEWER = 148, + PROTOCOL_TUENTI = 149, + PROTOCOL_LOTUS_NOTES = 150, + PROTOCOL_SAP = 151, + PROTOCOL_GTP = 152, + PROTOCOL_UPNP = 153, + PROTOCOL_LLMNR = 154, + PROTOCOL_REMOTE_SCAN = 155, + PROTOCOL_SPOTIFY = 156, + CONTENT_WEBM = 157, + PROTOCOL_H323 = 158, + PROTOCOL_OPENVPN = 159, + PROTOCOL_NOE = 160, + PROTOCOL_CISCOVPN = 161, + PROTOCOL_TEAMSPEAK = 162, + PROTOCOL_TOR = 163, + PROTOCOL_SKINNY = 164, + PROTOCOL_RTCP = 165, + PROTOCOL_RSYNC = 166, + PROTOCOL_ORACLE = 167, + PROTOCOL_CORBA = 168, + PROTOCOL_UBUNTUONE = 169, + PROTOCOL_WHOIS_DAS = 170, + PROTOCOL_COLLECTD = 171, + PROTOCOL_SOCKS = 172, + PROTOCOL_NINTENDO = 173, + PROTOCOL_RTMP = 174, + PROTOCOL_FTP_DATA = 175, + PROTOCOL_WIKIPEDIA = 176, + PROTOCOL_ZMQ = 177, + PROTOCOL_AMAZON = 178, + PROTOCOL_EBAY = 179, + PROTOCOL_CNN = 180, + PROTOCOL_MEGACO = 181, + PROTOCOL_REDIS = 182, + PROTOCOL_PANDO = 183, + PROTOCOL_VHUA = 184, + PROTOCOL_TELEGRAM = 185, + PROTOCOL_VEVO = 186, + PROTOCOL_PANDORA = 187, + PROTOCOL_QUIC = 188, + PROTOCOL_WHATSAPP_VOICE = 189, + PROTOCOL_EAQ = 190, + PROTOCOL_OOKLA = 191, + PROTOCOL_AMQP = 192, + PROTOCOL_KAKAOTALK = 193, + PROTOCOL_KAKAOTALK_VOICE = 194, + PROTOCOL_TWITCH = 195, + PROTOCOL_QUICKPLAY = 196, + PROTOCOL_WECHAT = 197, + PROTOCOL_MPEGTS = 198, + PROTOCOL_SNAPCHAT = 199, + PROTOCOL_SINA = 200, + PROTOCOL_HANGOUT = 201, + PROTOCOL_IFLIX = 202, + PROTOCOL_GITHUB = 203, + PROTOCOL_BJNP = 204, + PROTOCOL_1KXUN = 205, + PROTOCOL_IQIYI = 206, + PROTOCOL_SMPP = 207, + PROTOCOL_DNSCRYPT = 208, + PROTOCOL_TINC = 209, + PROTOCOL_DEEZER = 210, + PROTOCOL_INSTAGRAM = 211, + PROTOCOL_MICROSOFT = 212, + PROTOCOL_STARCRAFT = 213, + PROTOCOL_TEREDO = 214, + PROTOCOL_HOTSPOT_SHIELD = 215, + PROTOCOL_HEP = 216, + PROTOCOL_GOOGLE_DRIVE = 217, + PROTOCOL_OCS = 218, + PROTOCOL_OFFICE_365 = 219, + PROTOCOL_CLOUDFLARE = 220, + PROTOCOL_MS_ONE_DRIVE = 221, + PROTOCOL_MQTT = 222, + PROTOCOL_RX = 223, + PROTOCOL_APPLESTORE = 224, + PROTOCOL_OPENDNS = 225, + PROTOCOL_GIT = 226, + PROTOCOL_DRDA = 227, + PROTOCOL_PLAYSTORE = 228, + PROTOCOL_SOMEIP = 229, + PROTOCOL_FIX = 230, + PROTOCOL_PLAYSTATION = 231, + PROTOCOL_PASTEBIN = 232, + PROTOCOL_LINKEDIN = 233, + PROTOCOL_SOUNDCLOUD = 234, + PROTOCOL_CSGO = 235, + PROTOCOL_LISP = 236, + PROTOCOL_DIAMETER = 237, + PROTOCOL_APPLE_PUSH = 238, + PROTOCOL_GOOGLE_SERVICES = 239, + PROTOCOL_AMAZON_VIDEO = 240, + PROTOCOL_GOOGLE_DOCS = 241, + PROTOCOL_WHATSAPP_FILES = 242, +} +T.PROTOCOL_NO_MASTER_PROTO = T.PROTOCOL_UNKNOWN +return T + + diff --git a/lib/ljndpi/ndpi/protocol_ids_2_3.lua b/lib/ljndpi/ndpi/protocol_ids_2_3.lua new file mode 100644 index 0000000000..3f05a6f00c --- /dev/null +++ b/lib/ljndpi/ndpi/protocol_ids_2_3.lua @@ -0,0 +1,501 @@ +-- Generated by ljdnpi's tools/update-protocol-ids script +local T = { + [0] = "PROTOCOL_UNKNOWN", + [0] = "PROTOCOL_UNKNOWN", + [1] = "PROTOCOL_FTP_CONTROL", + [2] = "PROTOCOL_SIZE", + [2] = "PROTOCOL_MAIL_POP", + [3] = "PROTOCOL_MAIL_SMTP", + [4] = "PROTOCOL_MAIL_IMAP", + [5] = "PROTOCOL_DNS", + [6] = "PROTOCOL_IPP", + [7] = "PROTOCOL_HTTP", + [8] = "PROTOCOL_MDNS", + [9] = "PROTOCOL_NTP", + [10] = "PROTOCOL_NETBIOS", + [11] = "PROTOCOL_NFS", + [12] = "PROTOCOL_SSDP", + [13] = "PROTOCOL_BGP", + [14] = "PROTOCOL_SNMP", + [15] = "PROTOCOL_XDMCP", + [16] = "PROTOCOL_SMB", + [17] = "PROTOCOL_SYSLOG", + [18] = "PROTOCOL_DHCP", + [19] = "PROTOCOL_POSTGRES", + [20] = "PROTOCOL_MYSQL", + [21] = "PROTOCOL_HOTMAIL", + [22] = "PROTOCOL_DIRECT_DOWNLOAD_LINK", + [23] = "PROTOCOL_MAIL_POPS", + [24] = "PROTOCOL_APPLEJUICE", + [25] = "PROTOCOL_DIRECTCONNECT", + [26] = "PROTOCOL_NTOP", + [27] = "PROTOCOL_COAP", + [28] = "PROTOCOL_VMWARE", + [29] = "PROTOCOL_MAIL_SMTPS", + [30] = "PROTOCOL_FBZERO", + [31] = "PROTOCOL_UBNTAC2", + [32] = "PROTOCOL_KONTIKI", + [33] = "PROTOCOL_OPENFT", + [34] = "PROTOCOL_FASTTRACK", + [35] = "PROTOCOL_GNUTELLA", + [36] = "PROTOCOL_EDONKEY", + [37] = "PROTOCOL_BITTORRENT", + [38] = "PROTOCOL_SKYPE_CALL_OUT", + [39] = "PROTOCOL_MUSICALLY", + [40] = "PROTOCOL_FREE_40", + [41] = "PROTOCOL_FREE_41", + [42] = "PROTOCOL_FREE_42", + [43] = "PROTOCOL_FREE_43", + [44] = "PROTOCOL_FREE_44", + [45] = "PROTOCOL_FREE_45", + [46] = "PROTOCOL_FREE_46", + [47] = "PROTOCOL_XBOX", + [48] = "PROTOCOL_QQ", + [49] = "PROTOCOL_SKYPE_CALL_IN", + [50] = "PROTOCOL_RTSP", + [51] = "PROTOCOL_MAIL_IMAPS", + [52] = "PROTOCOL_ICECAST", + [53] = "PROTOCOL_PPLIVE", + [54] = "PROTOCOL_PPSTREAM", + [55] = "PROTOCOL_ZATTOO", + [56] = "PROTOCOL_SHOUTCAST", + [57] = "PROTOCOL_SOPCAST", + [58] = "PROTOCOL_TVANTS", + [59] = "PROTOCOL_TVUPLAYER", + [60] = "PROTOCOL_HTTP_DOWNLOAD", + [61] = "PROTOCOL_QQLIVE", + [62] = "PROTOCOL_THUNDER", + [63] = "PROTOCOL_SOULSEEK", + [64] = "PROTOCOL_SSL_NO_CERT", + [65] = "PROTOCOL_IRC", + [66] = "PROTOCOL_AYIYA", + [67] = "PROTOCOL_UNENCRYPTED_JABBER", + [68] = "PROTOCOL_MSN", + [69] = "PROTOCOL_OSCAR", + [70] = "PROTOCOL_YAHOO", + [71] = "PROTOCOL_BATTLEFIELD", + [72] = "PROTOCOL_GOOGLE_PLUS", + [73] = "PROTOCOL_IP_VRRP", + [74] = "PROTOCOL_STEAM", + [75] = "PROTOCOL_HALFLIFE2", + [76] = "PROTOCOL_WORLDOFWARCRAFT", + [77] = "PROTOCOL_TELNET", + [78] = "PROTOCOL_STUN", + [79] = "PROTOCOL_IP_IPSEC", + [80] = "PROTOCOL_IP_GRE", + [81] = "PROTOCOL_IP_ICMP", + [82] = "PROTOCOL_IP_IGMP", + [83] = "PROTOCOL_IP_EGP", + [84] = "PROTOCOL_IP_SCTP", + [85] = "PROTOCOL_IP_OSPF", + [86] = "PROTOCOL_IP_IP_IN_IP", + [87] = "PROTOCOL_RTP", + [88] = "PROTOCOL_RDP", + [89] = "PROTOCOL_VNC", + [90] = "PROTOCOL_PCANYWHERE", + [91] = "PROTOCOL_SSL", + [92] = "PROTOCOL_SSH", + [93] = "PROTOCOL_USENET", + [94] = "PROTOCOL_MGCP", + [95] = "PROTOCOL_IAX", + [96] = "PROTOCOL_TFTP", + [97] = "PROTOCOL_AFP", + [98] = "PROTOCOL_STEALTHNET", + [99] = "PROTOCOL_AIMINI", + [100] = "PROTOCOL_SIP", + [101] = "PROTOCOL_TRUPHONE", + [102] = "PROTOCOL_IP_ICMPV6", + [103] = "PROTOCOL_DHCPV6", + [104] = "PROTOCOL_ARMAGETRON", + [105] = "PROTOCOL_CROSSFIRE", + [106] = "PROTOCOL_DOFUS", + [107] = "PROTOCOL_FIESTA", + [108] = "PROTOCOL_FLORENSIA", + [109] = "PROTOCOL_GUILDWARS", + [110] = "PROTOCOL_HTTP_APPLICATION_ACTIVESYNC", + [111] = "PROTOCOL_KERBEROS", + [112] = "PROTOCOL_LDAP", + [113] = "PROTOCOL_MAPLESTORY", + [114] = "PROTOCOL_MSSQL_TDS", + [115] = "PROTOCOL_PPTP", + [116] = "PROTOCOL_WARCRAFT3", + [117] = "PROTOCOL_WORLD_OF_KUNG_FU", + [118] = "PROTOCOL_SLACK", + [119] = "PROTOCOL_FACEBOOK", + [120] = "PROTOCOL_TWITTER", + [121] = "PROTOCOL_DROPBOX", + [122] = "PROTOCOL_GMAIL", + [123] = "PROTOCOL_GOOGLE_MAPS", + [124] = "PROTOCOL_YOUTUBE", + [125] = "PROTOCOL_SKYPE", + [126] = "PROTOCOL_GOOGLE", + [127] = "PROTOCOL_DCERPC", + [128] = "PROTOCOL_NETFLOW", + [129] = "PROTOCOL_SFLOW", + [130] = "PROTOCOL_HTTP_CONNECT", + [131] = "PROTOCOL_HTTP_PROXY", + [132] = "PROTOCOL_CITRIX", + [133] = "PROTOCOL_NETFLIX", + [134] = "PROTOCOL_LASTFM", + [135] = "PROTOCOL_WAZE", + [136] = "PROTOCOL_YOUTUBE_UPLOAD", + [137] = "PROTOCOL_ICQ", + [138] = "PROTOCOL_CHECKMK", + [139] = "PROTOCOL_AJP", + [140] = "PROTOCOL_APPLE", + [141] = "PROTOCOL_WEBEX", + [142] = "PROTOCOL_WHATSAPP", + [143] = "PROTOCOL_APPLE_ICLOUD", + [144] = "PROTOCOL_VIBER", + [145] = "PROTOCOL_APPLE_ITUNES", + [146] = "PROTOCOL_RADIUS", + [147] = "PROTOCOL_WINDOWS_UPDATE", + [148] = "PROTOCOL_TEAMVIEWER", + [149] = "PROTOCOL_TUENTI", + [150] = "PROTOCOL_LOTUS_NOTES", + [151] = "PROTOCOL_SAP", + [152] = "PROTOCOL_GTP", + [153] = "PROTOCOL_UPNP", + [154] = "PROTOCOL_LLMNR", + [155] = "PROTOCOL_REMOTE_SCAN", + [156] = "PROTOCOL_SPOTIFY", + [157] = "PROTOCOL_MESSENGER", + [158] = "PROTOCOL_H323", + [159] = "PROTOCOL_OPENVPN", + [160] = "PROTOCOL_NOE", + [161] = "PROTOCOL_CISCOVPN", + [162] = "PROTOCOL_TEAMSPEAK", + [163] = "PROTOCOL_TOR", + [164] = "PROTOCOL_SKINNY", + [165] = "PROTOCOL_RTCP", + [166] = "PROTOCOL_RSYNC", + [167] = "PROTOCOL_ORACLE", + [168] = "PROTOCOL_CORBA", + [169] = "PROTOCOL_UBUNTUONE", + [170] = "PROTOCOL_WHOIS_DAS", + [171] = "PROTOCOL_COLLECTD", + [172] = "PROTOCOL_SOCKS", + [173] = "PROTOCOL_NINTENDO", + [174] = "PROTOCOL_RTMP", + [175] = "PROTOCOL_FTP_DATA", + [176] = "PROTOCOL_WIKIPEDIA", + [177] = "PROTOCOL_ZMQ", + [178] = "PROTOCOL_AMAZON", + [179] = "PROTOCOL_EBAY", + [180] = "PROTOCOL_CNN", + [181] = "PROTOCOL_MEGACO", + [182] = "PROTOCOL_REDIS", + [183] = "PROTOCOL_PANDO", + [184] = "PROTOCOL_VHUA", + [185] = "PROTOCOL_TELEGRAM", + [186] = "PROTOCOL_VEVO", + [187] = "PROTOCOL_PANDORA", + [188] = "PROTOCOL_QUIC", + [189] = "PROTOCOL_WHATSAPP_VOICE", + [190] = "PROTOCOL_EAQ", + [191] = "PROTOCOL_OOKLA", + [192] = "PROTOCOL_AMQP", + [193] = "PROTOCOL_KAKAOTALK", + [194] = "PROTOCOL_KAKAOTALK_VOICE", + [195] = "PROTOCOL_TWITCH", + [196] = "PROTOCOL_QUICKPLAY", + [197] = "PROTOCOL_WECHAT", + [198] = "PROTOCOL_MPEGTS", + [199] = "PROTOCOL_SNAPCHAT", + [200] = "PROTOCOL_SINA", + [201] = "PROTOCOL_HANGOUT", + [202] = "PROTOCOL_IFLIX", + [203] = "PROTOCOL_GITHUB", + [204] = "PROTOCOL_BJNP", + [205] = "PROTOCOL_1KXUN", + [206] = "PROTOCOL_IQIYI", + [207] = "PROTOCOL_SMPP", + [208] = "PROTOCOL_DNSCRYPT", + [209] = "PROTOCOL_TINC", + [210] = "PROTOCOL_DEEZER", + [211] = "PROTOCOL_INSTAGRAM", + [212] = "PROTOCOL_MICROSOFT", + [213] = "PROTOCOL_STARCRAFT", + [214] = "PROTOCOL_TEREDO", + [215] = "PROTOCOL_HOTSPOT_SHIELD", + [216] = "PROTOCOL_HEP", + [217] = "PROTOCOL_GOOGLE_DRIVE", + [218] = "PROTOCOL_OCS", + [219] = "PROTOCOL_OFFICE_365", + [220] = "PROTOCOL_CLOUDFLARE", + [221] = "PROTOCOL_MS_ONE_DRIVE", + [222] = "PROTOCOL_MQTT", + [223] = "PROTOCOL_RX", + [224] = "PROTOCOL_APPLESTORE", + [225] = "PROTOCOL_OPENDNS", + [226] = "PROTOCOL_GIT", + [227] = "PROTOCOL_DRDA", + [228] = "PROTOCOL_PLAYSTORE", + [229] = "PROTOCOL_SOMEIP", + [230] = "PROTOCOL_FIX", + [231] = "PROTOCOL_PLAYSTATION", + [232] = "PROTOCOL_PASTEBIN", + [233] = "PROTOCOL_LINKEDIN", + [234] = "PROTOCOL_SOUNDCLOUD", + [235] = "PROTOCOL_CSGO", + [236] = "PROTOCOL_LISP", + [237] = "PROTOCOL_DIAMETER", + [238] = "PROTOCOL_APPLE_PUSH", + [239] = "PROTOCOL_GOOGLE_SERVICES", + [240] = "PROTOCOL_AMAZON_VIDEO", + [241] = "PROTOCOL_GOOGLE_DOCS", + [242] = "PROTOCOL_WHATSAPP_FILES", + [243] = "PROTOCOL_VIDTO", + [244] = "PROTOCOL_RAPIDVIDEO", + [245] = "PROTOCOL_SHOWMAX", + PROTOCOL_UNKNOWN = 0, + PROTOCOL_UNKNOWN = 0, + PROTOCOL_FTP_CONTROL = 1, + PROTOCOL_SIZE = 2, + PROTOCOL_MAIL_POP = 2, + PROTOCOL_MAIL_SMTP = 3, + PROTOCOL_MAIL_IMAP = 4, + PROTOCOL_DNS = 5, + PROTOCOL_IPP = 6, + PROTOCOL_HTTP = 7, + PROTOCOL_MDNS = 8, + PROTOCOL_NTP = 9, + PROTOCOL_NETBIOS = 10, + PROTOCOL_NFS = 11, + PROTOCOL_SSDP = 12, + PROTOCOL_BGP = 13, + PROTOCOL_SNMP = 14, + PROTOCOL_XDMCP = 15, + PROTOCOL_SMB = 16, + PROTOCOL_SYSLOG = 17, + PROTOCOL_DHCP = 18, + PROTOCOL_POSTGRES = 19, + PROTOCOL_MYSQL = 20, + PROTOCOL_HOTMAIL = 21, + PROTOCOL_DIRECT_DOWNLOAD_LINK = 22, + PROTOCOL_MAIL_POPS = 23, + PROTOCOL_APPLEJUICE = 24, + PROTOCOL_DIRECTCONNECT = 25, + PROTOCOL_NTOP = 26, + PROTOCOL_COAP = 27, + PROTOCOL_VMWARE = 28, + PROTOCOL_MAIL_SMTPS = 29, + PROTOCOL_FBZERO = 30, + PROTOCOL_UBNTAC2 = 31, + PROTOCOL_KONTIKI = 32, + PROTOCOL_OPENFT = 33, + PROTOCOL_FASTTRACK = 34, + PROTOCOL_GNUTELLA = 35, + PROTOCOL_EDONKEY = 36, + PROTOCOL_BITTORRENT = 37, + PROTOCOL_SKYPE_CALL_OUT = 38, + PROTOCOL_MUSICALLY = 39, + PROTOCOL_FREE_40 = 40, + PROTOCOL_FREE_41 = 41, + PROTOCOL_FREE_42 = 42, + PROTOCOL_FREE_43 = 43, + PROTOCOL_FREE_44 = 44, + PROTOCOL_FREE_45 = 45, + PROTOCOL_FREE_46 = 46, + PROTOCOL_XBOX = 47, + PROTOCOL_QQ = 48, + PROTOCOL_SKYPE_CALL_IN = 49, + PROTOCOL_RTSP = 50, + PROTOCOL_MAIL_IMAPS = 51, + PROTOCOL_ICECAST = 52, + PROTOCOL_PPLIVE = 53, + PROTOCOL_PPSTREAM = 54, + PROTOCOL_ZATTOO = 55, + PROTOCOL_SHOUTCAST = 56, + PROTOCOL_SOPCAST = 57, + PROTOCOL_TVANTS = 58, + PROTOCOL_TVUPLAYER = 59, + PROTOCOL_HTTP_DOWNLOAD = 60, + PROTOCOL_QQLIVE = 61, + PROTOCOL_THUNDER = 62, + PROTOCOL_SOULSEEK = 63, + PROTOCOL_SSL_NO_CERT = 64, + PROTOCOL_IRC = 65, + PROTOCOL_AYIYA = 66, + PROTOCOL_UNENCRYPTED_JABBER = 67, + PROTOCOL_MSN = 68, + PROTOCOL_OSCAR = 69, + PROTOCOL_YAHOO = 70, + PROTOCOL_BATTLEFIELD = 71, + PROTOCOL_GOOGLE_PLUS = 72, + PROTOCOL_IP_VRRP = 73, + PROTOCOL_STEAM = 74, + PROTOCOL_HALFLIFE2 = 75, + PROTOCOL_WORLDOFWARCRAFT = 76, + PROTOCOL_TELNET = 77, + PROTOCOL_STUN = 78, + PROTOCOL_IP_IPSEC = 79, + PROTOCOL_IP_GRE = 80, + PROTOCOL_IP_ICMP = 81, + PROTOCOL_IP_IGMP = 82, + PROTOCOL_IP_EGP = 83, + PROTOCOL_IP_SCTP = 84, + PROTOCOL_IP_OSPF = 85, + PROTOCOL_IP_IP_IN_IP = 86, + PROTOCOL_RTP = 87, + PROTOCOL_RDP = 88, + PROTOCOL_VNC = 89, + PROTOCOL_PCANYWHERE = 90, + PROTOCOL_SSL = 91, + PROTOCOL_SSH = 92, + PROTOCOL_USENET = 93, + PROTOCOL_MGCP = 94, + PROTOCOL_IAX = 95, + PROTOCOL_TFTP = 96, + PROTOCOL_AFP = 97, + PROTOCOL_STEALTHNET = 98, + PROTOCOL_AIMINI = 99, + PROTOCOL_SIP = 100, + PROTOCOL_TRUPHONE = 101, + PROTOCOL_IP_ICMPV6 = 102, + PROTOCOL_DHCPV6 = 103, + PROTOCOL_ARMAGETRON = 104, + PROTOCOL_CROSSFIRE = 105, + PROTOCOL_DOFUS = 106, + PROTOCOL_FIESTA = 107, + PROTOCOL_FLORENSIA = 108, + PROTOCOL_GUILDWARS = 109, + PROTOCOL_HTTP_APPLICATION_ACTIVESYNC = 110, + PROTOCOL_KERBEROS = 111, + PROTOCOL_LDAP = 112, + PROTOCOL_MAPLESTORY = 113, + PROTOCOL_MSSQL_TDS = 114, + PROTOCOL_PPTP = 115, + PROTOCOL_WARCRAFT3 = 116, + PROTOCOL_WORLD_OF_KUNG_FU = 117, + PROTOCOL_SLACK = 118, + PROTOCOL_FACEBOOK = 119, + PROTOCOL_TWITTER = 120, + PROTOCOL_DROPBOX = 121, + PROTOCOL_GMAIL = 122, + PROTOCOL_GOOGLE_MAPS = 123, + PROTOCOL_YOUTUBE = 124, + PROTOCOL_SKYPE = 125, + PROTOCOL_GOOGLE = 126, + PROTOCOL_DCERPC = 127, + PROTOCOL_NETFLOW = 128, + PROTOCOL_SFLOW = 129, + PROTOCOL_HTTP_CONNECT = 130, + PROTOCOL_HTTP_PROXY = 131, + PROTOCOL_CITRIX = 132, + PROTOCOL_NETFLIX = 133, + PROTOCOL_LASTFM = 134, + PROTOCOL_WAZE = 135, + PROTOCOL_YOUTUBE_UPLOAD = 136, + PROTOCOL_ICQ = 137, + PROTOCOL_CHECKMK = 138, + PROTOCOL_AJP = 139, + PROTOCOL_APPLE = 140, + PROTOCOL_WEBEX = 141, + PROTOCOL_WHATSAPP = 142, + PROTOCOL_APPLE_ICLOUD = 143, + PROTOCOL_VIBER = 144, + PROTOCOL_APPLE_ITUNES = 145, + PROTOCOL_RADIUS = 146, + PROTOCOL_WINDOWS_UPDATE = 147, + PROTOCOL_TEAMVIEWER = 148, + PROTOCOL_TUENTI = 149, + PROTOCOL_LOTUS_NOTES = 150, + PROTOCOL_SAP = 151, + PROTOCOL_GTP = 152, + PROTOCOL_UPNP = 153, + PROTOCOL_LLMNR = 154, + PROTOCOL_REMOTE_SCAN = 155, + PROTOCOL_SPOTIFY = 156, + PROTOCOL_MESSENGER = 157, + PROTOCOL_H323 = 158, + PROTOCOL_OPENVPN = 159, + PROTOCOL_NOE = 160, + PROTOCOL_CISCOVPN = 161, + PROTOCOL_TEAMSPEAK = 162, + PROTOCOL_TOR = 163, + PROTOCOL_SKINNY = 164, + PROTOCOL_RTCP = 165, + PROTOCOL_RSYNC = 166, + PROTOCOL_ORACLE = 167, + PROTOCOL_CORBA = 168, + PROTOCOL_UBUNTUONE = 169, + PROTOCOL_WHOIS_DAS = 170, + PROTOCOL_COLLECTD = 171, + PROTOCOL_SOCKS = 172, + PROTOCOL_NINTENDO = 173, + PROTOCOL_RTMP = 174, + PROTOCOL_FTP_DATA = 175, + PROTOCOL_WIKIPEDIA = 176, + PROTOCOL_ZMQ = 177, + PROTOCOL_AMAZON = 178, + PROTOCOL_EBAY = 179, + PROTOCOL_CNN = 180, + PROTOCOL_MEGACO = 181, + PROTOCOL_REDIS = 182, + PROTOCOL_PANDO = 183, + PROTOCOL_VHUA = 184, + PROTOCOL_TELEGRAM = 185, + PROTOCOL_VEVO = 186, + PROTOCOL_PANDORA = 187, + PROTOCOL_QUIC = 188, + PROTOCOL_WHATSAPP_VOICE = 189, + PROTOCOL_EAQ = 190, + PROTOCOL_OOKLA = 191, + PROTOCOL_AMQP = 192, + PROTOCOL_KAKAOTALK = 193, + PROTOCOL_KAKAOTALK_VOICE = 194, + PROTOCOL_TWITCH = 195, + PROTOCOL_QUICKPLAY = 196, + PROTOCOL_WECHAT = 197, + PROTOCOL_MPEGTS = 198, + PROTOCOL_SNAPCHAT = 199, + PROTOCOL_SINA = 200, + PROTOCOL_HANGOUT = 201, + PROTOCOL_IFLIX = 202, + PROTOCOL_GITHUB = 203, + PROTOCOL_BJNP = 204, + PROTOCOL_1KXUN = 205, + PROTOCOL_IQIYI = 206, + PROTOCOL_SMPP = 207, + PROTOCOL_DNSCRYPT = 208, + PROTOCOL_TINC = 209, + PROTOCOL_DEEZER = 210, + PROTOCOL_INSTAGRAM = 211, + PROTOCOL_MICROSOFT = 212, + PROTOCOL_STARCRAFT = 213, + PROTOCOL_TEREDO = 214, + PROTOCOL_HOTSPOT_SHIELD = 215, + PROTOCOL_HEP = 216, + PROTOCOL_GOOGLE_DRIVE = 217, + PROTOCOL_OCS = 218, + PROTOCOL_OFFICE_365 = 219, + PROTOCOL_CLOUDFLARE = 220, + PROTOCOL_MS_ONE_DRIVE = 221, + PROTOCOL_MQTT = 222, + PROTOCOL_RX = 223, + PROTOCOL_APPLESTORE = 224, + PROTOCOL_OPENDNS = 225, + PROTOCOL_GIT = 226, + PROTOCOL_DRDA = 227, + PROTOCOL_PLAYSTORE = 228, + PROTOCOL_SOMEIP = 229, + PROTOCOL_FIX = 230, + PROTOCOL_PLAYSTATION = 231, + PROTOCOL_PASTEBIN = 232, + PROTOCOL_LINKEDIN = 233, + PROTOCOL_SOUNDCLOUD = 234, + PROTOCOL_CSGO = 235, + PROTOCOL_LISP = 236, + PROTOCOL_DIAMETER = 237, + PROTOCOL_APPLE_PUSH = 238, + PROTOCOL_GOOGLE_SERVICES = 239, + PROTOCOL_AMAZON_VIDEO = 240, + PROTOCOL_GOOGLE_DOCS = 241, + PROTOCOL_WHATSAPP_FILES = 242, + PROTOCOL_VIDTO = 243, + PROTOCOL_RAPIDVIDEO = 244, + PROTOCOL_SHOWMAX = 245, +} +T.PROTOCOL_NO_MASTER_PROTO = T.PROTOCOL_UNKNOWN +return T \ No newline at end of file From dd9bb127e45dd65fbe69bfe5816edd85e7272086 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Tue, 7 Aug 2018 14:19:15 +0200 Subject: [PATCH 08/35] Refactor the logger facility Move the logger out of core.lib into lib.logger and add documentation. Simplify the throttling code by tying it to the logging of discarded messages. Update in-tree references to the logger. Remove the token_bucket:rate() method which was kept for backward compatibility for the old logger code. --- src/apps/bridge/learning.lua | 3 +- src/apps/bridge/mac_table.lua | 3 +- src/apps/ipv6/nd_light.lua | 3 +- src/core/lib.lua | 166 ------------------------------ src/lib/README.logger.md | 141 +++++++++++++++++++++++++ src/lib/ipc/shmem/iftable_mib.lua | 3 +- src/lib/ipsec/esp.lua | 2 +- src/lib/logger.lua | 106 +++++++++++++++++++ src/lib/token_bucket.lua | 9 -- src/program/l2vpn/pseudowire.lua | 3 +- 10 files changed, 258 insertions(+), 181 deletions(-) create mode 100644 src/lib/README.logger.md create mode 100644 src/lib/logger.lua diff --git a/src/apps/bridge/learning.lua b/src/apps/bridge/learning.lua index 0edb4a0365..f4d5306cc1 100644 --- a/src/apps/bridge/learning.lua +++ b/src/apps/bridge/learning.lua @@ -82,6 +82,7 @@ local bridge_base = require("apps.bridge.base").bridge local mac_table = require("apps.bridge.mac_table") require("apps.bridge.learning_h") local ethernet = require("lib.protocol.ethernet") +local logger = require("lib.logger") local empty, receive, transmit = link.empty, link.receive, link.transmit local clone = packet.clone @@ -179,7 +180,7 @@ function bridge:new (arg) alloc_pft(o) -- Box to store a pointer to a MAC address in memory o._mac = ffi.new("uint8_t *[1]") - o._logger = lib.logger_new({ module = "bridge" }) + o._logger = logger.new({ module = "bridge" }) return o end diff --git a/src/apps/bridge/mac_table.lua b/src/apps/bridge/mac_table.lua index d9f1ed8862..86d4c8cad6 100644 --- a/src/apps/bridge/mac_table.lua +++ b/src/apps/bridge/mac_table.lua @@ -118,6 +118,7 @@ local ffi = require("ffi") local C = ffi.C local lib = require("core.lib") local murmur = require("lib.hash.murmur") +local logger = require("lib.logger") local band = require("bit").band require("apps.bridge.learning_h") @@ -206,7 +207,7 @@ function mac_table:new (config) -- C.mac_table_insert() o._tables_C = ffi.new("hash_table_t *[2]") alloc_tables(o, o._buckets) - o._logger = lib.logger_new({ module = "mac_table" }) + o._logger = logger.new({ module = "mac_table" }) timer.activate( timer.new("mac_table_timeout", function (t) diff --git a/src/apps/ipv6/nd_light.lua b/src/apps/ipv6/nd_light.lua index fc1febb6a8..bb3ffb4e86 100644 --- a/src/apps/ipv6/nd_light.lua +++ b/src/apps/ipv6/nd_light.lua @@ -47,6 +47,7 @@ local tlv = require("lib.protocol.icmp.nd.options.tlv") local filter = require("lib.pcap.filter") local timer = require("core.timer") local lib = require("core.lib") +local logger = require("lib.logger") nd_light = subClass(nil) nd_light._name = "Partial IPv6 neighbor discovery" @@ -236,7 +237,7 @@ function nd_light:new (arg) p = ffi.new("struct packet *[1]"), mem = ffi.new("uint8_t *[1]") } - o._logger = lib.logger_new({ module = 'nd_light' }) + o._logger = logger.new({ module = 'nd_light' }) return o end diff --git a/src/core/lib.lua b/src/core/lib.lua index 1c7a554fd6..b85ab0bd36 100644 --- a/src/core/lib.lua +++ b/src/core/lib.lua @@ -453,172 +453,6 @@ function root_check (message) end end --- Backward compatibility -token_bucket_new = require("lib.token_bucket").new - --- Simple rate-limited logging facility. Usage: --- --- local logger = lib.logger_new({ rate = , --- discard_rate = , --- fh = , --- flush = true|false, --- module = , --- date = true|false }) --- logger:log(message) --- --- maximum rate of messages per second. Additional --- messages are discarded. Default: 10 --- maximum rate of logging of the number of discarded --- messages. Default: 0.5 --- file handle to log to. Default: io.stdout --- flush flush after each message if true --- name of the module to include in the message --- date include date in messages if true --- --- The output format is --- : message --- --- The logger uses an automatic throttling mechanism to dynamically --- lower the logging rate when the rate of discarded messages exceeds --- the maximum log rate by a factor of 5 over one or multiple adjacent --- intervals of 10 seconds. For each such interval, the logging rate --- is reduced by a factor of 2 with a lower bound of 0.1 Hz (i.e. one --- message per 10 seconds). For each 10-second interval for which the --- rate of discarded messages is below the threshold, the logging rate --- is increased by 1/4 of the original rate, i.e. it takes at least 40 --- seconds to ramp back up to the original rate. --- --- The tables lib.logger_default and lib.logger_throttle are exposed --- to the user as part of the API. -logger_default = { - rate = 10, - discard_rate = 0.5, - fh = io.stdout, - flush = true, - module = '', - date = true, - date_fmt = "%b %d %Y %H:%M:%S ", -} -logger_throttle = { - interval = 10, -- Sampling interval for discard rate - excess = 5, -- Multiple of rate at which to start throttling - increment = 4, -- Fraction of rate to increase for un-throttling - min_rate = 0.1, -- Minimum throttled rate -} -local logger = { - default = logger_default, - throttle = logger_throttle, -} -logger.mt = { __index = logger } - -function logger_new (config) - local config = config or logger.default - local l = setmetatable({}, logger.mt) - _config = setmetatable({}, { __index = logger.default }) - for k, v in pairs(config) do - assert(_config[k], "Logger: unknown configuration option "..k) - _config[k] = v - end - l._config = _config - l._tb = token_bucket_new({ rate = _config.rate }) - l._discard_tb = token_bucket_new({ rate = _config.discard_rate }) - l._discards = 0 - local _throttle = { - discards = 0, - tstamp = C.get_monotonic_time(), - rate = _config.rate * logger.throttle.excess, - increment = _config.rate/logger.throttle.increment, - } - l._throttle = setmetatable(_throttle, { __index = logger.throttle }) - l._preamble = (l._config.module and l._config.module..': ') or '' - return l -end - --- Log message unless the rate limit is exceeded. Note that --- is evaluated upon the method call in any case, which can have --- a performance impact even when the message is discarded. This can --- be avoided by calling the can_log() method first, i.e. --- --- if logger:can_log() then --- logger:log('foo') --- end --- --- This framework should have very low processing overhead and should --- be safe to call even form within packet-processing loops. The --- bottleneck currently is the call to clock_gettime(). Care has been --- taken to make sure that this call is executed at most once in the --- non-rate limited code path. - -function logger:log (msg) - if self._tb:take(1) then - local config = self._config - local throttle = self._throttle - throttle.discards = throttle.discards + self._discards - local date = '' - if config.date then - date = os.date(config.date_fmt) - end - local preamble = date..self._preamble - local fh = config.fh - local now = C.get_monotonic_time() - local interval = now-throttle.tstamp - local samples = interval/throttle.interval - local drate = throttle.discards/interval - local current_rate = self._tb:rate() - if self._discards > 0 and self._discard_tb:take(1) then - fh:write(string.format(preamble.."%d messages discarded\n", - self._discards)) - throttle.discards = self._discards - self._discards = 0 - end - if samples >= 1 then - if drate > throttle.rate then - local min_rate = throttle.min_rate - if current_rate > min_rate then - local throttle_rate = math.max(min_rate, - current_rate/2^samples) - fh:write(string.format(preamble.."message discard rate %.2f exceeds " - .."threshold (%.2f), throttling logging rate to " - .."%.2f Hz%s\n", - drate, throttle.rate, throttle_rate, - (throttle_rate == min_rate and ' (minimum)') or '')) - self._tb:rate(throttle_rate) - end - else - local configured_rate = config.rate - if current_rate < configured_rate then - local throttle_rate = math.min(configured_rate, - current_rate + throttle.increment*samples) - fh:write(string.format(preamble.."unthrottling logging rate to " - .."%.2f Hz%s\n", - throttle_rate, - (throttle_rate == configured_rate and ' (maximum)') or '')) - self._tb:rate(throttle_rate) - end - end - throttle.discards = 0 - throttle.tstamp = now - end - fh:write(preamble..msg..'\n') - if config.flush then fh:flush() end - else - self._discards = self._discards + 1 - end -end - --- Return true if a message can be logged without being discarded, --- false otherwise. In the first case, it is guaranteed that the --- token bucket for the logging rate-limiter contains at least one --- token. In the second case, the rate-limit is hit and the counter --- of discarded messages is increased. -function logger:can_log () - if self._tb:can_take(1) then - return true - end - self._discards = self._discards + 1 - return false -end - -- Wrapper around os.getenv which only returns the variable's value if it -- is non-empty. function getenv (name) diff --git a/src/lib/README.logger.md b/src/lib/README.logger.md new file mode 100644 index 0000000000..13f748599e --- /dev/null +++ b/src/lib/README.logger.md @@ -0,0 +1,141 @@ +### Logger (lib.logger) + +The *logger* module implements a rate-limited logging facility with +optional throttling of the logging rate under stress. It uses +*lib.token_bucket* with the *rdtsc* time-source (if available) for +rate-limiting, which makes it suitable to be called from +critical code with minimal impact on performance. + +#### Functions + +— Function **new** *config* + +Creates an instance of a logger. The required *config* argument must +be a table with the following keys. + +— Key **rate** + +*Optional*. The rate in units of Hz at which the output of log +messages is limited. The default is 10 Hz. The maximum burst size +(the number of messages that can be posted back-to-back) is +numerically equal to **rate** (i.e. the maximum number of messages +allowed during an interval of one second). Messages that exceed the +rate limit are discarded. The number of discarded messages is +reported periodically, see the **discard_report_rate** configuration +option. + +— Key **discard_report_rate** + +*Optional*. The rate in units of Hz at which reporting of the number +of discarded messages is limited. The default is 0.2 Hz. + +— Key **fh** + +*Optional*. The file handle to which log messages are written. The +default is **io.stdout**. + +— Key **flush** + +*Optional*. A boolean that indicates wheter **fh** should be flushed +after each write. The default is **true**. + +— Key **module** + +*Optional*. An arbitrary string that will be prepended to each log +message to identify the component of the application that generated +the message. The default is the empty string. + +— Key **date** + +*Optional*. A boolean that indicates whether each log message should +be prepended by the current date and time according to the format +given by the **date_fmt** configuration option. The default is +**true**. + +— Key **date_fmt** + +*Optional*. A string that defines the format of the time stamp +prepended to each log message if the **date** configuration option is +**true**. It must be a valid format specifier as expected by the +**os.date** function. The default is **"%b %d %Y %H:%M:%S "**. + +— Key **throttle** + +*Optional*. A boolean that indicates whether automatic throttling of +the logging rate should be enabled. The default is **true**. + +The mechanism decrease the logging rate when the number of discarded +messages exceeds a certain threshold to allow a relatively high +logging rate under normal circumstances while avoiding large amounts +of messages during "logging storms". + +Throttling is coupled to the rate-limiting of discard reports as +follows. Whenever a discard report is logged (according to the +**discard_report_rate** option), the rate of discarded messages since +the last such event is calculated. + +If this rate exceeds a configurable multiple, called the _excess_, of +**rate**, the effective rate-limit is decreased by a factor of 2. The +effective rate-limit is bounded from below by a configurable minimum. + +If the rate of discarded messages is below the threshold, the +effective rate-limit is increased by a configurable fraction of +**rate**. The effective rate is bounded from above by **rate**. + +— Key **throttle_config** + +*Optional*. This is a table with the following keys. + + * Key **excess** + + *Optional*. The threshold for the rate of discarded messages at + which throttling is applied as detailed above is given by + **excess** \* **rate**. The default is 5 (i.e. the default + threshold is 50 Hz). + + * Key **increment** + + *Optional*. The fraction of **rate** at which the effective + rate-limit is increased when the rate of discarded messages is + below the threshold. The default is 4, i.e. the effective + increment of the rate is given by **rate**/4 by default. + + * Key **min_rate** + + *Optional*. The lower bound for the effective rate when + throttling is in effect. The default is 0.1 Hz. + +#### Methods + +The object returned by the **new** function provides the following +methods. + +— Method **logger:log** *msg* + +Print the string *msg* to the logger's file handle. The string is +prepended by the date and/or the module name according to the +configuration. If any messages have been discarded since the last time +a message has been successfully logged, the number of discarded +messages is logged as well, subject to the rate-limiting given by +**discard_report_rate**. If the discard report is allowd by that +rate-limit and throttling is enabled, the new effective logging rate +is calculated and applied as well. + +If the rate-limit is exceeded, the message is discarded. + +Note that *msg* is evaluated before the method is called. If the +evaluation is expensive (e.g. a concatenation of strings) and the +caller is in a performance-critical section of code, the **can_log** +method should be used to determine whether the message is allowed by +the rate-limiter, e.g. + +```Lua +if logger:can_log() then + logger:log("foo " .. "bar") +end +``` + +— Method **logger:can_log** + +Returns a **true** value if a message can be logged successfully, +**false** otherwise. diff --git a/src/lib/ipc/shmem/iftable_mib.lua b/src/lib/ipc/shmem/iftable_mib.lua index 20ace240c8..08ac38c0dc 100644 --- a/src/lib/ipc/shmem/iftable_mib.lua +++ b/src/lib/ipc/shmem/iftable_mib.lua @@ -5,6 +5,7 @@ local lib = require("core.lib") local mib = require("lib.ipc.shmem.mib") local counter = require("core.counter") local macaddress = require("lib.macaddress") +local logger = require("lib.logger") local ffi = require("ffi") local C = ffi.C @@ -29,7 +30,7 @@ function init_snmp (objs, name, counters, directory, interval) end local ifTable = mib:new({ directory = directory or nil, filename = name }) - local logger = lib.logger_new({ module = 'iftable_mib' }) + local logger = logger.new({ module = 'iftable_mib' }) -- ifTable ifTable:register('ifDescr', 'OctetStr', objs.ifDescr) ifTable:register('ifType', 'Integer32') diff --git a/src/lib/ipsec/esp.lua b/src/lib/ipsec/esp.lua index e48659c561..cd6aa0c327 100644 --- a/src/lib/ipsec/esp.lua +++ b/src/lib/ipsec/esp.lua @@ -29,7 +29,7 @@ local seq_no_t = require("lib.ipsec.seq_no_t") local lib = require("core.lib") local ffi = require("ffi") local C = ffi.C -local logger = lib.logger_new({ rate = 32, module = 'esp' }) +local logger = require("lib.logger").new({ rate = 32, module = 'esp' }) require("lib.ipsec.track_seq_no_h") local window_t = ffi.typeof("uint8_t[?]") diff --git a/src/lib/logger.lua b/src/lib/logger.lua new file mode 100644 index 0000000000..c163ac95fa --- /dev/null +++ b/src/lib/logger.lua @@ -0,0 +1,106 @@ +-- Use of this source code is governed by the Apache 2.0 license; see COPYING. + +module(...,package.seeall) + +local lib = require("core.lib") +local token_bucket = require("lib.token_bucket") +local tsc = require("lib.tsc") + +local logger = {} +local params = { + rate = { default = 10 }, + discard_report_rate = { default = 0.2 }, + fh = { default = io.stdout }, + flush = { default = true }, + module = { required = false }, + date = { default = true }, + date_fmt = { default = "%b %d %Y %H:%M:%S " }, + throttle = { default = true }, + throttle_config = { default = {} }, +} +local throttle_params = { + excess = { default = 5 }, -- Multiple of rate at which to start throttling + increment = { default = 4 }, -- Fraction of rate to increase for un-throttling + min_rate = { default = 0.1 }, -- Minimum throttled rate +} + +function new (arg) + local o = setmetatable(lib.parse(arg, params), { __index = logger }) + o.tb = token_bucket.new({ rate = o.rate }) + o.discard_tb = token_bucket.new({ rate = o.discard_report_rate }) + o.discards = 0 + o.tsc = tsc.new() + o.stamp = o.tsc:stamp() + o.preamble = (o.module and o.module..': ') or '' + if o.throttle then + o.throttle = lib.parse(o.throttle_config, throttle_params) + end + return o +end + +function logger:log (msg) + if self.tb:take(1) then + local date = (self.date and os.date(self.date_fmt)) or '' + local preamble = date..self.preamble + self.fh:write(("%s%s\n"):format(preamble, msg)) + if self.flush then self.fh:flush() end + + if self.discards > 0 and self.discard_tb:take(1) then + self.fh:write( + ("%s%d messages discarded\n"):format(preamble, self.discards) + ) + + if self.throttle then + local ticks = self.tsc:stamp() - self.stamp + local discard_rate = + self.discards * tonumber(self.tsc:tps())/tonumber(ticks) + local threshold = self.rate * self.throttle.excess + local current_rate = self.tb:get() + + if discard_rate > threshold then + local min_rate = self.throttle.min_rate + if current_rate > min_rate then + local new_rate = math.max(min_rate, current_rate/2) + self.fh:write( + ("%sMessage discard rate %.2f Hz exceeds " + .."threshold (%.2f Hz), throttling " + .."logging rate to %.2f Hz%s\n") + :format(preamble, discard_rate, threshold, new_rate, + (new_rate == min_rate and ' (minimum)') or '') + ) + self.tb:set(new_rate) + end + else + if current_rate < self.rate then + local new_rate = math.min(self.rate, + current_rate + self.rate/self.throttle.increment) + self.fh:write( + ("%sUnthrottling logging rate to %.2f Hz%s\n") + :format(preamble, new_rate, + (new_rate == self.rate and ' (maximum)') or '') + ) + self.tb:set(new_rate) + end + end + + end + + self.discards = 0 + self.stamp = self.tsc:stamp() + end + else + self.discards = self.discards + 1 + end +end + +-- Return true if a message can be logged without being discarded, +-- false otherwise. The latter increases the discard counter, +-- assuming the caller wants to actually log a message. +function logger:can_log () + if self.tb:can_take(1) then + return true + end + self.discards = self.discards + 1 + return false +end + diff --git a/src/lib/token_bucket.lua b/src/lib/token_bucket.lua index 9debd80d04..e0e8cd5637 100644 --- a/src/lib/token_bucket.lua +++ b/src/lib/token_bucket.lua @@ -48,15 +48,6 @@ function token_bucket:get () return self._rate, self._burst_size end --- For backward compatibility only -function token_bucket:rate (rate) - local old_rate = self._rate - if rate ~= nil then - self:set(rate, self._burst_size) - end - return old_rate -end - function token_bucket:can_take (n) local n = n or 1 local tokens = self._tokens diff --git a/src/program/l2vpn/pseudowire.lua b/src/program/l2vpn/pseudowire.lua index 63069ead0b..5262dcfb90 100644 --- a/src/program/l2vpn/pseudowire.lua +++ b/src/program/l2vpn/pseudowire.lua @@ -37,6 +37,7 @@ local filter = require("lib.pcap.filter") local pcap = require("apps.pcap.pcap") local cc = require("program.l2vpn.control_channel") local ipc_mib = require("lib.ipc.shmem.mib") +local logger = require("lib.logger") pseudowire = subClass(nil) pseudowire._name = "Pseudowire" @@ -229,7 +230,7 @@ function pseudowire:new (conf_in) o._conf = conf local bpf_program - o._logger = lib.logger_new({ module = o._name.." ("..o._conf.name..")" }) + o._logger = logger.new({ module = o._name.." ("..o._conf.name..")" }) -- Construct templates for the entire encapsulation chain -- Ethernet header From 2bbaa390fdb4641a3169b29835e0cecec5ac08b0 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Tue, 7 Aug 2018 15:14:06 +0200 Subject: [PATCH 09/35] lib.tsc: cache calibration of rdtsc Calibration causes long delays in some selftests that instantiate the new logger. --- src/lib/tsc.lua | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/lib/tsc.lua b/src/lib/tsc.lua index f12b74727c..2c3aa35ff0 100644 --- a/src/lib/tsc.lua +++ b/src/lib/tsc.lua @@ -32,17 +32,22 @@ assert(cpuinfo, "failed to read /proc/cpuinfo for tsc check") local have_usable_rdtsc = (cpuinfo:match("constant_tsc") and cpuinfo:match("nonstop_tsc")) +local rdtsc_tps + local time_sources = { rdtsc = { time_fn = rdtsc, calibrate_fn = function () - local start_ns = C.get_time_ns() - local start_ticks = rdtsc() - for _ = 1, calibration_interval do end - local end_ticks = rdtsc() - local end_ns = C.get_time_ns() - return tonumber(end_ticks - start_ticks)/tonumber(end_ns - start_ns) - * 1000000000 + 0ULL + if not rdtsc_tps then + local start_ns = C.get_time_ns() + local start_ticks = rdtsc() + for _ = 1, calibration_interval do end + local end_ticks = rdtsc() + local end_ns = C.get_time_ns() + rdtsc_tps = tonumber(end_ticks - start_ticks)/tonumber(end_ns - start_ns) + * 1000000000 + 0ULL + end + return rdtsc_tps end }, system = { From f0c6011fda3b457570c04a56a7258248dc12f443 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 08:39:16 +0100 Subject: [PATCH 10/35] Implement checksum computation using DynASM --- src/lib/newchecksum.dasl | 159 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 159 insertions(+) create mode 100644 src/lib/newchecksum.dasl diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl new file mode 100644 index 0000000000..f589a51102 --- /dev/null +++ b/src/lib/newchecksum.dasl @@ -0,0 +1,159 @@ +module(..., package.seeall) + +local dasm = require("dasm") +local lib = require("core.lib") +local ffi = require('ffi') +local C = ffi.C + +-- DynASM prelude. + +debug = false + +|.arch x64 +|.actionlist actions + +__anchor = {} +mcode = {} +size = 0 + +function assemble (name, prototype, generator) + local Dst = dasm.new(actions) + generator(Dst) + local mcode, size = Dst:build() + table.insert(__anchor, mcode) + if debug then + print("mcode dump: "..name) + dasm.dump(mcode, size) + end + return ffi.cast(prototype, mcode) +end + +local function gen_checksum () + return function (Dst) + -- Prologue. + | push rbp + | mov rbp, rsp + -- Accumulative sum. + | xor rax, rax -- Clear out rax. Stores accumulated sum. + | xor r9, r9 -- Clear out r9. Stores value of array. + | xor r8, r8 -- Clear out r8. Stores array index. + | mov rcx, rsi -- Rsi (2nd argument; size). Assign rsi to rcx. + | 1: + | cmp rcx, 8 -- If index is less than 8. + | jl >2 -- Jump to branch '2'. + | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. + | add rax, r9 -- Sum acc with r9. + | adc rax, 0 -- Sum carry-bit into acc. + | sub rcx, 8 -- Decrease index by 8. + | add r8, 8 -- Next 64-bit. + | jmp <1 -- Go to beginning of loop. + | 2: + | cmp rcx, 4 -- If index is less than 4. + | jl >3 -- Jump to branch '3'. + | mov r9d, dword [rdi + r8] -- Fetch 32-bit from data + r8 into r9d. + | add rax, r9 -- Sum acc with r9. Accumulate carry. + | sub rcx, 4 -- Decrease index by 4. + | add r8, 4 -- Next 32-bit. + | jmp <2 -- Go to beginning of loop. + | 3: + | cmp rcx, 2 -- If index is less than 2. + | jl >4 -- Jump to branch '4'. + | movzx r9, word [rdi + r8] -- Fetch 16-bit from data + r8 into r9. + | add rax, r9 -- Sum acc with r9. Accumulate carry. + | sub rcx, 2 -- Decrease index by 2. + | add r8, 2 -- Next 16-bit. + | jmp <3 -- Go to beginning of loop. + | 4: + | cmp rcx, 1 -- If index is less than 1. + | jl >5 -- Jump to branch '5'. + | movzx r9, byte [rdi + r8] -- Fetch 8-bit from data + r8 into r9. + | add rax, r9 -- Sum acc with r9. Accumulate carry. + -- Fold 64-bit into 16-bit. + | 5: + | mov r9, rax -- Assign acc to r9. + | shr r9, 32 -- Shift r9 32-bit. Stores higher part of acc. + | and rax, 0x00000000ffffffff -- Clear out higher-part of rax. Stores lower part of acc. + | add eax, r9d -- 32-bit sum of acc and r9. + | adc eax, 0 -- Sum carry to acc. + | mov r9d, eax -- Repeat for 16-bit. + | shr r9d, 16 + | and eax, 0x0000ffff + | add ax, r9w + | adc ax, 0 + -- One's complement. + | not rax -- One-complement of rax. + | and rax, 0xffff -- Clear out higher part of rax. + -- Epilogue. + | 6: + | mov rsp, rbp + | pop rbp + -- Return. + | ret + end +end + +local newchecksum = assemble("newchecksum", "uint32_t(*)(uint8_t*, uint32_t)", gen_checksum()) + +function selftest () + require("lib.checksum_h") + local function create_packet (size) + local pkt = { + data = ffi.new("uint8_t[?]", size), + length = size + } + for i=0,size-1 do + pkt.data[i] = math.random(255) + end + return pkt + end + local function benchmark (fn, times) + local now = os.clock() + local temp + for i=1,times do + temp = fn() + end + local ret = {os.clock() - now, temp} + return ret[1] + end + local function hex (num) + return ("0x%.2x"):format(num) + end + local ntohs = lib.ntohs + print("selftest: newchecksum") + + local size = 44 + print("14.4M; "..size.." bytes") + local pkt = create_packet(size) + local times = 14.4*10^6 + -- Verify checksum is correct. + assert(hex(C.cksum_generic(pkt.data, pkt.length, 0)) == hex(ntohs(newchecksum(pkt.data, pkt.length)))) + -- Benchmark for different architectures. + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0) end, times)) + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length) end, times)) + + size = 550 + print("2M; "..size.." bytes") + local pkt = create_packet(size) + local times = 2*10^6 + -- Verify checksum is correct. + assert(hex(C.cksum_generic(pkt.data, pkt.length, 0)) == hex(ntohs(newchecksum(pkt.data, pkt.length)))) + -- Benchmark for different architectures. + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0) end, times)) + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length) end, times)) + + size = 1500 + print("1M; "..size.." bytes") + local pkt = create_packet(size) + local times = 1*10^6 + -- Verify checksum is correct. + assert(hex(C.cksum_generic(pkt.data, pkt.length, 0)) == hex(ntohs(newchecksum(pkt.data, pkt.length)))) + -- Benchmark for different architectures. + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0) end, times)) + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length) end, times)) +end From 9a96d576f0034e07033f7ec499f0052f062047fb Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 11:43:28 +0100 Subject: [PATCH 11/35] Add reference implementation of checksum computation in Lua --- src/lib/newchecksum.dasl | 33 ++++++++++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 3 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index f589a51102..1743480da4 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -1,5 +1,6 @@ module(..., package.seeall) +local bit = require("bit") local dasm = require("dasm") local lib = require("core.lib") local ffi = require('ffi') @@ -94,6 +95,29 @@ end local newchecksum = assemble("newchecksum", "uint32_t(*)(uint8_t*, uint32_t)", gen_checksum()) +-- Reference implementation in Lua. +local function checksum_lua (data, size) + local function r16 (data) + return ffi.cast("uint16_t*", data)[0] + end + local csum = 0 + local i = size + while i > 1 do + local word = r16(data + (size - i)) + csum = csum + word + i = i - 2 + end + if i == 1 then + csum = csum + data[size-1] + end + while true do + local carry = bit.rshift(csum, 16) + if carry == 0 then break end + csum = bit.band(csum, 0xffff) + carry + end + return bit.band(bit.bnot(csum), 0xffff) +end + function selftest () require("lib.checksum_h") local function create_packet (size) @@ -126,7 +150,8 @@ function selftest () local pkt = create_packet(size) local times = 14.4*10^6 -- Verify checksum is correct. - assert(hex(C.cksum_generic(pkt.data, pkt.length, 0)) == hex(ntohs(newchecksum(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) -- Benchmark for different architectures. print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) @@ -138,7 +163,8 @@ function selftest () local pkt = create_packet(size) local times = 2*10^6 -- Verify checksum is correct. - assert(hex(C.cksum_generic(pkt.data, pkt.length, 0)) == hex(ntohs(newchecksum(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) -- Benchmark for different architectures. print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) @@ -150,7 +176,8 @@ function selftest () local pkt = create_packet(size) local times = 1*10^6 -- Verify checksum is correct. - assert(hex(C.cksum_generic(pkt.data, pkt.length, 0)) == hex(ntohs(newchecksum(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) -- Benchmark for different architectures. print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) From d42747c7391325c2605cad75ac4131137395b0c1 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 15:54:43 +0100 Subject: [PATCH 12/35] Convert loops to ifs The snippets of code that deal with the remaining bytes should be ifs and not whiles. For instance, if the remaining bytes to sum are 7, this number is decomposed as 4 + 2 + 1. For all other numbers lower to 8 their decomposition is a sum of different values, thus there won't be iterations. --- src/lib/newchecksum.dasl | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index 1743480da4..136e6ac04c 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -55,7 +55,6 @@ local function gen_checksum () | add rax, r9 -- Sum acc with r9. Accumulate carry. | sub rcx, 4 -- Decrease index by 4. | add r8, 4 -- Next 32-bit. - | jmp <2 -- Go to beginning of loop. | 3: | cmp rcx, 2 -- If index is less than 2. | jl >4 -- Jump to branch '4'. @@ -63,7 +62,6 @@ local function gen_checksum () | add rax, r9 -- Sum acc with r9. Accumulate carry. | sub rcx, 2 -- Decrease index by 2. | add r8, 2 -- Next 16-bit. - | jmp <3 -- Go to beginning of loop. | 4: | cmp rcx, 1 -- If index is less than 1. | jl >5 -- Jump to branch '5'. From 9da791f9e26d23f81bc6c2b15aba6a60ab9387c5 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 19:51:20 +0100 Subject: [PATCH 13/35] Remove unnecessary label --- src/lib/newchecksum.dasl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index 136e6ac04c..24d148d37e 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -83,7 +83,6 @@ local function gen_checksum () | not rax -- One-complement of rax. | and rax, 0xffff -- Clear out higher part of rax. -- Epilogue. - | 6: | mov rsp, rbp | pop rbp -- Return. From f3969f0920844418ca79cddb7b63bed98f5aa515 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 19:47:29 +0100 Subject: [PATCH 14/35] Add at 16 bytes strides --- src/lib/newchecksum.dasl | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index 24d148d37e..a7c785d391 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -40,35 +40,44 @@ local function gen_checksum () | xor r8, r8 -- Clear out r8. Stores array index. | mov rcx, rsi -- Rsi (2nd argument; size). Assign rsi to rcx. | 1: - | cmp rcx, 8 -- If index is less than 8. + | cmp rcx, 16 -- If index is less than 8. | jl >2 -- Jump to branch '2'. | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. + | adc rax, [rdi + r8 + 8] -- Sum carry-bit into acc. | adc rax, 0 -- Sum carry-bit into acc. - | sub rcx, 8 -- Decrease index by 8. - | add r8, 8 -- Next 64-bit. + | sub rcx, 16 -- Decrease index by 8. + | add r8, 16 -- Next 64-bit. | jmp <1 -- Go to beginning of loop. | 2: + | cmp rcx, 8 -- If index is less than 8. + | jl >3 -- Jump to branch '2'. + | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. + | add rax, r9 -- Sum acc with r9. + | adc rax, 0 -- Sum carry-bit into acc. + | sub rcx, 8 -- Decrease index by 8. + | add r8, 8 -- Next 64-bit. + | 3: | cmp rcx, 4 -- If index is less than 4. - | jl >3 -- Jump to branch '3'. + | jl >4 -- Jump to branch '3'. | mov r9d, dword [rdi + r8] -- Fetch 32-bit from data + r8 into r9d. | add rax, r9 -- Sum acc with r9. Accumulate carry. | sub rcx, 4 -- Decrease index by 4. | add r8, 4 -- Next 32-bit. - | 3: + | 4: | cmp rcx, 2 -- If index is less than 2. - | jl >4 -- Jump to branch '4'. + | jl >5 -- Jump to branch '4'. | movzx r9, word [rdi + r8] -- Fetch 16-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. Accumulate carry. | sub rcx, 2 -- Decrease index by 2. | add r8, 2 -- Next 16-bit. - | 4: + | 5: | cmp rcx, 1 -- If index is less than 1. - | jl >5 -- Jump to branch '5'. + | jl >6 -- Jump to branch '5'. | movzx r9, byte [rdi + r8] -- Fetch 8-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. Accumulate carry. -- Fold 64-bit into 16-bit. - | 5: + | 6: | mov r9, rax -- Assign acc to r9. | shr r9, 32 -- Shift r9 32-bit. Stores higher part of acc. | and rax, 0x00000000ffffffff -- Clear out higher-part of rax. Stores lower part of acc. From 52e845790d3758a3cb5846779ce5ccfd358b7afc Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 20:14:41 +0100 Subject: [PATCH 15/35] Fix comments --- src/lib/newchecksum.dasl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index a7c785d391..dd622fc58d 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -40,14 +40,14 @@ local function gen_checksum () | xor r8, r8 -- Clear out r8. Stores array index. | mov rcx, rsi -- Rsi (2nd argument; size). Assign rsi to rcx. | 1: - | cmp rcx, 16 -- If index is less than 8. + | cmp rcx, 16 -- If index is less than 16. | jl >2 -- Jump to branch '2'. | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. - | adc rax, [rdi + r8 + 8] -- Sum carry-bit into acc. + | adc rax, [rdi + r8 + 8] -- Sum with carry next qword. | adc rax, 0 -- Sum carry-bit into acc. - | sub rcx, 16 -- Decrease index by 8. - | add r8, 16 -- Next 64-bit. + | sub rcx, 16 -- Decrease index by 8. + | add r8, 16 -- Jump two qwords. | jmp <1 -- Go to beginning of loop. | 2: | cmp rcx, 8 -- If index is less than 8. From 12fd28cfb6dc817778e97b2da9dfe5596637668a Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 9 Feb 2018 20:27:24 +0100 Subject: [PATCH 16/35] Sum at 32 bytes strides --- src/lib/newchecksum.dasl | 33 ++++++++++++++++++++++----------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index dd622fc58d..504518f71e 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -40,44 +40,55 @@ local function gen_checksum () | xor r8, r8 -- Clear out r8. Stores array index. | mov rcx, rsi -- Rsi (2nd argument; size). Assign rsi to rcx. | 1: - | cmp rcx, 16 -- If index is less than 16. + | cmp rcx, 32 -- If index is less than 16. | jl >2 -- Jump to branch '2'. | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. + | add rax, r9 -- Sum acc with qword[0]. + | adc rax, [rdi + r8 + 8] -- Sum with carry qword[1]. + | adc rax, [rdi + r8 + 16] -- Sum with carry qword[2]. + | adc rax, [rdi + r8 + 24] -- Sum with carry qword[3] + | adc rax, 0 -- Sum carry-bit into acc. + | sub rcx, 32 -- Decrease index by 8. + | add r8, 32 -- Jump two qwords. + | jmp <1 -- Go to beginning of loop. + | 2: + | cmp rcx, 16 -- If index is less than 16. + | jl >3 -- Jump to branch '2'. + | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. | adc rax, [rdi + r8 + 8] -- Sum with carry next qword. | adc rax, 0 -- Sum carry-bit into acc. | sub rcx, 16 -- Decrease index by 8. | add r8, 16 -- Jump two qwords. - | jmp <1 -- Go to beginning of loop. - | 2: + | 3: | cmp rcx, 8 -- If index is less than 8. - | jl >3 -- Jump to branch '2'. + | jl >4 -- Jump to branch '2'. | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. | adc rax, 0 -- Sum carry-bit into acc. | sub rcx, 8 -- Decrease index by 8. | add r8, 8 -- Next 64-bit. - | 3: + | 4: | cmp rcx, 4 -- If index is less than 4. - | jl >4 -- Jump to branch '3'. + | jl >5 -- Jump to branch '3'. | mov r9d, dword [rdi + r8] -- Fetch 32-bit from data + r8 into r9d. | add rax, r9 -- Sum acc with r9. Accumulate carry. | sub rcx, 4 -- Decrease index by 4. | add r8, 4 -- Next 32-bit. - | 4: + | 5: | cmp rcx, 2 -- If index is less than 2. - | jl >5 -- Jump to branch '4'. + | jl >6 -- Jump to branch '4'. | movzx r9, word [rdi + r8] -- Fetch 16-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. Accumulate carry. | sub rcx, 2 -- Decrease index by 2. | add r8, 2 -- Next 16-bit. - | 5: + | 6: | cmp rcx, 1 -- If index is less than 1. - | jl >6 -- Jump to branch '5'. + | jl >7 -- Jump to branch '5'. | movzx r9, byte [rdi + r8] -- Fetch 8-bit from data + r8 into r9. | add rax, r9 -- Sum acc with r9. Accumulate carry. -- Fold 64-bit into 16-bit. - | 6: + | 7: | mov r9, rax -- Assign acc to r9. | shr r9, 32 -- Shift r9 32-bit. Stores higher part of acc. | and rax, 0x00000000ffffffff -- Clear out higher-part of rax. Stores lower part of acc. From 1ed8aa5192b53ac96637f926ec5879835f4e2809 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Sun, 11 Feb 2018 10:48:12 +0100 Subject: [PATCH 17/35] Remove unnecessary assignment to register --- src/lib/newchecksum.dasl | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index 504518f71e..19ff4c78c7 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -42,8 +42,7 @@ local function gen_checksum () | 1: | cmp rcx, 32 -- If index is less than 16. | jl >2 -- Jump to branch '2'. - | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. - | add rax, r9 -- Sum acc with qword[0]. + | add rax, [rdi + r8] -- Sum acc with qword[0]. | adc rax, [rdi + r8 + 8] -- Sum with carry qword[1]. | adc rax, [rdi + r8 + 16] -- Sum with carry qword[2]. | adc rax, [rdi + r8 + 24] -- Sum with carry qword[3] @@ -54,17 +53,15 @@ local function gen_checksum () | 2: | cmp rcx, 16 -- If index is less than 16. | jl >3 -- Jump to branch '2'. - | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. - | add rax, r9 -- Sum acc with r9. - | adc rax, [rdi + r8 + 8] -- Sum with carry next qword. + | add rax, [rdi + r8] -- Sum acc with qword[0]. + | adc rax, [rdi + r8 + 8] -- Sum with carry qword[1]. | adc rax, 0 -- Sum carry-bit into acc. | sub rcx, 16 -- Decrease index by 8. | add r8, 16 -- Jump two qwords. | 3: | cmp rcx, 8 -- If index is less than 8. | jl >4 -- Jump to branch '2'. - | mov r9, [rdi + r8] -- Fetch 64-bit from data + r8 into r9. - | add rax, r9 -- Sum acc with r9. + | add rax, [rdi + r8] -- Sum acc with qword[0]. | adc rax, 0 -- Sum carry-bit into acc. | sub rcx, 8 -- Decrease index by 8. | add r8, 8 -- Next 64-bit. From a7bac04983f9317c9948f2e2e600c5d5604764fb Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Wed, 25 Apr 2018 17:13:00 +0200 Subject: [PATCH 18/35] Print out nanseconds by byte and per csum --- src/lib/newchecksum.dasl | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index 19ff4c78c7..62b4d1e933 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -146,12 +146,15 @@ function selftest () end local function benchmark (fn, times) local now = os.clock() - local temp + local csum for i=1,times do - temp = fn() + csum, pkt = fn() end - local ret = {os.clock() - now, temp} - return ret[1] + local elapse = os.clock() - now + local ns_per_csum = elapse * 10e9 / times + local ns_per_byte = ns_per_csum / pkt.length + local ret = {elapse = elapse, ns_per_csum = ns_per_csum, ns_per_byte = ns_per_byte, csum = csum} + return ("elapse: %.6f; ns_per_csum: %.2f; ns_per_byte: %.2f"):format(ret.elapse, ret.ns_per_csum, ret.ns_per_byte) end local function hex (num) return ("0x%.2x"):format(num) @@ -167,10 +170,10 @@ function selftest () assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0) end, times)) - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length) end, times)) + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) size = 550 print("2M; "..size.." bytes") @@ -180,10 +183,10 @@ function selftest () assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0) end, times)) - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length) end, times)) + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) size = 1500 print("1M; "..size.." bytes") @@ -193,8 +196,8 @@ function selftest () assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0) end, times)) - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0) end, times)) - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0) end, times)) - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length) end, times)) + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) end From ca059dda316868d1bc5d3a463398bb071bb355d8 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Wed, 15 Aug 2018 06:24:31 +0000 Subject: [PATCH 19/35] Check AVX2 and SSE2 are available --- src/lib/newchecksum.dasl | 70 ++++++++++++++++------------------------ 1 file changed, 28 insertions(+), 42 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index 62b4d1e933..bb84c377c9 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -134,6 +134,10 @@ end function selftest () require("lib.checksum_h") + local cpuinfo = lib.readfile("/proc/cpuinfo", "*a") + assert(cpuinfo, "failed to read /proc/cpuinfo for hardware check") + local have_avx2 = cpuinfo:match("avx2") + local have_sse2 = cpuinfo:match("sse2") local function create_packet (size) local pkt = { data = ffi.new("uint8_t[?]", size), @@ -156,48 +160,30 @@ function selftest () local ret = {elapse = elapse, ns_per_csum = ns_per_csum, ns_per_byte = ns_per_byte, csum = csum} return ("elapse: %.6f; ns_per_csum: %.2f; ns_per_byte: %.2f"):format(ret.elapse, ret.ns_per_csum, ret.ns_per_byte) end - local function hex (num) - return ("0x%.2x"):format(num) + local function benchmark_report (size, mpps) + local function hex (num) + return ("0x%.2x"):format(num) + end + local ntohs = lib.ntohs + local times = mpps*10^6 + local pkt = create_packet(size) + -- Verify checksum is correct. + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) + print(mpps.."M; "..size.." bytes") + -- Benchmark for different architectures. + print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) + if have_sse2 then + print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) + end + if have_avx2 then + print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) + end + print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) end - local ntohs = lib.ntohs - print("selftest: newchecksum") - local size = 44 - print("14.4M; "..size.." bytes") - local pkt = create_packet(size) - local times = 14.4*10^6 - -- Verify checksum is correct. - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) - -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) - - size = 550 - print("2M; "..size.." bytes") - local pkt = create_packet(size) - local times = 2*10^6 - -- Verify checksum is correct. - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) - -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) - - size = 1500 - print("1M; "..size.." bytes") - local pkt = create_packet(size) - local times = 1*10^6 - -- Verify checksum is correct. - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) - -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) + print("selftest: newchecksum") + benchmark_report(44, 14.4) + benchmark_report(550, 2) + benchmark_report(1500, 1) end From f38ec15ccd33c415c9c8afc8c4f30e6c7d29e87b Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Wed, 15 Aug 2018 06:47:01 +0000 Subject: [PATCH 20/35] Add function for verifying correctness of new checksum computation --- src/lib/newchecksum.dasl | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/src/lib/newchecksum.dasl b/src/lib/newchecksum.dasl index bb84c377c9..4651bc56c1 100644 --- a/src/lib/newchecksum.dasl +++ b/src/lib/newchecksum.dasl @@ -161,15 +161,8 @@ function selftest () return ("elapse: %.6f; ns_per_csum: %.2f; ns_per_byte: %.2f"):format(ret.elapse, ret.ns_per_csum, ret.ns_per_byte) end local function benchmark_report (size, mpps) - local function hex (num) - return ("0x%.2x"):format(num) - end - local ntohs = lib.ntohs local times = mpps*10^6 local pkt = create_packet(size) - -- Verify checksum is correct. - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) print(mpps.."M; "..size.." bytes") -- Benchmark for different architectures. print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) @@ -181,8 +174,20 @@ function selftest () end print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) end + local function verify_correctness () + local function hex (num) + return ("0x%.2x"):format(num) + end + local ntohs = lib.ntohs + for size=44,1500 do + local pkt = create_packet(size) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) + end + end print("selftest: newchecksum") + verify_correctness() benchmark_report(44, 14.4) benchmark_report(550, 2) benchmark_report(1500, 1) From 7d5eeab4df6163b1b0cd76002dbf86ed79423937 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 16 Aug 2018 12:18:23 +0200 Subject: [PATCH 21/35] Remove AVX2 and SSE2 checksum computations --- src/Makefile | 14 ++------ src/arch/avx2.c | 84 ------------------------------------------- src/arch/sse2.c | 94 ------------------------------------------------- 3 files changed, 2 insertions(+), 190 deletions(-) delete mode 100644 src/arch/avx2.c delete mode 100644 src/arch/sse2.c diff --git a/src/Makefile b/src/Makefile index b738c223f8..422cecc5b9 100644 --- a/src/Makefile +++ b/src/Makefile @@ -13,12 +13,11 @@ OBJDIR = $(patsubst %,obj/%,$(SRCDIR)) LUASRC = $(shell find . -regex '[^\#]*\.lua' -printf '%P ') PFLUASRC = $(shell cd ../lib/pflua/src && \ find . -regex '[^\#]*\.lua' -printf '%P ') -CSRC = $(shell find . -regex '[^\#]*\.c' -not -regex './arch/.*' -printf '%P ') +CSRC = $(shell find . -regex '[^\#]*\.c' -printf '%P ') CHDR = $(shell find . -regex '[^\#]*\.h' -printf '%P ') ASM = $(shell find . -regex '[^\#]*\.dasl' -printf '%P ') PFLUAASM = $(shell cd ../lib/pflua/src && \ find . -regex '[^\#]*\.dasl' -printf '%P ') -ARCHSRC= $(shell find . -regex '^./arch/[^\#]*\.c' -printf '%P ') RMSRC = $(shell find . -name '*.md' -not -regex './obj.*' -printf '%P ') # regexp is to include program/foo but not program/foo/bar PROGRAM = $(shell find program -regex '^[^/]+/[^/]+' -type d -printf '%P ') @@ -30,7 +29,6 @@ LUAOBJ := $(patsubst %.lua,obj/%_lua.o,$(LUASRC)) PFLUAOBJ := $(patsubst %.lua,obj/%_lua.o,$(PFLUASRC)) COBJ := $(patsubst %.c,obj/%_c.o, $(CSRC)) HOBJ := $(patsubst %.h,obj/%_h.o, $(CHDR)) -ARCHOBJ:= $(patsubst %.c,obj/%_c.o, $(ARCHSRC)) ASMOBJ := $(patsubst %.dasl,obj/%_dasl.o, $(ASM)) PFLUAASMOBJ := $(patsubst %.dasl,obj/%_dasl.o, $(PFLUAASM)) JITOBJS:= $(patsubst %,obj/jit_%.o,$(JITSRC)) @@ -56,7 +54,7 @@ TESTSCRIPTS = $(shell find . -name "selftest.*" -executable | xargs) PATH := ../lib/luajit/usr/local/bin:$(PATH) -snabb: $(LUAOBJ) $(PFLUAOBJ) $(HOBJ) $(COBJ) $(ARCHOBJ) $(ASMOBJ) $(PFLUAASMOBJ) $(INCOBJ) $(YANGOBJ) $(LUAJIT_A) +snabb: $(LUAOBJ) $(PFLUAOBJ) $(HOBJ) $(COBJ) $(ASMOBJ) $(PFLUAASMOBJ) $(INCOBJ) $(YANGOBJ) $(LUAJIT_A) $(E) "GEN obj/version.lua.gen" $(Q) ../generate-version-lua.sh > obj/version.lua.gen $(E) "LUA obj/version.lua" @@ -137,14 +135,6 @@ $(COBJ): obj/%_c.o: %.c $(CHDR) Makefile | $(OBJDIR) $(E) "C $@" $(Q) $(CC) $(DEBUG) -O3 -Wl,-E -I ../lib/luajit/src -I . -include $(CURDIR)/../gcc-preinclude.h -c -Wall -Werror -o $@ $< -obj/arch/avx2_c.o: arch/avx2.c Makefile - $(E) "C(AVX2) $@" - $(Q) $(CC) -O2 -mavx2 $(DEBUG) -Wl,-E -I ../lib/luajit/src -I . -include $(CURDIR)/../gcc-preinclude.h -c -Wall -Werror -o $@ $< - -obj/arch/sse2_c.o: arch/sse2.c Makefile - $(E) "C(SSE2) $@" - $(Q) $(CC) -O2 -msse2 $(DEBUG) -Wl,-E -I ../lib/luajit/src -I . -include $(CURDIR)/../gcc-preinclude.h -c -Wall -Werror -o $@ $< - $(HOBJ): obj/%_h.o: %.h Makefile | $(OBJDIR) $(E) "H $@" @(echo -n "module(...,package.seeall); require(\"ffi\").cdef[=============["; \ diff --git a/src/arch/avx2.c b/src/arch/avx2.c deleted file mode 100644 index fce7e78a0e..0000000000 --- a/src/arch/avx2.c +++ /dev/null @@ -1,84 +0,0 @@ -/* Use of this source code is governed by the Apache 2.0 license; see COPYING. - * Based on original SSE2 code by Tony Rogvall that is - * copyright 2011 Teclo Networks AG. MIT licensed by Juho Snellman. */ - -/* IP checksum routine for AVX2. */ - -#include -#include -#include -#include "lib/checksum.h" -#include "lib/checksum_lib.h" - -static inline uint32_t cksum_avx2_loop(unsigned char *p, size_t n) -{ - __m256i sum0, sum1, zero; - uint32_t s[8] __attribute__((aligned(32))); // aligned for avx2 store - uint32_t sum2; - - zero = _mm256_set_epi64x(0,0,0,0); - sum0 = zero; - sum1 = zero; - - while(n) { - size_t k = (n >= 0xff) ? 0xff : n; - __m256i t0,t1; - __m256i s0 = zero; - __m256i s1 = zero; - n -= k; - while (k) { - __m256i src = _mm256_loadu_si256((__m256i const*) p); - __m256i t; - - t = _mm256_unpacklo_epi8(src, zero); - s0 = _mm256_adds_epu16(s0, t); - t = _mm256_unpackhi_epi8(src, zero); - s1 = _mm256_adds_epu16(s1, t); - p += sizeof(src); - k--; - } - - // LOW - combine S0 and S1 into sum0 - t0 = _mm256_unpacklo_epi16(s0, zero); - sum0 = _mm256_add_epi32(sum0, t0); - t1 = _mm256_unpacklo_epi16(s1, zero); - sum1 = _mm256_add_epi32(sum1, t1); - - // HIGH - combine S0 and S1 into sum1 - t0 = _mm256_unpackhi_epi16(s0, zero); - sum0 = _mm256_add_epi32(sum0, t0); - t1 = _mm256_unpackhi_epi16(s1, zero); - sum1 = _mm256_add_epi32(sum1, t1); - } - // here we must sum the 4-32 bit sums into one 32 bit sum - _mm256_store_si256((__m256i*)s, sum0); - sum2 = (s[0]<<8) + s[1] + (s[2]<<8) + s[3] + (s[4]<<8) + s[5] + (s[6]<<8) + s[7]; - _mm256_store_si256((__m256i*)s, sum1); - sum2 += (s[0]<<8) + s[1] + (s[2]<<8) + s[3] + (s[4]<<8) + s[5] + (s[6]<<8) + s[7]; - - return sum2; -} - -uint16_t cksum_avx2(unsigned char *p, size_t n, uint16_t initial) -{ - uint32_t sum = initial; - - if (n < 128) { return cksum_generic(p, n, initial); } - if (n >= 64) { - size_t k = (n >> 5); - sum += cksum_avx2_loop(p, k); - n -= (32*k); - p += (32*k); - } - if (n > 1) { - size_t k = (n>>1); // number of 16-bit words - sum += cksum_ua_loop(p, k); - n -= (2*k); - p += (2*k); - } - if (n) // take care of left over byte - sum += (p[0] << 8); - while(sum>>16) - sum = (sum & 0xFFFF) + (sum>>16); - return (uint16_t)~sum; -} diff --git a/src/arch/sse2.c b/src/arch/sse2.c deleted file mode 100644 index f98878e871..0000000000 --- a/src/arch/sse2.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Use of this source code is governed by the Apache 2.0 license; see COPYING. - * Original code by Tony Rogvall that is - * copyright 2011 Teclo Networks AG. MIT licensed by Juho Snellman. */ - -/* IP checksum routine for SSE2. */ - -#include -#include -#include -#include "lib/checksum.h" -#include "lib/checksum_lib.h" - -// -// this loop may only run when data is aligned 16 byte aligned -// n is number of 16 byte vectors -// -static inline uint32_t cksum_sse2_loop(unsigned char *p, size_t n) -{ - __m128i sum0, sum1, zero; - uint32_t s[4]; - uint32_t sum2; - - zero = _mm_set_epi32(0,0,0,0); - sum0 = zero; - sum1 = zero; - - while(n) { - size_t k = (n >= 0xff) ? 0xff : n; - __m128i t0,t1; - __m128i s0 = zero; - __m128i s1 = zero; - n -= k; - while (k) { - __m128i src = _mm_load_si128((__m128i const*) p); - __m128i t; - - t = _mm_unpacklo_epi8(src, zero); - s0 = _mm_adds_epu16(s0, t); - t = _mm_unpackhi_epi8(src, zero); - s1 = _mm_adds_epu16(s1, t); - p += sizeof(src); - k--; - } - - // LOW - combine S0 and S1 into sum0 - t0 = _mm_unpacklo_epi16(s0, zero); - sum0 = _mm_add_epi32(sum0, t0); - t1 = _mm_unpacklo_epi16(s1, zero); - sum1 = _mm_add_epi32(sum1, t1); - - // HIGH - combine S0 and S1 into sum1 - t0 = _mm_unpackhi_epi16(s0, zero); - sum0 = _mm_add_epi32(sum0, t0); - t1 = _mm_unpackhi_epi16(s1, zero); - sum1 = _mm_add_epi32(sum1, t1); - } - // here we must sum the 4-32 bit sums into one 32 bit sum - _mm_store_si128((__m128i*)s, sum0); - sum2 = (s[0]<<8) + s[1] + (s[2]<<8) + s[3]; - _mm_store_si128((__m128i*)s, sum1); - sum2 += (s[0]<<8) + s[1] + (s[2]<<8) + s[3]; - return sum2; -} - -uint16_t cksum_sse2(unsigned char *p, size_t n, uint16_t initial) -{ - uint32_t sum = initial; - - if (n < 128) { return cksum_generic(p, n, initial); } - int unaligned = (unsigned long) p & 0xf; - if (unaligned) { - size_t k = (0x10 - unaligned) >> 1; - sum += cksum_ua_loop(p, k); - n -= (2*k); - p += (2*k); - } - if (n >= 32) { // fast even with only two vectors - size_t k = (n >> 4); - sum += cksum_sse2_loop(p, k); - n -= (16*k); - p += (16*k); - } - if (n > 1) { - size_t k = (n>>1); // number of 16-bit words - sum += cksum_ua_loop(p, k); - n -= (2*k); - p += (2*k); - } - if (n) // take care of left over byte - sum += (p[0] << 8); - while(sum>>16) - sum = (sum & 0xFFFF) + (sum>>16); - return (uint16_t)~sum; -} From 24ee9fbac064b77dac0d5fe977aff72439c9610d Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 16 Aug 2018 13:58:17 +0200 Subject: [PATCH 22/35] Use new checksum function by default The change required to support third argument 'initial', return value as host-byte order value and adapt some selftests. --- .../newchecksum.dasl => arch/checksum.dasl} | 31 +++++++------------ src/lib/checksum.lua | 27 ++-------------- 2 files changed, 15 insertions(+), 43 deletions(-) rename src/{lib/newchecksum.dasl => arch/checksum.dasl} (84%) diff --git a/src/lib/newchecksum.dasl b/src/arch/checksum.dasl similarity index 84% rename from src/lib/newchecksum.dasl rename to src/arch/checksum.dasl index 4651bc56c1..d247edf2ee 100644 --- a/src/lib/newchecksum.dasl +++ b/src/arch/checksum.dasl @@ -35,10 +35,11 @@ local function gen_checksum () | push rbp | mov rbp, rsp -- Accumulative sum. - | xor rax, rax -- Clear out rax. Stores accumulated sum. + | mov rax, rdx -- Dx (3rd argument: initial). + | xchg al, ah -- Swap to convert to host-bytes order. + | mov rcx, rsi -- Rsi (2nd argument; size). | xor r9, r9 -- Clear out r9. Stores value of array. | xor r8, r8 -- Clear out r8. Stores array index. - | mov rcx, rsi -- Rsi (2nd argument; size). Assign rsi to rcx. | 1: | cmp rcx, 32 -- If index is less than 16. | jl >2 -- Jump to branch '2'. @@ -99,6 +100,8 @@ local function gen_checksum () -- One's complement. | not rax -- One-complement of rax. | and rax, 0xffff -- Clear out higher part of rax. + -- Swap. + | xchg al, ah -- Epilogue. | mov rsp, rbp | pop rbp @@ -107,8 +110,6 @@ local function gen_checksum () end end -local newchecksum = assemble("newchecksum", "uint32_t(*)(uint8_t*, uint32_t)", gen_checksum()) - -- Reference implementation in Lua. local function checksum_lua (data, size) local function r16 (data) @@ -132,12 +133,10 @@ local function checksum_lua (data, size) return bit.band(bit.bnot(csum), 0xffff) end +checksum = assemble("checksum", "uint32_t(*)(uint8_t*, uint32_t, uint16_t)", gen_checksum()) + function selftest () require("lib.checksum_h") - local cpuinfo = lib.readfile("/proc/cpuinfo", "*a") - assert(cpuinfo, "failed to read /proc/cpuinfo for hardware check") - local have_avx2 = cpuinfo:match("avx2") - local have_sse2 = cpuinfo:match("sse2") local function create_packet (size) local pkt = { data = ffi.new("uint8_t[?]", size), @@ -165,14 +164,8 @@ function selftest () local pkt = create_packet(size) print(mpps.."M; "..size.." bytes") -- Benchmark for different architectures. - print("Gen: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) - if have_sse2 then - print("SSE2: ", benchmark(function() return C.cksum_sse2(pkt.data, pkt.length, 0), pkt end, times)) - end - if have_avx2 then - print("AVX2: ", benchmark(function() return C.cksum_avx2(pkt.data, pkt.length, 0), pkt end, times)) - end - print("New: ", benchmark(function() return newchecksum(pkt.data, pkt.length), pkt end, times)) + print("C: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) + print("ASM: ", benchmark(function() return checksum(pkt.data, pkt.length, 0), pkt end, times)) end local function verify_correctness () local function hex (num) @@ -181,12 +174,12 @@ function selftest () local ntohs = lib.ntohs for size=44,1500 do local pkt = create_packet(size) - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) - assert(hex(ntohs(newchecksum(pkt.data, pkt.length))) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) + assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) end end - print("selftest: newchecksum") + print("selftest: checksum") verify_correctness() benchmark_report(44, 14.4) benchmark_report(550, 2) diff --git a/src/lib/checksum.lua b/src/lib/checksum.lua index 05ebc07849..4eb3d801a7 100644 --- a/src/lib/checksum.lua +++ b/src/lib/checksum.lua @@ -10,17 +10,7 @@ local ffi = require("ffi") local C = ffi.C local band, lshift = bit.band, bit.lshift --- Select ipsum(pointer, len, initial) function based on hardware --- capability. -local cpuinfo = lib.readfile("/proc/cpuinfo", "*a") -assert(cpuinfo, "failed to read /proc/cpuinfo for hardware check") -local have_avx2 = cpuinfo:match("avx2") -local have_sse2 = cpuinfo:match("sse2") - -if have_avx2 then ipsum = C.cksum_avx2 -elseif have_sse2 then ipsum = C.cksum_sse2 -else ipsum = C.cksum_generic end - +ipsum = require("arch.checksum").checksum function finish_packet (buf, len, offset) ffi.cast('uint16_t *', buf+offset)[0] = lib.htons(ipsum(buf, len, 0)) @@ -105,24 +95,13 @@ function selftest () local tests = 1000 local n = 1000000 local array = ffi.new("char[?]", n) - for i = 0, n-1 do array[i] = i end - local avx2ok, sse2ok = 0, 0 + for i = 0, n-1 do array[i] = i end for i = 1, tests do local initial = math.random(0, 0xFFFF) - local ref = C.cksum_generic(array+i*2, i*10+i, initial) - if have_avx2 and C.cksum_avx2(array+i*2, i*10+i, initial) == ref then - avx2ok = avx2ok + 1 - end - if have_sse2 and C.cksum_sse2(array+i*2, i*10+i, initial) == ref then - sse2ok = sse2ok + 1 - end + local ref = C.cksum_generic(array+i*2, i*10+i, initial) assert(ipsum(array+i*2, i*10+i, initial) == ref, "API function check") end - if have_avx2 then print("avx2: "..avx2ok.."/"..tests) else print("no avx2") end - if have_sse2 then print("sse2: "..sse2ok.."/"..tests) else print("no sse2") end selftest_ipv4_tcp() - assert(not have_avx2 or avx2ok == tests, "AVX2 test failed") - assert(not have_sse2 or sse2ok == tests, "SSE2 test failed") print("selftest: ok") end From ced75004fa453a08e0b218a1ea6b09bfdad96782 Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Thu, 23 Aug 2018 17:16:27 +0200 Subject: [PATCH 23/35] Add snabbmark checksum subprogram --- src/arch/checksum.dasl | 43 ++++++----------------------- src/program/snabbmark/README | 3 ++ src/program/snabbmark/snabbmark.lua | 40 +++++++++++++++++++++++++++ 3 files changed, 51 insertions(+), 35 deletions(-) diff --git a/src/arch/checksum.dasl b/src/arch/checksum.dasl index d247edf2ee..a188f75658 100644 --- a/src/arch/checksum.dasl +++ b/src/arch/checksum.dasl @@ -136,7 +136,11 @@ end checksum = assemble("checksum", "uint32_t(*)(uint8_t*, uint32_t, uint16_t)", gen_checksum()) function selftest () + print("selftest: checksum") require("lib.checksum_h") + local function hex (num) + return ("0x%.2x"):format(num) + end local function create_packet (size) local pkt = { data = ffi.new("uint8_t[?]", size), @@ -147,41 +151,10 @@ function selftest () end return pkt end - local function benchmark (fn, times) - local now = os.clock() - local csum - for i=1,times do - csum, pkt = fn() - end - local elapse = os.clock() - now - local ns_per_csum = elapse * 10e9 / times - local ns_per_byte = ns_per_csum / pkt.length - local ret = {elapse = elapse, ns_per_csum = ns_per_csum, ns_per_byte = ns_per_byte, csum = csum} - return ("elapse: %.6f; ns_per_csum: %.2f; ns_per_byte: %.2f"):format(ret.elapse, ret.ns_per_csum, ret.ns_per_byte) - end - local function benchmark_report (size, mpps) - local times = mpps*10^6 + local ntohs = lib.ntohs + for size=44,1500 do local pkt = create_packet(size) - print(mpps.."M; "..size.." bytes") - -- Benchmark for different architectures. - print("C: ", benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) - print("ASM: ", benchmark(function() return checksum(pkt.data, pkt.length, 0), pkt end, times)) + assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) + assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) end - local function verify_correctness () - local function hex (num) - return ("0x%.2x"):format(num) - end - local ntohs = lib.ntohs - for size=44,1500 do - local pkt = create_packet(size) - assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(ntohs(checksum_lua(pkt.data, pkt.length)))) - assert(hex(checksum(pkt.data, pkt.length, 0)) == hex(C.cksum_generic(pkt.data, pkt.length, 0))) - end - end - - print("selftest: checksum") - verify_correctness() - benchmark_report(44, 14.4) - benchmark_report(550, 2) - benchmark_report(1500, 1) end diff --git a/src/program/snabbmark/README b/src/program/snabbmark/README index 23e074babf..c85478e1e6 100644 --- a/src/program/snabbmark/README +++ b/src/program/snabbmark/README @@ -50,3 +50,6 @@ Usage: snabbmark ctable Benchmark insertion and lookup for the "ctable" data structure. + + snabbmark checksum + Benchmark checksum computation implementations in C and DynASM. diff --git a/src/program/snabbmark/snabbmark.lua b/src/program/snabbmark/snabbmark.lua index c33d815735..1a9f604203 100644 --- a/src/program/snabbmark/snabbmark.lua +++ b/src/program/snabbmark/snabbmark.lua @@ -27,6 +27,8 @@ function run (args) hash(unpack(args)) elseif command == 'ctable' and #args == 0 then ctable(unpack(args)) + elseif command == 'checksum' and #args == 0 then + checksum_bench(unpack(args)) else print(usage) main.exit(1) @@ -571,3 +573,41 @@ function ctable () stride = stride * 2 until stride > 256 end + +function checksum_bench () + require("lib.checksum_h") + local checksum = require('arch.checksum').checksum + local function create_packet (size) + local pkt = { + data = ffi.new("uint8_t[?]", size), + length = size + } + for i=0,size-1 do + pkt.data[i] = math.random(255) + end + return pkt + end + local function benchmark (fn, times) + local now = os.clock() + local csum + for i=1,times do + csum, pkt = fn() + end + local elapse = os.clock() - now + local ns_per_csum = elapse * 10e9 / times + local ns_per_byte = ns_per_csum / pkt.length + local ret = {elapse = elapse, ns_per_csum = ns_per_csum, ns_per_byte = ns_per_byte, csum = csum} + return ("%.2f ns per checksum; %.2f ns per byte"):format(ret.ns_per_csum, ret.ns_per_byte) + end + local function benchmark_report (size, mpps) + local times = mpps*10^6 + local pkt = create_packet(size) + io.stdout:write("C: ", "Size="..size.." bytes".."; MPPS="..mpps.."M; ") + print(benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) + io.stdout:write("ASM: ", "Size="..size.." bytes".."; MPPS="..mpps.."M; ") + print(benchmark(function() return checksum(pkt.data, pkt.length, 0), pkt end, times)) + end + benchmark_report(44, 14.4) + benchmark_report(550, 2) + benchmark_report(1516, 1) +end From 542a179683c8e2226c02c2a81847feb0a7ab16fb Mon Sep 17 00:00:00 2001 From: Diego Pino Garcia Date: Fri, 24 Aug 2018 10:08:41 +0200 Subject: [PATCH 24/35] Benchmark checksum using PMU utilities --- src/program/snabbmark/snabbmark.lua | 39 ++++++++++++++++++----------- 1 file changed, 25 insertions(+), 14 deletions(-) diff --git a/src/program/snabbmark/snabbmark.lua b/src/program/snabbmark/snabbmark.lua index 1a9f604203..84438c959d 100644 --- a/src/program/snabbmark/snabbmark.lua +++ b/src/program/snabbmark/snabbmark.lua @@ -587,25 +587,36 @@ function checksum_bench () end return pkt end - local function benchmark (fn, times) - local now = os.clock() - local csum - for i=1,times do - csum, pkt = fn() + local function test_perf (f, iterations, what) + require('jit').flush() + io.write(tostring(what or f)..': ') + io.flush() + local cycles, ns, res = measure(f, iterations) + if cycles then + cycles = cycles/iterations + io.write(('%.2f cycles, '):format(cycles)) end - local elapse = os.clock() - now - local ns_per_csum = elapse * 10e9 / times - local ns_per_byte = ns_per_csum / pkt.length - local ret = {elapse = elapse, ns_per_csum = ns_per_csum, ns_per_byte = ns_per_byte, csum = csum} - return ("%.2f ns per checksum; %.2f ns per byte"):format(ret.ns_per_csum, ret.ns_per_byte) + ns = ns/iterations + io.write(('%.2f ns per iteration (result: %s)'):format( + ns, tostring(res))) + return res, ns end local function benchmark_report (size, mpps) local times = mpps*10^6 local pkt = create_packet(size) - io.stdout:write("C: ", "Size="..size.." bytes".."; MPPS="..mpps.."M; ") - print(benchmark(function() return C.cksum_generic(pkt.data, pkt.length, 0), pkt end, times)) - io.stdout:write("ASM: ", "Size="..size.." bytes".."; MPPS="..mpps.."M; ") - print(benchmark(function() return checksum(pkt.data, pkt.length, 0), pkt end, times)) + local header = "Size=%d bytes; MPPS=%d M" + local _, ns = test_perf(function(times) + local ret + for i=1,times do ret = C.cksum_generic(pkt.data, pkt.length, 0) end + return ret + end, times, "C: "..header:format(size, mpps)) + print(('; %.2f ns per byte'):format(ns/size)) + local _, ns = test_perf(function(times) + local ret + for i=1,times do ret = checksum(pkt.data, pkt.length, 0) end + return ret + end, times, "ASM: "..header:format(size, mpps)) + print(('; %.2f ns per byte'):format(ns/size)) end benchmark_report(44, 14.4) benchmark_report(550, 2) From 7b75fbf8a8d2902a103ad4a35b6fed32678c0531 Mon Sep 17 00:00:00 2001 From: Andy Wingo Date: Wed, 5 Sep 2018 12:29:15 +0200 Subject: [PATCH 25/35] Ensure vhost-user socket paths are NUL-terminated Found via GCC 8.2's -Werror=stringop-truncation. NUL termination is required by the AF_UNIX socket API. --- src/apps/vhost/vhost_user.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/apps/vhost/vhost_user.c b/src/apps/vhost/vhost_user.c index 77752f93a5..31c62dde59 100644 --- a/src/apps/vhost/vhost_user.c +++ b/src/apps/vhost/vhost_user.c @@ -33,7 +33,7 @@ int vhost_user_connect(const char *path) } un.sun_family = AF_UNIX; - strncpy(un.sun_path, path, sizeof(un.sun_path)); + strncpy(un.sun_path, path, sizeof(un.sun_path)-1); if (connect(sock, (struct sockaddr *) &un, sizeof(un)) == -1) { close(sock); @@ -54,7 +54,7 @@ int vhost_user_listen(const char *path) } un.sun_family = AF_UNIX; - strncpy(un.sun_path, path, sizeof(un.sun_path)); + strncpy(un.sun_path, path, sizeof(un.sun_path)-1); unlink(un.sun_path); if (bind(sock, (struct sockaddr *) &un, sizeof(un)) == -1) { close(sock); From d06314cbd08184c0bf071abc1d2fa40aa6d00104 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Fri, 14 Dec 2018 14:23:03 +0100 Subject: [PATCH 26/35] lwaftr.ctable_wrapper: add cleanup function to random eviction Add an optional callback which is invoked on an evicted entry to perform cleanup before the entry is purged from the table. --- src/apps/lwaftr/ctable_wrapper.lua | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/apps/lwaftr/ctable_wrapper.lua b/src/apps/lwaftr/ctable_wrapper.lua index 7804f5c473..1957cccbda 100644 --- a/src/apps/lwaftr/ctable_wrapper.lua +++ b/src/apps/lwaftr/ctable_wrapper.lua @@ -13,7 +13,7 @@ local HASH_MAX = 0xFFFFFFFF -- This is only called when the table is 'full'. -- Notably, it cannot be called on an empty table, -- so there is no risk of an infinite loop. -local function evict_random_entry(ctab) +local function evict_random_entry(ctab, cleanup_fn) local random_hash = math.random(0, HASH_MAX - 1) local index = floor(random_hash*ctab.scale + 0.5) local entries = ctab.entries @@ -25,15 +25,17 @@ local function evict_random_entry(ctab) end end local ptr = ctab.entries + index + if cleanup_fn then cleanup_fn(ptr) end ctab:remove_ptr(ptr) end -- Behave exactly like insertion, except if the table is full: if it -- is, then evict a random entry instead of resizing. -local function add_with_random_eviction(self, key, value, updates_allowed) +local function add_with_random_eviction(self, key, value, updates_allowed, + cleanup_fn) local did_evict = false if self.occupancy + 1 > self.occupancy_hi then - evict_random_entry(self) + evict_random_entry(self, cleanup_fn) did_evict = true end return ctable.CTable.add(self, key, value, updates_allowed), did_evict From a44d8e1f37c3ef144e9e648c9abcb5eb4f0570ba Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Fri, 14 Dec 2018 14:43:46 +0100 Subject: [PATCH 27/35] apps.ipv6.fragment: canonicalize pointers, simplify ICMP matching Make sure that packet.append() is called with a pointer of type uint8_t *. The detection of ICMP packets for PMTUD is simplified by only checking for next_header 58 on the fast path. --- src/apps/ipv6/fragment.lua | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/apps/ipv6/fragment.lua b/src/apps/ipv6/fragment.lua index e588118a01..91c33955c3 100644 --- a/src/apps/ipv6/fragment.lua +++ b/src/apps/ipv6/fragment.lua @@ -12,7 +12,6 @@ local counter = require("core.counter") local link = require("core.link") local alarms = require('lib.yang.alarms') local ctable = require('lib.ctable') -local filter = require('lib.pcap.filter') local datagram = require('lib.protocol.datagram') local ethernet = require('lib.protocol.ethernet') local ipv6_hdr = require('lib.protocol.ipv6') @@ -141,8 +140,6 @@ function Fragmenter:new(conf) o.tsc = tsc.new() o.pmtu_timeout_ticks = o.tsc:tps() * o.pmtu_timeout o.pmtu_timer = lib.throttle(o.pmtu_timeout/10) - -- ICMP6 Packet Too Big (Type 2) - o.ptb_filter = filter:new("icmp6 and ip6[40] = 2") o.dgram = datagram:new() packet.free(o.dgram:packet()) @@ -206,7 +203,8 @@ function Fragmenter:fragment_and_transmit(in_next_header, in_pkt_box, mtu) while offset < total_payload_size do local in_pkt = in_pkt_box[0] local out_pkt = packet.allocate() - packet.append(out_pkt, in_pkt.data, ether_ipv6_header_len) + packet.append(out_pkt, ffi.cast("uint8_t *", in_pkt.data), + ether_ipv6_header_len) local out_h = ffi.cast(ether_ipv6_header_ptr_t, out_pkt.data) local fragment_h = ffi.cast(fragment_header_ptr_t, out_h.ipv6.payload) out_pkt.length = out_pkt.length + fragment_header_len @@ -218,7 +216,8 @@ function Fragmenter:fragment_and_transmit(in_next_header, in_pkt_box, mtu) else payload_size = total_payload_size - offset end - packet.append(out_pkt, in_pkt.data + ether_ipv6_header_len + offset, + packet.append(out_pkt, ffi.cast("uint8_t *", in_pkt.data + + ether_ipv6_header_len + offset), payload_size) out_h.ipv6.next_header = fragment_proto @@ -234,11 +233,13 @@ function Fragmenter:fragment_and_transmit(in_next_header, in_pkt_box, mtu) end function Fragmenter:process_ptb (pkt) - counter.add(self.shm["ipv6-pmtud-ptb-received"]) local dgram = self.dgram:new(pkt, ethernet) dgram:parse_n(3) local _, ipv6, icmp = unpack(dgram:stack()) local payload, length = dgram:payload() + if not icmp:type() == 2 then return false end + local ptb = dgram:parse() + counter.add(self.shm["ipv6-pmtud-ptb-received"]) if (#self.pmtu_local_addresses > 0 and not self.pmtu_local_address_table:lookup_ptr(ipv6:dst())) then @@ -247,7 +248,6 @@ function Fragmenter:process_ptb (pkt) end if icmp:checksum_check(payload, length, ipv6) then - local ptb = dgram:parse() local mtu = ptb:mtu() local payload, length = dgram:payload() local orig_hdr = self.ipv6_hdr:new_from_mem(payload, length) @@ -346,7 +346,8 @@ function Fragmenter:push () if self.pmtud then for _ = 1, link.nreadable(south) do local pkt = link.receive(south) - if self.ptb_filter:match(pkt.data, pkt.length) then + local h = ffi.cast(ether_ipv6_header_ptr_t, pkt.data) + if h.ipv6.next_header == 58 then -- ICMP6 if self:process_ptb(pkt) then packet.free(pkt) else From 4e28690822e7a208227203bbdb8de93dd083b84e Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Fri, 14 Dec 2018 14:57:50 +0100 Subject: [PATCH 28/35] apps.ipv6.reassemble: fix packet leak --- src/apps/ipv6/reassemble.lua | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 9aad6025e4..3920f5f632 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -223,6 +223,10 @@ function Reassembler:reassembly_error(entry, icmp_error) end end +local function cleanup_evicted_entry (entry) + packet.free(entry.value.packet) +end + function Reassembler:lookup_reassembly(h, fragment_id) local key = self.scratch_fragment_key key.src_addr, key.dst_addr, key.fragment_id = @@ -241,7 +245,8 @@ function Reassembler:lookup_reassembly(h, fragment_id) reassembly.packet.length = ether_ipv6_header_len local did_evict = false - entry, did_evict = self.ctab:add(key, reassembly, false) + entry, did_evict = self.ctab:add(key, reassembly, false, + cleanup_evicted_entry) if did_evict then self:record_eviction() end return entry end From d7a51c6b4ab8f3f33ac5cabe5fa22e9536c5598c Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Fri, 14 Dec 2018 14:59:43 +0100 Subject: [PATCH 29/35] apps.ipv6.reassemble: avoid spurious sort Respect the precondition for sort_array(). Use bit.band instead of modulo operator to check for multple of 8 of the fragment size. --- src/apps/ipv6/reassemble.lua | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 3920f5f632..1ce4e1a3fa 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -278,8 +278,8 @@ function Reassembler:handle_fragment(pkt) end reassembly.fragment_starts[fcount] = frag_start reassembly.fragment_ends[fcount] = frag_start + frag_size - if reassembly.fragment_starts[fcount] < - reassembly.fragment_starts[fcount - 1] then + if (fcount > 0 and reassembly.fragment_starts[fcount] < + reassembly.fragment_starts[fcount - 1]) then sort_array(reassembly.fragment_starts, fcount) sort_array(reassembly.fragment_ends, fcount) end @@ -291,7 +291,7 @@ function Reassembler:handle_fragment(pkt) else reassembly.final_start = frag_start end - elseif frag_size % 8 ~= 0 then + elseif bit.band(frag_size, 0x7) ~= 0 then -- The size of all non-terminal fragments must be a multiple of 8. -- Here we should send "ICMP Parameter Problem, Code 0 to the -- source of the fragment, pointing to the Payload Length field of From 2e5b5e89bd5046f266b8d99570d558d7bfa74a4e Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Fri, 14 Dec 2018 15:06:38 +0100 Subject: [PATCH 30/35] apps.ipv6.reassemble: copy header from first fragment The headers of all fragments are derived from the unfragmentable part of the original packet, hence the distinction for fragment #0 is not necessary. --- src/apps/ipv6/reassemble.lua | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 1ce4e1a3fa..b2f0fd39ac 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -227,7 +227,8 @@ local function cleanup_evicted_entry (entry) packet.free(entry.value.packet) end -function Reassembler:lookup_reassembly(h, fragment_id) +function Reassembler:lookup_reassembly(h, fragment) + local fragment_id = ntohl(fragment.id) local key = self.scratch_fragment_key key.src_addr, key.dst_addr, key.fragment_id = h.ipv6.src_ip, h.ipv6.dst_ip, fragment_id @@ -241,8 +242,8 @@ function Reassembler:lookup_reassembly(h, fragment_id) reassembly.running_length = ether_ipv6_header_len reassembly.tstamp = self.tsc:stamp() reassembly.packet = packet.allocate() - -- Fragment 0 will fill in the contents of this data. - reassembly.packet.length = ether_ipv6_header_len + packet.append(reassembly.packet, ffi.cast("uint8_t *", h), + ether_ipv6_header_len) local did_evict = false entry, did_evict = self.ctab:add(key, reassembly, false, @@ -257,20 +258,12 @@ function Reassembler:handle_fragment(pkt) -- Note: keep the number of local variables to a minimum when -- calling lookup_reassembly to avoid "register coalescing too -- complex" trace aborts in ctable. - local entry = self:lookup_reassembly(h, ntohl(fragment.id)) + local entry = self:lookup_reassembly(h, fragment) local reassembly = entry.value local fragment_offset_and_flags = ntohs(fragment.fragment_offset_and_flags) local frag_start = bit.band(fragment_offset_and_flags, fragment_offset_mask) local frag_size = ntohs(h.ipv6.payload_length) - fragment_header_len - - -- Header comes from unfragmentable part of packet 0. - if frag_start == 0 then - local header = ffi.cast(ether_ipv6_header_ptr_t, reassembly.packet.data) - ffi.copy(header, h, ether_ipv6_header_len) - header.ipv6.next_header = fragment.next_header - -- Payload length will be overwritten at end. - end local fcount = reassembly.fragment_count if fcount + 1 > self.max_fragments_per_reassembly then -- Too many fragments to reassembly this packet; fail. @@ -326,6 +319,7 @@ function Reassembler:handle_fragment(pkt) do local header = ffi.cast(ether_ipv6_header_ptr_t, reassembly.packet.data) header.ipv6.payload_length = htons(reassembly.packet.length - ether_ipv6_header_len) + header.ipv6.next_header = fragment.next_header end return self:reassembly_success(entry) end From f7a00fff13a0f76d1494123394b1c53a972511a3 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Mon, 17 Dec 2018 17:17:09 +0100 Subject: [PATCH 31/35] apps.ipv6.fragment: fix bug in ICMP type match --- src/apps/ipv6/fragment.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/ipv6/fragment.lua b/src/apps/ipv6/fragment.lua index 91c33955c3..88649d9e21 100644 --- a/src/apps/ipv6/fragment.lua +++ b/src/apps/ipv6/fragment.lua @@ -237,7 +237,7 @@ function Fragmenter:process_ptb (pkt) dgram:parse_n(3) local _, ipv6, icmp = unpack(dgram:stack()) local payload, length = dgram:payload() - if not icmp:type() == 2 then return false end + if icmp:type() ~= 2 then return false end local ptb = dgram:parse() counter.add(self.shm["ipv6-pmtud-ptb-received"]) From 08ff28f03bf7475a7f053e6e527a6dde1a71f0e9 Mon Sep 17 00:00:00 2001 From: Asumu Takikawa Date: Tue, 11 Dec 2018 23:11:33 +0000 Subject: [PATCH 32/35] ljsyscall: ensure size matches mask for get_mempolicy On a call to get_mempolicy, the maxnode argument should match the size of the given nodemask to avoid buffer overruns. This commit ensures the size is ok when ljsyscall generates the nodemask structure. Cherry-picked from: https://github.com/Igalia/snabb/pull/1198 --- lib/ljsyscall/syscall/linux/syscalls.lua | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/lib/ljsyscall/syscall/linux/syscalls.lua b/lib/ljsyscall/syscall/linux/syscalls.lua index dac558db89..fb6da2ea06 100644 --- a/lib/ljsyscall/syscall/linux/syscalls.lua +++ b/lib/ljsyscall/syscall/linux/syscalls.lua @@ -487,9 +487,17 @@ end function S.get_mempolicy(mode, mask, addr, flags) mode = mode or t.int1() - mask = mktype(t.bitmask, mask) - -- Size should be at least equals to maxnumnodes. - local size = ffi.cast("uint64_t", math.max(tonumber(mask.size), get_maxnumnodes())) + local size + if ffi.istype(t.bitmask, mask) then + -- if mask was provided by the caller, then use its size + -- and let the syscall error if it's too small + size = ffi.cast("uint64_t", tonumber(mask.size)) + else + local mask_for_size = t.bitmask(mask) + -- Size should be at least equals to maxnumnodes. + size = ffi.cast("uint64_t", math.max(tonumber(mask_for_size.size), get_maxnumnodes())) + mask = t.bitmask(mask, tonumber(size)) + end local ret, err = C.get_mempolicy(mode, mask.mask, size, addr or 0, c.MPOL_FLAG[flags]) if ret == -1 then return nil, t.error(err or errno()) end return { mode=mode[0], mask=mask } From 57cc28065cb0e14c381b0170d8bfdf1c9a31d6e9 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Wed, 9 Jan 2019 10:09:47 +0100 Subject: [PATCH 33/35] apps.ipv6.reassemble: remove over-eager optimization of module operator The operator specializes to bitops automatically. --- src/apps/ipv6/reassemble.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index b2f0fd39ac..fd6f8c2f90 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -284,7 +284,7 @@ function Reassembler:handle_fragment(pkt) else reassembly.final_start = frag_start end - elseif bit.band(frag_size, 0x7) ~= 0 then + elseif frag_size % 8 ~= 0 then -- The size of all non-terminal fragments must be a multiple of 8. -- Here we should send "ICMP Parameter Problem, Code 0 to the -- source of the fragment, pointing to the Payload Length field of From d054ec01426e082e047cf1d97f07c8093d03c93b Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Wed, 9 Jan 2019 10:11:17 +0100 Subject: [PATCH 34/35] apps.ipv6.reassemble: use max_payload constant in packet size check --- src/apps/ipv6/reassemble.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index fd6f8c2f90..46ed36a208 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -295,7 +295,7 @@ function Reassembler:handle_fragment(pkt) -- Limit the scope of max_data_offset do local max_data_offset = ether_ipv6_header_len + frag_start + frag_size - if max_data_offset > ffi.sizeof(reassembly.packet.data) then + if max_data_offset > packet.max_payload then -- Snabb packets have a maximum size of 10240 bytes. return self:reassembly_error(entry) end From 69473ebd7f98bdcc3fce7225dfa3471b7c5c54e4 Mon Sep 17 00:00:00 2001 From: Alexander Gall Date: Tue, 29 Jan 2019 15:08:00 +0100 Subject: [PATCH 35/35] apps.ipv6.reassemble: fix check for valid packet length Take padding to minimum Ethernet frame size into account. --- src/apps/ipv6/reassemble.lua | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/apps/ipv6/reassemble.lua b/src/apps/ipv6/reassemble.lua index 46ed36a208..03f2388e5a 100644 --- a/src/apps/ipv6/reassemble.lua +++ b/src/apps/ipv6/reassemble.lua @@ -87,7 +87,10 @@ local fragment_header_ptr_t = ffi.typeof('$*', fragment_header_t) -- Precondition: packet already has IPv6 ethertype. local function ipv6_packet_has_valid_length(h, len) if len < ether_ipv6_header_len then return false end - return ntohs(h.ipv6.payload_length) == len - ether_ipv6_header_len + -- The minimum Ethernet frame size is 60 bytes (without FCS). Those + -- frames may contain padding bytes. + local payload_length = ntohs(h.ipv6.payload_length) + return payload_length <= 60 or payload_length == len - ether_ipv6_header_len end local function swap(array, i, j)