This patch adds the REJECT support from ingress for both stacks ipv4 and ipv6, but also, both types ICMP and TCP RESET. This ability is required in devices that need to REJECT legitimate clients which traffic are forwarded from the ingress hook. Signed-off-by: Laura Garcia Liebana <nevola@xxxxxxxxx> --- net/netfilter/Kconfig | 10 +++++ net/netfilter/Makefile | 1 + net/netfilter/nft_reject_netdev.c | 65 +++++++++++++++++++++++++++++++ 3 files changed, 76 insertions(+) create mode 100644 net/netfilter/nft_reject_netdev.c diff --git a/net/netfilter/Kconfig b/net/netfilter/Kconfig index 468fea1aebba..25200f249778 100644 --- a/net/netfilter/Kconfig +++ b/net/netfilter/Kconfig @@ -681,6 +681,16 @@ config NFT_FIB_NETDEV The lookup will be delegated to the IPv4 or IPv6 FIB depending on the protocol of the packet. +config NFT_REJECT_NETDEV + depends on NFT_REJECT_IPV4 + depends on NFT_REJECT_IPV6 + tristate "Netfilter nf_tables netdev REJECT support" + help + This option enables the REJECT support from the netdev table. + The return packet generation will be delegated to the IPv4 + or IPv6 ICMP or TCP RST implementation depending on the + protocol of the packet. + endif # NF_TABLES_NETDEV endif # NF_TABLES diff --git a/net/netfilter/Makefile b/net/netfilter/Makefile index 0e0ded87e27b..33da7bf1b68e 100644 --- a/net/netfilter/Makefile +++ b/net/netfilter/Makefile @@ -101,6 +101,7 @@ obj-$(CONFIG_NFT_QUEUE) += nft_queue.o obj-$(CONFIG_NFT_QUOTA) += nft_quota.o obj-$(CONFIG_NFT_REJECT) += nft_reject.o obj-$(CONFIG_NFT_REJECT_INET) += nft_reject_inet.o +obj-$(CONFIG_NFT_REJECT_NETDEV) += nft_reject_netdev.o obj-$(CONFIG_NFT_TUNNEL) += nft_tunnel.o obj-$(CONFIG_NFT_COUNTER) += nft_counter.o obj-$(CONFIG_NFT_LOG) += nft_log.o diff --git a/net/netfilter/nft_reject_netdev.c b/net/netfilter/nft_reject_netdev.c new file mode 100644 index 000000000000..64123d80210d --- /dev/null +++ b/net/netfilter/nft_reject_netdev.c @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright (c) 2020 Laura Garcia Liebana <nevola@xxxxxxxxx> + */ + +#include <linux/kernel.h> +#include <linux/init.h> +#include <linux/module.h> +#include <linux/netlink.h> +#include <linux/netfilter.h> +#include <linux/netfilter/nf_tables.h> +#include <net/netfilter/nf_tables.h> +#include <net/netfilter/nft_reject.h> +#include <net/netfilter/ipv4/nft_reject_ipv4.h> +#include <net/netfilter/ipv6/nft_reject_ipv6.h> + +static void nft_reject_netdev_eval(const struct nft_expr *expr, + struct nft_regs *regs, + const struct nft_pktinfo *pkt) +{ + switch (ntohs(pkt->skb->protocol)) { + case ETH_P_IP: + nft_reject_ipv4_eval(expr, regs, pkt); + break; + case ETH_P_IPV6: + nft_reject_ipv6_eval(expr, regs, pkt); + break; + } +} + +static struct nft_expr_type nft_reject_netdev_type; +static const struct nft_expr_ops nft_reject_netdev_ops = { + .type = &nft_reject_netdev_type, + .size = NFT_EXPR_SIZE(sizeof(struct nft_reject)), + .eval = nft_reject_netdev_eval, + .init = nft_reject_init, + .dump = nft_reject_dump, + .validate = nft_reject_generic_validate, +}; + +static struct nft_expr_type nft_reject_netdev_type __read_mostly = { + .family = NFPROTO_NETDEV, + .name = "reject", + .ops = &nft_reject_netdev_ops, + .policy = nft_reject_policy, + .maxattr = NFTA_REJECT_MAX, + .owner = THIS_MODULE, +}; + +static int __init nft_reject_netdev_module_init(void) +{ + return nft_register_expr(&nft_reject_netdev_type); +} + +static void __exit nft_reject_netdev_module_exit(void) +{ + nft_unregister_expr(&nft_reject_netdev_type); +} + +module_init(nft_reject_netdev_module_init); +module_exit(nft_reject_netdev_module_exit); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Laura Garcia Liebana <nevola@xxxxxxxxx>"); +MODULE_ALIAS_NFT_AF_EXPR(5, "reject"); -- 2.20.1