The FreeRADIUS server $Id: f3670dba8951ca10eb4948feb3dc3db9423a334f $
Loading...
Searching...
No Matches
base.c
Go to the documentation of this file.
1/*
2 * This program is free software; you can redistribute it and/or modify
3 * it under the terms of the GNU General Public License as published by
4 * the Free Software Foundation; either version 2 of the License, or
5 * (at your option) any later version.
6 *
7 * This program is distributed in the hope that it will be useful,
8 * but WITHOUT ANY WARRANTY; without even the implied warranty of
9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 * GNU General Public License for more details.
11 *
12 * You should have received a copy of the GNU General Public License
13 * along with this program; if not, write to the Free Software
14 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
15 */
16
17/**
18 * $Id: 15a2458158752f78a5c57fda9856a72f8e28ab4c $
19 * @file src/process/bfd/base.c
20 * @brief BFD processing.
21 *
22 * @copyright 2023 Network RADIUS SAS (legal@networkradius.com)
23 */
24#include <freeradius-devel/util/debug.h>
25#include <freeradius-devel/bfd/bfd.h>
26#include "bfd/session.h"
27
28static fr_dict_t const *dict_bfd;
29
35
39
42 { .out = &attr_packet_type, .name = "Packet-Type", .type = FR_TYPE_UINT32, .dict = &dict_bfd},
43
44 { .out = &attr_bfd_packet, .name = "Packet", .type = FR_TYPE_STRUCT, .dict = &dict_bfd},
45 { .out = &attr_bfd_state, .name = "Packet.state", .type = FR_TYPE_UINT8, .dict = &dict_bfd},
46
48};
49
50#define SECTION(_x) \
51 CONF_SECTION *recv_ ## _x; \
52 CONF_SECTION *send_ ## _x
53
54typedef struct {
55 uint64_t nothing; // so that the next field isn't at offset 0
56
57 SECTION(admin_down);
58 SECTION(down);
62
66
67#define PROCESS_PACKET_TYPE fr_bfd_packet_code_t
68#define PROCESS_CODE_MAX FR_BFD_CODE_MAX
69#define PROCESS_PACKET_CODE_VALID FR_BFD_PACKET_CODE_VALID
70#define PROCESS_INST process_bfd_t
71
72#define PROCESS_SEND_RECV (1)
73
74#include <freeradius-devel/server/process.h>
75
77{
78 rlm_rcode_t rcode = RESULT_RCODE;
80 uint32_t state = 0;
81
83
85
86 if (rcode == RLM_MODULE_FAIL) {
87 state = FR_BFD_ADMIN_DOWN;
88 } else {
89 /*
90 * Check for a state / reply code.
91 */
92 vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_packet_type);
93 if (vp) {
94 if (!PROCESS_PACKET_CODE_VALID(vp->vp_uint32)) {
95 REDEBUG("Invalid BFD packet type %u", vp->vp_uint32);
97 }
98 state = vp->vp_uint32;
99 } else {
100 vp = fr_pair_find_by_da(&request->reply_pairs, NULL, attr_bfd_packet);
101 if (vp) vp = fr_pair_find_by_da_nested(&vp->vp_group, NULL, attr_bfd_state);
102 if (vp) {
103 if (!PROCESS_PACKET_CODE_VALID(vp->vp_uint8)) {
104 REDEBUG("Invalid BFD state %u", vp->vp_uint8);
106 }
107 state = vp->vp_uint8;
108 }
109 }
110 }
111
112 request->reply->code = state;
113
114 request->reply->timestamp = fr_time();
115
117}
118
119
120/*
121 * recv FOO
122 */
123static fr_process_state_t const process_state_packet[] = {
124 [ FR_BFD_ADMIN_DOWN ] = {
125 .default_reply = FR_BFD_DOWN,
126 .default_rcode = RLM_MODULE_NOOP,
127 .recv = recv_generic,
128 .resume = resume_recv_bfd,
129 .section_offset = offsetof(process_bfd_sections_t, recv_admin_down),
130 },
131
132 [ FR_BFD_DOWN ] = {
133 .default_reply = FR_BFD_DOWN,
134 .default_rcode = RLM_MODULE_NOOP,
135 .recv = recv_generic,
136 .resume = resume_recv_bfd,
137 .section_offset = offsetof(process_bfd_sections_t, recv_down),
138 },
139
140 [ FR_BFD_INIT ] = {
141 .default_reply = FR_BFD_UP,
142 .default_rcode = RLM_MODULE_NOOP,
143 .recv = recv_generic,
144 .resume = resume_recv_bfd,
145 .section_offset = offsetof(process_bfd_sections_t, recv_init),
146 },
147
148 [ FR_BFD_UP ] = {
149 .default_reply = FR_BFD_UP,
150 .default_rcode = RLM_MODULE_NOOP,
151 .recv = recv_generic,
152 .resume = resume_recv_bfd,
153 .section_offset = offsetof(process_bfd_sections_t, recv_up),
154 },
155};
156
157/*
158 * send FOO
159 */
160static fr_process_state_t const process_state_reply[] = {
161 [ FR_BFD_ADMIN_DOWN ] = {
162 .default_rcode = RLM_MODULE_NOOP,
163 .send = send_generic,
164 .resume = resume_send_generic,
165 .section_offset = offsetof(process_bfd_sections_t, send_admin_down),
166 },
167
168 [ FR_BFD_DOWN ] = {
169 .default_rcode = RLM_MODULE_NOOP,
170 .send = send_generic,
171 .resume = resume_send_generic,
172 .section_offset = offsetof(process_bfd_sections_t, send_down),
173 },
174
175 [ FR_BFD_INIT ] = {
176 .default_rcode = RLM_MODULE_NOOP,
177 .send = send_generic,
178 .resume = resume_send_generic,
179 .section_offset = offsetof(process_bfd_sections_t, send_init),
180 },
181
182 [ FR_BFD_UP ] = {
183 .default_rcode = RLM_MODULE_NOOP,
184 .send = send_generic,
185 .resume = resume_send_generic,
186 .section_offset = offsetof(process_bfd_sections_t, send_up),
187 },
188};
189
190static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
191{
192 fr_process_state_t const *state;
193 bfd_wrapper_t const *wrapper;
194
196
198 fr_assert(PROCESS_PACKET_CODE_VALID(request->packet->code));
199
200 request->component = "bfd";
201 request->module = NULL;
202
203 fr_assert(request->proto_dict == dict_bfd);
204
205 wrapper = (bfd_wrapper_t const *) request->packet->data;
206
207 /*
208 * If there's no packet, we must be calling the "send" routine
209 */
210 if (wrapper->type == BFD_WRAPPER_SEND_PACKET) {
211
212 UPDATE_STATE(reply);
213
214 return state->send(p_result, mctx, request);
215 }
216
218
219 UPDATE_STATE(packet);
220
221 if (!state->recv) {
222 REDEBUG("Invalid packet type (%u)", request->packet->code);
224 }
225
226 return state->recv(p_result, mctx, request);
227}
228
229/*
230 * We send and receive the same packet types.
231 */
232#define SEND_RECV(_x, _y) \
233 { \
234 .section = SECTION_NAME("recv", _x), \
235 .actions = &mod_actions_postauth, \
236 .offset = PROCESS_CONF_OFFSET(recv_ ## _y), \
237 }, \
238 { \
239 .section = SECTION_NAME("send", _x), \
240 .actions = &mod_actions_postauth, \
241 .offset = PROCESS_CONF_OFFSET(send_ ## _y), \
242 }
243
245 SEND_RECV("Admin-Down", admin_down),
246 SEND_RECV("Down", down),
247 SEND_RECV("Init", init),
248 SEND_RECV("Up", up),
249
251};
252
253
256 .common = {
257 .magic = MODULE_MAGIC_INIT,
258 .name = "bfd",
260 MODULE_RCTX(process_rctx_t)
261 },
262 .process = mod_process,
263 .compile_list = compile_list,
264 .dict = &dict_bfd,
265 .packet_type = &attr_packet_type
266};
unlang_action_t
Returned by unlang_op_t calls, determine the next action of the interpreter.
Definition action.h:35
@ UNLANG_ACTION_CALCULATE_RESULT
Calculate a new section rlm_rcode_t value.
Definition action.h:37
@ FR_BFD_INIT
Definition bfd.h:146
@ FR_BFD_ADMIN_DOWN
Definition bfd.h:144
@ FR_BFD_UP
Definition bfd.h:147
@ FR_BFD_DOWN
Definition bfd.h:145
#define UNUSED
Definition build.h:384
fr_dict_attr_t const ** out
Where to write a pointer to the resolved fr_dict_attr_t.
Definition dict.h:292
fr_dict_t const ** out
Where to write a pointer to the loaded/resolved fr_dict_t.
Definition dict.h:305
#define DICT_AUTOLOAD_TERMINATOR
Definition dict.h:311
Specifies an attribute which must be present for the module to function.
Definition dict.h:291
Specifies a dictionary which must be loaded/loadable for the module to function.
Definition dict.h:304
#define MODULE_MAGIC_INIT
Stop people using different module/library/server versions together.
Definition dl_module.h:63
fr_dict_attr_t const * attr_packet_type
Definition base.c:91
#define fr_time()
Definition event.c:60
@ BFD_WRAPPER_SEND_PACKET
Definition session.h:127
@ BFD_WRAPPER_RECV_PACKET
Definition session.h:126
uint32_t type
Definition session.h:142
@ FR_TYPE_UINT8
8 Bit unsigned integer.
@ FR_TYPE_UINT32
32 Bit unsigned integer.
@ FR_TYPE_STRUCT
like TLV, but without T or L, and fixed-width children
unsigned int uint32_t
module_instance_t const * mi
Instance of the module being instantiated.
Definition module_ctx.h:42
Temporary structure to hold arguments for module calls.
Definition module_ctx.h:41
fr_pair_t * fr_pair_find_by_da_nested(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find a pair with a matching fr_dict_attr_t, by walking the nested fr_dict_attr_t tree.
Definition pair.c:784
fr_pair_t * fr_pair_find_by_da(fr_pair_list_t const *list, fr_pair_t const *prev, fr_dict_attr_t const *da)
Find the first pair with a matching da.
Definition pair.c:707
static unlang_action_t mod_process(unlang_result_t *p_result, module_ctx_t const *mctx, request_t *request)
Definition base.c:168
static const virtual_server_compile_t compile_list[]
Definition base.c:192
fr_dict_autoload_t process_bfd_dict[]
Definition base.c:31
static fr_dict_attr_t const * attr_bfd_packet
Definition base.c:37
process_bfd_sections_t sections
Definition base.c:64
fr_process_module_t process_bfd
Definition base.c:255
static fr_dict_attr_t const * attr_bfd_state
Definition base.c:38
static fr_process_state_t const process_state_reply[]
Definition base.c:160
fr_dict_attr_autoload_t process_bfd_dict_attr[]
Definition base.c:41
RESUME_FLAG(recv_bfd, UNUSED,)
Definition base.c:76
static fr_dict_t const * dict_bfd
Definition base.c:28
#define SEND_RECV(_x, _y)
Definition base.c:232
#define PROCESS_PACKET_CODE_VALID
Definition base.c:69
static fr_process_state_t const process_state_packet[]
Definition base.c:123
#define PROCESS_TRACE
Trace each state function as it's entered.
Definition process.h:55
module_t common
Common fields for all loadable modules.
Common public symbol definition for all process modules.
#define fr_assert(_expr)
Definition rad_assert.h:37
#define REDEBUG(fmt,...)
#define RETURN_UNLANG_FAIL
Definition rcode.h:63
rlm_rcode_t
Return codes indicating the result of the module call.
Definition rcode.h:44
@ RLM_MODULE_FAIL
Module failed, don't reply.
Definition rcode.h:48
@ RLM_MODULE_NOOP
Module succeeded without doing anything.
Definition rcode.h:54
@ RLM_MODULE_NUMCODES
How many valid return codes there are.
Definition rcode.h:57
void * data
Module's instance data.
Definition module.h:293
#define MODULE_RCTX(_ctype)
Definition module.h:259
#define MODULE_INST(_ctype)
Definition module.h:257
init
Enter the EAP-IDENTITY state.
fr_pair_t * vp
uint64_t nothing
Definition base.c:55
Stores an attribute, a value and various bits of other data.
Definition pair.h:68
#define talloc_get_type_abort_const
Definition talloc.h:117
#define COMPILE_TERMINATOR
Processing sections which are allowed in this virtual server.