Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Got rid of packet.clone_to_memory #406

Merged
merged 2 commits into from
Aug 30, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
45 changes: 27 additions & 18 deletions src/apps/lwaftr/fragmentv4_hardened.lua
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@ local function reassembly_status(reassembly_buf)
if reassembly_buf.final_start == 0 then
return FRAGMENT_MISSING
end
if reassembly_buf.running_length ~= reassembly_buf.reassembly_packet.length then
if reassembly_buf.running_length ~= reassembly_buf.reassembly_length then
return FRAGMENT_MISSING
end
if not verify_valid_offsets(reassembly_buf) then
Expand All @@ -149,9 +149,15 @@ local function fix_pkt_checksum(pkt)
htons(ipsum(pkt.data + ehs, ihl, 0)))
end

local function pseudo_clone(data, len)
local p = packet.allocate()
p.headroom = 0
packet.append(p, data, len)
return p
end

local function attempt_reassembly(frags_table, reassembly_buf, fragment)
local ihl = get_ihl_from_offset(fragment, ehs)
local reassembly_pkt = reassembly_buf.reassembly_packet
local frag_id = get_frag_id(fragment)
if frag_id ~= reassembly_buf.fragment_id then -- unreachable
error("Impossible case reached in v4 reassembly") --REASSEMBLY_INVALID
Expand Down Expand Up @@ -187,25 +193,29 @@ local function attempt_reassembly(frags_table, reassembly_buf, fragment)
-- Specifically, it requires this file to know the details of struct packet.
local skip_headers = reassembly_buf.reassembly_base
local dst_offset = skip_headers + frag_start
local last_ok = packet_payload_size - reassembly_pkt.headroom
local last_ok = packet_payload_size
if dst_offset + frag_size > last_ok then
-- Prevent a buffer overflow. The relevant RFC allows hosts to silently discard
-- reassemblies above a certain rather small size, smaller than this.
return REASSEMBLY_INVALID
end
ffi.copy(reassembly_pkt.data + dst_offset,
local reassembly_data = reassembly_buf.reassembly_data
ffi.copy(reassembly_data + dst_offset,
fragment.data + skip_headers,
frag_size)
local max_data_offset = skip_headers + frag_start + frag_size
reassembly_pkt.length = math.max(reassembly_pkt.length, max_data_offset)
reassembly_buf.reassembly_length = math.max(reassembly_buf.reassembly_length,
max_data_offset)
reassembly_buf.running_length = reassembly_buf.running_length + frag_size

local restatus = reassembly_status(reassembly_buf)
if restatus == REASSEMBLY_OK then
local pkt_len = htons(reassembly_buf.reassembly_length - ehs)
local o_len = ehs + o_ipv4_total_length
wr16(reassembly_pkt.data + o_len, htons(reassembly_pkt.length - ehs))
fix_pkt_checksum(reassembly_pkt)
local reassembled_packet = packet.clone(reassembly_buf.reassembly_packet)
wr16(reassembly_data + o_len, pkt_len)
local reassembled_packet = pseudo_clone(reassembly_buf.reassembly_data,
reassembly_buf.reassembly_length)
fix_pkt_checksum(reassembled_packet)
free_reassembly_buf_and_pkt(fragment, frags_table)
return REASSEMBLY_OK, reassembled_packet
else
Expand All @@ -221,13 +231,11 @@ local function packet_to_reassembly_buffer(pkt)
reassembly_buf.fragment_id = get_frag_id(pkt)
reassembly_buf.reassembly_base = ehs + ihl

local tmplen = pkt.length
pkt.length = ehs + ihl
local repkt = reassembly_buf.reassembly_packet
packet.clone_to_memory(repkt, pkt)
wr32(repkt.data + ehs + o_ipv4_identification, 0) -- Clear fragmentation data
reassembly_buf.running_length = pkt.length
pkt.length = tmplen
local headers_len = ehs + ihl
local re_data = reassembly_buf.reassembly_data
ffi.copy(re_data, pkt.data, headers_len)
wr32(re_data + ehs + o_ipv4_identification, 0) -- Clear fragmentation data
reassembly_buf.running_length = headers_len
return reassembly_buf
end

Expand Down Expand Up @@ -256,10 +264,11 @@ function initialize_frag_table(max_fragmented_packets, max_pkt_frag)
uint16_t final_start;
uint16_t reassembly_base;
uint16_t fragment_id;
uint32_t running_length;
struct packet reassembly_packet;
uint32_t running_length; // bytes copied so far
uint16_t reassembly_length; // analog to packet.length
uint8_t reassembly_data[$];
} __attribute((packed))]],
max_frags_per_packet, max_frags_per_packet)
max_frags_per_packet, max_frags_per_packet, packet.max_payload)
scratch_rbuf = ipv4_reassembly_buffer_t()

local max_occupy = 0.9
Expand Down
41 changes: 24 additions & 17 deletions src/apps/lwaftr/fragmentv6_hardened.lua
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ local function reassembly_status(reassembly_buf)
if reassembly_buf.final_start == 0 then
return FRAGMENT_MISSING
end
if reassembly_buf.running_length ~= reassembly_buf.reassembly_packet.length then
if reassembly_buf.running_length ~= reassembly_buf.reassembly_length then
return FRAGMENT_MISSING
end
if not verify_valid_offsets(reassembly_buf) then
Expand All @@ -145,8 +145,14 @@ local function reassembly_status(reassembly_buf)
return REASSEMBLY_OK
end

local function pseudo_clone(data, len)
local p = packet.allocate()
p.headroom = 0
packet.append(p, data, len)
return p
end

local function attempt_reassembly(frags_table, reassembly_buf, fragment)
local reassembly_pkt = reassembly_buf.reassembly_packet
local frag_id = get_frag_id(fragment)
if frag_id ~= reassembly_buf.fragment_id then -- unreachable
error("Impossible case reached in v6 reassembly") --REASSEMBLY_INVALID
Expand Down Expand Up @@ -182,22 +188,24 @@ local function attempt_reassembly(frags_table, reassembly_buf, fragment)
-- Specifically, it requires this file to know the details of struct packet.
local skip_headers = reassembly_buf.reassembly_base
local dst_offset = skip_headers + frag_start
local last_ok = packet_payload_size - reassembly_pkt.headroom
local last_ok = packet_payload_size
if dst_offset + frag_size > last_ok then
-- Prevent a buffer overflow. The relevant RFC allows hosts to silently discard
-- reassemblies above a certain rather small size, smaller than this.
return REASSEMBLY_INVALID
end
ffi.copy(reassembly_pkt.data + dst_offset,
ffi.copy(reassembly_buf.reassembly_data + dst_offset,
fragment.data + skip_headers + ipv6_frag_header_size,
frag_size)
local max_data_offset = skip_headers + frag_start + frag_size
reassembly_pkt.length = math.max(reassembly_pkt.length, max_data_offset)
reassembly_buf.reassembly_length = math.max(reassembly_buf.reassembly_length,
max_data_offset)
reassembly_buf.running_length = reassembly_buf.running_length + frag_size

local restatus = reassembly_status(reassembly_buf)
if restatus == REASSEMBLY_OK then
local reassembled_packet = packet.clone(reassembly_buf.reassembly_packet)
local reassembled_packet = pseudo_clone(reassembly_buf.reassembly_data,
reassembly_buf.reassembly_length)
free_reassembly_buf_and_pkt(fragment, frags_table)
return REASSEMBLY_OK, reassembled_packet
else
Expand All @@ -212,17 +220,15 @@ local function packet_to_reassembly_buffer(pkt)
reassembly_buf.fragment_id = get_frag_id(pkt)
reassembly_buf.reassembly_base = ehs + ipv6_fixed_header_size

local tmplen = pkt.length
pkt.length = ehs + ipv6_fixed_header_size
local repkt = reassembly_buf.reassembly_packet
packet.clone_to_memory(repkt, pkt)
reassembly_buf.running_length = pkt.length
local reassembly_data = reassembly_buf.reassembly_data
local headers_len = ehs + ipv6_fixed_header_size
ffi.copy(reassembly_data, pkt.data, headers_len)
reassembly_buf.running_length = headers_len

pkt.length = tmplen
--Take the next header information from the fragment
local next_header_base_offset = ehs + o_ipv6_next_header
local next_header_frag_offset = ehs + ipv6_fixed_header_size -- +0
repkt.data[next_header_base_offset] = pkt.data[next_header_frag_offset]
reassembly_data[next_header_base_offset] = pkt.data[next_header_frag_offset]

return reassembly_buf
end
Expand All @@ -239,7 +245,7 @@ local function hash_ipv6(key)
return hash
end

function initialize_frag_table(max_fragmented_packets, max_pkt_frag, memuse_counter)
function initialize_frag_table(max_fragmented_packets, max_pkt_frag)
-- Initialize module-scoped variables
max_frags_per_packet = max_pkt_frag
ipv6_reassembly_buffer_t = ffi.typeof([[
Expand All @@ -250,10 +256,11 @@ function initialize_frag_table(max_fragmented_packets, max_pkt_frag, memuse_coun
uint16_t final_start;
uint16_t reassembly_base;
uint32_t fragment_id;
uint32_t running_length;
struct packet reassembly_packet;
uint32_t running_length; // bytes copied so far
uint16_t reassembly_length; // analog to packet.length
uint8_t reassembly_data[$];
} __attribute((packed))]],
max_frags_per_packet, max_frags_per_packet)
max_frags_per_packet, max_frags_per_packet, packet.max_payload)
scratch_rbuf = ipv6_reassembly_buffer_t()

local max_occupy = 0.9
Expand Down
16 changes: 5 additions & 11 deletions src/core/packet.lua
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,19 @@ function new_packet ()
return p
end

-- Clone srcp into pre-allocated memory for dstp, in a way compatible
-- with the current definition of struct packet.
function clone_to_memory(dstp, srcp)
dstp.length = srcp.length
dstp.headroom = srcp.headroom
dstp.data = dstp.data_ + dstp.headroom
ffi.copy(dstp.data, srcp.data, srcp.length)
end

-- Create an exact copy of a packet.
function clone (p)
local p2 = allocate()
clone_to_memory(p2, p)
p2.length = p.length
p2.headroom = p.headroom
p2.data = p2.data_ + p2.headroom
ffi.copy(p2.data, p.data, p.length)
return p2
end

-- Append data to the end of a packet.
function append (p, ptr, len)
assert(p.length + len <= max_payload, "packet payload overflow")
assert(p.length + len + p.headroom <= max_payload, "packet payload overflow")
ffi.copy(p.data + p.length, ptr, len)
p.length = p.length + len
return p
Expand Down
4 changes: 2 additions & 2 deletions src/program/lwaftr/tests/data/counters/arp-for-next-hop.lua
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
return {
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv4-bytes"] = 42,
["out-ipv4-frag-not"] = 1,
["out-ipv4-packets"] = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ return {
["in-ipv4-bytes"] = 1494,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-icmpv4-bytes"] = 590,
["out-icmpv4-packets"] = 1,
["out-ipv4-bytes"] = 590,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,6 @@ return {
["in-ipv4-bytes"] = 1494,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ return {
["in-ipv6-bytes"] = 106,
["in-ipv6-frag-reassembly-unneeded"] = 1,
["in-ipv6-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 106,
["out-ipv6-frag-not"] = 1,
["out-ipv6-packets"] = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,6 @@ return {
["in-ipv6-bytes"] = 138,
["in-ipv6-frag-reassembly-unneeded"] = 1,
["in-ipv6-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ return {
["in-ipv6-bytes"] = 138,
["in-ipv6-frag-reassembly-unneeded"] = 1,
["in-ipv6-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 138,
["out-ipv6-frag-not"] = 1,
["out-ipv6-packets"] = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ return {
["in-ipv6-bytes"] = 74,
["in-ipv6-frag-reassembly-unneeded"] = 1,
["in-ipv6-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 74,
["out-ipv6-frag-not"] = 1,
["out-ipv6-packets"] = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ return {
["in-ipv4-frag-needsreassembly"] = 3,
["in-ipv4-frag-reassembled"] = 1,
["in-ipv4-packets"] = 3,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 1584,
["out-ipv6-frag"] = 2,
["out-ipv6-packets"] = 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,6 @@ return {
["in-ipv4-bytes"] = 66,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@ return {
["in-ipv4-bytes"] = 66,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-icmpv4-bytes"] = 94,
["out-icmpv4-packets"] = 1,
["out-ipv4-bytes"] = 94,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ return {
["in-ipv4-bytes"] = 66,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 106,
["out-ipv6-frag-not"] = 1,
["out-ipv6-packets"] = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ return {
["in-ipv4-frag-needsreassembly"] = 3,
["in-ipv4-frag-reassembled"] = 1,
["in-ipv4-packets"] = 3,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 1500,
["out-ipv6-frag-not"] = 1,
["out-ipv6-packets"] = 1,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ return {
["in-ipv4-bytes"] = 1494,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 1604,
["out-ipv6-frag"] = 2,
["out-ipv6-packets"] = 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ return {
["in-ipv4-bytes"] = 2734,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 2906,
["out-ipv6-frag"] = 3,
["out-ipv6-packets"] = 3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ return {
["in-ipv4-bytes"] = 1474,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 1584,
["out-ipv6-frag"] = 2,
["out-ipv6-packets"] = 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ return {
["in-ipv4-bytes"] = 1474,
["in-ipv4-frag-reassembly-unneeded"] = 1,
["in-ipv4-packets"] = 1,
["memuse-ipv4-frag-reassembly-buffer"] = 464194024,
["memuse-ipv6-frag-reassembly-buffer"] = 465349620,
["memuse-ipv4-frag-reassembly-buffer"] = 463571780,
["memuse-ipv6-frag-reassembly-buffer"] = 464727376,
["out-ipv6-bytes"] = 1514,
["out-ipv6-frag-not"] = 1,
["out-ipv6-packets"] = 1,
Expand Down
Loading