root/net/netfilter/nft_fib.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. nft_fib_validate
  2. nft_fib_init
  3. nft_fib_dump
  4. nft_fib_store_result

   1 // SPDX-License-Identifier: GPL-2.0-only
   2 /*
   3  *
   4  * Generic part shared by ipv4 and ipv6 backends.
   5  */
   6 
   7 #include <linux/kernel.h>
   8 #include <linux/init.h>
   9 #include <linux/module.h>
  10 #include <linux/netlink.h>
  11 #include <linux/netfilter.h>
  12 #include <linux/netfilter/nf_tables.h>
  13 #include <net/netfilter/nf_tables_core.h>
  14 #include <net/netfilter/nf_tables.h>
  15 #include <net/netfilter/nft_fib.h>
  16 
  17 const struct nla_policy nft_fib_policy[NFTA_FIB_MAX + 1] = {
  18         [NFTA_FIB_DREG]         = { .type = NLA_U32 },
  19         [NFTA_FIB_RESULT]       = { .type = NLA_U32 },
  20         [NFTA_FIB_FLAGS]        = { .type = NLA_U32 },
  21 };
  22 EXPORT_SYMBOL(nft_fib_policy);
  23 
  24 #define NFTA_FIB_F_ALL (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR | \
  25                         NFTA_FIB_F_MARK | NFTA_FIB_F_IIF | NFTA_FIB_F_OIF | \
  26                         NFTA_FIB_F_PRESENT)
  27 
  28 int nft_fib_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
  29                      const struct nft_data **data)
  30 {
  31         const struct nft_fib *priv = nft_expr_priv(expr);
  32         unsigned int hooks;
  33 
  34         switch (priv->result) {
  35         case NFT_FIB_RESULT_OIF: /* fallthrough */
  36         case NFT_FIB_RESULT_OIFNAME:
  37                 hooks = (1 << NF_INET_PRE_ROUTING);
  38                 break;
  39         case NFT_FIB_RESULT_ADDRTYPE:
  40                 if (priv->flags & NFTA_FIB_F_IIF)
  41                         hooks = (1 << NF_INET_PRE_ROUTING) |
  42                                 (1 << NF_INET_LOCAL_IN) |
  43                                 (1 << NF_INET_FORWARD);
  44                 else if (priv->flags & NFTA_FIB_F_OIF)
  45                         hooks = (1 << NF_INET_LOCAL_OUT) |
  46                                 (1 << NF_INET_POST_ROUTING) |
  47                                 (1 << NF_INET_FORWARD);
  48                 else
  49                         hooks = (1 << NF_INET_LOCAL_IN) |
  50                                 (1 << NF_INET_LOCAL_OUT) |
  51                                 (1 << NF_INET_FORWARD) |
  52                                 (1 << NF_INET_PRE_ROUTING) |
  53                                 (1 << NF_INET_POST_ROUTING);
  54 
  55                 break;
  56         default:
  57                 return -EINVAL;
  58         }
  59 
  60         return nft_chain_validate_hooks(ctx->chain, hooks);
  61 }
  62 EXPORT_SYMBOL_GPL(nft_fib_validate);
  63 
  64 int nft_fib_init(const struct nft_ctx *ctx, const struct nft_expr *expr,
  65                  const struct nlattr * const tb[])
  66 {
  67         struct nft_fib *priv = nft_expr_priv(expr);
  68         unsigned int len;
  69         int err;
  70 
  71         if (!tb[NFTA_FIB_DREG] || !tb[NFTA_FIB_RESULT] || !tb[NFTA_FIB_FLAGS])
  72                 return -EINVAL;
  73 
  74         priv->flags = ntohl(nla_get_be32(tb[NFTA_FIB_FLAGS]));
  75 
  76         if (priv->flags == 0 || (priv->flags & ~NFTA_FIB_F_ALL))
  77                 return -EINVAL;
  78 
  79         if ((priv->flags & (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR)) ==
  80                            (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR))
  81                 return -EINVAL;
  82         if ((priv->flags & (NFTA_FIB_F_IIF | NFTA_FIB_F_OIF)) ==
  83                            (NFTA_FIB_F_IIF | NFTA_FIB_F_OIF))
  84                 return -EINVAL;
  85         if ((priv->flags & (NFTA_FIB_F_SADDR | NFTA_FIB_F_DADDR)) == 0)
  86                 return -EINVAL;
  87 
  88         priv->result = ntohl(nla_get_be32(tb[NFTA_FIB_RESULT]));
  89         priv->dreg = nft_parse_register(tb[NFTA_FIB_DREG]);
  90 
  91         switch (priv->result) {
  92         case NFT_FIB_RESULT_OIF:
  93                 if (priv->flags & NFTA_FIB_F_OIF)
  94                         return -EINVAL;
  95                 len = sizeof(int);
  96                 break;
  97         case NFT_FIB_RESULT_OIFNAME:
  98                 if (priv->flags & NFTA_FIB_F_OIF)
  99                         return -EINVAL;
 100                 len = IFNAMSIZ;
 101                 break;
 102         case NFT_FIB_RESULT_ADDRTYPE:
 103                 len = sizeof(u32);
 104                 break;
 105         default:
 106                 return -EINVAL;
 107         }
 108 
 109         err = nft_validate_register_store(ctx, priv->dreg, NULL,
 110                                           NFT_DATA_VALUE, len);
 111         if (err < 0)
 112                 return err;
 113 
 114         return 0;
 115 }
 116 EXPORT_SYMBOL_GPL(nft_fib_init);
 117 
 118 int nft_fib_dump(struct sk_buff *skb, const struct nft_expr *expr)
 119 {
 120         const struct nft_fib *priv = nft_expr_priv(expr);
 121 
 122         if (nft_dump_register(skb, NFTA_FIB_DREG, priv->dreg))
 123                 return -1;
 124 
 125         if (nla_put_be32(skb, NFTA_FIB_RESULT, htonl(priv->result)))
 126                 return -1;
 127 
 128         if (nla_put_be32(skb, NFTA_FIB_FLAGS, htonl(priv->flags)))
 129                 return -1;
 130 
 131         return 0;
 132 }
 133 EXPORT_SYMBOL_GPL(nft_fib_dump);
 134 
 135 void nft_fib_store_result(void *reg, const struct nft_fib *priv,
 136                           const struct net_device *dev)
 137 {
 138         u32 *dreg = reg;
 139         int index;
 140 
 141         switch (priv->result) {
 142         case NFT_FIB_RESULT_OIF:
 143                 index = dev ? dev->ifindex : 0;
 144                 *dreg = (priv->flags & NFTA_FIB_F_PRESENT) ? !!index : index;
 145                 break;
 146         case NFT_FIB_RESULT_OIFNAME:
 147                 if (priv->flags & NFTA_FIB_F_PRESENT)
 148                         *dreg = !!dev;
 149                 else
 150                         strncpy(reg, dev ? dev->name : "", IFNAMSIZ);
 151                 break;
 152         default:
 153                 WARN_ON_ONCE(1);
 154                 *dreg = 0;
 155                 break;
 156         }
 157 }
 158 EXPORT_SYMBOL_GPL(nft_fib_store_result);
 159 
 160 MODULE_LICENSE("GPL");
 161 MODULE_AUTHOR("Florian Westphal <fw@strlen.de>");

/* [<][>][^][v][top][bottom][index][help] */