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 Original line Diff line number Diff line
@@ -40,10 +40,6 @@ config NF_TABLES_IPV4
	depends on NF_TABLES
	depends on NF_TABLES
	tristate "IPv4 nf_tables support"
	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
config NFT_CHAIN_ROUTE_IPV4
	depends on NF_TABLES_IPV4
	depends on NF_TABLES_IPV4
	tristate "IPv4 nf_tables route chain support"
	tristate "IPv4 nf_tables route chain support"
+0 −1
Original line number Original line 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_NAT_PROTO_GRE) += nf_nat_proto_gre.o


obj-$(CONFIG_NF_TABLES_IPV4) += nf_tables_ipv4.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_ROUTE_IPV4) += nft_chain_route_ipv4.o
obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o
obj-$(CONFIG_NF_TABLES_ARP) += nf_tables_arp.o
+6 −0
Original line number Original line Diff line number Diff line
@@ -465,6 +465,12 @@ config NFT_QUEUE
	  This is required if you intend to use the userspace queueing
	  This is required if you intend to use the userspace queueing
	  infrastructure (also known as NFQUEUE) from nftables.
	  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
config NFT_COMPAT
	depends on NF_TABLES
	depends on NF_TABLES
	depends on NETFILTER_XTABLES
	depends on NETFILTER_XTABLES
+1 −0
Original line number Original line 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_LIMIT)		+= nft_limit.o
obj-$(CONFIG_NFT_NAT)		+= nft_nat.o
obj-$(CONFIG_NFT_NAT)		+= nft_nat.o
obj-$(CONFIG_NFT_QUEUE)		+= nft_queue.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_RBTREE)	+= nft_rbtree.o
obj-$(CONFIG_NFT_HASH)		+= nft_hash.o
obj-$(CONFIG_NFT_HASH)		+= nft_hash.o
obj-$(CONFIG_NFT_COUNTER)	+= nft_counter.o
obj-$(CONFIG_NFT_COUNTER)	+= nft_counter.o
+23 −2
Original line number Original line Diff line number Diff line
/*
/*
 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
 * 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
 * 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
 * it under the terms of the GNU General Public License version 2 as
@@ -16,10 +17,16 @@
#include <linux/netfilter/nf_tables.h>
#include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
#include <net/netfilter/nf_tables.h>
#include <net/icmp.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 {
struct nft_reject {
	enum nft_reject_types	type:8;
	enum nft_reject_types	type:8;
	u8			icmp_code;
	u8			icmp_code;
	u8			family;
};
};


static void nft_reject_eval(const struct nft_expr *expr,
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)
			      const struct nft_pktinfo *pkt)
{
{
	struct nft_reject *priv = nft_expr_priv(expr);
	struct nft_reject *priv = nft_expr_priv(expr);
	struct net *net = dev_net((pkt->in != NULL) ? pkt->in : pkt->out);


	switch (priv->type) {
	switch (priv->type) {
	case NFT_REJECT_ICMP_UNREACH:
	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;
		break;
	case NFT_REJECT_TCP_RST:
	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;
		break;
	}
	}


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


	priv->family = ctx->afi->family;
	priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
	priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
	switch (priv->type) {
	switch (priv->type) {
	case NFT_REJECT_ICMP_UNREACH:
	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);
	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;
		goto nla_put_failure;


	switch (priv->type) {
	switch (priv->type) {