cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

nft_reject.c (3400B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright (c) 2008-2009 Patrick McHardy <kaber@trash.net>
      4 * Copyright (c) 2013 Eric Leblond <eric@regit.org>
      5 *
      6 * Development of this code funded by Astaro AG (http://www.astaro.com/)
      7 */
      8
      9#include <linux/kernel.h>
     10#include <linux/init.h>
     11#include <linux/module.h>
     12#include <linux/netlink.h>
     13#include <linux/netfilter.h>
     14#include <linux/netfilter/nf_tables.h>
     15#include <net/netfilter/nf_tables.h>
     16#include <net/netfilter/nft_reject.h>
     17#include <linux/icmp.h>
     18#include <linux/icmpv6.h>
     19
     20const struct nla_policy nft_reject_policy[NFTA_REJECT_MAX + 1] = {
     21	[NFTA_REJECT_TYPE]		= { .type = NLA_U32 },
     22	[NFTA_REJECT_ICMP_CODE]		= { .type = NLA_U8 },
     23};
     24EXPORT_SYMBOL_GPL(nft_reject_policy);
     25
     26int nft_reject_validate(const struct nft_ctx *ctx,
     27			const struct nft_expr *expr,
     28			const struct nft_data **data)
     29{
     30	return nft_chain_validate_hooks(ctx->chain,
     31					(1 << NF_INET_LOCAL_IN) |
     32					(1 << NF_INET_FORWARD) |
     33					(1 << NF_INET_LOCAL_OUT) |
     34					(1 << NF_INET_PRE_ROUTING));
     35}
     36EXPORT_SYMBOL_GPL(nft_reject_validate);
     37
     38int nft_reject_init(const struct nft_ctx *ctx,
     39		    const struct nft_expr *expr,
     40		    const struct nlattr * const tb[])
     41{
     42	struct nft_reject *priv = nft_expr_priv(expr);
     43	int icmp_code;
     44
     45	if (tb[NFTA_REJECT_TYPE] == NULL)
     46		return -EINVAL;
     47
     48	priv->type = ntohl(nla_get_be32(tb[NFTA_REJECT_TYPE]));
     49	switch (priv->type) {
     50	case NFT_REJECT_ICMP_UNREACH:
     51	case NFT_REJECT_ICMPX_UNREACH:
     52		if (tb[NFTA_REJECT_ICMP_CODE] == NULL)
     53			return -EINVAL;
     54
     55		icmp_code = nla_get_u8(tb[NFTA_REJECT_ICMP_CODE]);
     56		if (priv->type == NFT_REJECT_ICMPX_UNREACH &&
     57		    icmp_code > NFT_REJECT_ICMPX_MAX)
     58			return -EINVAL;
     59
     60		priv->icmp_code = icmp_code;
     61		break;
     62	case NFT_REJECT_TCP_RST:
     63		break;
     64	default:
     65		return -EINVAL;
     66	}
     67
     68	return 0;
     69}
     70EXPORT_SYMBOL_GPL(nft_reject_init);
     71
     72int nft_reject_dump(struct sk_buff *skb, const struct nft_expr *expr)
     73{
     74	const struct nft_reject *priv = nft_expr_priv(expr);
     75
     76	if (nla_put_be32(skb, NFTA_REJECT_TYPE, htonl(priv->type)))
     77		goto nla_put_failure;
     78
     79	switch (priv->type) {
     80	case NFT_REJECT_ICMP_UNREACH:
     81	case NFT_REJECT_ICMPX_UNREACH:
     82		if (nla_put_u8(skb, NFTA_REJECT_ICMP_CODE, priv->icmp_code))
     83			goto nla_put_failure;
     84		break;
     85	default:
     86		break;
     87	}
     88
     89	return 0;
     90
     91nla_put_failure:
     92	return -1;
     93}
     94EXPORT_SYMBOL_GPL(nft_reject_dump);
     95
     96static u8 icmp_code_v4[NFT_REJECT_ICMPX_MAX + 1] = {
     97	[NFT_REJECT_ICMPX_NO_ROUTE]		= ICMP_NET_UNREACH,
     98	[NFT_REJECT_ICMPX_PORT_UNREACH]		= ICMP_PORT_UNREACH,
     99	[NFT_REJECT_ICMPX_HOST_UNREACH]		= ICMP_HOST_UNREACH,
    100	[NFT_REJECT_ICMPX_ADMIN_PROHIBITED]	= ICMP_PKT_FILTERED,
    101};
    102
    103int nft_reject_icmp_code(u8 code)
    104{
    105	if (WARN_ON_ONCE(code > NFT_REJECT_ICMPX_MAX))
    106		return ICMP_NET_UNREACH;
    107
    108	return icmp_code_v4[code];
    109}
    110
    111EXPORT_SYMBOL_GPL(nft_reject_icmp_code);
    112
    113
    114static u8 icmp_code_v6[NFT_REJECT_ICMPX_MAX + 1] = {
    115	[NFT_REJECT_ICMPX_NO_ROUTE]		= ICMPV6_NOROUTE,
    116	[NFT_REJECT_ICMPX_PORT_UNREACH]		= ICMPV6_PORT_UNREACH,
    117	[NFT_REJECT_ICMPX_HOST_UNREACH]		= ICMPV6_ADDR_UNREACH,
    118	[NFT_REJECT_ICMPX_ADMIN_PROHIBITED]	= ICMPV6_ADM_PROHIBITED,
    119};
    120
    121int nft_reject_icmpv6_code(u8 code)
    122{
    123	if (WARN_ON_ONCE(code > NFT_REJECT_ICMPX_MAX))
    124		return ICMPV6_NOROUTE;
    125
    126	return icmp_code_v6[code];
    127}
    128
    129EXPORT_SYMBOL_GPL(nft_reject_icmpv6_code);
    130
    131MODULE_LICENSE("GPL");
    132MODULE_AUTHOR("Patrick McHardy <kaber@trash.net>");
    133MODULE_DESCRIPTION("Netfilter x_tables over nftables module");