]>
Commit | Line | Data |
---|---|---|
a468701d YK |
1 | /* x_tables module for setting the IPv4/IPv6 DSCP field, Version 1.8 |
2 | * | |
3 | * (C) 2002 by Harald Welte <laforge@netfilter.org> | |
4 | * based on ipt_FTOS.c (C) 2000 by Matthew G. Marsh <mgm@paktronix.com> | |
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 | * See RFC2474 for a description of the DSCP field within the IP Header. | |
a468701d YK |
11 | */ |
12 | ||
13 | #include <linux/module.h> | |
14 | #include <linux/skbuff.h> | |
15 | #include <linux/ip.h> | |
16 | #include <linux/ipv6.h> | |
17 | #include <net/dsfield.h> | |
18 | ||
19 | #include <linux/netfilter/x_tables.h> | |
20 | #include <linux/netfilter/xt_DSCP.h> | |
21 | ||
22 | MODULE_AUTHOR("Harald Welte <laforge@netfilter.org>"); | |
23 | MODULE_DESCRIPTION("x_tables DSCP modification module"); | |
24 | MODULE_LICENSE("GPL"); | |
25 | MODULE_ALIAS("ipt_DSCP"); | |
26 | MODULE_ALIAS("ip6t_DSCP"); | |
27 | ||
d3c5ee6d JE |
28 | static unsigned int |
29 | dscp_tg(struct sk_buff *skb, const struct net_device *in, | |
30 | const struct net_device *out, unsigned int hooknum, | |
31 | const struct xt_target *target, const void *targinfo) | |
a468701d YK |
32 | { |
33 | const struct xt_DSCP_info *dinfo = targinfo; | |
3db05fea | 34 | u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; |
a468701d YK |
35 | |
36 | if (dscp != dinfo->dscp) { | |
3db05fea | 37 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
a468701d YK |
38 | return NF_DROP; |
39 | ||
3db05fea | 40 | ipv4_change_dsfield(ip_hdr(skb), (__u8)(~XT_DSCP_MASK), |
a468701d YK |
41 | dinfo->dscp << XT_DSCP_SHIFT); |
42 | ||
43 | } | |
44 | return XT_CONTINUE; | |
45 | } | |
46 | ||
d3c5ee6d JE |
47 | static unsigned int |
48 | dscp_tg6(struct sk_buff *skb, const struct net_device *in, | |
49 | const struct net_device *out, unsigned int hooknum, | |
50 | const struct xt_target *target, const void *targinfo) | |
a468701d YK |
51 | { |
52 | const struct xt_DSCP_info *dinfo = targinfo; | |
3db05fea | 53 | u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; |
a468701d YK |
54 | |
55 | if (dscp != dinfo->dscp) { | |
3db05fea | 56 | if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) |
a468701d YK |
57 | return NF_DROP; |
58 | ||
3db05fea | 59 | ipv6_change_dsfield(ipv6_hdr(skb), (__u8)(~XT_DSCP_MASK), |
a468701d YK |
60 | dinfo->dscp << XT_DSCP_SHIFT); |
61 | } | |
62 | return XT_CONTINUE; | |
63 | } | |
64 | ||
d3c5ee6d JE |
65 | static bool |
66 | dscp_tg_check(const char *tablename, const void *e_void, | |
67 | const struct xt_target *target, void *targinfo, | |
68 | unsigned int hook_mask) | |
a468701d YK |
69 | { |
70 | const u_int8_t dscp = ((struct xt_DSCP_info *)targinfo)->dscp; | |
71 | ||
7c4e36bc | 72 | if (dscp > XT_DSCP_MAX) { |
a468701d | 73 | printk(KERN_WARNING "DSCP: dscp %x out of range\n", dscp); |
e1931b78 | 74 | return false; |
a468701d | 75 | } |
e1931b78 | 76 | return true; |
a468701d YK |
77 | } |
78 | ||
d3c5ee6d | 79 | static struct xt_target dscp_tg_reg[] __read_mostly = { |
4470bbc7 PM |
80 | { |
81 | .name = "DSCP", | |
82 | .family = AF_INET, | |
d3c5ee6d JE |
83 | .checkentry = dscp_tg_check, |
84 | .target = dscp_tg, | |
4470bbc7 PM |
85 | .targetsize = sizeof(struct xt_DSCP_info), |
86 | .table = "mangle", | |
87 | .me = THIS_MODULE, | |
88 | }, | |
89 | { | |
90 | .name = "DSCP", | |
91 | .family = AF_INET6, | |
d3c5ee6d JE |
92 | .checkentry = dscp_tg_check, |
93 | .target = dscp_tg6, | |
4470bbc7 PM |
94 | .targetsize = sizeof(struct xt_DSCP_info), |
95 | .table = "mangle", | |
96 | .me = THIS_MODULE, | |
97 | }, | |
a468701d YK |
98 | }; |
99 | ||
d3c5ee6d | 100 | static int __init dscp_tg_init(void) |
a468701d | 101 | { |
d3c5ee6d | 102 | return xt_register_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg)); |
a468701d YK |
103 | } |
104 | ||
d3c5ee6d | 105 | static void __exit dscp_tg_exit(void) |
a468701d | 106 | { |
d3c5ee6d | 107 | xt_unregister_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg)); |
a468701d YK |
108 | } |
109 | ||
d3c5ee6d JE |
110 | module_init(dscp_tg_init); |
111 | module_exit(dscp_tg_exit); |