The FreeRADIUS server  $Id: 15bac2a4c627c01d1aa2047687b3418955ac7f00 $
Data Structures | Macros | Functions | Variables
rlm_redis_ippool.c File Reference

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

#include <freeradius-devel/server/base.h>
#include <freeradius-devel/server/module_rlm.h>
#include <freeradius-devel/server/modpriv.h>
#include <freeradius-devel/util/debug.h>
#include <freeradius-devel/util/base16.h>
#include <freeradius-devel/util/token.h>
#include <freeradius-devel/redis/base.h>
#include <freeradius-devel/redis/cluster.h>
#include <freeradius-devel/unlang/call_env.h>
#include "redis_ippool.h"
+ Include dependency graph for rlm_redis_ippool.c:

Go to the source code of this file.

Data Structures

struct  redis_ippool_alloc_call_env_t
 Call environment used when calling redis_ippool allocate method. More...
 
struct  redis_ippool_bulk_release_call_env_t
 Call environment used when calling redis_ippool bulk release method. More...
 
struct  redis_ippool_release_call_env_t
 Call environment used when calling redis_ippool release method. More...
 
struct  redis_ippool_update_call_env_t
 Call environment used when calling redis_ippool update method. More...
 
struct  rlm_redis_ippool_t
 rlm_redis module instance More...
 

Macros

#define CHECK_POOL_NAME
 
#define EOL   "\n"
 

Functions

static void ippool_action_print (request_t *request, ippool_action_t action, fr_log_lvl_t lvl, fr_value_box_t const *key_prefix, fr_value_box_t const *ip, fr_value_box_t const *owner, fr_value_box_t const *gateway_id, uint32_t expires)
 
static fr_redis_rcode_t ippool_script (redisReply **out, request_t *request, fr_redis_cluster_t *cluster, uint8_t const *key, size_t key_len, uint32_t wait_num, fr_time_delta_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_t *request, uint32_t wait_num, redisReply *reply)
 Check the requisite number of slaves replicated the lease info. More...
 
static unlang_action_t mod_alloc (rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
 
static unlang_action_t mod_bulk_release (rlm_rcode_t *p_result, UNUSED module_ctx_t const *mctx, request_t *request)
 
static int mod_instantiate (module_inst_ctx_t const *mctx)
 
static int mod_load (void)
 
static unlang_action_t mod_release (rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
 
static unlang_action_t mod_update (rlm_rcode_t *p_result, module_ctx_t const *mctx, request_t *request)
 
static ippool_rcode_t redis_ippool_allocate (rlm_redis_ippool_t const *inst, request_t *request, redis_ippool_alloc_call_env_t *env, uint32_t lease_time)
 Allocate a new IP address from a pool. More...
 
static ippool_rcode_t redis_ippool_release (rlm_redis_ippool_t const *inst, request_t *request, fr_value_box_t const *key_prefix, fr_ipaddr_t *ip, fr_value_box_t const *owner)
 Release an existing IP address in a pool. More...
 
static ippool_rcode_t redis_ippool_update (rlm_redis_ippool_t const *inst, request_t *request, redis_ippool_update_call_env_t *env, fr_ipaddr_t *ip, fr_value_box_t const *owner, fr_value_box_t const *gateway_id, 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_t module_config []
 
static conf_parser_t redis_config []
 
static const call_env_method_t redis_ippool_alloc_method_env
 
static const call_env_method_t redis_ippool_bulk_release_method_env
 
static const call_env_method_t redis_ippool_release_method_env
 
static const call_env_method_t redis_ippool_update_method_env
 
module_rlm_t rlm_redis_ippool
 

Detailed Description

IP Allocation module with a redis backend.

Id
9d1bf3253334ed370d92df4e726a7b7475e74e79
Author
Arran Cudbard-Bell

Performs lease management using a Redis backed.

Creates three types of objects:

Definition in file rlm_redis_ippool.c.


Data Structure Documentation

◆ redis_ippool_alloc_call_env_t

struct redis_ippool_alloc_call_env_t

Call environment used when calling redis_ippool allocate method.

Definition at line 108 of file rlm_redis_ippool.c.

+ Collaboration diagram for redis_ippool_alloc_call_env_t:
Data Fields
tmpl_t * allocated_address_attr Attribute to populate with allocated IP.
tmpl_t * expiry_attr Time at which the lease will expire.
fr_value_box_t gateway_id Gateway identifier, usually NAS-Identifier or Option 82 gateway.

Used for bulk lease cleanups.

fr_value_box_t lease_time How long an IP address should be allocated for.
fr_value_box_t offer_time How long we should reserve a lease for during the pre-allocation stage (typically responding to DHCP discover).
fr_value_box_t owner Unique lease owner identifier.

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

fr_value_box_t pool_name Name of the pool we're allocating IP addresses from.
tmpl_t * range_attr Attribute to write the range ID to.
fr_value_box_t requested_address Attribute to read the IP for renewal from.

◆ redis_ippool_bulk_release_call_env_t

struct redis_ippool_bulk_release_call_env_t

Call environment used when calling redis_ippool bulk release method.

Definition at line 177 of file rlm_redis_ippool.c.

+ Collaboration diagram for redis_ippool_bulk_release_call_env_t:
Data Fields
fr_value_box_t gateway_id Gateway identifier, usually NAS-Identifier or Option 82 gateway.

Used for bulk lease cleanups.

fr_value_box_t pool_name Name of the pool we're allocating IP addresses from.

◆ redis_ippool_release_call_env_t

struct redis_ippool_release_call_env_t

Call environment used when calling redis_ippool release method.

Definition at line 160 of file rlm_redis_ippool.c.

+ Collaboration diagram for redis_ippool_release_call_env_t:
Data Fields
fr_value_box_t gateway_id Gateway identifier, usually NAS-Identifier or Option 82 gateway.

Used for bulk lease cleanups.

fr_value_box_t owner Unique lease owner identifier.

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

fr_value_box_t pool_name Name of the pool we're allocating IP addresses from.
fr_value_box_t requested_address Attribute to read the IP for renewal from.

◆ redis_ippool_update_call_env_t

struct redis_ippool_update_call_env_t

Call environment used when calling redis_ippool update method.

Definition at line 136 of file rlm_redis_ippool.c.

+ Collaboration diagram for redis_ippool_update_call_env_t:
Data Fields
tmpl_t * allocated_address_attr Attribute to populate with allocated IP.
tmpl_t * expiry_attr Time at which the lease will expire.
fr_value_box_t gateway_id Gateway identifier, usually NAS-Identifier or Option 82 gateway.

Used for bulk lease cleanups.

fr_value_box_t lease_time How long an IP address should be allocated for.
fr_value_box_t owner Unique lease owner identifier.

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

fr_value_box_t pool_name Name of the pool we're allocating IP addresses from.
tmpl_t * range_attr Attribute to write the range ID to.
fr_value_box_t requested_address Attribute to read the IP for renewal from.

◆ rlm_redis_ippool_t

struct rlm_redis_ippool_t

rlm_redis module instance

Definition at line 61 of file rlm_redis_ippool.c.

+ Collaboration diagram for rlm_redis_ippool_t:
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 allocated_address_attr if updates are successful.
bool ipv4_integer Whether IPv4 addresses should be cast to integers, for renew operations.
char const * name Instance name.
uint32_t wait_num How many slaves we want to acknowledge allocations or updates.
fr_time_delta_t wait_timeout How long we wait for slaves to acknowledge writing.

Macro Definition Documentation

◆ CHECK_POOL_NAME

#define CHECK_POOL_NAME
Value:
if (env->pool_name.vb_length > IPPOOL_MAX_KEY_PREFIX_SIZE) { \
REDEBUG("Pool name too long. Expected %u bytes, got %ld bytes", \
IPPOOL_MAX_KEY_PREFIX_SIZE, env->pool_name.vb_length); \
RETURN_MODULE_FAIL; \
} \
if (env->pool_name.vb_length == 0) { \
RDEBUG2("Empty pool name. Doing nothing"); \
RETURN_MODULE_NOOP; \
}
#define IPPOOL_MAX_KEY_PREFIX_SIZE
Definition: redis_ippool.h:56

Definition at line 1090 of file rlm_redis_ippool.c.

◆ EOL

#define EOL   "\n"

Definition at line 246 of file rlm_redis_ippool.c.

Function Documentation

◆ ippool_action_print()

static void ippool_action_print ( request_t request,
ippool_action_t  action,
fr_log_lvl_t  lvl,
fr_value_box_t const *  key_prefix,
fr_value_box_t const *  ip,
fr_value_box_t const *  owner,
fr_value_box_t const *  gateway_id,
uint32_t  expires 
)
static

Definition at line 484 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ippool_script()

static fr_redis_rcode_t ippool_script ( redisReply **  out,
request_t request,
fr_redis_cluster_t cluster,
uint8_t const *  key,
size_t  key_len,
uint32_t  wait_num,
fr_time_delta_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 to replicate the data.
[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 559 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ ippool_wait_check()

static int ippool_wait_check ( request_t 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 467 of file rlm_redis_ippool.c.

+ Here is the caller graph for this function:

◆ mod_alloc()

static unlang_action_t mod_alloc ( rlm_rcode_t p_result,
module_ctx_t const *  mctx,
request_t request 
)
static

Definition at line 1101 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

◆ mod_bulk_release()

static unlang_action_t mod_bulk_release ( rlm_rcode_t p_result,
UNUSED module_ctx_t const *  mctx,
request_t request 
)
static

Definition at line 1227 of file rlm_redis_ippool.c.

◆ mod_instantiate()

static int mod_instantiate ( module_inst_ctx_t const *  mctx)
static

Definition at line 1234 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

◆ mod_load()

static int mod_load ( void  )
static

Definition at line 1277 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

◆ mod_release()

static unlang_action_t mod_release ( rlm_rcode_t p_result,
module_ctx_t const *  mctx,
request_t request 
)
static

Definition at line 1193 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

◆ mod_update()

static unlang_action_t mod_update ( rlm_rcode_t p_result,
module_ctx_t const *  mctx,
request_t request 
)
static

Definition at line 1131 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:

◆ redis_ippool_allocate()

static ippool_rcode_t redis_ippool_allocate ( rlm_redis_ippool_t const *  inst,
request_t request,
redis_ippool_alloc_call_env_t env,
uint32_t  lease_time 
)
static

Allocate a new IP address from a pool.

Definition at line 696 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ redis_ippool_release()

static ippool_rcode_t redis_ippool_release ( rlm_redis_ippool_t const *  inst,
request_t request,
fr_value_box_t const *  key_prefix,
fr_ipaddr_t ip,
fr_value_box_t const *  owner 
)
static

Release an existing IP address in a pool.

Definition at line 1015 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ redis_ippool_update()

static ippool_rcode_t redis_ippool_update ( rlm_redis_ippool_t const *  inst,
request_t request,
redis_ippool_update_call_env_t env,
fr_ipaddr_t ip,
fr_value_box_t const *  owner,
fr_value_box_t const *  gateway_id,
uint32_t  expires 
)
static

Update an existing IP address in a pool.

Definition at line 878 of file rlm_redis_ippool.c.

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ lua_alloc_cmd

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] Lease owner 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 260 of file rlm_redis_ippool.c.

◆ lua_alloc_digest

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

Definition at line 331 of file rlm_redis_ippool.c.

◆ lua_release_cmd

char lua_release_cmd[]
static

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 416 of file rlm_redis_ippool.c.

◆ lua_release_digest

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

Definition at line 456 of file rlm_redis_ippool.c.

◆ lua_update_cmd

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] Lease owner 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 348 of file rlm_redis_ippool.c.

◆ lua_update_digest

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

Definition at line 399 of file rlm_redis_ippool.c.

◆ module_config

conf_parser_t module_config[]
static
Initial value:
= {
{ FR_CONF_OFFSET("wait_num", rlm_redis_ippool_t, wait_num) },
{ FR_CONF_OFFSET("wait_timeout", rlm_redis_ippool_t, wait_timeout) },
{ FR_CONF_DEPRECATED("ip_address", rlm_redis_ippool_t, NULL) },
{ FR_CONF_DEPRECATED("reply_attr", rlm_redis_ippool_t, NULL) },
{ FR_CONF_OFFSET("ipv4_integer", rlm_redis_ippool_t, ipv4_integer) },
{ FR_CONF_OFFSET("copy_on_update", rlm_redis_ippool_t, copy_on_update), .dflt = "yes", .quote = T_BARE_WORD },
{ FR_CONF_POINTER("redis", 0, CONF_FLAG_SUBSECTION, NULL), .subcs = redis_config },
}
#define CONF_PARSER_TERMINATOR
Definition: cf_parse.h:626
#define FR_CONF_DEPRECATED(_name, _struct, _field)
conf_parser_t entry which raises an error if a matching CONF_PAIR is found
Definition: cf_parse.h:385
#define FR_CONF_OFFSET(_name, _struct, _field)
conf_parser_t which parses a single CONF_PAIR, writing the result to a field in a struct
Definition: cf_parse.h:268
#define FR_CONF_POINTER(_name, _type, _flags, _res_p)
conf_parser_t which parses a single CONF_PAIR producing a single global result
Definition: cf_parse.h:310
@ CONF_FLAG_SUBSECTION
Instead of putting the information into a configuration structure, the configuration file routines MA...
Definition: cf_parse.h:400
static conf_parser_t redis_config[]
rlm_redis module instance
@ T_BARE_WORD
Definition: token.h:120

Definition at line 86 of file rlm_redis_ippool.c.

◆ redis_config

conf_parser_t redis_config[]
static
Initial value:
= {
}
#define REDIS_COMMON_CONFIG
Definition: base.h:133

Definition at line 81 of file rlm_redis_ippool.c.

◆ redis_ippool_alloc_method_env

const call_env_method_t redis_ippool_alloc_method_env
static
Initial value:
= {
.env = (call_env_parser_t[]){
redis_ippool_alloc_call_env_t, gateway_id ), .pair.dflt = "", .pair.dflt_quote = T_SINGLE_QUOTED_STRING },
.pair.dflt = "%{%{Requested-IP-Address} || %{Net.Src.IP}}", .pair.dflt_quote = T_DOUBLE_QUOTED_STRING },
.pair.dflt = "&reply.IP-Pool.Range", .pair.dflt_quote = T_BARE_WORD },
}
}
#define CALL_ENV_TERMINATOR
Definition: call_env.h:212
#define FR_CALL_ENV_METHOD_OUT(_inst)
Helper macro for populating the size/type fields of a call_env_method_t from the output structure typ...
Definition: call_env.h:216
@ CALL_ENV_FLAG_CONCAT
If the tmpl produced multiple boxes they should be concatenated.
Definition: call_env.h:74
@ CALL_ENV_FLAG_ATTRIBUTE
Tmpl must contain an attribute reference.
Definition: call_env.h:84
@ CALL_ENV_FLAG_NONE
Definition: call_env.h:72
@ CALL_ENV_FLAG_REQUIRED
Associated conf pair or section is required.
Definition: call_env.h:73
@ CALL_ENV_FLAG_NULLABLE
Tmpl expansions are allowed to produce no output.
Definition: call_env.h:78
#define FR_CALL_ENV_OFFSET(_name, _cast_type, _flags, _struct, _field)
Specify a call_env_parser_t which writes out runtime results to the specified field.
Definition: call_env.h:316
#define FR_CALL_ENV_PARSE_ONLY_OFFSET(_name, _cast_type, _flags, _struct, _parse_field)
Specify a call_env_parser_t which writes out the result of the parsing phase to the field specified.
Definition: call_env.h:365
Per method call config.
Definition: call_env.h:171
@ FR_TYPE_STRING
String of printable characters.
Definition: merged_model.c:83
@ FR_TYPE_UINT32
32 Bit unsigned integer.
Definition: merged_model.c:99
@ FR_TYPE_VOID
User data.
Definition: merged_model.c:127
@ FR_TYPE_COMBO_IP_ADDR
IPv4 or IPv6 address depending on length.
Definition: merged_model.c:91
Call environment used when calling redis_ippool allocate method.
@ T_SINGLE_QUOTED_STRING
Definition: token.h:122
@ T_DOUBLE_QUOTED_STRING
Definition: token.h:121

Definition at line 184 of file rlm_redis_ippool.c.

◆ redis_ippool_bulk_release_method_env

const call_env_method_t redis_ippool_bulk_release_method_env
static

◆ redis_ippool_release_method_env

const call_env_method_t redis_ippool_release_method_env
static
Initial value:

Definition at line 223 of file rlm_redis_ippool.c.

◆ redis_ippool_update_method_env

const call_env_method_t redis_ippool_update_method_env
static
Initial value:
= {
.env = (call_env_parser_t[]) {
.pair.dflt = "", .pair.dflt_quote = T_SINGLE_QUOTED_STRING },
.pair.dflt = "%{%{Requested-IP-Address} || %{Net.Src.IP}}", .pair.dflt_quote = T_DOUBLE_QUOTED_STRING },
.pair.dflt = "&reply.IP-Pool.Range", .pair.dflt_quote = T_BARE_WORD },
}
}
Call environment used when calling redis_ippool update method.

Definition at line 205 of file rlm_redis_ippool.c.

◆ rlm_redis_ippool

module_rlm_t rlm_redis_ippool

Definition at line 1285 of file rlm_redis_ippool.c.