~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/net/netfilter/nft_range.c

Version: ~ [ linux-5.10-rc5 ] ~ [ linux-5.9.10 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.79 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.159 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.208 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.245 ] ~ [ linux-4.8.17 ] ~ [ linux-4.7.10 ] ~ [ linux-4.6.7 ] ~ [ linux-4.5.7 ] ~ [ linux-4.4.245 ] ~ [ linux-4.3.6 ] ~ [ linux-4.2.8 ] ~ [ linux-4.1.52 ] ~ [ linux-4.0.9 ] ~ [ linux-3.19.8 ] ~ [ linux-3.18.140 ] ~ [ linux-3.17.8 ] ~ [ linux-3.16.85 ] ~ [ linux-3.15.10 ] ~ [ linux-3.14.79 ] ~ [ linux-3.13.11 ] ~ [ linux-3.12.74 ] ~ [ linux-3.11.10 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.5 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 // SPDX-License-Identifier: GPL-2.0-only
  2 /*
  3  * Copyright (c) 2016 Pablo Neira Ayuso <pablo@netfilter.org>
  4  */
  5 
  6 #include <linux/kernel.h>
  7 #include <linux/init.h>
  8 #include <linux/module.h>
  9 #include <linux/netlink.h>
 10 #include <linux/netfilter.h>
 11 #include <linux/netfilter/nf_tables.h>
 12 #include <net/netfilter/nf_tables_core.h>
 13 #include <net/netfilter/nf_tables.h>
 14 
 15 struct nft_range_expr {
 16         struct nft_data         data_from;
 17         struct nft_data         data_to;
 18         enum nft_registers      sreg:8;
 19         u8                      len;
 20         enum nft_range_ops      op:8;
 21 };
 22 
 23 void nft_range_eval(const struct nft_expr *expr,
 24                     struct nft_regs *regs, const struct nft_pktinfo *pkt)
 25 {
 26         const struct nft_range_expr *priv = nft_expr_priv(expr);
 27         int d1, d2;
 28 
 29         d1 = memcmp(&regs->data[priv->sreg], &priv->data_from, priv->len);
 30         d2 = memcmp(&regs->data[priv->sreg], &priv->data_to, priv->len);
 31         switch (priv->op) {
 32         case NFT_RANGE_EQ:
 33                 if (d1 < 0 || d2 > 0)
 34                         regs->verdict.code = NFT_BREAK;
 35                 break;
 36         case NFT_RANGE_NEQ:
 37                 if (d1 >= 0 && d2 <= 0)
 38                         regs->verdict.code = NFT_BREAK;
 39                 break;
 40         }
 41 }
 42 
 43 static const struct nla_policy nft_range_policy[NFTA_RANGE_MAX + 1] = {
 44         [NFTA_RANGE_SREG]               = { .type = NLA_U32 },
 45         [NFTA_RANGE_OP]                 = { .type = NLA_U32 },
 46         [NFTA_RANGE_FROM_DATA]          = { .type = NLA_NESTED },
 47         [NFTA_RANGE_TO_DATA]            = { .type = NLA_NESTED },
 48 };
 49 
 50 static int nft_range_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
 51                         const struct nlattr * const tb[])
 52 {
 53         struct nft_range_expr *priv = nft_expr_priv(expr);
 54         struct nft_data_desc desc_from, desc_to;
 55         int err;
 56         u32 op;
 57 
 58         if (!tb[NFTA_RANGE_SREG]      ||
 59             !tb[NFTA_RANGE_OP]        ||
 60             !tb[NFTA_RANGE_FROM_DATA] ||
 61             !tb[NFTA_RANGE_TO_DATA])
 62                 return -EINVAL;
 63 
 64         err = nft_data_init(NULL, &priv->data_from, sizeof(priv->data_from),
 65                             &desc_from, tb[NFTA_RANGE_FROM_DATA]);
 66         if (err < 0)
 67                 return err;
 68 
 69         err = nft_data_init(NULL, &priv->data_to, sizeof(priv->data_to),
 70                             &desc_to, tb[NFTA_RANGE_TO_DATA]);
 71         if (err < 0)
 72                 goto err1;
 73 
 74         if (desc_from.len != desc_to.len) {
 75                 err = -EINVAL;
 76                 goto err2;
 77         }
 78 
 79         priv->sreg = nft_parse_register(tb[NFTA_RANGE_SREG]);
 80         err = nft_validate_register_load(priv->sreg, desc_from.len);
 81         if (err < 0)
 82                 goto err2;
 83 
 84         err = nft_parse_u32_check(tb[NFTA_RANGE_OP], U8_MAX, &op);
 85         if (err < 0)
 86                 goto err2;
 87 
 88         switch (op) {
 89         case NFT_RANGE_EQ:
 90         case NFT_RANGE_NEQ:
 91                 break;
 92         default:
 93                 err = -EINVAL;
 94                 goto err2;
 95         }
 96 
 97         priv->op  = op;
 98         priv->len = desc_from.len;
 99         return 0;
100 err2:
101         nft_data_release(&priv->data_to, desc_to.type);
102 err1:
103         nft_data_release(&priv->data_from, desc_from.type);
104         return err;
105 }
106 
107 static int nft_range_dump(struct sk_buff *skb, const struct nft_expr *expr)
108 {
109         const struct nft_range_expr *priv = nft_expr_priv(expr);
110 
111         if (nft_dump_register(skb, NFTA_RANGE_SREG, priv->sreg))
112                 goto nla_put_failure;
113         if (nla_put_be32(skb, NFTA_RANGE_OP, htonl(priv->op)))
114                 goto nla_put_failure;
115 
116         if (nft_data_dump(skb, NFTA_RANGE_FROM_DATA, &priv->data_from,
117                           NFT_DATA_VALUE, priv->len) < 0 ||
118             nft_data_dump(skb, NFTA_RANGE_TO_DATA, &priv->data_to,
119                           NFT_DATA_VALUE, priv->len) < 0)
120                 goto nla_put_failure;
121         return 0;
122 
123 nla_put_failure:
124         return -1;
125 }
126 
127 static const struct nft_expr_ops nft_range_ops = {
128         .type           = &nft_range_type,
129         .size           = NFT_EXPR_SIZE(sizeof(struct nft_range_expr)),
130         .eval           = nft_range_eval,
131         .init           = nft_range_init,
132         .dump           = nft_range_dump,
133 };
134 
135 struct nft_expr_type nft_range_type __read_mostly = {
136         .name           = "range",
137         .ops            = &nft_range_ops,
138         .policy         = nft_range_policy,
139         .maxattr        = NFTA_RANGE_MAX,
140         .owner          = THIS_MODULE,
141 };
142 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | Wiki (Japanese) | Wiki (English) | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

osdn.jp