Root/
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. |
11 | */ |
12 | #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt |
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("Xtables: DSCP/TOS field modification"); |
24 | MODULE_LICENSE("GPL"); |
25 | MODULE_ALIAS("ipt_DSCP"); |
26 | MODULE_ALIAS("ip6t_DSCP"); |
27 | MODULE_ALIAS("ipt_TOS"); |
28 | MODULE_ALIAS("ip6t_TOS"); |
29 | |
30 | static unsigned int |
31 | dscp_tg(struct sk_buff *skb, const struct xt_action_param *par) |
32 | { |
33 | const struct xt_DSCP_info *dinfo = par->targinfo; |
34 | u_int8_t dscp = ipv4_get_dsfield(ip_hdr(skb)) >> XT_DSCP_SHIFT; |
35 | |
36 | if (dscp != dinfo->dscp) { |
37 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
38 | return NF_DROP; |
39 | |
40 | ipv4_change_dsfield(ip_hdr(skb), (__u8)(~XT_DSCP_MASK), |
41 | dinfo->dscp << XT_DSCP_SHIFT); |
42 | |
43 | } |
44 | return XT_CONTINUE; |
45 | } |
46 | |
47 | static unsigned int |
48 | dscp_tg6(struct sk_buff *skb, const struct xt_action_param *par) |
49 | { |
50 | const struct xt_DSCP_info *dinfo = par->targinfo; |
51 | u_int8_t dscp = ipv6_get_dsfield(ipv6_hdr(skb)) >> XT_DSCP_SHIFT; |
52 | |
53 | if (dscp != dinfo->dscp) { |
54 | if (!skb_make_writable(skb, sizeof(struct ipv6hdr))) |
55 | return NF_DROP; |
56 | |
57 | ipv6_change_dsfield(ipv6_hdr(skb), (__u8)(~XT_DSCP_MASK), |
58 | dinfo->dscp << XT_DSCP_SHIFT); |
59 | } |
60 | return XT_CONTINUE; |
61 | } |
62 | |
63 | static int dscp_tg_check(const struct xt_tgchk_param *par) |
64 | { |
65 | const struct xt_DSCP_info *info = par->targinfo; |
66 | |
67 | if (info->dscp > XT_DSCP_MAX) { |
68 | pr_info("dscp %x out of range\n", info->dscp); |
69 | return -EDOM; |
70 | } |
71 | return 0; |
72 | } |
73 | |
74 | static unsigned int |
75 | tos_tg(struct sk_buff *skb, const struct xt_action_param *par) |
76 | { |
77 | const struct xt_tos_target_info *info = par->targinfo; |
78 | struct iphdr *iph = ip_hdr(skb); |
79 | u_int8_t orig, nv; |
80 | |
81 | orig = ipv4_get_dsfield(iph); |
82 | nv = (orig & ~info->tos_mask) ^ info->tos_value; |
83 | |
84 | if (orig != nv) { |
85 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
86 | return NF_DROP; |
87 | iph = ip_hdr(skb); |
88 | ipv4_change_dsfield(iph, 0, nv); |
89 | } |
90 | |
91 | return XT_CONTINUE; |
92 | } |
93 | |
94 | static unsigned int |
95 | tos_tg6(struct sk_buff *skb, const struct xt_action_param *par) |
96 | { |
97 | const struct xt_tos_target_info *info = par->targinfo; |
98 | struct ipv6hdr *iph = ipv6_hdr(skb); |
99 | u_int8_t orig, nv; |
100 | |
101 | orig = ipv6_get_dsfield(iph); |
102 | nv = (orig & ~info->tos_mask) ^ info->tos_value; |
103 | |
104 | if (orig != nv) { |
105 | if (!skb_make_writable(skb, sizeof(struct iphdr))) |
106 | return NF_DROP; |
107 | iph = ipv6_hdr(skb); |
108 | ipv6_change_dsfield(iph, 0, nv); |
109 | } |
110 | |
111 | return XT_CONTINUE; |
112 | } |
113 | |
114 | static struct xt_target dscp_tg_reg[] __read_mostly = { |
115 | { |
116 | .name = "DSCP", |
117 | .family = NFPROTO_IPV4, |
118 | .checkentry = dscp_tg_check, |
119 | .target = dscp_tg, |
120 | .targetsize = sizeof(struct xt_DSCP_info), |
121 | .table = "mangle", |
122 | .me = THIS_MODULE, |
123 | }, |
124 | { |
125 | .name = "DSCP", |
126 | .family = NFPROTO_IPV6, |
127 | .checkentry = dscp_tg_check, |
128 | .target = dscp_tg6, |
129 | .targetsize = sizeof(struct xt_DSCP_info), |
130 | .table = "mangle", |
131 | .me = THIS_MODULE, |
132 | }, |
133 | { |
134 | .name = "TOS", |
135 | .revision = 1, |
136 | .family = NFPROTO_IPV4, |
137 | .table = "mangle", |
138 | .target = tos_tg, |
139 | .targetsize = sizeof(struct xt_tos_target_info), |
140 | .me = THIS_MODULE, |
141 | }, |
142 | { |
143 | .name = "TOS", |
144 | .revision = 1, |
145 | .family = NFPROTO_IPV6, |
146 | .table = "mangle", |
147 | .target = tos_tg6, |
148 | .targetsize = sizeof(struct xt_tos_target_info), |
149 | .me = THIS_MODULE, |
150 | }, |
151 | }; |
152 | |
153 | static int __init dscp_tg_init(void) |
154 | { |
155 | return xt_register_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg)); |
156 | } |
157 | |
158 | static void __exit dscp_tg_exit(void) |
159 | { |
160 | xt_unregister_targets(dscp_tg_reg, ARRAY_SIZE(dscp_tg_reg)); |
161 | } |
162 | |
163 | module_init(dscp_tg_init); |
164 | module_exit(dscp_tg_exit); |
165 |
Branches:
ben-wpan
ben-wpan-stefan
javiroman/ks7010
jz-2.6.34
jz-2.6.34-rc5
jz-2.6.34-rc6
jz-2.6.34-rc7
jz-2.6.35
jz-2.6.36
jz-2.6.37
jz-2.6.38
jz-2.6.39
jz-3.0
jz-3.1
jz-3.11
jz-3.12
jz-3.13
jz-3.15
jz-3.16
jz-3.18-dt
jz-3.2
jz-3.3
jz-3.4
jz-3.5
jz-3.6
jz-3.6-rc2-pwm
jz-3.9
jz-3.9-clk
jz-3.9-rc8
jz47xx
jz47xx-2.6.38
master
Tags:
od-2011-09-04
od-2011-09-18
v2.6.34-rc5
v2.6.34-rc6
v2.6.34-rc7
v3.9