* [PATCH nf-next 1/2] netfilter: nft: refactor reject verdict source code
@ 2020-06-08 19:00 Laura Garcia Liebana
0 siblings, 0 replies; only message in thread
From: Laura Garcia Liebana @ 2020-06-08 19:00 UTC (permalink / raw)
To: netfilter-devel; +Cc: pablo, devel
Within REJECT modules there are duplicated code for different
families, so this patch re-structures the source code in order
to reuse as much as possible. The refactoring produces ~30 lines
removed in total and prepares the code to be added the ingress
support of REJECT.
Signed-off-by: Laura Garcia Liebana <nevola@gmail.com>
---
include/net/netfilter/ipv4/nft_reject_ipv4.h | 9 ++
include/net/netfilter/ipv6/nft_reject_ipv6.h | 9 ++
include/net/netfilter/nft_reject.h | 3 +
net/ipv4/netfilter/nft_reject_ipv4.c | 12 ++-
net/ipv6/netfilter/nft_reject_ipv6.c | 16 ++-
net/netfilter/nft_reject.c | 29 +++++-
net/netfilter/nft_reject_inet.c | 101 ++-----------------
7 files changed, 77 insertions(+), 102 deletions(-)
create mode 100644 include/net/netfilter/ipv4/nft_reject_ipv4.h
create mode 100644 include/net/netfilter/ipv6/nft_reject_ipv6.h
diff --git a/include/net/netfilter/ipv4/nft_reject_ipv4.h b/include/net/netfilter/ipv4/nft_reject_ipv4.h
new file mode 100644
index 000000000000..364810b613c2
--- /dev/null
+++ b/include/net/netfilter/ipv4/nft_reject_ipv4.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _NFT_REJECT_IPV4_H_
+#define _NFT_REJECT_IPV4_H_
+
+void nft_reject_ipv4_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+
+#endif
diff --git a/include/net/netfilter/ipv6/nft_reject_ipv6.h b/include/net/netfilter/ipv6/nft_reject_ipv6.h
new file mode 100644
index 000000000000..568297083858
--- /dev/null
+++ b/include/net/netfilter/ipv6/nft_reject_ipv6.h
@@ -0,0 +1,9 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _NFT_REJECT_IPV6_H_
+#define _NFT_REJECT_IPV6_H_
+
+void nft_reject_ipv6_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt);
+
+#endif
diff --git a/include/net/netfilter/nft_reject.h b/include/net/netfilter/nft_reject.h
index 56b123a42220..3a3a0a4eaac9 100644
--- a/include/net/netfilter/nft_reject.h
+++ b/include/net/netfilter/nft_reject.h
@@ -26,5 +26,8 @@ int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr);
int nft_reject_icmp_code(u8 code);
int nft_reject_icmpv6_code(u8 code);
+int nft_reject_generic_validate(const struct nft_ctx *ctx,
+ const struct nft_expr *expr,
+ const struct nft_data **data);
#endif
diff --git a/net/ipv4/netfilter/nft_reject_ipv4.c b/net/ipv4/netfilter/nft_reject_ipv4.c
index 7e6fd5cde50f..39414795a5c2 100644
--- a/net/ipv4/netfilter/nft_reject_ipv4.c
+++ b/net/ipv4/netfilter/nft_reject_ipv4.c
@@ -16,9 +16,9 @@
#include <net/netfilter/ipv4/nf_reject.h>
#include <net/netfilter/nft_reject.h>
-static void nft_reject_ipv4_eval(const struct nft_expr *expr,
- struct nft_regs *regs,
- const struct nft_pktinfo *pkt)
+void nft_reject_ipv4_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
@@ -29,12 +29,18 @@ static void nft_reject_ipv4_eval(const struct nft_expr *expr,
case NFT_REJECT_TCP_RST:
nf_send_reset(nft_net(pkt), pkt->skb, nft_hook(pkt));
break;
+ case NFT_REJECT_ICMPX_UNREACH:
+ nf_send_unreach(pkt->skb,
+ nft_reject_icmp_code(priv->icmp_code),
+ nft_hook(pkt));
+ break;
default:
break;
}
regs->verdict.code = NF_DROP;
}
+EXPORT_SYMBOL_GPL(nft_reject_ipv4_eval);
static struct nft_expr_type nft_reject_ipv4_type;
static const struct nft_expr_ops nft_reject_ipv4_ops = {
diff --git a/net/ipv6/netfilter/nft_reject_ipv6.c b/net/ipv6/netfilter/nft_reject_ipv6.c
index 680a28ce29fd..8a2ad7ad387e 100644
--- a/net/ipv6/netfilter/nft_reject_ipv6.c
+++ b/net/ipv6/netfilter/nft_reject_ipv6.c
@@ -15,13 +15,17 @@
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nft_reject.h>
#include <net/netfilter/ipv6/nf_reject.h>
+#include <net/ipv6.h>
-static void nft_reject_ipv6_eval(const struct nft_expr *expr,
- struct nft_regs *regs,
- const struct nft_pktinfo *pkt)
+void nft_reject_ipv6_eval(const struct nft_expr *expr,
+ struct nft_regs *regs,
+ const struct nft_pktinfo *pkt)
{
struct nft_reject *priv = nft_expr_priv(expr);
+ if (!ipv6_mod_enabled())
+ return;
+
switch (priv->type) {
case NFT_REJECT_ICMP_UNREACH:
nf_send_unreach6(nft_net(pkt), pkt->skb, priv->icmp_code,
@@ -30,12 +34,18 @@ static void nft_reject_ipv6_eval(const struct nft_expr *expr,
case NFT_REJECT_TCP_RST:
nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
break;
+ case NFT_REJECT_ICMPX_UNREACH:
+ nf_send_unreach6(nft_net(pkt), pkt->skb,
+ nft_reject_icmpv6_code(priv->icmp_code),
+ nft_hook(pkt));
+ break;
default:
break;
}
regs->verdict.code = NF_DROP;
}
+EXPORT_SYMBOL_GPL(nft_reject_ipv6_eval);
static struct nft_expr_type nft_reject_ipv6_type;
static const struct nft_expr_ops nft_reject_ipv6_ops = {
diff --git a/net/netfilter/nft_reject.c b/net/netfilter/nft_reject.c
index 5eac28269bdb..bd796e4e8468 100644
--- a/net/netfilter/nft_reject.c
+++ b/net/netfilter/nft_reject.c
@@ -26,6 +26,20 @@ EXPORT_SYMBOL_GPL(nft_reject_policy);
int nft_reject_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nft_data **data)
+{
+ struct nft_reject *priv = nft_expr_priv(expr);
+
+ if (priv->type != NFT_REJECT_ICMP_UNREACH &&
+ priv->type != NFT_REJECT_TCP_RST)
+ return -EINVAL;
+
+ return nft_reject_generic_validate(ctx, expr, data);
+}
+EXPORT_SYMBOL_GPL(nft_reject_validate);
+
+int nft_reject_generic_validate(const struct nft_ctx *ctx,
+ const struct nft_expr *expr,
+ const struct nft_data **data)
{
return nft_chain_validate_hooks(ctx->chain,
(1 << NF_INET_LOCAL_IN) |
@@ -33,13 +47,14 @@ int nft_reject_validate(const struct nft_ctx *ctx,
(1 << NF_INET_LOCAL_OUT) |
(1 << NF_INET_PRE_ROUTING));
}
-EXPORT_SYMBOL_GPL(nft_reject_validate);
+EXPORT_SYMBOL_GPL(nft_reject_generic_validate);
int nft_reject_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nlattr * const tb[])
{
struct nft_reject *priv = nft_expr_priv(expr);
+ int icmp_code;
if (tb[NFTA_REJECT_TYPE] == NULL)
return -EINVAL;
@@ -47,15 +62,22 @@ int nft_reject_init(const struct nft_ctx *ctx,
priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
switch (priv->type) {
case NFT_REJECT_ICMP_UNREACH:
+ case NFT_REJECT_ICMPX_UNREACH:
if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
return -EINVAL;
- priv->icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
+
+ icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
+ if (priv->type == NFT_REJECT_ICMPX_UNREACH &&
+ icmp_code > NFT_REJECT_ICMPX_MAX)
+ return -EINVAL;
+
+ priv->icmp_code = icmp_code;
+ break;
case NFT_REJECT_TCP_RST:
break;
default:
return -EINVAL;
}
-
return 0;
}
EXPORT_SYMBOL_GPL(nft_reject_init);
@@ -69,6 +91,7 @@ int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr)
switch (priv->type) {
case NFT_REJECT_ICMP_UNREACH:
+ case NFT_REJECT_ICMPX_UNREACH:
if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
goto nla_put_failure;
break;
diff --git a/net/netfilter/nft_reject_inet.c b/net/netfilter/nft_reject_inet.c
index f41f414b72d1..4c5d37b1bd22 100644
--- a/net/netfilter/nft_reject_inet.c
+++ b/net/netfilter/nft_reject_inet.c
@@ -1,6 +1,7 @@
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (c) 2014 Patrick McHardy <kaber@trash.net>
+ * Copyright (c) 2020 Laura Garcia Liebana <nevola@gmail.com>
*/
#include <linux/kernel.h>
@@ -11,107 +12,21 @@
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nft_reject.h>
-#include <net/netfilter/ipv4/nf_reject.h>
-#include <net/netfilter/ipv6/nf_reject.h>
+#include <net/netfilter/ipv4/nft_reject_ipv4.h>
+#include <net/netfilter/ipv6/nft_reject_ipv6.h>
static void nft_reject_inet_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
- struct nft_reject *priv = nft_expr_priv(expr);
-
switch (nft_pf(pkt)) {
case NFPROTO_IPV4:
- switch (priv->type) {
- case NFT_REJECT_ICMP_UNREACH:
- nf_send_unreach(pkt->skb, priv->icmp_code,
- nft_hook(pkt));
- break;
- case NFT_REJECT_TCP_RST:
- nf_send_reset(nft_net(pkt), pkt->skb, nft_hook(pkt));
- break;
- case NFT_REJECT_ICMPX_UNREACH:
- nf_send_unreach(pkt->skb,
- nft_reject_icmp_code(priv->icmp_code),
- nft_hook(pkt));
- break;
- }
+ nft_reject_ipv4_eval(expr, regs, pkt);
break;
case NFPROTO_IPV6:
- switch (priv->type) {
- case NFT_REJECT_ICMP_UNREACH:
- nf_send_unreach6(nft_net(pkt), pkt->skb,
- priv->icmp_code, nft_hook(pkt));
- break;
- case NFT_REJECT_TCP_RST:
- nf_send_reset6(nft_net(pkt), pkt->skb, nft_hook(pkt));
- break;
- case NFT_REJECT_ICMPX_UNREACH:
- nf_send_unreach6(nft_net(pkt), pkt->skb,
- nft_reject_icmpv6_code(priv->icmp_code),
- nft_hook(pkt));
- break;
- }
- break;
- }
-
- regs->verdict.code = NF_DROP;
-}
-
-static int nft_reject_inet_init(const struct nft_ctx *ctx,
- const struct nft_expr *expr,
- const struct nlattr * const tb[])
-{
- struct nft_reject *priv = nft_expr_priv(expr);
- int icmp_code;
-
- if (tb[NFTA_REJECT_TYPE] == NULL)
- return -EINVAL;
-
- priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
- switch (priv->type) {
- case NFT_REJECT_ICMP_UNREACH:
- case NFT_REJECT_ICMPX_UNREACH:
- if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
- return -EINVAL;
-
- icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
- if (priv->type == NFT_REJECT_ICMPX_UNREACH &&
- icmp_code > NFT_REJECT_ICMPX_MAX)
- return -EINVAL;
-
- priv->icmp_code = icmp_code;
+ nft_reject_ipv6_eval(expr, regs, pkt);
break;
- case NFT_REJECT_TCP_RST:
- break;
- default:
- return -EINVAL;
}
- return 0;
-}
-
-static int nft_reject_inet_dump(struct sk_buff *skb,
- const struct nft_expr *expr)
-{
- const struct nft_reject *priv = nft_expr_priv(expr);
-
- if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
- goto nla_put_failure;
-
- switch (priv->type) {
- case NFT_REJECT_ICMP_UNREACH:
- case NFT_REJECT_ICMPX_UNREACH:
- if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
- goto nla_put_failure;
- break;
- default:
- break;
- }
-
- return 0;
-
-nla_put_failure:
- return -1;
}
static struct nft_expr_type nft_reject_inet_type;
@@ -119,9 +34,9 @@ static const struct nft_expr_ops nft_reject_inet_ops = {
.type = &nft_reject_inet_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_reject)),
.eval = nft_reject_inet_eval,
- .init = nft_reject_inet_init,
- .dump = nft_reject_inet_dump,
- .validate = nft_reject_validate,
+ .init = nft_reject_init,
+ .dump = nft_reject_dump,
+ .validate = nft_reject_generic_validate,
};
static struct nft_expr_type nft_reject_inet_type __read_mostly = {
--
2.20.1
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2020-06-08 19:00 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2020-06-08 19:00 [PATCH nf-next 1/2] netfilter: nft: refactor reject verdict source code Laura Garcia Liebana
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.