1
1
/*-
2
- * Copyright (c) 2010-2013 The NetBSD Foundation, Inc.
2
+ * Copyright (c) 2010-2019 The NetBSD Foundation, Inc.
3
3
* All rights reserved.
4
4
*
5
5
* This material is based upon work partially supported by The
@@ -40,8 +40,6 @@ __KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.19 2019/01/19 21:19:31 rmind Exp $");
40
40
41
41
#include <sys/kmem.h>
42
42
#include <sys/pserialize.h>
43
- #include <sys/mutex.h>
44
- #include <net/pfil.h>
45
43
#include <sys/module.h>
46
44
#endif
47
45
@@ -55,20 +53,20 @@ __KERNEL_RCSID(0, "$NetBSD: npf_alg.c,v 1.19 2019/01/19 21:19:31 rmind Exp $");
55
53
56
54
struct npf_alg {
57
55
const char * na_name ;
58
- u_int na_slot ;
56
+ unsigned na_slot ;
59
57
};
60
58
61
59
struct npf_algset {
62
60
/* List of ALGs and the count. */
63
61
npf_alg_t alg_list [NPF_MAX_ALGS ];
64
- u_int alg_count ;
62
+ unsigned alg_count ;
65
63
66
64
/* Matching, inspection and translation functions. */
67
65
npfa_funcs_t alg_funcs [NPF_MAX_ALGS ];
68
66
};
69
67
70
- static const char alg_prefix [] = "npf_alg_" ;
71
- #define NPF_EXT_PREFLEN (sizeof(alg_prefix ) - 1)
68
+ #define NPF_ALG_PREF "npf_alg_"
69
+ #define NPF_ALG_PREFLEN (sizeof(NPF_ALG_PREF ) - 1)
72
70
73
71
void
74
72
npf_alg_init (npf_t * npf )
@@ -94,7 +92,7 @@ npf_alg_lookup(npf_t *npf, const char *name)
94
92
95
93
KASSERT (npf_config_locked_p (npf ));
96
94
97
- for (u_int i = 0 ; i < aset -> alg_count ; i ++ ) {
95
+ for (unsigned i = 0 ; i < aset -> alg_count ; i ++ ) {
98
96
npf_alg_t * alg = & aset -> alg_list [i ];
99
97
const char * aname = alg -> na_name ;
100
98
@@ -111,9 +109,9 @@ npf_alg_construct(npf_t *npf, const char *name)
111
109
112
110
npf_config_enter (npf );
113
111
if ((alg = npf_alg_lookup (npf , name )) == NULL ) {
114
- char modname [NPF_EXT_PREFLEN + 64 ];
112
+ char modname [NPF_ALG_PREFLEN + 64 ];
115
113
116
- snprintf (modname , sizeof (modname ), "%s%s" , alg_prefix , name );
114
+ snprintf (modname , sizeof (modname ), "%s%s" , NPF_ALG_PREF , name );
117
115
npf_config_exit (npf );
118
116
119
117
if (module_autoload (modname , MODULE_CLASS_MISC ) != 0 ) {
@@ -135,7 +133,7 @@ npf_alg_register(npf_t *npf, const char *name, const npfa_funcs_t *funcs)
135
133
npf_algset_t * aset = npf -> algset ;
136
134
npfa_funcs_t * afuncs ;
137
135
npf_alg_t * alg ;
138
- u_int i ;
136
+ unsigned i ;
139
137
140
138
npf_config_enter (npf );
141
139
if (npf_alg_lookup (npf , name ) != NULL ) {
178
176
npf_alg_unregister (npf_t * npf , npf_alg_t * alg )
179
177
{
180
178
npf_algset_t * aset = npf -> algset ;
181
- u_int i = alg -> na_slot ;
179
+ unsigned i = alg -> na_slot ;
182
180
npfa_funcs_t * afuncs ;
183
181
184
182
/* Deactivate the functions first. */
@@ -198,7 +196,16 @@ npf_alg_unregister(npf_t *npf, npf_alg_t *alg)
198
196
}
199
197
200
198
/*
201
- * npf_alg_match: call ALG matching inspectors, determine if any ALG matches.
199
+ * npf_alg_match: call the ALG matching inspectors.
200
+ *
201
+ * The purpose of the "matching" inspector function in the ALG API
202
+ * is to determine whether this connection matches the ALG criteria
203
+ * i.e. is concerning the ALG. If yes, ALG can associate itself with
204
+ * the given NAT state structure and set/save an arbitrary parameter.
205
+ * This is done using the using the npf_nat_setalg() function.
206
+ *
207
+ * => This is called when the packet matches the dynamic NAT policy
208
+ * and the NAT state entry is being created for it [NAT-ESTABLISH].
202
209
*/
203
210
bool
204
211
npf_alg_match (npf_cache_t * npc , npf_nat_t * nt , int di )
@@ -207,8 +214,10 @@ npf_alg_match(npf_cache_t *npc, npf_nat_t *nt, int di)
207
214
bool match = false;
208
215
int s ;
209
216
217
+ KASSERTMSG (npf_iscached (npc , NPC_IP46 ), "expecting protocol number" );
218
+
210
219
s = pserialize_read_enter ();
211
- for (u_int i = 0 ; i < aset -> alg_count ; i ++ ) {
220
+ for (unsigned i = 0 ; i < aset -> alg_count ; i ++ ) {
212
221
const npfa_funcs_t * f = & aset -> alg_funcs [i ];
213
222
214
223
if (f -> match && f -> match (npc , nt , di )) {
@@ -221,16 +230,26 @@ npf_alg_match(npf_cache_t *npc, npf_nat_t *nt, int di)
221
230
}
222
231
223
232
/*
224
- * npf_alg_exec: execute ALG hooks for translation.
233
+ * npf_alg_exec: execute the ALG translation processors.
234
+ *
235
+ * The ALG function would perform any additional packet translation
236
+ * or manipulation here. The translate function will be called by
237
+ * once the ALG has been associated with the NAT state through the
238
+ * npf_alg_match() inspector.
239
+ *
240
+ * => This is called when the packet is being translated according
241
+ * to the dynamic NAT logic [NAT-TRANSLATE].
225
242
*/
226
243
void
227
244
npf_alg_exec (npf_cache_t * npc , npf_nat_t * nt , bool forw )
228
245
{
229
246
npf_algset_t * aset = npc -> npc_ctx -> algset ;
230
247
int s ;
231
248
249
+ KASSERTMSG (npf_iscached (npc , NPC_IP46 ), "expecting protocol number" );
250
+
232
251
s = pserialize_read_enter ();
233
- for (u_int i = 0 ; i < aset -> alg_count ; i ++ ) {
252
+ for (unsigned i = 0 ; i < aset -> alg_count ; i ++ ) {
234
253
const npfa_funcs_t * f = & aset -> alg_funcs [i ];
235
254
236
255
if (f -> translate ) {
@@ -240,6 +259,23 @@ npf_alg_exec(npf_cache_t *npc, npf_nat_t *nt, bool forw)
240
259
pserialize_read_exit (s );
241
260
}
242
261
262
+ /*
263
+ * npf_alg_conn: query ALGs giving which may perform a custom state lookup.
264
+ *
265
+ * The purpose of ALG connection inspection function is to provide
266
+ * ALGs with a mechanism to override the regular connection state
267
+ * lookup, if they need to. For example, some ALGs may want to
268
+ * extract and use a different 5-tuple to perform a lookup.
269
+ *
270
+ * => This is called at the beginning of the connection state lookup
271
+ * function [CONN-LOOKUP].
272
+ *
273
+ * => Must use the npf_conn_lookup() function to perform the custom
274
+ * connection state lookup and return the result.
275
+ *
276
+ * => Returning NULL will result in NPF performing a regular state
277
+ * lookup for the packet.
278
+ */
243
279
npf_conn_t *
244
280
npf_alg_conn (npf_cache_t * npc , int di )
245
281
{
@@ -248,7 +284,7 @@ npf_alg_conn(npf_cache_t *npc, int di)
248
284
int s ;
249
285
250
286
s = pserialize_read_enter ();
251
- for (u_int i = 0 ; i < aset -> alg_count ; i ++ ) {
287
+ for (unsigned i = 0 ; i < aset -> alg_count ; i ++ ) {
252
288
const npfa_funcs_t * f = & aset -> alg_funcs [i ];
253
289
254
290
if (!f -> inspect )
@@ -260,14 +296,17 @@ npf_alg_conn(npf_cache_t *npc, int di)
260
296
return con ;
261
297
}
262
298
299
+ /*
300
+ * npf_alg_export: serialise the configuration of ALGs.
301
+ */
263
302
int
264
303
npf_alg_export (npf_t * npf , nvlist_t * npf_dict )
265
304
{
266
305
npf_algset_t * aset = npf -> algset ;
267
306
268
307
KASSERT (npf_config_locked_p (npf ));
269
308
270
- for (u_int i = 0 ; i < aset -> alg_count ; i ++ ) {
309
+ for (unsigned i = 0 ; i < aset -> alg_count ; i ++ ) {
271
310
const npf_alg_t * alg = & aset -> alg_list [i ];
272
311
nvlist_t * algdict ;
273
312
0 commit comments