11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/*
21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * IPv6 raw table, a port of the IPv4 raw table to IPv6
31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *
41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu>
51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */
61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h>
71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/netfilter_ipv6/ip6_tables.h>
85a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
106e23ae2a48750bda407a4a58f52a4865d7308bf5Patrick McHardy#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT))
111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
1235aad0ffdf548617940ca1e78be1f2e0bafc4496Jan Engelhardtstatic const struct xt_table packet_raw = {
131ab1457c42bc078e5a9becd82a7f9f940b55c53aYOSHIFUJI Hideaki	.name = "raw",
141ab1457c42bc078e5a9becd82a7f9f940b55c53aYOSHIFUJI Hideaki	.valid_hooks = RAW_VALID_HOOKS,
152e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte	.me = THIS_MODULE,
16f88e6a8a50a603f8347343e75d035889784a507cJan Engelhardt	.af = NFPROTO_IPV6,
179c13886665c43600bd0af4b38e33c654e648e078Jozsef Kadlecsik	.priority = NF_IP6_PRI_RAW,
181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds};
191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The work comes in here from netfilter.c. */
211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int
22795aa6ef6a1aba99050735eadd0c2341b789b53bPatrick McHardyip6table_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb,
23737535c5cf3524e4bfaa91e22edefd52eccabbceJan Engelhardt		  const struct net_device *in, const struct net_device *out,
24737535c5cf3524e4bfaa91e22edefd52eccabbceJan Engelhardt		  int (*okfn)(struct sk_buff *))
251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
262b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt	const struct net *net = dev_net((in != NULL) ? in : out);
271339dd91719f3e841b113ddaccd30fd87b9d2332Alexey Dobriyan
28795aa6ef6a1aba99050735eadd0c2341b789b53bPatrick McHardy	return ip6t_do_table(skb, ops->hooknum, in, out,
29795aa6ef6a1aba99050735eadd0c2341b789b53bPatrick McHardy			     net->ipv6.ip6table_raw);
301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
322b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardtstatic struct nf_hook_ops *rawtable_ops __read_mostly;
331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
348280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyanstatic int __net_init ip6table_raw_net_init(struct net *net)
358280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan{
36e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt	struct ip6t_replace *repl;
37e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt
38e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt	repl = ip6t_alloc_initial_table(&packet_raw);
39e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt	if (repl == NULL)
40e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt		return -ENOMEM;
418280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	net->ipv6.ip6table_raw =
42e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt		ip6t_register_table(net, &packet_raw, repl);
43e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt	kfree(repl);
448c6ffba0eddc8c110dbf444f51354ce42069abfcRusty Russell	return PTR_ERR_OR_ZERO(net->ipv6.ip6table_raw);
458280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan}
468280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan
478280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyanstatic void __net_exit ip6table_raw_net_exit(struct net *net)
488280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan{
49f54e9367f8499a9bf6b2afbc0dce63e1d53c525aAlexey Dobriyan	ip6t_unregister_table(net, net->ipv6.ip6table_raw);
508280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan}
518280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan
528280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyanstatic struct pernet_operations ip6table_raw_net_ops = {
538280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	.init = ip6table_raw_net_init,
548280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	.exit = ip6table_raw_net_exit,
558280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan};
568280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan
5765b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic int __init ip6table_raw_init(void)
581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	int ret;
601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
618280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	ret = register_pernet_subsys(&ip6table_raw_net_ops);
628280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	if (ret < 0)
638280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan		return ret;
641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	/* Register hooks */
662b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt	rawtable_ops = xt_hook_link(&packet_raw, ip6table_raw_hook);
672b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt	if (IS_ERR(rawtable_ops)) {
682b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt		ret = PTR_ERR(rawtable_ops);
691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds		goto cleanup_table;
702b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt	}
711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cleanup_table:
758280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	unregister_pernet_subsys(&ip6table_raw_net_ops);
761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds	return ret;
771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
7965b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic void __exit ip6table_raw_fini(void)
801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{
812b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt	xt_hook_unlink(&packet_raw, rawtable_ops);
828280aa6182f03c4e27dc235ce0440bc94927dc28Alexey Dobriyan	unregister_pernet_subsys(&ip6table_raw_net_ops);
831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}
841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds
8565b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_init(ip6table_raw_init);
8665b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_exit(ip6table_raw_fini);
871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL");
88