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

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
...@@ -40,10 +40,6 @@ config NF_TABLES_IPV4 ...@@ -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"
......
...@@ -28,7 +28,6 @@ obj-$(CONFIG_NF_NAT_SNMP_BASIC) += nf_nat_snmp_basic.o ...@@ -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
......
...@@ -465,6 +465,12 @@ config NFT_QUEUE ...@@ -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
......
...@@ -77,6 +77,7 @@ obj-$(CONFIG_NFT_CT) += nft_ct.o ...@@ -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
......
/* /*
* 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 @@ ...@@ -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, ...@@ -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, ...@@ -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) ...@@ -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) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment