[NETFILTER]: Mark hooks __read_mostly
[safe/jmp/linux-2.6] / net / ipv4 / netfilter / ipt_TOS.c
1 /* This is a module which is used for setting the TOS field of a packet. */
2
3 /* (C) 1999-2001 Paul `Rusty' Russell
4  * (C) 2002-2004 Netfilter Core Team <coreteam@netfilter.org>
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License version 2 as
8  * published by the Free Software Foundation.
9  */
10
11 #include <linux/module.h>
12 #include <linux/skbuff.h>
13 #include <linux/ip.h>
14 #include <net/checksum.h>
15
16 #include <linux/netfilter/x_tables.h>
17 #include <linux/netfilter_ipv4/ipt_TOS.h>
18
19 MODULE_LICENSE("GPL");
20 MODULE_AUTHOR("Netfilter Core Team <coreteam@netfilter.org>");
21 MODULE_DESCRIPTION("iptables TOS mangling module");
22
23 static unsigned int
24 tos_tg(struct sk_buff *skb, const struct net_device *in,
25        const struct net_device *out, unsigned int hooknum,
26        const struct xt_target *target, const void *targinfo)
27 {
28         const struct ipt_tos_target_info *tosinfo = targinfo;
29         struct iphdr *iph = ip_hdr(skb);
30
31         if ((iph->tos & IPTOS_TOS_MASK) != tosinfo->tos) {
32                 __u8 oldtos;
33                 if (!skb_make_writable(skb, sizeof(struct iphdr)))
34                         return NF_DROP;
35                 iph = ip_hdr(skb);
36                 oldtos = iph->tos;
37                 iph->tos = (iph->tos & IPTOS_PREC_MASK) | tosinfo->tos;
38                 csum_replace2(&iph->check, htons(oldtos), htons(iph->tos));
39         }
40         return XT_CONTINUE;
41 }
42
43 static bool
44 tos_tg_check(const char *tablename, const void *e_void,
45              const struct xt_target *target, void *targinfo,
46              unsigned int hook_mask)
47 {
48         const u_int8_t tos = ((struct ipt_tos_target_info *)targinfo)->tos;
49
50         if (tos != IPTOS_LOWDELAY
51             && tos != IPTOS_THROUGHPUT
52             && tos != IPTOS_RELIABILITY
53             && tos != IPTOS_MINCOST
54             && tos != IPTOS_NORMALSVC) {
55                 printk(KERN_WARNING "TOS: bad tos value %#x\n", tos);
56                 return false;
57         }
58         return true;
59 }
60
61 static struct xt_target tos_tg_reg __read_mostly = {
62         .name           = "TOS",
63         .family         = AF_INET,
64         .target         = tos_tg,
65         .targetsize     = sizeof(struct ipt_tos_target_info),
66         .table          = "mangle",
67         .checkentry     = tos_tg_check,
68         .me             = THIS_MODULE,
69 };
70
71 static int __init tos_tg_init(void)
72 {
73         return xt_register_target(&tos_tg_reg);
74 }
75
76 static void __exit tos_tg_exit(void)
77 {
78         xt_unregister_target(&tos_tg_reg);
79 }
80
81 module_init(tos_tg_init);
82 module_exit(tos_tg_exit);