Commit c78efc99 authored by Florian Westphal's avatar Florian Westphal Committed by Pablo Neira Ayuso

netfilter: nf_tables: nat: merge nft_redir protocol specific modules

before:
 text	   data	    bss	    dec	    hex	filename
 990	    832	      0	   1822	    71e nft_redir.ko
 697	    896	      0	   1593	    639 nft_redir_ipv4.ko
 713	    896	      0	   1609	    649	nft_redir_ipv6.ko

after:
 text	   data	    bss	    dec	    hex	filename
 1910	    960	      0	   2870	    b36	nft_redir.ko

size is reduced, all helpers from nft_redir.ko can be made static.
Signed-off-by: default avatarFlorian Westphal <fw@strlen.de>
Signed-off-by: default avatarPablo Neira Ayuso <pablo@netfilter.org>
parent 20fdaf6e
/* SPDX-License-Identifier: GPL-2.0 */
#ifndef _NFT_REDIR_H_
#define _NFT_REDIR_H_
struct nft_redir {
enum nft_registers sreg_proto_min:8;
enum nft_registers sreg_proto_max:8;
u16 flags;
};
extern const struct nla_policy nft_redir_policy[];
int nft_redir_init(const struct nft_ctx *ctx,
const struct nft_expr *expr,
const struct nlattr * const tb[]);
int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr);
int nft_redir_validate(const struct nft_ctx *ctx, const struct nft_expr *expr,
const struct nft_data **data);
#endif /* _NFT_REDIR_H_ */
...@@ -115,14 +115,6 @@ config NFT_MASQ_IPV4 ...@@ -115,14 +115,6 @@ config NFT_MASQ_IPV4
This is the expression that provides IPv4 masquerading support for This is the expression that provides IPv4 masquerading support for
nf_tables. nf_tables.
config NFT_REDIR_IPV4
tristate "IPv4 redirect support for nf_tables"
depends on NF_TABLES_IPV4
depends on NFT_REDIR
select NF_NAT_REDIRECT
help
This is the expression that provides IPv4 redirect support for
nf_tables.
endif # NF_TABLES endif # NF_TABLES
config NF_NAT_SNMP_BASIC config NF_NAT_SNMP_BASIC
......
...@@ -29,7 +29,6 @@ obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o ...@@ -29,7 +29,6 @@ obj-$(CONFIG_NFT_CHAIN_NAT_IPV4) += nft_chain_nat_ipv4.o
obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o obj-$(CONFIG_NFT_REJECT_IPV4) += nft_reject_ipv4.o
obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o obj-$(CONFIG_NFT_FIB_IPV4) += nft_fib_ipv4.o
obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o obj-$(CONFIG_NFT_MASQ_IPV4) += nft_masq_ipv4.o
obj-$(CONFIG_NFT_REDIR_IPV4) += nft_redir_ipv4.o
obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o obj-$(CONFIG_NFT_DUP_IPV4) += nft_dup_ipv4.o
# flow table support # flow table support
......
/*
* Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#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.h>
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_redirect.h>
#include <net/netfilter/nft_redir.h>
static void nft_redir_ipv4_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_redir *priv = nft_expr_priv(expr);
struct nf_nat_ipv4_multi_range_compat mr;
memset(&mr, 0, sizeof(mr));
if (priv->sreg_proto_min) {
mr.range[0].min.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_min]);
mr.range[0].max.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_max]);
mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
mr.range[0].flags |= priv->flags;
regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr, nft_hook(pkt));
}
static void
nft_redir_ipv4_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
nf_ct_netns_put(ctx->net, NFPROTO_IPV4);
}
static struct nft_expr_type nft_redir_ipv4_type;
static const struct nft_expr_ops nft_redir_ipv4_ops = {
.type = &nft_redir_ipv4_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
.eval = nft_redir_ipv4_eval,
.init = nft_redir_init,
.destroy = nft_redir_ipv4_destroy,
.dump = nft_redir_dump,
.validate = nft_redir_validate,
};
static struct nft_expr_type nft_redir_ipv4_type __read_mostly = {
.family = NFPROTO_IPV4,
.name = "redir",
.ops = &nft_redir_ipv4_ops,
.policy = nft_redir_policy,
.maxattr = NFTA_REDIR_MAX,
.owner = THIS_MODULE,
};
static int __init nft_redir_ipv4_module_init(void)
{
return nft_register_expr(&nft_redir_ipv4_type);
}
static void __exit nft_redir_ipv4_module_exit(void)
{
nft_unregister_expr(&nft_redir_ipv4_type);
}
module_init(nft_redir_ipv4_module_init);
module_exit(nft_redir_ipv4_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
MODULE_ALIAS_NFT_AF_EXPR(AF_INET, "redir");
...@@ -49,14 +49,6 @@ config NFT_MASQ_IPV6 ...@@ -49,14 +49,6 @@ config NFT_MASQ_IPV6
This is the expression that provides IPv4 masquerading support for This is the expression that provides IPv4 masquerading support for
nf_tables. nf_tables.
config NFT_REDIR_IPV6
tristate "IPv6 redirect support for nf_tables"
depends on NFT_REDIR
select NF_NAT_REDIRECT
help
This is the expression that provides IPv4 redirect support for
nf_tables.
endif # NF_NAT endif # NF_NAT
config NFT_REJECT_IPV6 config NFT_REJECT_IPV6
......
...@@ -31,7 +31,6 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o ...@@ -31,7 +31,6 @@ obj-$(CONFIG_NFT_CHAIN_ROUTE_IPV6) += nft_chain_route_ipv6.o
obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o obj-$(CONFIG_NFT_CHAIN_NAT_IPV6) += nft_chain_nat_ipv6.o
obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o obj-$(CONFIG_NFT_REJECT_IPV6) += nft_reject_ipv6.o
obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o obj-$(CONFIG_NFT_MASQ_IPV6) += nft_masq_ipv6.o
obj-$(CONFIG_NFT_REDIR_IPV6) += nft_redir_ipv6.o
obj-$(CONFIG_NFT_DUP_IPV6) += nft_dup_ipv6.o obj-$(CONFIG_NFT_DUP_IPV6) += nft_dup_ipv6.o
obj-$(CONFIG_NFT_FIB_IPV6) += nft_fib_ipv6.o obj-$(CONFIG_NFT_FIB_IPV6) += nft_fib_ipv6.o
......
/*
* Copyright (c) 2014 Arturo Borrero Gonzalez <arturo@debian.org>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#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.h>
#include <net/netfilter/nf_nat.h>
#include <net/netfilter/nft_redir.h>
#include <net/netfilter/nf_nat_redirect.h>
static void nft_redir_ipv6_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_redir *priv = nft_expr_priv(expr);
struct nf_nat_range2 range;
memset(&range, 0, sizeof(range));
if (priv->sreg_proto_min) {
range.min_proto.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_min]);
range.max_proto.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_max]);
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
range.flags |= priv->flags;
regs->verdict.code =
nf_nat_redirect_ipv6(pkt->skb, &range, nft_hook(pkt));
}
static void
nft_redir_ipv6_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
nf_ct_netns_put(ctx->net, NFPROTO_IPV6);
}
static struct nft_expr_type nft_redir_ipv6_type;
static const struct nft_expr_ops nft_redir_ipv6_ops = {
.type = &nft_redir_ipv6_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
.eval = nft_redir_ipv6_eval,
.init = nft_redir_init,
.destroy = nft_redir_ipv6_destroy,
.dump = nft_redir_dump,
.validate = nft_redir_validate,
};
static struct nft_expr_type nft_redir_ipv6_type __read_mostly = {
.family = NFPROTO_IPV6,
.name = "redir",
.ops = &nft_redir_ipv6_ops,
.policy = nft_redir_policy,
.maxattr = NFTA_REDIR_MAX,
.owner = THIS_MODULE,
};
static int __init nft_redir_ipv6_module_init(void)
{
return nft_register_expr(&nft_redir_ipv6_type);
}
static void __exit nft_redir_ipv6_module_exit(void)
{
nft_unregister_expr(&nft_redir_ipv6_type);
}
module_init(nft_redir_ipv6_module_init);
module_exit(nft_redir_ipv6_module_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir");
...@@ -541,6 +541,7 @@ config NFT_REDIR ...@@ -541,6 +541,7 @@ config NFT_REDIR
depends on NF_CONNTRACK depends on NF_CONNTRACK
depends on NF_NAT depends on NF_NAT
tristate "Netfilter nf_tables redirect support" tristate "Netfilter nf_tables redirect support"
select NF_NAT_REDIRECT
help help
This options adds the "redirect" expression that you can use This options adds the "redirect" expression that you can use
to perform NAT in the redirect flavour. to perform NAT in the redirect flavour.
......
...@@ -13,19 +13,24 @@ ...@@ -13,19 +13,24 @@
#include <linux/netfilter.h> #include <linux/netfilter.h>
#include <linux/netfilter/nf_tables.h> #include <linux/netfilter/nf_tables.h>
#include <net/netfilter/nf_nat.h> #include <net/netfilter/nf_nat.h>
#include <net/netfilter/nf_nat_redirect.h>
#include <net/netfilter/nf_tables.h> #include <net/netfilter/nf_tables.h>
#include <net/netfilter/nft_redir.h>
const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = { struct nft_redir {
enum nft_registers sreg_proto_min:8;
enum nft_registers sreg_proto_max:8;
u16 flags;
};
static const struct nla_policy nft_redir_policy[NFTA_REDIR_MAX + 1] = {
[NFTA_REDIR_REG_PROTO_MIN] = { .type = NLA_U32 }, [NFTA_REDIR_REG_PROTO_MIN] = { .type = NLA_U32 },
[NFTA_REDIR_REG_PROTO_MAX] = { .type = NLA_U32 }, [NFTA_REDIR_REG_PROTO_MAX] = { .type = NLA_U32 },
[NFTA_REDIR_FLAGS] = { .type = NLA_U32 }, [NFTA_REDIR_FLAGS] = { .type = NLA_U32 },
}; };
EXPORT_SYMBOL_GPL(nft_redir_policy);
int nft_redir_validate(const struct nft_ctx *ctx, static int nft_redir_validate(const struct nft_ctx *ctx,
const struct nft_expr *expr, const struct nft_expr *expr,
const struct nft_data **data) const struct nft_data **data)
{ {
int err; int err;
...@@ -37,11 +42,10 @@ int nft_redir_validate(const struct nft_ctx *ctx, ...@@ -37,11 +42,10 @@ int nft_redir_validate(const struct nft_ctx *ctx,
(1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_PRE_ROUTING) |
(1 << NF_INET_LOCAL_OUT)); (1 << NF_INET_LOCAL_OUT));
} }
EXPORT_SYMBOL_GPL(nft_redir_validate);
int nft_redir_init(const struct nft_ctx *ctx, static int nft_redir_init(const struct nft_ctx *ctx,
const struct nft_expr *expr, const struct nft_expr *expr,
const struct nlattr * const tb[]) const struct nlattr * const tb[])
{ {
struct nft_redir *priv = nft_expr_priv(expr); struct nft_redir *priv = nft_expr_priv(expr);
unsigned int plen; unsigned int plen;
...@@ -77,7 +81,6 @@ int nft_redir_init(const struct nft_ctx *ctx, ...@@ -77,7 +81,6 @@ int nft_redir_init(const struct nft_ctx *ctx,
return nf_ct_netns_get(ctx->net, ctx->family); return nf_ct_netns_get(ctx->net, ctx->family);
} }
EXPORT_SYMBOL_GPL(nft_redir_init);
int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr) int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
{ {
...@@ -101,7 +104,134 @@ int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr) ...@@ -101,7 +104,134 @@ int nft_redir_dump(struct sk_buff *skb, const struct nft_expr *expr)
nla_put_failure: nla_put_failure:
return -1; return -1;
} }
EXPORT_SYMBOL_GPL(nft_redir_dump);
static void nft_redir_ipv4_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_redir *priv = nft_expr_priv(expr);
struct nf_nat_ipv4_multi_range_compat mr;
memset(&mr, 0, sizeof(mr));
if (priv->sreg_proto_min) {
mr.range[0].min.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_min]);
mr.range[0].max.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_max]);
mr.range[0].flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
mr.range[0].flags |= priv->flags;
regs->verdict.code = nf_nat_redirect_ipv4(pkt->skb, &mr, nft_hook(pkt));
}
static void
nft_redir_ipv4_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
nf_ct_netns_put(ctx->net, NFPROTO_IPV4);
}
static struct nft_expr_type nft_redir_ipv4_type;
static const struct nft_expr_ops nft_redir_ipv4_ops = {
.type = &nft_redir_ipv4_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
.eval = nft_redir_ipv4_eval,
.init = nft_redir_init,
.destroy = nft_redir_ipv4_destroy,
.dump = nft_redir_dump,
.validate = nft_redir_validate,
};
static struct nft_expr_type nft_redir_ipv4_type __read_mostly = {
.family = NFPROTO_IPV4,
.name = "redir",
.ops = &nft_redir_ipv4_ops,
.policy = nft_redir_policy,
.maxattr = NFTA_REDIR_MAX,
.owner = THIS_MODULE,
};
#ifdef CONFIG_NF_TABLES_IPV6
static void nft_redir_ipv6_eval(const struct nft_expr *expr,
struct nft_regs *regs,
const struct nft_pktinfo *pkt)
{
struct nft_redir *priv = nft_expr_priv(expr);
struct nf_nat_range2 range;
memset(&range, 0, sizeof(range));
if (priv->sreg_proto_min) {
range.min_proto.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_min]);
range.max_proto.all = (__force __be16)nft_reg_load16(
&regs->data[priv->sreg_proto_max]);
range.flags |= NF_NAT_RANGE_PROTO_SPECIFIED;
}
range.flags |= priv->flags;
regs->verdict.code =
nf_nat_redirect_ipv6(pkt->skb, &range, nft_hook(pkt));
}
static void
nft_redir_ipv6_destroy(const struct nft_ctx *ctx, const struct nft_expr *expr)
{
nf_ct_netns_put(ctx->net, NFPROTO_IPV6);
}
static struct nft_expr_type nft_redir_ipv6_type;
static const struct nft_expr_ops nft_redir_ipv6_ops = {
.type = &nft_redir_ipv6_type,
.size = NFT_EXPR_SIZE(sizeof(struct nft_redir)),
.eval = nft_redir_ipv6_eval,
.init = nft_redir_init,
.destroy = nft_redir_ipv6_destroy,
.dump = nft_redir_dump,
.validate = nft_redir_validate,
};
static struct nft_expr_type nft_redir_ipv6_type __read_mostly = {
.family = NFPROTO_IPV6,
.name = "redir",
.ops = &nft_redir_ipv6_ops,
.policy = nft_redir_policy,
.maxattr = NFTA_REDIR_MAX,
.owner = THIS_MODULE,
};
#endif
static int __init nft_redir_module_init(void)
{
int ret = nft_register_expr(&nft_redir_ipv4_type);
if (ret)
return ret;
#ifdef CONFIG_NF_TABLES_IPV6
ret = nft_register_expr(&nft_redir_ipv6_type);
if (ret) {
nft_unregister_expr(&nft_redir_ipv4_type);
return ret;
}
#endif
return ret;
}
static void __exit nft_redir_module_exit(void)
{
nft_unregister_expr(&nft_redir_ipv4_type);
#ifdef CONFIG_NF_TABLES_IPV6
nft_unregister_expr(&nft_redir_ipv6_type);
#endif
}
module_init(nft_redir_module_init);
module_exit(nft_redir_module_exit);
MODULE_LICENSE("GPL"); MODULE_LICENSE("GPL");
MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>"); MODULE_AUTHOR("Arturo Borrero Gonzalez <arturo@debian.org>");
MODULE_ALIAS_NFT_AF_EXPR(AF_INET4, "redir");
MODULE_ALIAS_NFT_AF_EXPR(AF_INET6, "redir");
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment