48#include <freeradius-devel/server/virtual_servers.h>
49#include <freeradius-devel/server/pair.h>
50#include <freeradius-devel/server/process_types.h>
55# define PROCESS_TRACE RDEBUG3("Entered state %s", __FUNCTION__)
64# error PROCESS_INST must be defined to the C type of the process instance e.g. process_bfd_t
68# define PROCESS_RCTX process_rctx_t
71#if defined(PROCESS_RCTX) && defined(PROCESS_RCTX_EXTRA_FIELDS)
72# error Only one of PROCESS_RCTX (the type of the rctx struct) OR PROCESS_RCTX_EXTRA_FIELDS (extra fields for the common rctx struct) can be defined.
75#ifndef PROCESS_RCTX_RESULT
76# define PROCESS_RCTX_RESULT result
79#define PROCESS_CONF_OFFSET(_x) offsetof(PROCESS_INST, sections._x)
80#define RESULT_UNUSED UNUSED
82#if defined(PROCESS_INST) && defined(PROCESS_PACKET_TYPE) && defined(PROCESS_PACKET_CODE_VALID)
85#ifndef PROCESS_STATE_EXTRA_FIELDS
86# define PROCESS_STATE_EXTRA_FIELDS
89#ifndef PROCESS_RCTX_EXTRA_FIELDS
90# define PROCESS_RCTX_EXTRA_FIELDS
98 size_t section_offset;
118 PROCESS_RCTX_EXTRA_FIELDS
130DIAG_OFF(tentative-definition-compat)
137#ifndef PROCESS_SEND_RECV
138#define process_state_packet process_state
139#define process_state_reply process_state
149#define UPDATE_STATE_CS(_x) \
151 state = &process_state_ ## _x[request->_x->code]; \
152 memcpy(&cs, (CONF_SECTION * const *) (((uint8_t const *) &inst->sections) + state->section_offset), sizeof(cs)); \
155#define UPDATE_STATE(_x) state = &process_state_ ## _x [request->_x->code]
157#define RECV(_x) static inline unlang_action_t recv_ ## _x(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
158#define SEND(_x) static inline unlang_action_t send_ ## _x(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
159#define SEND_NO_RESULT(_x) static inline unlang_action_t send_ ## _x(UNUSED unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
160#define RESUME(_x) static inline unlang_action_t resume_ ## _x(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
161#define RESUME_FLAG(_x, _p_result_flag, _mctx_flag) static inline unlang_action_t resume_ ## _x(_p_result_flag unlang_result_t *p_result, _mctx_flag module_ctx_t const *mctx, request_t *request)
172#define RESULT_RCODE (((PROCESS_RCTX *)mctx->rctx)->result.rcode)
173#define RESULT_P process_result_reset(&(((PROCESS_RCTX *)mctx->rctx)->result), state)
186static inline CC_HINT(always_inline)
191 our_mctx.
rctx = rctx;
193 return method(p_result, &our_mctx, request);
198#define CALL_RECV(_x) recv_ ## _x(p_result, mctx, request)
202#define CALL_RECV_RCTX(_x, _rctx) process_with_rctx(p_result, mctx, request, recv_ ## _x, _rctx);
206#define CALL_SEND(_x) send_ ## _x(p_result, mctx, request)
210#define CALL_RESUME(_x) resume_ ## _x(p_result, mctx, request)
214#define CALL_SEND_STATE(_state) state->send(p_result, mctx, request)
218#define CALL_SEND_TYPE(_x) call_send_type(process_state_reply[(request->reply->code = _x)].send, p_result, mctx, request)
229 return send(p_result, mctx, request);
235 fr_process_state_t
const *state;
240 UPDATE_STATE_CS(packet);
249 REDEBUG(
"Invalid packet type (%u)", request->packet->code);
257 cs, state->default_rcode, state->resume,
258 NULL, 0, mctx->
rctx);
264 fr_process_state_t
const *state;
270 UPDATE_STATE(packet);
272 request->reply->code = state->packet_type[rcode];
273 if (!request->reply->code) request->reply->code = state->default_reply;
274#ifdef PROCESS_CODE_DO_NOT_RESPOND
282 return state->send(p_result, mctx, request);
288 fr_process_state_t
const *state;
294 UPDATE_STATE(packet);
296 request->reply->code = state->packet_type[rcode];
297 if (!request->reply->code) request->reply->code = state->default_reply;
298#ifdef PROCESS_CODE_DO_NOT_RESPOND
307SEND_NO_RESULT(generic)
311 fr_process_state_t
const *state;
324 UPDATE_STATE_CS(reply);
340 vp->vp_uint32 = request->reply->code;
350 request->reply->code =
vp->vp_uint32;
351 UPDATE_STATE_CS(reply);
355 RWDEBUG(
"Ignoring invalid packet-type reply.%pP",
vp);
356 goto update_packet_type;
369 RWDEBUG(
"No 'send %s { ... } section was found.",
name);
371 RWDEBUG(
"No 'send %u { ... } section was found.", request->reply->code);
376 cs, state->default_rcode, state->resume,
377 NULL, 0, mctx->
rctx);
384 fr_process_state_t
const *state;
399 UPDATE_STATE_CS(reply);
402 switch (state->packet_type[rcode]) {
404 p_result->rcode = state->result_rcode;
422 (state->packet_type[rcode] != request->reply->code)) {
425 request->reply->code = state->packet_type[rcode];
426 UPDATE_STATE_CS(reply);
431 cs, state->default_rcode, state->send,
432 NULL, 0, mctx->
rctx);
434 p_result->rcode = state->result_rcode;
436 fr_assert(!state->packet_type[rcode] || (state->packet_type[rcode] == request->reply->code));
439#ifdef PROCESS_CODE_DO_NOT_RESPOND
445 RDEBUG(
"The 'send %s' section returned %s - not sending a response",
450 p_result->rcode = state->result_rcode;
456 request->reply->timestamp =
fr_time();
458#ifdef PROCESS_CODE_DO_NOT_RESPOND
463 RDEBUG(
"Not sending reply to client");
472#ifdef PROCESS_CODE_DYNAMIC_CLIENT
477 request->reply->timestamp =
fr_time();
487 fr_process_state_t
const *state;
494 RDEBUG(
"new client was successful.");
495 cs =
inst->sections.add_client;
500 RDEBUG(
"new client was denied.");
501 cs =
inst->sections.deny_client;
506 request->component = NULL;
507 request->module = NULL;
511 request->reply->timestamp =
fr_time();
518 NULL, 0, mctx->
rctx);
525 fr_process_state_t
const *state;
527 UPDATE_STATE(packet);
531 cs =
inst->sections.new_client;
536 NULL, 0, mctx->
rctx);
539#define DYNAMIC_CLIENT_SECTIONS \
541 .section = SECTION_NAME("new", "client"), \
542 .actions = &mod_actions_authorize, \
543 .offset = PROCESS_CONF_OFFSET(new_client), \
546 .section = SECTION_NAME("add", "client"), \
547 .actions = &mod_actions_authorize, \
548 .offset = PROCESS_CONF_OFFSET(add_client), \
551 .section = SECTION_NAME("deny", "client"), \
552 .actions = &mod_actions_authorize, \
553 .offset = PROCESS_CONF_OFFSET(deny_client), \
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
A section grouping multiple CONF_PAIR.
char const * cf_section_name2(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
char const * cf_section_name1(CONF_SECTION const *cs)
Return the second identifier of a CONF_SECTION.
static fr_dict_attr_t const * attr_packet_type
char const * fr_dict_enum_name_by_value(fr_dict_attr_t const *da, fr_value_box_t const *value)
Lookup the name of an enum value in a fr_dict_attr_t.
#define UNLANG_RESULT_RCODE(_x)
module_instance_t const * mi
Instance of the module being instantiated.
void * rctx
Resume ctx that a module previously set.
Temporary structure to hold arguments for module calls.
#define PROCESS_PACKET_TYPE
static fr_process_state_t const process_state[]
#define PROCESS_PACKET_CODE_VALID
#define PROCESS_CODE_DO_NOT_RESPOND
static fr_process_state_t const process_state_reply[]
RESUME_FLAG(recv_bfd, UNUSED,)
static fr_process_state_t const process_state_packet[]
#define PROCESS_CODE_DYNAMIC_CLIENT
#define PROCESS_STATE_EXTRA_FIELDS
RECV(for_any_server)
Validate a solicit/rebind/confirm message.
#define PROCESS_TRACE
Trace each state function as it's entered.
fr_table_num_sorted_t const rcode_table[]
#define RETURN_UNLANG_FAIL
rlm_rcode_t
Return codes indicating the result of the module call.
@ RLM_MODULE_OK
The module is OK, continue.
@ RLM_MODULE_FAIL
Module failed, don't reply.
@ RLM_MODULE_UPDATED
OK (pairs modified).
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
@ RLM_MODULE_HANDLED
The module handled the request, so stop.
void * data
Module's instance data.
unlang_action_t(* module_method_t)(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Module section callback.
#define pair_update_reply(_attr, _da)
Return or allocate a fr_pair_t in the reply list.
#define pair_delete_reply(_pair_or_da)
Delete a fr_pair_t in the reply list.
unlang_action_t unlang_module_yield_to_section(unlang_result_t *p_result, request_t *request, CONF_SECTION *subcs, rlm_rcode_t default_rcode, module_method_t resume, unlang_module_signal_t signal, fr_signal_t sigmask, void *rctx)
eap_aka_sim_process_conf_t * inst
fr_aka_sim_id_type_t type
#define fr_time()
Allow us to arbitrarily manipulate time.
Stores an attribute, a value and various bits of other data.
#define fr_table_str_by_value(_table, _number, _def)
Convert an integer to a string.
#define fr_box_uint32(_val)