Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

netfilter: nft_redir: add inet support

allows to redirect both ipv4 and ipv6 with a single rule in an
inet nat table.

Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>

authored by

Florian Westphal and committed by
Pablo Neira Ayuso
63ce3940 071657d2

+61
+61
net/netfilter/nft_redir.c
··· 202 202 }; 203 203 #endif 204 204 205 + #ifdef CONFIG_NF_TABLES_INET 206 + static void nft_redir_inet_eval(const struct nft_expr *expr, 207 + struct nft_regs *regs, 208 + const struct nft_pktinfo *pkt) 209 + { 210 + switch (nft_pf(pkt)) { 211 + case NFPROTO_IPV4: 212 + return nft_redir_ipv4_eval(expr, regs, pkt); 213 + case NFPROTO_IPV6: 214 + return nft_redir_ipv6_eval(expr, regs, pkt); 215 + } 216 + 217 + WARN_ON_ONCE(1); 218 + } 219 + 220 + static void 221 + nft_redir_inet_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr) 222 + { 223 + nf_ct_netns_put(ctx->net, NFPROTO_INET); 224 + } 225 + 226 + static struct nft_expr_type nft_redir_inet_type; 227 + static const struct nft_expr_ops nft_redir_inet_ops = { 228 + .type = &nft_redir_inet_type, 229 + .size = NFT_EXPR_SIZE(sizeof(struct nft_redir)), 230 + .eval = nft_redir_inet_eval, 231 + .init = nft_redir_init, 232 + .destroy = nft_redir_inet_destroy, 233 + .dump = nft_redir_dump, 234 + .validate = nft_redir_validate, 235 + }; 236 + 237 + static struct nft_expr_type nft_redir_inet_type __read_mostly = { 238 + .family = NFPROTO_INET, 239 + .name = "redir", 240 + .ops = &nft_redir_inet_ops, 241 + .policy = nft_redir_policy, 242 + .maxattr = NFTA_MASQ_MAX, 243 + .owner = THIS_MODULE, 244 + }; 245 + 246 + static int __init nft_redir_module_init_inet(void) 247 + { 248 + return nft_register_expr(&nft_redir_inet_type); 249 + } 250 + #else 251 + static inline int nft_redir_module_init_inet(void) { return 0; } 252 + #endif 253 + 205 254 static int __init nft_redir_module_init(void) 206 255 { 207 256 int ret = nft_register_expr(&nft_redir_ipv4_type); ··· 266 217 } 267 218 #endif 268 219 220 + ret = nft_redir_module_init_inet(); 221 + if (ret < 0) { 222 + nft_unregister_expr(&nft_redir_ipv4_type); 223 + #ifdef CONFIG_NF_TABLES_IPV6 224 + nft_unregister_expr(&nft_redir_ipv6_type); 225 + #endif 226 + return ret; 227 + } 228 + 269 229 return ret; 270 230 } 271 231 ··· 283 225 nft_unregister_expr(&nft_redir_ipv4_type); 284 226 #ifdef CONFIG_NF_TABLES_IPV6 285 227 nft_unregister_expr(&nft_redir_ipv6_type); 228 + #endif 229 + #ifdef CONFIG_NF_TABLES_INET 230 + nft_unregister_expr(&nft_redir_inet_type); 286 231 #endif 287 232 } 288 233