Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit bee11dc7 authored by Eric Leblond's avatar Eric Leblond Committed by Pablo Neira Ayuso
Browse files

netfilter: nft_reject: support for IPv6 and TCP reset



This patch moves nft_reject_ipv4 to nft_reject and adds support
for IPv6 protocol. This patch uses functions included in nf_reject.h
to implement reject by TCP reset.

The code has to be build as a module if NF_TABLES_IPV6 is also a
module to avoid compilation error due to usage of IPv6 functions.
This has been done in Kconfig by using the construct:

 depends on NF_TABLES_IPV6 || !NF_TABLES_IPV6

This seems a bit weird in terms of syntax but works perfectly.

Signed-off-by: default avatarEric Leblond <eric@regit.org>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent cc70d069
Loading
Loading
Loading
Loading
+0 −4
Original line number Diff line number Diff line
@@ -40,10 +40,6 @@ config NF_TABLES_IPV4
	depends on NF_TABLES
	tristate "IPv4 nf_tables support"

config NFT_REJECT_IPV4
	depends on NF_TABLES_IPV4
	tristate "nf_tables IPv4 reject support"

config NFT_CHAIN_ROUTE_IPV4
	depends on NF_TABLES_IPV4
	tristate "IPv4 nf_tables route chain support"
+0 −1
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o
obj-$(CONFIG_NF_NAT_PROTO_GRE) += nf_nat_proto_gre.o

obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.o
obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV4) += nft_chain_route_ipv4.o
obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o
+6 −0
Original line number Diff line number Diff line
@@ -465,6 +465,12 @@ config NFT_QUEUE
	  This is required if you intend to use the userspace queueing
	  infrastructure (also known as NFQUEUE) from nftables.

config NFT_REJECT
	depends on NF_TABLES
	depends on NF_TABLES_IPV6 || !NF_TABLES_IPV6
	default m if NETFILTER_ADVANCED=n
	tristate "Netfilter nf_tables reject support"

config NFT_COMPAT
	depends on NF_TABLES
	depends on NETFILTER_XTABLES
+1 −0
Original line number Diff line number Diff line
@@ -77,6 +77,7 @@ obj-$(CONFIG_NFT_CT) += nft_ct.o
obj-$(CONFIG_NFT_LIMIT)		+= nft_limit.o
obj-$(CONFIG_NFT_NAT)		+= nft_nat.o
obj-$(CONFIG_NFT_QUEUE)		+= nft_queue.o
obj-$(CONFIG_NFT_REJECT) 	+= nft_reject.o
obj-$(CONFIG_NFT_RBTREE)	+= nft_rbtree.o
obj-$(CONFIG_NFT_HASH)		+= nft_hash.o
obj-$(CONFIG_NFT_COUNTER)	+= nft_counter.o
+23 −2
Original line number Diff line number Diff line
/*
 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
 * Copyright (c) 2013 Eric Leblond <eric@regit.org>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
@@ -16,10 +17,16 @@
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
#include <net/icmp.h>
#include <net/netfilter/ipv4/nf_reject.h>

#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
#include <net/netfilter/ipv6/nf_reject.h>
#endif

struct nft_reject {
	enum nft_reject_types	type:8;
	u8			icmp_code;
	u8			family;
};

static void nft_reject_eval(const struct nft_expr *expr,
@@ -27,12 +34,25 @@ static void nft_reject_eval(const struct nft_expr *expr,
			      const struct nft_pktinfo *pkt)
{
	struct nft_reject *priv = nft_expr_priv(expr);
	struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);

	switch (priv->type) {
	case NFT_REJECT_ICMP_UNREACH:
		icmp_send(pkt->skb, ICMP_DEST_UNREACH, priv->icmp_code, 0);
		if (priv->family == NFPROTO_IPV4)
			nf_send_unreach(pkt->skb, priv->icmp_code);
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
		else if (priv->family == NFPROTO_IPV6)
			nf_send_unreach6(net, pkt->skb, priv->icmp_code,
				      pkt->hooknum);
#endif
		break;
	case NFT_REJECT_TCP_RST:
		if (priv->family == NFPROTO_IPV4)
			nf_send_reset(pkt->skb, pkt->hooknum);
#if IS_ENABLED(CONFIG_NF_TABLES_IPV6)
		else if (priv->family == NFPROTO_IPV6)
			nf_send_reset6(net, pkt->skb, pkt->hooknum);
#endif
		break;
	}

@@ -53,6 +73,7 @@ static int nft_reject_init(const struct nft_ctx *ctx,
	if (tb[NFTA_REJECT_TYPE] == NULL)
		return -EINVAL;

	priv->family = ctx->afi->family;
	priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
	switch (priv->type) {
	case NFT_REJECT_ICMP_UNREACH:
@@ -72,7 +93,7 @@ static int nft_reject_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, priv->type))
	if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
		goto nla_put_failure;

	switch (priv->type) {