Skip to content

Commit

Permalink
Merge PR #1465 (upstream lwAFTR 2022.01.13) into max-next
Browse files Browse the repository at this point in the history
  • Loading branch information
eugeneia committed Jan 13, 2022
2 parents 660e4c8 + 3f3c40c commit 2d7341e
Show file tree
Hide file tree
Showing 63 changed files with 1,796 additions and 276 deletions.
32 changes: 27 additions & 5 deletions src/apps/ipv4/arp.lua
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,14 @@ end
ARP = {}
ARP.shm = {
["next-hop-macaddr-v4"] = {counter},
["in-arp-request-bytes"] = {counter},
["in-arp-request-packets"] = {counter},
["out-arp-request-bytes"] = {counter},
["out-arp-request-packets"] = {counter},
["in-arp-reply-bytes"] = {counter},
["in-arp-reply-packets"] = {counter},
["out-arp-reply-bytes"] = {counter},
["out-arp-reply-packets"] = {counter},
}
local arp_config_params = {
-- Source MAC address will default to a random address.
Expand Down Expand Up @@ -186,6 +194,8 @@ function ARP:maybe_send_arp_request (output)
end

function ARP:send_arp_request (output)
counter.add(self.shm["out-arp-request-bytes"], self.arp_request_pkt.length)
counter.add(self.shm["out-arp-request-packets"])
transmit(output, packet.clone(self.arp_request_pkt))
end

Expand Down Expand Up @@ -239,11 +249,18 @@ function ARP:push()
h.arp.hlen ~= 6 or h.arp.plen ~= 4) then
-- Ignore invalid packet.
elseif ntohs(h.arp.oper) == arp_oper_request then
counter.add(self.shm["in-arp-request-bytes"], p.length)
counter.add(self.shm["in-arp-request-packets"])
if self.self_ip and ipv4_eq(h.arp.tpa, self.self_ip) then
transmit(osouth, make_arp_reply(self.self_mac, self.self_ip,
h.arp.sha, h.arp.spa))
local reply = make_arp_reply(self.self_mac, self.self_ip,
h.arp.sha, h.arp.spa)
counter.add(self.shm["out-arp-reply-bytes"], reply.length)
counter.add(self.shm["out-arp-reply-packets"])
transmit(osouth, reply)
end
elseif ntohs(h.arp.oper) == arp_oper_reply then
counter.add(self.shm["in-arp-reply-bytes"], p.length)
counter.add(self.shm["in-arp-reply-packets"])
if self.next_ip and ipv4_eq(h.arp.spa, self.next_ip) then
self:arp_resolved(self.next_ip, copy_mac(h.arp.sha), 'remote')
end
Expand Down Expand Up @@ -276,9 +293,14 @@ end
function selftest()
print('selftest: arp')

local arp = ARP:new({ self_ip = ipv4:pton('1.2.3.4'),
next_ip = ipv4:pton('5.6.7.8'),
shared_next_mac_key = "foo" })
local c = config.new()
config.app(c, 'arp', ARP, {
self_ip = ipv4:pton('1.2.3.4'),
next_ip = ipv4:pton('5.6.7.8'),
shared_next_mac_key = "foo"
})
engine.configure(c)
local arp = engine.app_table.arp
arp.input = { south=link.new('south in'), north=link.new('north in') }
arp.output = { south=link.new('south out'), north=link.new('north out') }

Expand Down
15 changes: 14 additions & 1 deletion src/apps/ipv4/echo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,14 @@ local function ipv4_header_length(h)
return bit.band(h.version_and_ihl, ipv4_ihl_mask) * 4
end

ICMPEcho = {}
ICMPEcho = {
shm = {
['in-icmpv4-echo-bytes'] = {counter},
['in-icmpv4-echo-packets'] = {counter},
['out-icmpv4-echo-bytes'] = {counter},
['out-icmpv4-echo-packets'] = {counter},
}
}

function ICMPEcho:new(conf)
local addresses = {}
Expand Down Expand Up @@ -139,6 +146,12 @@ function ICMPEcho:respond_to_echo_request(pkt)
ipsum(out.data + ether_header_len + ipv4_header_len,
out.length - ether_header_len - ipv4_header_len, 0))

-- Update counters
counter.add(self.shm['in-icmpv4-echo-bytes'], pkt.length)
counter.add(self.shm['in-icmpv4-echo-packets'])
counter.add(self.shm['out-icmpv4-echo-bytes'], out.length)
counter.add(self.shm['out-icmpv4-echo-packets'])

link.transmit(self.output.south, out)

return true
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ipv4/fragment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ end
local function ipv4_packet_has_valid_length(h, len)
if len < ffi.sizeof(ether_ipv4_header_t) then return false end
if ipv4_header_length(h.ipv4) < 20 then return false end
return ntohs(h.ipv4.total_length) == len - ether_header_len
return ntohs(h.ipv4.total_length) <= len - ether_header_len
end

Fragmenter = {}
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ipv4/reassemble.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ local function ipv4_packet_has_valid_length(h, len)
if len < ffi.sizeof(ether_ipv4_header_t) then return false end
local ihl = bit.band(h.ipv4.version_and_ihl, ipv4_ihl_mask)
if ihl < 5 then return false end
return ntohs(h.ipv4.total_length) == len - ether_header_len
return ntohs(h.ipv4.total_length) <= len - ether_header_len
end

-- IPv4 requires recalculating an embedded checksum.
Expand Down
15 changes: 14 additions & 1 deletion src/apps/ipv6/echo.lua
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,14 @@ local icmp_header_ptr_t = ffi.typeof('$*', icmp_header_t)

local function ipv6_equals(a, b) return ffi.C.memcmp(a, b, 16) == 0 end

ICMPEcho = {}
ICMPEcho = {
shm = {
['in-icmpv6-echo-bytes'] = {counter},
['in-icmpv6-echo-packets'] = {counter},
['out-icmpv6-echo-bytes'] = {counter},
['out-icmpv6-echo-packets'] = {counter},
}
}

function ICMPEcho:new(conf)
local addresses = {}
Expand Down Expand Up @@ -131,6 +138,12 @@ function ICMPEcho:respond_to_echo_request(pkt)
ffi.sizeof(ipv6_pseudo_header_t),
0))))

-- Update counters
counter.add(self.shm['in-icmpv6-echo-bytes'], pkt.length)
counter.add(self.shm['in-icmpv6-echo-packets'])
counter.add(self.shm['out-icmpv6-echo-bytes'], out.length)
counter.add(self.shm['out-icmpv6-echo-packets'])

link.transmit(self.output.south, out)

return true
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ipv6/fragment.lua
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ 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
return ntohs(h.ipv6.payload_length) <= len - ether_ipv6_header_len
end

Fragmenter = {}
Expand Down
2 changes: 1 addition & 1 deletion src/apps/ipv6/reassemble.lua
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ local function ipv6_packet_has_valid_length(h, 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
return payload_length <= len - ether_ipv6_header_len
end

local function swap(array, i, j)
Expand Down
2 changes: 1 addition & 1 deletion src/apps/lwaftr/binding_table.lua
Original file line number Diff line number Diff line change
Expand Up @@ -279,7 +279,7 @@ function selftest()
local mem = require("lib.stream.mem")
local yang = require('lib.yang.yang')
local data = require('lib.yang.data')
local schema = yang.load_schema_by_name('snabb-softwire-v2')
local schema = yang.load_schema_by_name('snabb-softwire-v3')
local grammar = data.config_grammar_from_schema(schema)
local subgrammar = assert(grammar.members['softwire-config'])
local subgrammar = assert(subgrammar.members['binding-table'])
Expand Down
38 changes: 11 additions & 27 deletions src/apps/lwaftr/lwaftr.lua
Original file line number Diff line number Diff line change
Expand Up @@ -339,22 +339,7 @@ local function drop(pkt)
packet.free(pkt)
end

local function select_instance(conf)
local function table_merge(t1, t2)
local ret = {}
for k,v in pairs(t1) do ret[k] = v end
for k,v in pairs(t2) do ret[k] = v end
return ret
end
local device, id, queue = lwutil.parse_instance(conf)
conf.softwire_config.external_interface = table_merge(
conf.softwire_config.external_interface, queue.external_interface)
conf.softwire_config.internal_interface = table_merge(
conf.softwire_config.internal_interface, queue.internal_interface)
return conf
end

LwAftr = { yang_schema = 'snabb-softwire-v2' }
LwAftr = { yang_schema = 'snabb-softwire-v3' }
-- Fields:
-- - direction: "in", "out", "hairpin", "drop";
-- If "direction" is "drop":
Expand Down Expand Up @@ -407,10 +392,10 @@ LwAftr.shm = {
["in-ipv4-packets"] = {counter},
["in-ipv6-bytes"] = {counter},
["in-ipv6-packets"] = {counter},
["out-icmpv4-bytes"] = {counter},
["out-icmpv4-packets"] = {counter},
["out-icmpv6-bytes"] = {counter},
["out-icmpv6-packets"] = {counter},
["out-icmpv4-error-bytes"] = {counter},
["out-icmpv4-error-packets"] = {counter},
["out-icmpv6-error-bytes"] = {counter},
["out-icmpv6-error-packets"] = {counter},
["out-ipv4-bytes"] = {counter},
["out-ipv4-packets"] = {counter},
["out-ipv6-bytes"] = {counter},
Expand All @@ -420,9 +405,8 @@ LwAftr.shm = {
function LwAftr:new(conf)
if conf.debug then debug = true end
local o = setmetatable({}, {__index=LwAftr})
conf = select_instance(conf).softwire_config
conf = lwutil.merge_instance(conf).softwire_config
o.conf = conf

o.binding_table = bt.load(conf.binding_table)
o.inet_lookup_queue = bt.BTLookupQueue.new(o.binding_table)
o.hairpin_lookup_queue = bt.BTLookupQueue.new(o.binding_table)
Expand Down Expand Up @@ -465,7 +449,7 @@ end

-- The following two methods are called by lib.ptree.worker in reaction
-- to binding table changes, via
-- lib/ptree/support/snabb-softwire-v2.lua.
-- lib/ptree/support/snabb-softwire-v3.lua.
function LwAftr:add_softwire_entry(entry_blob)
self.binding_table:add_softwire_entry(entry_blob)
end
Expand Down Expand Up @@ -508,8 +492,8 @@ function LwAftr:transmit_icmpv6_reply (pkt)
-- Send packet if limit not reached.
if self.icmpv6_error_count < rate_limiting.packets then
self.icmpv6_error_count = self.icmpv6_error_count + 1
counter.add(self.shm["out-icmpv6-bytes"], pkt.length)
counter.add(self.shm["out-icmpv6-packets"])
counter.add(self.shm["out-icmpv6-error-bytes"], pkt.length)
counter.add(self.shm["out-icmpv6-error-packets"])
counter.add(self.shm["out-ipv6-bytes"], pkt.length)
counter.add(self.shm["out-ipv6-packets"])
return transmit(self.o6, pkt)
Expand Down Expand Up @@ -552,8 +536,8 @@ function LwAftr:transmit_icmpv4_reply(pkt, orig_pkt, orig_pkt_link)
-- Send packet if limit not reached.
if self.icmpv4_error_count < rate_limiting.packets then
self.icmpv4_error_count = self.icmpv4_error_count + 1
counter.add(self.shm["out-icmpv4-bytes"], pkt.length)
counter.add(self.shm["out-icmpv4-packets"])
counter.add(self.shm["out-icmpv4-error-bytes"], pkt.length)
counter.add(self.shm["out-icmpv4-error-packets"])
-- Only locally generated error packets are handled here. We transmit
-- them right away, instead of calling transmit_ipv4, because they are
-- never hairpinned and should not be counted by the "out-ipv4" counter.
Expand Down
87 changes: 73 additions & 14 deletions src/apps/lwaftr/lwutil.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ local bit = require("bit")
local ffi = require("ffi")
local lib = require("core.lib")
local cltable = require("lib.cltable")
local binary = require("lib.yang.binary")

local band = bit.band
local cast = ffi.cast
Expand All @@ -21,24 +22,82 @@ local ntohs = lib.ntohs

-- Return device PCI address, queue ID, and queue configuration.
function parse_instance(conf)
local device, instance
for k, v in pairs(conf.softwire_config.instance) do
assert(device == nil, "configuration has more than one instance")
device, instance = k, v
if conf.worker_config then
local device = conf.worker_config.device
local id = conf.worker_config.queue_id
local queue = conf.softwire_config.instance[device].queue[id]
return device, id, queue
else
local device, id
for dev in pairs(conf.softwire_config.instance) do
assert(not device, "Config contains more than one device")
device = dev
end
for queue in pairs(conf.softwire_config.instance[device].queue) do
assert(not id, "Config contains more than one queue")
id = queue
end
return device, id, conf.softwire_config.instance[device].queue[id]
end
assert(device ~= nil, "configuration has no instance")
local id, queue
for k, v in pairs(instance.queue) do
assert(id == nil, "configuration has more than one RSS queue")
id, queue = k, v
end

function is_on_a_stick(conf, device)
local instance = conf.softwire_config.instance[device]
if not instance.external_device then return true end
return device == instance.external_device
end

function is_lowest_queue(conf)
local device, id = parse_instance(conf)
for n in pairs(conf.softwire_config.instance[device].queue) do
if id > n then return false end
end
assert(id ~= nil, "configuration has no RSS queues")
return device, id, queue
return true
end

function is_on_a_stick(device, queue)
if not queue.external_interface.device and device then return true end
return device == queue.external_interface.device
function num_queues(conf)
local n = 0
local device, id = parse_instance(conf)
for _ in pairs(conf.softwire_config.instance[device].queue) do
n = n + 1
end
return n
end

function select_instance(conf)
local copier = binary.config_copier_for_schema_by_name('snabb-softwire-v3')
local device, id = parse_instance(conf)
local copy = copier(conf)()
local instance = copy.softwire_config.instance
for other_device, queues in pairs(conf.softwire_config.instance) do
if other_device ~= device then
instance[other_device] = nil
else
for other_id, _ in pairs(queues.queue) do
if other_id ~= id then
instance[device].queue[other_id] = nil
end
end
end
end
return copy
end

function merge_instance (conf)
local function table_merge(t1, t2)
local ret = {}
for k,v in pairs(t1) do ret[k] = v end
for k,v in pairs(t2) do ret[k] = v end
return ret
end
local copier = binary.config_copier_for_schema_by_name('snabb-softwire-v3')
local copy = copier(conf)()
local _, _, queue = parse_instance(conf)
copy.softwire_config.external_interface = table_merge(
conf.softwire_config.external_interface, queue.external_interface)
copy.softwire_config.internal_interface = table_merge(
conf.softwire_config.internal_interface, queue.internal_interface)
return copy
end

function get_ihl_from_offset(pkt, offset)
Expand Down

0 comments on commit 2d7341e

Please sign in to comment.