Skip to content

Commit ee394f9

Browse files
ffmanceraummakynes
authored andcommitted
netfilter: nft_synproxy: add synproxy stateful object support
Register a new synproxy stateful object type into the stateful object infrastructure. Signed-off-by: Fernando Fernandez Mancera <[email protected]> Signed-off-by: Pablo Neira Ayuso <[email protected]>
1 parent 3474a2c commit ee394f9

File tree

2 files changed

+124
-22
lines changed

2 files changed

+124
-22
lines changed

include/uapi/linux/netfilter/nf_tables.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1481,7 +1481,8 @@ enum nft_ct_expectation_attributes {
14811481
#define NFT_OBJECT_CT_TIMEOUT 7
14821482
#define NFT_OBJECT_SECMARK 8
14831483
#define NFT_OBJECT_CT_EXPECT 9
1484-
#define __NFT_OBJECT_MAX 10
1484+
#define NFT_OBJECT_SYNPROXY 10
1485+
#define __NFT_OBJECT_MAX 11
14851486
#define NFT_OBJECT_MAX (__NFT_OBJECT_MAX - 1)
14861487

14871488
/**

net/netfilter/nft_synproxy.c

Lines changed: 122 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts,
2424
const struct tcphdr *tcp,
2525
struct synproxy_net *snet,
2626
struct nf_synproxy_info *info,
27-
struct nft_synproxy *priv)
27+
const struct nft_synproxy *priv)
2828
{
2929
this_cpu_inc(snet->stats->syn_received);
3030
if (tcp->ece && tcp->cwr)
@@ -41,14 +41,13 @@ static void nft_synproxy_tcp_options(struct synproxy_options *opts,
4141
NF_SYNPROXY_OPT_ECN);
4242
}
4343

44-
static void nft_synproxy_eval_v4(const struct nft_expr *expr,
44+
static void nft_synproxy_eval_v4(const struct nft_synproxy *priv,
4545
struct nft_regs *regs,
4646
const struct nft_pktinfo *pkt,
4747
const struct tcphdr *tcp,
4848
struct tcphdr *_tcph,
4949
struct synproxy_options *opts)
5050
{
51-
struct nft_synproxy *priv = nft_expr_priv(expr);
5251
struct nf_synproxy_info info = priv->info;
5352
struct net *net = nft_net(pkt);
5453
struct synproxy_net *snet = synproxy_pernet(net);
@@ -73,14 +72,13 @@ static void nft_synproxy_eval_v4(const struct nft_expr *expr,
7372
}
7473

7574
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
76-
static void nft_synproxy_eval_v6(const struct nft_expr *expr,
75+
static void nft_synproxy_eval_v6(const struct nft_synproxy *priv,
7776
struct nft_regs *regs,
7877
const struct nft_pktinfo *pkt,
7978
const struct tcphdr *tcp,
8079
struct tcphdr *_tcph,
8180
struct synproxy_options *opts)
8281
{
83-
struct nft_synproxy *priv = nft_expr_priv(expr);
8482
struct nf_synproxy_info info = priv->info;
8583
struct net *net = nft_net(pkt);
8684
struct synproxy_net *snet = synproxy_pernet(net);
@@ -105,9 +103,9 @@ static void nft_synproxy_eval_v6(const struct nft_expr *expr,
105103
}
106104
#endif /* CONFIG_NF_TABLES_IPV6*/
107105

108-
static void nft_synproxy_eval(const struct nft_expr *expr,
109-
struct nft_regs *regs,
110-
const struct nft_pktinfo *pkt)
106+
static void nft_synproxy_do_eval(const struct nft_synproxy *priv,
107+
struct nft_regs *regs,
108+
const struct nft_pktinfo *pkt)
111109
{
112110
struct synproxy_options opts = {};
113111
struct sk_buff *skb = pkt->skb;
@@ -140,23 +138,22 @@ static void nft_synproxy_eval(const struct nft_expr *expr,
140138

141139
switch (skb->protocol) {
142140
case htons(ETH_P_IP):
143-
nft_synproxy_eval_v4(expr, regs, pkt, tcp, &_tcph, &opts);
141+
nft_synproxy_eval_v4(priv, regs, pkt, tcp, &_tcph, &opts);
144142
return;
145143
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
146144
case htons(ETH_P_IPV6):
147-
nft_synproxy_eval_v6(expr, regs, pkt, tcp, &_tcph, &opts);
145+
nft_synproxy_eval_v6(priv, regs, pkt, tcp, &_tcph, &opts);
148146
return;
149147
#endif
150148
}
151149
regs->verdict.code = NFT_BREAK;
152150
}
153151

154-
static int nft_synproxy_init(const struct nft_ctx *ctx,
155-
const struct nft_expr *expr,
156-
const struct nlattr * const tb[])
152+
static int nft_synproxy_do_init(const struct nft_ctx *ctx,
153+
const struct nlattr * const tb[],
154+
struct nft_synproxy *priv)
157155
{
158156
struct synproxy_net *snet = synproxy_pernet(ctx->net);
159-
struct nft_synproxy *priv = nft_expr_priv(expr);
160157
u32 flags;
161158
int err;
162159

@@ -206,8 +203,7 @@ static int nft_synproxy_init(const struct nft_ctx *ctx,
206203
return err;
207204
}
208205

209-
static void nft_synproxy_destroy(const struct nft_ctx *ctx,
210-
const struct nft_expr *expr)
206+
static void nft_synproxy_do_destroy(const struct nft_ctx *ctx)
211207
{
212208
struct synproxy_net *snet = synproxy_pernet(ctx->net);
213209

@@ -229,10 +225,8 @@ static void nft_synproxy_destroy(const struct nft_ctx *ctx,
229225
nf_ct_netns_put(ctx->net, ctx->family);
230226
}
231227

232-
static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr)
228+
static int nft_synproxy_do_dump(struct sk_buff *skb, struct nft_synproxy *priv)
233229
{
234-
const struct nft_synproxy *priv = nft_expr_priv(expr);
235-
236230
if (nla_put_be16(skb, NFTA_SYNPROXY_MSS, htons(priv->info.mss)) ||
237231
nla_put_u8(skb, NFTA_SYNPROXY_WSCALE, priv->info.wscale) ||
238232
nla_put_be32(skb, NFTA_SYNPROXY_FLAGS, htonl(priv->info.options)))
@@ -244,6 +238,15 @@ static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr)
244238
return -1;
245239
}
246240

241+
static void nft_synproxy_eval(const struct nft_expr *expr,
242+
struct nft_regs *regs,
243+
const struct nft_pktinfo *pkt)
244+
{
245+
const struct nft_synproxy *priv = nft_expr_priv(expr);
246+
247+
nft_synproxy_do_eval(priv, regs, pkt);
248+
}
249+
247250
static int nft_synproxy_validate(const struct nft_ctx *ctx,
248251
const struct nft_expr *expr,
249252
const struct nft_data **data)
@@ -252,6 +255,28 @@ static int nft_synproxy_validate(const struct nft_ctx *ctx,
252255
(1 << NF_INET_FORWARD));
253256
}
254257

258+
static int nft_synproxy_init(const struct nft_ctx *ctx,
259+
const struct nft_expr *expr,
260+
const struct nlattr * const tb[])
261+
{
262+
struct nft_synproxy *priv = nft_expr_priv(expr);
263+
264+
return nft_synproxy_do_init(ctx, tb, priv);
265+
}
266+
267+
static void nft_synproxy_destroy(const struct nft_ctx *ctx,
268+
const struct nft_expr *expr)
269+
{
270+
nft_synproxy_do_destroy(ctx);
271+
}
272+
273+
static int nft_synproxy_dump(struct sk_buff *skb, const struct nft_expr *expr)
274+
{
275+
struct nft_synproxy *priv = nft_expr_priv(expr);
276+
277+
return nft_synproxy_do_dump(skb, priv);
278+
}
279+
255280
static struct nft_expr_type nft_synproxy_type;
256281
static const struct nft_expr_ops nft_synproxy_ops = {
257282
.eval = nft_synproxy_eval,
@@ -271,14 +296,89 @@ static struct nft_expr_type nft_synproxy_type __read_mostly = {
271296
.maxattr = NFTA_SYNPROXY_MAX,
272297
};
273298

299+
static int nft_synproxy_obj_init(const struct nft_ctx *ctx,
300+
const struct nlattr * const tb[],
301+
struct nft_object *obj)
302+
{
303+
struct nft_synproxy *priv = nft_obj_data(obj);
304+
305+
return nft_synproxy_do_init(ctx, tb, priv);
306+
}
307+
308+
static void nft_synproxy_obj_destroy(const struct nft_ctx *ctx,
309+
struct nft_object *obj)
310+
{
311+
nft_synproxy_do_destroy(ctx);
312+
}
313+
314+
static int nft_synproxy_obj_dump(struct sk_buff *skb,
315+
struct nft_object *obj, bool reset)
316+
{
317+
struct nft_synproxy *priv = nft_obj_data(obj);
318+
319+
return nft_synproxy_do_dump(skb, priv);
320+
}
321+
322+
static void nft_synproxy_obj_eval(struct nft_object *obj,
323+
struct nft_regs *regs,
324+
const struct nft_pktinfo *pkt)
325+
{
326+
const struct nft_synproxy *priv = nft_obj_data(obj);
327+
328+
nft_synproxy_do_eval(priv, regs, pkt);
329+
}
330+
331+
static void nft_synproxy_obj_update(struct nft_object *obj,
332+
struct nft_object *newobj)
333+
{
334+
struct nft_synproxy *newpriv = nft_obj_data(newobj);
335+
struct nft_synproxy *priv = nft_obj_data(obj);
336+
337+
priv->info = newpriv->info;
338+
}
339+
340+
static struct nft_object_type nft_synproxy_obj_type;
341+
static const struct nft_object_ops nft_synproxy_obj_ops = {
342+
.type = &nft_synproxy_obj_type,
343+
.size = sizeof(struct nft_synproxy),
344+
.init = nft_synproxy_obj_init,
345+
.destroy = nft_synproxy_obj_destroy,
346+
.dump = nft_synproxy_obj_dump,
347+
.eval = nft_synproxy_obj_eval,
348+
.update = nft_synproxy_obj_update,
349+
};
350+
351+
static struct nft_object_type nft_synproxy_obj_type __read_mostly = {
352+
.type = NFT_OBJECT_SYNPROXY,
353+
.ops = &nft_synproxy_obj_ops,
354+
.maxattr = NFTA_SYNPROXY_MAX,
355+
.policy = nft_synproxy_policy,
356+
.owner = THIS_MODULE,
357+
};
358+
274359
static int __init nft_synproxy_module_init(void)
275360
{
276-
return nft_register_expr(&nft_synproxy_type);
361+
int err;
362+
363+
err = nft_register_obj(&nft_synproxy_obj_type);
364+
if (err < 0)
365+
return err;
366+
367+
err = nft_register_expr(&nft_synproxy_type);
368+
if (err < 0)
369+
goto err;
370+
371+
return 0;
372+
373+
err:
374+
nft_unregister_obj(&nft_synproxy_obj_type);
375+
return err;
277376
}
278377

279378
static void __exit nft_synproxy_module_exit(void)
280379
{
281-
return nft_unregister_expr(&nft_synproxy_type);
380+
nft_unregister_expr(&nft_synproxy_type);
381+
nft_unregister_obj(&nft_synproxy_obj_type);
282382
}
283383

284384
module_init(nft_synproxy_module_init);
@@ -287,3 +387,4 @@ module_exit(nft_synproxy_module_exit);
287387
MODULE_LICENSE("GPL");
288388
MODULE_AUTHOR("Fernando Fernandez <[email protected]>");
289389
MODULE_ALIAS_NFT_EXPR("synproxy");
390+
MODULE_ALIAS_NFT_OBJ(NFT_OBJECT_SYNPROXY);

0 commit comments

Comments
 (0)