All Data Structures Files Functions Variables Typedefs Enumerations Enumerator Macros Groups Pages
Data Structures | Macros | Typedefs | Functions | Variables
rlm_redis_ippool.c File Reference

IP Allocation module with a redis backend. More...

#include <freeradius-devel/radiusd.h>
#include <freeradius-devel/modules.h>
#include <freeradius-devel/modpriv.h>
#include <freeradius-devel/rad_assert.h>
#include "redis.h"
#include "cluster.h"
#include "redis_ippool.h"
+ Include dependency graph for rlm_redis_ippool.c:

Go to the source code of this file.

Data Structures

struct  rlm_redis_ippool
 rlm_redis module instance More...
 

Macros

#define EOL   "\n"
 

Typedefs

typedef struct rlm_redis_ippool rlm_redis_ippool_t
 rlm_redis module instance More...
 

Functions

static void ippool_action_print (REQUEST *request, ippool_action_t action, log_lvl_t lvl, uint8_t const *key_prefix, size_t key_prefix_len, char const *ip_str, uint8_t const *device_id, size_t device_id_len, uint8_t const *gateway_id, size_t gateway_id_len, uint32_t expires)
 
static ssize_t ippool_pool_name (uint8_t out[], size_t outlen, rlm_redis_ippool_t *inst, REQUEST *request)
 Find the pool name we'll be allocating from. More...
 
static fr_redis_rcode_t ippool_script (redisReply **out, REQUEST *request, fr_redis_cluster_t *cluster, uint8_t const *key, size_t key_len, uint32_t wait_num, uint32_t wait_timeout, char const digest[], char const *script, char const *cmd,...)
 Execute a script against Redis cluster. More...
 
static int ippool_wait_check (REQUEST *request, uint32_t wait_num, redisReply *reply)
 Check the requisite number of slaves replicated the lease info. More...
 
static rlm_rcode_t mod_accounting (void *instance, REQUEST *request) CC_HINT(nonnull)
 
static rlm_rcode_t mod_action (rlm_redis_ippool_t *inst, REQUEST *request, ippool_action_t action)
 
static rlm_rcode_t mod_authorize (void *instance, REQUEST *request) CC_HINT(nonnull)
 
static int mod_bootstrap (CONF_SECTION *conf, void *instance)
 
static int mod_instantiate (CONF_SECTION *conf, void *instance)
 
static rlm_rcode_t mod_post_auth (void *instance, REQUEST *request) CC_HINT(nonnull)
 
static ippool_rcode_t redis_ippool_allocate (rlm_redis_ippool_t *inst, REQUEST *request, uint8_t const *key_prefix, size_t key_prefix_len, uint8_t const *device_id, size_t device_id_len, uint8_t const *gateway_id, size_t gateway_id_len, uint32_t expires)
 Allocate a new IP address from a pool. More...
 
static ippool_rcode_t redis_ippool_release (rlm_redis_ippool_t *inst, REQUEST *request, uint8_t const *key_prefix, size_t key_prefix_len, fr_ipaddr_t *ip, uint8_t const *device_id, size_t device_id_len)
 Release an existing IP address in a pool. More...
 
static ippool_rcode_t redis_ippool_update (rlm_redis_ippool_t *inst, REQUEST *request, uint8_t const *key_prefix, size_t key_prefix_len, fr_ipaddr_t *ip, uint8_t const *device_id, size_t device_id_len, uint8_t const *gateway_id, size_t gateway_id_len, uint32_t expires)
 Update an existing IP address in a pool. More...
 

Variables

static char lua_alloc_cmd []
 Lua script for allocating new leases. More...
 
static char lua_alloc_digest [(SHA1_DIGEST_LENGTH *2)+1]
 
static char lua_release_cmd []
 Lua script for releasing leases. More...
 
static char lua_release_digest [(SHA1_DIGEST_LENGTH *2)+1]
 
static char lua_update_cmd []
 Lua script for updating leases. More...
 
static char lua_update_digest [(SHA1_DIGEST_LENGTH *2)+1]
 
static CONF_PARSER module_config []
 
static CONF_PARSER redis_config []
 
module_t rlm_redis_ippool
 

Detailed Description

IP Allocation module with a redis backend.

Id:
501ad5ec61f5c42c5006ec247b1a562178b7a8d2
Author
Arran Cudbard-Bell

Definition in file rlm_redis_ippool.c.


Data Structure Documentation

struct rlm_redis_ippool

rlm_redis module instance

Definition at line 42 of file rlm_redis_ippool.c.

+ Collaboration diagram for rlm_redis_ippool:
Data Fields
fr_redis_cluster_t * cluster Redis cluster.
fr_redis_conf_t conf Connection parameters for the Redis server.

Must be first field in this struct.

bool copy_on_update Copy the address provided by ip_address to the reply_attr if updates are successful.
vp_tmpl_t * device_id Unique device identifier.

Could be mac-address or a combination of User-Name and something unique to the device.

vp_tmpl_t * expiry_attr Time at which the lease will expire.
vp_tmpl_t * gateway_id Gateway identifier, usually NAS-Identifier or the actual Option 82 gateway.

Used for bulk lease cleanups.

vp_tmpl_t * ip_address Attribute to read the IP for renewal from.
bool ipv4_integer Whether IPv4 addresses should be cast to integers, for renew operations.
vp_tmpl_t * lease_time How long an IP address should be allocated for.
char const * name Instance name.
vp_tmpl_t * offer_time How long we should reserve a lease for during the pre-allocation stage (typically responding to DHCP discover).
vp_tmpl_t * pool_name Name of the pool we're allocating IP addresses from.
vp_tmpl_t * range_attr Attribute to write the range ID to.
vp_tmpl_t * reply_attr IP attribute and destination.
uint32_t wait_num How many slaves we want to acknowledge allocations or updates.
struct timeval wait_timeout How long we wait for slaves to acknowledge writing.

Macro Definition Documentation

#define EOL   "\n"

Definition at line 115 of file rlm_redis_ippool.c.

Typedef Documentation

rlm_redis module instance

Function Documentation

static void ippool_action_print ( REQUEST request,
ippool_action_t  action,
log_lvl_t  lvl,
uint8_t const *  key_prefix,
size_t  key_prefix_len,
char const *  ip_str,
uint8_t const *  device_id,
size_t  device_id_len,
uint8_t const *  gateway_id,
size_t  gateway_id_len,
uint32_t  expires 
)
static

Definition at line 358 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static ssize_t ippool_pool_name ( uint8_t  out[],
size_t  outlen,
rlm_redis_ippool_t inst,
REQUEST request 
)
inlinestatic

Find the pool name we'll be allocating from.

Parameters
outWhere to write the pool name.
outlenSize of the output buffer.
instThis instance of the rlm_redis_ippool module.
requestThe current request.
Returns
  • <= 0 on error.
  • > 0 on success (length of data written to out).

Definition at line 338 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static fr_redis_rcode_t ippool_script ( redisReply **  out,
REQUEST request,
fr_redis_cluster_t cluster,
uint8_t const *  key,
size_t  key_len,
uint32_t  wait_num,
uint32_t  wait_timeout,
char const  digest[],
char const *  script,
char const *  cmd,
  ... 
)
static

Execute a script against Redis cluster.

Handles uploading the script to the server if required.

Note
All replies will be freed on error.
Parameters
[out]outWhere to write Redis reply object resulting from the command.
[in]requestThe current request.
[in]clusterconfiguration.
[in]keyto use to determine the cluster node.
[in]key_lenlength of the key.
[in]wait_numIf > 0 wait until this many slaves have replicated the data from the last command.
[in]wait_timeoutHow long to wait for slaves.
[in]digestof script.
[in]scriptto upload.
[in]cmdEVALSHA command to execute.
[in]...Arguments for the eval command.
Returns
status of the command.

Definition at line 434 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static int ippool_wait_check ( REQUEST request,
uint32_t  wait_num,
redisReply *  reply 
)
inlinestatic

Check the requisite number of slaves replicated the lease info.

Parameters
requestThe current request.
wait_numNumber of slaves required.
replywe got from the server.
Returns
  • 0 if enough slaves replicated the data.
  • -1 if too few slaves replicated the data, or another error.

Definition at line 311 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static rlm_rcode_t mod_accounting ( void *  instance,
REQUEST request 
)
static

Definition at line 1197 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

static rlm_rcode_t mod_action ( rlm_redis_ippool_t inst,
REQUEST request,
ippool_action_t  action 
)
static

Definition at line 995 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static rlm_rcode_t mod_authorize ( void *  instance,
REQUEST request 
)
static

Definition at line 1235 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

static int mod_bootstrap ( CONF_SECTION conf,
void *  instance 
)
static

Definition at line 1262 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

static int mod_instantiate ( CONF_SECTION conf,
void *  instance 
)
static

Definition at line 1275 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

static rlm_rcode_t mod_post_auth ( void *  instance,
REQUEST request 
)
static

Definition at line 1249 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

static ippool_rcode_t redis_ippool_allocate ( rlm_redis_ippool_t inst,
REQUEST request,
uint8_t const *  key_prefix,
size_t  key_prefix_len,
uint8_t const *  device_id,
size_t  device_id_len,
uint8_t const *  gateway_id,
size_t  gateway_id_len,
uint32_t  expires 
)
static

Allocate a new IP address from a pool.

Definition at line 560 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static ippool_rcode_t redis_ippool_release ( rlm_redis_ippool_t inst,
REQUEST request,
uint8_t const *  key_prefix,
size_t  key_prefix_len,
fr_ipaddr_t ip,
uint8_t const *  device_id,
size_t  device_id_len 
)
static

Release an existing IP address in a pool.

Definition at line 915 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

static ippool_rcode_t redis_ippool_update ( rlm_redis_ippool_t inst,
REQUEST request,
uint8_t const *  key_prefix,
size_t  key_prefix_len,
fr_ipaddr_t ip,
uint8_t const *  device_id,
size_t  device_id_len,
uint8_t const *  gateway_id,
size_t  gateway_id_len,
uint32_t  expires 
)
static

Update an existing IP address in a pool.

Definition at line 770 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

+ Here is the caller graph for this function:

Variable Documentation

char lua_alloc_cmd[]
static

Lua script for allocating new leases.

  • KEYS[1] The pool name.
  • ARGV[1] Wall time (seconds since epoch).
  • ARGV[2] Expires in (seconds).
  • ARGV[3] Device identifier (administratively configured).
  • ARGV[4] (optional) Gateway identifier.

Returns

{ <rcode>[, <ip>][, <range>][, <lease time>][, <counter>] } 
  • IPPOOL_RCODE_SUCCESS lease updated..
  • IPPOOL_RCODE_NOT_FOUND lease not found in pool.

Definition at line 129 of file rlm_redis_ippool.c.

char lua_alloc_digest[(SHA1_DIGEST_LENGTH *2)+1]
static

Definition at line 184 of file rlm_redis_ippool.c.

char lua_release_cmd[]
static
Initial value:
=
"local ret" EOL
"local found" EOL
"local pool_key" EOL
"local address_key" EOL
"local device_key" EOL
"address_key = '{' .. KEYS[1] .. '}:"IPPOOL_ADDRESS_KEY":' .. ARGV[2]" EOL
"found = redis.call('HGET', address_key, 'device')" EOL
"if not found then" EOL
"end" EOL
"if found and found ~= ARGV[3] then" EOL
" return { " STRINGIFY(_IPPOOL_RCODE_DEVICE_MISMATCH) ", found[2] }" EOL
"end" EOL
"pool_key = '{' .. KEYS[1] .. '}:"IPPOOL_POOL_KEY"'" EOL
"redis.call('ZADD', pool_key, 'XX', ARGV[1] - 1, ARGV[2])" EOL
"device_key = '{' .. KEYS[1] .. '}:"IPPOOL_DEVICE_KEY":' .. ARGV[3]" EOL
"redis.call('DEL', device_key)" EOL
"return { " EOL
" redis.call('HINCRBY', address_key, 'counter', 1) - 1" EOL
"}"
#define IPPOOL_POOL_KEY
Definition: redis_ippool.h:60
#define EOL
#define _IPPOOL_RCODE_DEVICE_MISMATCH
Definition: redis_ippool.h:39
#define _IPPOOL_RCODE_NOT_FOUND
Definition: redis_ippool.h:37
#define _IPPOOL_RCODE_SUCCESS
Definition: redis_ippool.h:36
#define STRINGIFY(x)
Definition: build.h:34
#define IPPOOL_DEVICE_KEY
Definition: redis_ippool.h:62
#define IPPOOL_ADDRESS_KEY
Definition: redis_ippool.h:61

Lua script for releasing leases.

  • KEYS[1] The pool name.
  • ARGV[1] Wall time (seconds since epoch).
  • ARGV[2] IP address to release.
  • ARGV[3] Client identifier.

Sets the expiry time to be NOW() - 1 to maximise time between IP address allocations.

Returns

array { <rcode>[, <counter>] } 
  • IPPOOL_RCODE_SUCCESS lease updated..
  • IPPOOL_RCODE_NOT_FOUND lease not found in pool.
  • IPPOOL_RCODE_DEVICE_MISMATCH lease was allocated to a different client..

Definition at line 264 of file rlm_redis_ippool.c.

char lua_release_digest[(SHA1_DIGEST_LENGTH *2)+1]
static

Definition at line 300 of file rlm_redis_ippool.c.

char lua_update_cmd[]
static

Lua script for updating leases.

  • KEYS[1] The pool name.
  • ARGV[1] Wall time (seconds since epoch).
  • ARGV[2] Expires in (seconds).
  • ARGV[3] IP address to update.
  • ARGV[4] Device identifier.
  • ARGV[5] (optional) Gateway identifier.

Returns

array { <rcode>[, <range>] } 
  • IPPOOL_RCODE_SUCCESS lease updated..
  • IPPOOL_RCODE_NOT_FOUND lease not found in pool.
  • IPPOOL_RCODE_EXPIRED lease has already expired.
  • IPPOOL_RCODE_DEVICE_MISMATCH lease was allocated to a different client.

Definition at line 201 of file rlm_redis_ippool.c.

char lua_update_digest[(SHA1_DIGEST_LENGTH *2)+1]
static

Definition at line 247 of file rlm_redis_ippool.c.

CONF_PARSER module_config[]
static
Initial value:
= {
{ FR_CONF_OFFSET("gateway", PW_TYPE_TMPL, rlm_redis_ippool_t, gateway_id) },
{ FR_CONF_OFFSET("offer_time", PW_TYPE_TMPL, rlm_redis_ippool_t, offer_time) },
{ FR_CONF_OFFSET("wait_num", PW_TYPE_INTEGER, rlm_redis_ippool_t, wait_num) },
{ FR_CONF_OFFSET("wait_timeout", PW_TYPE_TIMEVAL, rlm_redis_ippool_t, wait_timeout) },
{ FR_CONF_OFFSET("ip_address", PW_TYPE_TMPL | PW_TYPE_REQUIRED, rlm_redis_ippool_t, ip_address), .dflt = "%{%{DHCP-Requested-IP-Address}:-%{DHCP-Client-IP-Address}}", .quote = T_DOUBLE_QUOTED_STRING },
{ FR_CONF_OFFSET("reply_attr", PW_TYPE_TMPL | PW_TYPE_ATTRIBUTE | PW_TYPE_REQUIRED, rlm_redis_ippool_t, reply_attr), .dflt = "&reply:DHCP-Your-IP-Address", .quote = T_BARE_WORD },
{ FR_CONF_OFFSET("range_attr", PW_TYPE_TMPL | PW_TYPE_ATTRIBUTE | PW_TYPE_REQUIRED, rlm_redis_ippool_t, range_attr), .dflt = "&reply:Pool-Range", .quote = T_BARE_WORD },
{ FR_CONF_OFFSET("expiry_attr", PW_TYPE_TMPL | PW_TYPE_ATTRIBUTE, rlm_redis_ippool_t, expiry_attr) },
{ FR_CONF_OFFSET("ipv4_integer", PW_TYPE_BOOLEAN, rlm_redis_ippool_t, ipv4_integer) },
{ FR_CONF_OFFSET("copy_on_update", PW_TYPE_BOOLEAN, rlm_redis_ippool_t, copy_on_update), .dflt = "yes", .quote = T_BARE_WORD },
{ FR_CONF_POINTER("redis", PW_TYPE_SUBSECTION, NULL), .dflt = redis_config },
}
Time value (struct timeval), only for config items.
Definition: radius.h:55
static CONF_PARSER redis_config[]
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
#define PW_TYPE_SUBSECTION
Definition: conffile.h:188
rlm_redis module instance
A truth value.
Definition: radius.h:56
32 Bit unsigned integer.
Definition: radius.h:34
#define FR_CONF_OFFSET(_n, _t, _s, _f)
Definition: conffile.h:168
#define PW_TYPE_REQUIRED
Error out if no matching CONF_PAIR is found, and no dflt value is set.
Definition: conffile.h:200
#define PW_TYPE_ATTRIBUTE
Value must resolve to attribute in dict (deprecated, use PW_TYPE_TMPL).
Definition: conffile.h:201
#define FR_CONF_POINTER(_n, _t, _p)
Definition: conffile.h:172
#define PW_TYPE_TMPL
CONF_PAIR should be parsed as a template.
Definition: conffile.h:208

Definition at line 87 of file rlm_redis_ippool.c.

CONF_PARSER redis_config[]
static
Initial value:
= {
}
#define CONF_PARSER_TERMINATOR
Definition: conffile.h:289
#define REDIS_COMMON_CONFIG
Definition: redis.h:106

Definition at line 82 of file rlm_redis_ippool.c.

Initial value:
= {
.magic = RLM_MODULE_INIT,
.name = "redis",
.inst_size = sizeof(rlm_redis_ippool_t),
.config = module_config,
.bootstrap = mod_bootstrap,
.instantiate = mod_instantiate,
.methods = {
},
}
static rlm_rcode_t mod_authorize(void *instance, REQUEST *request) CC_HINT(nonnull)
7 methods index for postauth section.
Definition: modules.h:48
#define RLM_TYPE_THREAD_SAFE
Module is threadsafe.
Definition: modules.h:75
#define RLM_MODULE_INIT
Definition: modules.h:86
static int mod_instantiate(CONF_SECTION *conf, void *instance)
static rlm_rcode_t mod_post_auth(void *instance, REQUEST *request) CC_HINT(nonnull)
struct rlm_redis_ippool rlm_redis_ippool_t
rlm_redis module instance
static int mod_bootstrap(CONF_SECTION *conf, void *instance)
3 methods index for accounting section.
Definition: modules.h:44
static CONF_PARSER module_config[]
static rlm_rcode_t mod_accounting(void *instance, REQUEST *request) CC_HINT(nonnull)
1 methods index for authorize section.
Definition: modules.h:42

Definition at line 1326 of file rlm_redis_ippool.c.