Skip to content

Commit

Permalink
Merge pull request #366 from dpino/ndp-without-timers
Browse files Browse the repository at this point in the history
Do not use timers to implement NS requests and retries
  • Loading branch information
dpino authored Jul 14, 2016
2 parents d2e3eb4 + 9e86b23 commit e4bbac5
Show file tree
Hide file tree
Showing 2 changed files with 27 additions and 50 deletions.
61 changes: 27 additions & 34 deletions src/apps/lwaftr/ipv6_apps.lua
Original file line number Diff line number Diff line change
Expand Up @@ -165,62 +165,55 @@ function Fragmenter:push ()
end
end

local NS_RESOLVE_THRESHOLD = 5 -- Time limit to resolve IPv6 addr to MAC.

-- TODO: handle any NS retry policy code here
function NDP:new(conf)
local o = setmetatable({}, {__index=NDP})
o.conf = conf
-- TODO: verify that the src and dst ipv6 addresses and src mac address
-- have been provided, in pton format.
if not conf.dst_eth then
o.do_ns_request = true
self.ns_pkt = ndp.form_ns(conf.src_eth, conf.src_ipv6, conf.dst_ipv6)
self.ns_interval = 3 -- Send a new NS every three seconds.
self.ns_max_retries = 5 -- Max number of NS retries.
self.ns_retries = 0
end
o.dst_eth = conf.dst_eth -- Intentionally nil if to request by NS
return o
end

function NDP:maybe_send_ns_request (output)
if self.dst_eth then return end
if self.ns_retries == self.ns_max_retries then
error(("Could not resolve IPv6 address: %s"):format(
ipv6:ntop(self.conf.dst_ipv6)))
end
self.next_ns_time = self.next_ns_time or engine.now()
if self.next_ns_time <= engine.now() then
self:send_ns(output)
self.next_ns_time = engine.now() + self.ns_interval
self.ns_retries = self.ns_retries + 1
end
end

function NDP:send_ns (output)
transmit(output, packet.clone(self.ns_pkt))
end

function NDP:push()
local isouth, osouth = self.input.south, self.output.south
local inorth, onorth = self.input.north, self.output.north
if self.do_ns_request then
self.do_ns_request = false
local ns_pkt = ndp.form_ns(self.conf.src_eth, self.conf.src_ipv6,
self.conf.dst_ipv6)
-- Send a NS packet inmediately.
transmit(osouth, packet.clone(ns_pkt))

-- Send a new NS packet after every second.
timer.activate(timer.new("retry_ns",
function ()
transmit(osouth, packet.clone(ns_pkt))
end,
1e9,
"repeating"))

-- Abort execution if NS_RESOLVE_THRESHOLD expires.
local function abort()
error(("Could not resolve IPv6 address: %s"):format(
ipv6:ntop(self.conf.dst_ipv6)))
main.exit(1)
end
timer.activate(timer.new("retry_ns_threshold",
abort,
NS_RESOLVE_THRESHOLD * 1e9))

-- TODO: do unsolicited neighbor advertisement on start and on
-- configuration reloads?
-- This would be an optimization, not a correctness issue
end
-- TODO: do unsolicited neighbor advertisement on start and on
-- configuration reloads?
-- This would be an optimization, not a correctness issue
self:maybe_send_ns_request(osouth)

for _=1,link.nreadable(isouth) do
local p = receive(isouth)
if ndp.is_ndp(p) then
if not self.dst_eth and ndp.is_solicited_neighbor_advertisement(p) then
local dst_ethernet = ndp.get_dst_ethernet(p, {self.conf.dst_ipv6})
if dst_ethernet then
self.dst_eth = dst_ethernet
timer.deactivate("retry_ns_threshold")
timer.deactivate("retry_ns")
end
packet.free(p)
elseif ndp.is_neighbor_solicitation_for_addr(p, self.conf.src_ipv6) then
Expand Down
16 changes: 0 additions & 16 deletions src/core/timer.lua
Original file line number Diff line number Diff line change
Expand Up @@ -75,17 +75,6 @@ local function is_timer (t)
return type(t) == "table" and (t.name and t.fn and t.ticks)
end

function deactivate (timer_or_name)
local name = timer_or_name
if is_timer(timer_or_name) then
name = timer_or_name.name
end
assert(type(name) == "string", "Incorrect value. Timer name expected")
local tick, pos = find_timer(name)
if not tick then return end
table.remove(timers[tick], pos)
end

function new (name, fn, nanos, mode)
return { name = name,
fn = fn,
Expand All @@ -96,11 +85,6 @@ end
function selftest ()
print("selftest: timer")

-- Test deactivate.
local t = new("timer", function() end, 1e6)
activate(t)
deactivate(t)

ticks = 0
local ntimers, runtime = 10000, 100000
local count, expected_count = 0, 0
Expand Down

0 comments on commit e4bbac5

Please sign in to comment.