All of lore.kernel.org
 help / color / mirror / Atom feed
From: Laura Garcia Liebana <nevola@gmail.com>
To: netfilter-devel@vger.kernel.org
Cc: pablo@netfilter.org, devel@zevenet.com
Subject: [PATCH nf-next 1/2] netfilter: nft: refactor reject verdict source code
Date: Mon, 8 Jun 2020 21:00:21 +0200	[thread overview]
Message-ID: <20200608190021.GA23098@nevthink> (raw)

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


                 reply	other threads:[~2020-06-08 19:00 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200608190021.GA23098@nevthink \
    --to=nevola@gmail.com \
    --cc=devel@zevenet.com \
    --cc=netfilter-devel@vger.kernel.org \
    --cc=pablo@netfilter.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.