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