ebtable_nat.c 3.0 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
/*
 *  ebtable_nat
 *
 *	Authors:
 *	Bart De Schuymer <bdschuym@pandora.be>
 *
 *  April, 2002
 *
 */

#include <linux/netfilter_bridge/ebtables.h>
#include <linux/module.h>

#define NAT_VALID_HOOKS ((1 << NF_BR_PRE_ROUTING) | (1 << NF_BR_LOCAL_OUT) | \
   (1 << NF_BR_POST_ROUTING))

static struct ebt_entries initial_chains[] =
{
	{
		.name	= "PREROUTING",
		.policy	= EBT_ACCEPT,
	},
	{
		.name	= "OUTPUT",
		.policy	= EBT_ACCEPT,
	},
	{
		.name	= "POSTROUTING",
		.policy	= EBT_ACCEPT,
	}
};

33
static struct ebt_replace_kernel initial_table =
L
Linus Torvalds 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
{
	.name		= "nat",
	.valid_hooks	= NAT_VALID_HOOKS,
	.entries_size	= 3 * sizeof(struct ebt_entries),
	.hook_entry	= {
		[NF_BR_PRE_ROUTING]	= &initial_chains[0],
		[NF_BR_LOCAL_OUT]	= &initial_chains[1],
		[NF_BR_POST_ROUTING]	= &initial_chains[2],
	},
	.entries	= (char *)initial_chains,
};

static int check(const struct ebt_table_info *info, unsigned int valid_hooks)
{
	if (valid_hooks & ~NAT_VALID_HOOKS)
		return -EINVAL;
	return 0;
}

53
static struct ebt_table frame_nat =
L
Linus Torvalds 已提交
54 55 56 57 58 59 60 61 62
{
	.name		= "nat",
	.table		= &initial_table,
	.valid_hooks	= NAT_VALID_HOOKS,
	.check		= check,
	.me		= THIS_MODULE,
};

static unsigned int
63
ebt_nat_in(unsigned int hook, struct sk_buff *skb, const struct net_device *in
L
Linus Torvalds 已提交
64 65
   , const struct net_device *out, int (*okfn)(struct sk_buff *))
{
66
	return ebt_do_table(hook, skb, in, out, dev_net(in)->xt.frame_nat);
L
Linus Torvalds 已提交
67 68 69
}

static unsigned int
70
ebt_nat_out(unsigned int hook, struct sk_buff *skb, const struct net_device *in
L
Linus Torvalds 已提交
71 72
   , const struct net_device *out, int (*okfn)(struct sk_buff *))
{
73
	return ebt_do_table(hook, skb, in, out, dev_net(out)->xt.frame_nat);
L
Linus Torvalds 已提交
74 75
}

76
static struct nf_hook_ops ebt_ops_nat[] __read_mostly = {
L
Linus Torvalds 已提交
77
	{
78
		.hook		= ebt_nat_out,
L
Linus Torvalds 已提交
79
		.owner		= THIS_MODULE,
80
		.pf		= NFPROTO_BRIDGE,
L
Linus Torvalds 已提交
81 82 83 84
		.hooknum	= NF_BR_LOCAL_OUT,
		.priority	= NF_BR_PRI_NAT_DST_OTHER,
	},
	{
85
		.hook		= ebt_nat_out,
L
Linus Torvalds 已提交
86
		.owner		= THIS_MODULE,
87
		.pf		= NFPROTO_BRIDGE,
L
Linus Torvalds 已提交
88 89 90 91
		.hooknum	= NF_BR_POST_ROUTING,
		.priority	= NF_BR_PRI_NAT_SRC,
	},
	{
92
		.hook		= ebt_nat_in,
L
Linus Torvalds 已提交
93
		.owner		= THIS_MODULE,
94
		.pf		= NFPROTO_BRIDGE,
L
Linus Torvalds 已提交
95 96 97 98 99
		.hooknum	= NF_BR_PRE_ROUTING,
		.priority	= NF_BR_PRI_NAT_DST_BRIDGED,
	},
};

100 101 102
static int __net_init frame_nat_net_init(struct net *net)
{
	net->xt.frame_nat = ebt_register_table(net, &frame_nat);
103
	return PTR_ERR_OR_ZERO(net->xt.frame_nat);
104 105 106 107
}

static void __net_exit frame_nat_net_exit(struct net *net)
{
108
	ebt_unregister_table(net, net->xt.frame_nat);
109 110 111 112 113 114 115
}

static struct pernet_operations frame_nat_net_ops = {
	.init = frame_nat_net_init,
	.exit = frame_nat_net_exit,
};

116
static int __init ebtable_nat_init(void)
L
Linus Torvalds 已提交
117
{
118
	int ret;
L
Linus Torvalds 已提交
119

120 121 122
	ret = register_pernet_subsys(&frame_nat_net_ops);
	if (ret < 0)
		return ret;
123 124
	ret = nf_register_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
	if (ret < 0)
125
		unregister_pernet_subsys(&frame_nat_net_ops);
L
Linus Torvalds 已提交
126 127 128
	return ret;
}

129
static void __exit ebtable_nat_fini(void)
L
Linus Torvalds 已提交
130
{
131
	nf_unregister_hooks(ebt_ops_nat, ARRAY_SIZE(ebt_ops_nat));
132
	unregister_pernet_subsys(&frame_nat_net_ops);
L
Linus Torvalds 已提交
133 134
}

135 136
module_init(ebtable_nat_init);
module_exit(ebtable_nat_fini);
L
Linus Torvalds 已提交
137
MODULE_LICENSE("GPL");