1 /* 2 * IPv6 raw table, a port of the IPv4 raw table to IPv6 3 * 4 * Copyright (C) 2003 Jozsef Kadlecsik <kadlec@blackhole.kfki.hu> 5 */ 6 #include <linux/module.h> 7 #include <linux/netfilter_ipv6/ip6_tables.h> 8 9 #define RAW_VALID_HOOKS ((1 << NF_INET_PRE_ROUTING) | (1 << NF_INET_LOCAL_OUT)) 10 11 static struct 12 { 13 struct ip6t_replace repl; 14 struct ip6t_standard entries[2]; 15 struct ip6t_error term; 16 } initial_table __net_initdata = { 17 .repl = { 18 .name = "raw", 19 .valid_hooks = RAW_VALID_HOOKS, 20 .num_entries = 3, 21 .size = sizeof(struct ip6t_standard) * 2 + sizeof(struct ip6t_error), 22 .hook_entry = { 23 [NF_INET_PRE_ROUTING] = 0, 24 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) 25 }, 26 .underflow = { 27 [NF_INET_PRE_ROUTING] = 0, 28 [NF_INET_LOCAL_OUT] = sizeof(struct ip6t_standard) 29 }, 30 }, 31 .entries = { 32 IP6T_STANDARD_INIT(NF_ACCEPT), /* PRE_ROUTING */ 33 IP6T_STANDARD_INIT(NF_ACCEPT), /* LOCAL_OUT */ 34 }, 35 .term = IP6T_ERROR_INIT, /* ERROR */ 36 }; 37 38 static struct xt_table packet_raw = { 39 .name = "raw", 40 .valid_hooks = RAW_VALID_HOOKS, 41 .lock = __RW_LOCK_UNLOCKED(packet_raw.lock), 42 .me = THIS_MODULE, 43 .af = AF_INET6, 44 }; 45 46 /* The work comes in here from netfilter.c. */ 47 static unsigned int 48 ip6t_pre_routing_hook(unsigned int hook, 49 struct sk_buff *skb, 50 const struct net_device *in, 51 const struct net_device *out, 52 int (*okfn)(struct sk_buff *)) 53 { 54 return ip6t_do_table(skb, hook, in, out, 55 dev_net(in)->ipv6.ip6table_raw); 56 } 57 58 static unsigned int 59 ip6t_local_out_hook(unsigned int hook, 60 struct sk_buff *skb, 61 const struct net_device *in, 62 const struct net_device *out, 63 int (*okfn)(struct sk_buff *)) 64 { 65 return ip6t_do_table(skb, hook, in, out, 66 dev_net(out)->ipv6.ip6table_raw); 67 } 68 69 static struct nf_hook_ops ip6t_ops[] __read_mostly = { 70 { 71 .hook = ip6t_pre_routing_hook, 72 .pf = PF_INET6, 73 .hooknum = NF_INET_PRE_ROUTING, 74 .priority = NF_IP6_PRI_FIRST, 75 .owner = THIS_MODULE, 76 }, 77 { 78 .hook = ip6t_local_out_hook, 79 .pf = PF_INET6, 80 .hooknum = NF_INET_LOCAL_OUT, 81 .priority = NF_IP6_PRI_FIRST, 82 .owner = THIS_MODULE, 83 }, 84 }; 85 86 static int __net_init ip6table_raw_net_init(struct net *net) 87 { 88 /* Register table */ 89 net->ipv6.ip6table_raw = 90 ip6t_register_table(net, &packet_raw, &initial_table.repl); 91 if (IS_ERR(net->ipv6.ip6table_raw)) 92 return PTR_ERR(net->ipv6.ip6table_raw); 93 return 0; 94 } 95 96 static void __net_exit ip6table_raw_net_exit(struct net *net) 97 { 98 ip6t_unregister_table(net->ipv6.ip6table_raw); 99 } 100 101 static struct pernet_operations ip6table_raw_net_ops = { 102 .init = ip6table_raw_net_init, 103 .exit = ip6table_raw_net_exit, 104 }; 105 106 static int __init ip6table_raw_init(void) 107 { 108 int ret; 109 110 ret = register_pernet_subsys(&ip6table_raw_net_ops); 111 if (ret < 0) 112 return ret; 113 114 /* Register hooks */ 115 ret = nf_register_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 116 if (ret < 0) 117 goto cleanup_table; 118 119 return ret; 120 121 cleanup_table: 122 unregister_pernet_subsys(&ip6table_raw_net_ops); 123 return ret; 124 } 125 126 static void __exit ip6table_raw_fini(void) 127 { 128 nf_unregister_hooks(ip6t_ops, ARRAY_SIZE(ip6t_ops)); 129 unregister_pernet_subsys(&ip6table_raw_net_ops); 130 } 131 132 module_init(ip6table_raw_init); 133 module_exit(ip6table_raw_fini); 134 MODULE_LICENSE("GPL"); 135