1e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 'raw' table, which is the very first hooked in at PRE_ROUTING and LOCAL_OUT . 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_ipv4/ip_tables.h> 85a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h> 9802169a4b0f71d25a0f798a9c0657a565b1e79bcPatrick McHardy#include <net/ip.h> 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 116e23ae2a48750bda407a4a58f52a4865d7308bf5Patrick McHardy#define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1335aad0ffdf548617940ca1e78be1f2e0bafc4496Jan Engelhardtstatic const struct xt_table packet_raw = { 14e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki .name = "raw", 15e905a9edab7f4f14f9213b52234e4a346c690911YOSHIFUJI Hideaki .valid_hooks = RAW_VALID_HOOKS, 162e4e6a17af35be359cc8f1c924f8f198fbd478ccHarald Welte .me = THIS_MODULE, 17f88e6a8a50a603f8347343e75d035889784a507cJan Engelhardt .af = NFPROTO_IPV4, 182b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt .priority = NF_IP_PRI_RAW, 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* The work comes in here from netfilter.c. */ 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int 23795aa6ef6a1aba99050735eadd0c2341b789b53bPatrick McHardyiptable_raw_hook(const struct nf_hook_ops *ops, struct sk_buff *skb, 24737535c5cf3524e4bfaa91e22edefd52eccabbceJan Engelhardt const struct net_device *in, const struct net_device *out, 25737535c5cf3524e4bfaa91e22edefd52eccabbceJan Engelhardt int (*okfn)(struct sk_buff *)) 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 272b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt const struct net *net; 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 29795aa6ef6a1aba99050735eadd0c2341b789b53bPatrick McHardy if (ops->hooknum == NF_INET_LOCAL_OUT && 302b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt (skb->len < sizeof(struct iphdr) || 312b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt ip_hdrlen(skb) < sizeof(struct iphdr))) 322b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt /* root is playing with raw sockets. */ 33802169a4b0f71d25a0f798a9c0657a565b1e79bcPatrick McHardy return NF_ACCEPT; 342b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt 352b21e051472fdb4680076278b2ccf63ebc1cc3bcJan Engelhardt net = dev_net((in != NULL) ? in : out); 36795aa6ef6a1aba99050735eadd0c2341b789b53bPatrick McHardy return ipt_do_table(skb, ops->hooknum, in, out, net->ipv4.iptable_raw); 37802169a4b0f71d25a0f798a9c0657a565b1e79bcPatrick McHardy} 38802169a4b0f71d25a0f798a9c0657a565b1e79bcPatrick McHardy 392b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardtstatic struct nf_hook_ops *rawtable_ops __read_mostly; 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 419335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyanstatic int __net_init iptable_raw_net_init(struct net *net) 429335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan{ 43e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt struct ipt_replace *repl; 44e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt 45e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt repl = ipt_alloc_initial_table(&packet_raw); 46e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt if (repl == NULL) 47e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt return -ENOMEM; 489335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan net->ipv4.iptable_raw = 49e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt ipt_register_table(net, &packet_raw, repl); 50e3eaa9910b380530cfd2c0670fcd3f627674da8aJan Engelhardt kfree(repl); 518c6ffba0eddc8c110dbf444f51354ce42069abfcRusty Russell return PTR_ERR_OR_ZERO(net->ipv4.iptable_raw); 529335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan} 539335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan 549335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyanstatic void __net_exit iptable_raw_net_exit(struct net *net) 559335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan{ 56f54e9367f8499a9bf6b2afbc0dce63e1d53c525aAlexey Dobriyan ipt_unregister_table(net, net->ipv4.iptable_raw); 579335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan} 589335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan 599335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyanstatic struct pernet_operations iptable_raw_net_ops = { 609335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan .init = iptable_raw_net_init, 619335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan .exit = iptable_raw_net_exit, 629335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan}; 639335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan 6465b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic int __init iptable_raw_init(void) 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int ret; 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 689335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan ret = register_pernet_subsys(&iptable_raw_net_ops); 699335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan if (ret < 0) 709335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan return ret; 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Register hooks */ 732b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt rawtable_ops = xt_hook_link(&packet_raw, iptable_raw_hook); 742b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt if (IS_ERR(rawtable_ops)) { 752b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt ret = PTR_ERR(rawtable_ops); 7690efbed18a30d78145419cdbd44f9ec152efeb16Jean Sacren unregister_pernet_subsys(&iptable_raw_net_ops); 772b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt } 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return ret; 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8265b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonstatic void __exit iptable_raw_fini(void) 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 842b95efe7f6bb750256a702cc32d33b0cb2cd8223Jan Engelhardt xt_hook_unlink(&packet_raw, rawtable_ops); 859335f047fe61587ec82ff12fbb1220bcfdd32006Alexey Dobriyan unregister_pernet_subsys(&iptable_raw_net_ops); 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 8865b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_init(iptable_raw_init); 8965b4b4e81a5094d52cbe372b887b1779abe53f9bAndrew Mortonmodule_exit(iptable_raw_fini); 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsMODULE_LICENSE("GPL"); 91