Skip to content

Commit

Permalink
replace redis_ippool C based IP iterator with Lua one (improves #1744)
Browse files Browse the repository at this point in the history
We no longer filter skip the 'broadcast' address as some topologies
it can be used and it is trivial to remove after adding.
  • Loading branch information
jimdigriz committed May 31, 2020
1 parent a668c4c commit b8809ba
Show file tree
Hide file tree
Showing 8 changed files with 625 additions and 553 deletions.
45 changes: 32 additions & 13 deletions raddb/mods-config/redis_ippool/add.lua
Original file line number Diff line number Diff line change
@@ -1,29 +1,48 @@
-- Lua script for adding a pool
--
-- - KEYS[1] The pool name.
-- - ARGV[1] IP address of lease.
-- - ARGV[2] range.
-- - ARGV[1] IP address/range of lease(s).
-- - ARGV[2] Prefix to add (0 = auto => 64 for IPv6, 32 for IPv4).
-- - ARGV[3] (optional) Range ID.
--
-- Returns array { <rcode> }
-- - IPPOOL_RCODE_SUCCESS lease updated.
-- Returns array { <rcode>[, <counter> ] }
-- - IPPOOL_RCODE_SUCCESS
-- - IPPOOL_RCODE_FAIL

local ret
local ok
local range
local prefix

local pool_key
local address_key

local counter

ok, range = pcall(iptool.parse, ARGV[1])
if not ok then
return { ippool_rcode_fail }
end
prefix = toprefix(ARGV[1], ARGV[2])
if guard(range, prefix) then
return { ippool_rcode_fail }
end

pool_key = "{" .. KEYS[1] .. "}:" .. ippool_key.pool
ret = redis.call("ZADD", pool_key, "NX", 0, ARGV[1])

address_key = "{" .. KEYS[1] .. "}:" .. ippool_key.address .. ":" .. ARGV[1]
counter = 0
for addr in iptool.iter(range, prefix) do
local ret = redis.call("ZADD", pool_key, "NX", 0, addr)
local address_key = "{" .. KEYS[1] .. "}:" .. ippool_key.address .. ":" .. addr

if ARGV[3] then
ret = redis.call("HSET", address_key, "range", ARGV[3]) or ret
else
ret = redis.call("HDEL", address_key, "range") or ret
end

if ARGV[2] then
ret = redis.call("HSET", address_key, "range", ARGV[2]) or ret
else
redis.call("HDEL", address_key, "range")
counter = counter + ret
end

return {
ippool_rcode.success,
ret
counter
}
7 changes: 4 additions & 3 deletions raddb/mods-config/redis_ippool/alloc.lua
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
--
-- Sticky IPs work by setting the TTL on the device_key to 10x ARGV[1]
--
-- Returns { <rcode>[, <ip>][, <range>][, <lease time>][, <counter>] }
-- Returns { <rcode>[, <ip>, <range>, <lease time> ] }
-- - IPPOOL_RCODE_SUCCESS lease updated.
-- - IPPOOL_RCODE_POOL_EMPTY no available leases in pool.

Expand Down Expand Up @@ -68,10 +68,11 @@ end

redis.call("SET", device_key, ip, "EX", 10 * expires_in)

redis.call("HINCRBY", address_key, "counter", 1)

return {
ippool_rcode.success,
ip,
redis.call("HGET", address_key, "range"),
expires_in,
redis.call("HINCRBY", address_key, "counter", 1)
expires_in
}
55 changes: 36 additions & 19 deletions raddb/mods-config/redis_ippool/delete.lua
Original file line number Diff line number Diff line change
@@ -1,39 +1,56 @@
-- Lua script for deleting a lease
--
-- - KEYS[1] The pool name.
-- - ARGV[1] IP address to delete.
-- - ARGV[1] IP address/range of lease(s).
-- - ARGV[2] Prefix to add (0 = auto => 64 for IPv6, 32 for IPv4).
--
-- Removes the IP entry in the ZSET, then removes the address hash, and the device key
-- if one exists.
--
-- Will work with partially removed IP addresses (where the ZSET entry is absent but other
-- elements were not cleaned up).
--
-- Returns
-- - 0 if no ip addresses were removed.
-- - 1 if an ip address was removed.
-- Returns array { <rcode>[, <counter> ] }
-- - IPPOOL_RCODE_SUCCESS
-- - IPPOOL_RCODE_FAIL

local found
local ret
local ok
local range
local prefix

local address_key
local pool_key
local device_key

local counter

ok, range = pcall(iptool.parse, ARGV[1])
if not ok then
return { ippool_rcode_fail }
end
prefix = toprefix(ARGV[1], ARGV[2])
if guard(range, prefix) then
return { ippool_rcode_fail }
end

pool_key = "{" .. KEYS[1] .. "}:" .. ippool_key.pool

ret = redis.call("ZREM", pool_key, ARGV[1])
counter = 0
for addr in iptool.iter(range, prefix) do
local ret = redis.call("ZREM", pool_key, addr)
local address_key = "{" .. KEYS[1] .. "}:" .. ippool_key.address .. ":" .. addr

address_key = "{" .. KEYS[1] .. "}:" .. ippool_key.address .. ":" .. ARGV[1]
local found = redis.call("HGET", address_key, "device")
if found then
local device_key = "{" .. KEYS[1] .. "}:" .. ippool_key.device .. ":" .. found

found = redis.call("HGET", address_key, "device")
if not found then
return ret
end
redis.call("DEL", address_key)
ret = redis.call("DEL", address_key) or ret
-- Remove the association between the device and a lease
ret = redis.call("DEL", device_key) or ret
end

-- Remove the association between the device and a lease
device_key = "{" .. KEYS[1] .. "}:" .. ippool_key.device .. ":" .. found
redis.call("DEL", device_key)
counter = counter + ret
end

return 1
return {
ippool_rcode.success,
counter
}
Loading

0 comments on commit b8809ba

Please sign in to comment.