Commit 5b4d383a1a562de6955cacd72e20809064ee137f
Committed by
David S. Miller
1 parent
fa95c28322
Exists in
master
and in
7 other branches
[ICMP]: ICMP_MIB_OUTMSGS increment duplicated
Commit "96793b482540f3a26e2188eaf75cb56b7829d3e3" (Add ICMPMsgStats MIB (RFC 4293)) made a mistake. In that patch, David L added a icmp_out_count() in ip_push_pending_frames(), remove icmp_out_count() from icmp_reply(). But he forgot to remove icmp_out_count() from icmp_send() too. Since icmp_send and icmp_reply will call icmp_push_reply, which will call ip_push_pending_frames, a duplicated increment happened in icmp_send. This patch remove the icmp_out_count from icmp_send too. Signed-off-by: Wang Chen <wangchen@cn.fujitsu.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Showing 1 changed file with 0 additions and 1 deletions Inline Diff
net/ipv4/icmp.c
1 | /* | 1 | /* |
2 | * NET3: Implementation of the ICMP protocol layer. | 2 | * NET3: Implementation of the ICMP protocol layer. |
3 | * | 3 | * |
4 | * Alan Cox, <alan@redhat.com> | 4 | * Alan Cox, <alan@redhat.com> |
5 | * | 5 | * |
6 | * Version: $Id: icmp.c,v 1.85 2002/02/01 22:01:03 davem Exp $ | 6 | * Version: $Id: icmp.c,v 1.85 2002/02/01 22:01:03 davem Exp $ |
7 | * | 7 | * |
8 | * This program is free software; you can redistribute it and/or | 8 | * This program is free software; you can redistribute it and/or |
9 | * modify it under the terms of the GNU General Public License | 9 | * modify it under the terms of the GNU General Public License |
10 | * as published by the Free Software Foundation; either version | 10 | * as published by the Free Software Foundation; either version |
11 | * 2 of the License, or (at your option) any later version. | 11 | * 2 of the License, or (at your option) any later version. |
12 | * | 12 | * |
13 | * Some of the function names and the icmp unreach table for this | 13 | * Some of the function names and the icmp unreach table for this |
14 | * module were derived from [icmp.c 1.0.11 06/02/93] by | 14 | * module were derived from [icmp.c 1.0.11 06/02/93] by |
15 | * Ross Biro, Fred N. van Kempen, Mark Evans, Alan Cox, Gerhard Koerting. | 15 | * Ross Biro, Fred N. van Kempen, Mark Evans, Alan Cox, Gerhard Koerting. |
16 | * Other than that this module is a complete rewrite. | 16 | * Other than that this module is a complete rewrite. |
17 | * | 17 | * |
18 | * Fixes: | 18 | * Fixes: |
19 | * Clemens Fruhwirth : introduce global icmp rate limiting | 19 | * Clemens Fruhwirth : introduce global icmp rate limiting |
20 | * with icmp type masking ability instead | 20 | * with icmp type masking ability instead |
21 | * of broken per type icmp timeouts. | 21 | * of broken per type icmp timeouts. |
22 | * Mike Shaver : RFC1122 checks. | 22 | * Mike Shaver : RFC1122 checks. |
23 | * Alan Cox : Multicast ping reply as self. | 23 | * Alan Cox : Multicast ping reply as self. |
24 | * Alan Cox : Fix atomicity lockup in ip_build_xmit | 24 | * Alan Cox : Fix atomicity lockup in ip_build_xmit |
25 | * call. | 25 | * call. |
26 | * Alan Cox : Added 216,128 byte paths to the MTU | 26 | * Alan Cox : Added 216,128 byte paths to the MTU |
27 | * code. | 27 | * code. |
28 | * Martin Mares : RFC1812 checks. | 28 | * Martin Mares : RFC1812 checks. |
29 | * Martin Mares : Can be configured to follow redirects | 29 | * Martin Mares : Can be configured to follow redirects |
30 | * if acting as a router _without_ a | 30 | * if acting as a router _without_ a |
31 | * routing protocol (RFC 1812). | 31 | * routing protocol (RFC 1812). |
32 | * Martin Mares : Echo requests may be configured to | 32 | * Martin Mares : Echo requests may be configured to |
33 | * be ignored (RFC 1812). | 33 | * be ignored (RFC 1812). |
34 | * Martin Mares : Limitation of ICMP error message | 34 | * Martin Mares : Limitation of ICMP error message |
35 | * transmit rate (RFC 1812). | 35 | * transmit rate (RFC 1812). |
36 | * Martin Mares : TOS and Precedence set correctly | 36 | * Martin Mares : TOS and Precedence set correctly |
37 | * (RFC 1812). | 37 | * (RFC 1812). |
38 | * Martin Mares : Now copying as much data from the | 38 | * Martin Mares : Now copying as much data from the |
39 | * original packet as we can without | 39 | * original packet as we can without |
40 | * exceeding 576 bytes (RFC 1812). | 40 | * exceeding 576 bytes (RFC 1812). |
41 | * Willy Konynenberg : Transparent proxying support. | 41 | * Willy Konynenberg : Transparent proxying support. |
42 | * Keith Owens : RFC1191 correction for 4.2BSD based | 42 | * Keith Owens : RFC1191 correction for 4.2BSD based |
43 | * path MTU bug. | 43 | * path MTU bug. |
44 | * Thomas Quinot : ICMP Dest Unreach codes up to 15 are | 44 | * Thomas Quinot : ICMP Dest Unreach codes up to 15 are |
45 | * valid (RFC 1812). | 45 | * valid (RFC 1812). |
46 | * Andi Kleen : Check all packet lengths properly | 46 | * Andi Kleen : Check all packet lengths properly |
47 | * and moved all kfree_skb() up to | 47 | * and moved all kfree_skb() up to |
48 | * icmp_rcv. | 48 | * icmp_rcv. |
49 | * Andi Kleen : Move the rate limit bookkeeping | 49 | * Andi Kleen : Move the rate limit bookkeeping |
50 | * into the dest entry and use a token | 50 | * into the dest entry and use a token |
51 | * bucket filter (thanks to ANK). Make | 51 | * bucket filter (thanks to ANK). Make |
52 | * the rates sysctl configurable. | 52 | * the rates sysctl configurable. |
53 | * Yu Tianli : Fixed two ugly bugs in icmp_send | 53 | * Yu Tianli : Fixed two ugly bugs in icmp_send |
54 | * - IP option length was accounted wrongly | 54 | * - IP option length was accounted wrongly |
55 | * - ICMP header length was not accounted | 55 | * - ICMP header length was not accounted |
56 | * at all. | 56 | * at all. |
57 | * Tristan Greaves : Added sysctl option to ignore bogus | 57 | * Tristan Greaves : Added sysctl option to ignore bogus |
58 | * broadcast responses from broken routers. | 58 | * broadcast responses from broken routers. |
59 | * | 59 | * |
60 | * To Fix: | 60 | * To Fix: |
61 | * | 61 | * |
62 | * - Should use skb_pull() instead of all the manual checking. | 62 | * - Should use skb_pull() instead of all the manual checking. |
63 | * This would also greatly simply some upper layer error handlers. --AK | 63 | * This would also greatly simply some upper layer error handlers. --AK |
64 | * | 64 | * |
65 | */ | 65 | */ |
66 | 66 | ||
67 | #include <linux/module.h> | 67 | #include <linux/module.h> |
68 | #include <linux/types.h> | 68 | #include <linux/types.h> |
69 | #include <linux/jiffies.h> | 69 | #include <linux/jiffies.h> |
70 | #include <linux/kernel.h> | 70 | #include <linux/kernel.h> |
71 | #include <linux/fcntl.h> | 71 | #include <linux/fcntl.h> |
72 | #include <linux/socket.h> | 72 | #include <linux/socket.h> |
73 | #include <linux/in.h> | 73 | #include <linux/in.h> |
74 | #include <linux/inet.h> | 74 | #include <linux/inet.h> |
75 | #include <linux/inetdevice.h> | 75 | #include <linux/inetdevice.h> |
76 | #include <linux/netdevice.h> | 76 | #include <linux/netdevice.h> |
77 | #include <linux/string.h> | 77 | #include <linux/string.h> |
78 | #include <linux/netfilter_ipv4.h> | 78 | #include <linux/netfilter_ipv4.h> |
79 | #include <net/snmp.h> | 79 | #include <net/snmp.h> |
80 | #include <net/ip.h> | 80 | #include <net/ip.h> |
81 | #include <net/route.h> | 81 | #include <net/route.h> |
82 | #include <net/protocol.h> | 82 | #include <net/protocol.h> |
83 | #include <net/icmp.h> | 83 | #include <net/icmp.h> |
84 | #include <net/tcp.h> | 84 | #include <net/tcp.h> |
85 | #include <net/udp.h> | 85 | #include <net/udp.h> |
86 | #include <net/raw.h> | 86 | #include <net/raw.h> |
87 | #include <linux/skbuff.h> | 87 | #include <linux/skbuff.h> |
88 | #include <net/sock.h> | 88 | #include <net/sock.h> |
89 | #include <linux/errno.h> | 89 | #include <linux/errno.h> |
90 | #include <linux/timer.h> | 90 | #include <linux/timer.h> |
91 | #include <linux/init.h> | 91 | #include <linux/init.h> |
92 | #include <asm/system.h> | 92 | #include <asm/system.h> |
93 | #include <asm/uaccess.h> | 93 | #include <asm/uaccess.h> |
94 | #include <net/checksum.h> | 94 | #include <net/checksum.h> |
95 | 95 | ||
96 | /* | 96 | /* |
97 | * Build xmit assembly blocks | 97 | * Build xmit assembly blocks |
98 | */ | 98 | */ |
99 | 99 | ||
100 | struct icmp_bxm { | 100 | struct icmp_bxm { |
101 | struct sk_buff *skb; | 101 | struct sk_buff *skb; |
102 | int offset; | 102 | int offset; |
103 | int data_len; | 103 | int data_len; |
104 | 104 | ||
105 | struct { | 105 | struct { |
106 | struct icmphdr icmph; | 106 | struct icmphdr icmph; |
107 | __be32 times[3]; | 107 | __be32 times[3]; |
108 | } data; | 108 | } data; |
109 | int head_len; | 109 | int head_len; |
110 | struct ip_options replyopts; | 110 | struct ip_options replyopts; |
111 | unsigned char optbuf[40]; | 111 | unsigned char optbuf[40]; |
112 | }; | 112 | }; |
113 | 113 | ||
114 | /* | 114 | /* |
115 | * Statistics | 115 | * Statistics |
116 | */ | 116 | */ |
117 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics) __read_mostly; | 117 | DEFINE_SNMP_STAT(struct icmp_mib, icmp_statistics) __read_mostly; |
118 | DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics) __read_mostly; | 118 | DEFINE_SNMP_STAT(struct icmpmsg_mib, icmpmsg_statistics) __read_mostly; |
119 | 119 | ||
120 | /* An array of errno for error messages from dest unreach. */ | 120 | /* An array of errno for error messages from dest unreach. */ |
121 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ | 121 | /* RFC 1122: 3.2.2.1 States that NET_UNREACH, HOST_UNREACH and SR_FAILED MUST be considered 'transient errs'. */ |
122 | 122 | ||
123 | struct icmp_err icmp_err_convert[] = { | 123 | struct icmp_err icmp_err_convert[] = { |
124 | { | 124 | { |
125 | .errno = ENETUNREACH, /* ICMP_NET_UNREACH */ | 125 | .errno = ENETUNREACH, /* ICMP_NET_UNREACH */ |
126 | .fatal = 0, | 126 | .fatal = 0, |
127 | }, | 127 | }, |
128 | { | 128 | { |
129 | .errno = EHOSTUNREACH, /* ICMP_HOST_UNREACH */ | 129 | .errno = EHOSTUNREACH, /* ICMP_HOST_UNREACH */ |
130 | .fatal = 0, | 130 | .fatal = 0, |
131 | }, | 131 | }, |
132 | { | 132 | { |
133 | .errno = ENOPROTOOPT /* ICMP_PROT_UNREACH */, | 133 | .errno = ENOPROTOOPT /* ICMP_PROT_UNREACH */, |
134 | .fatal = 1, | 134 | .fatal = 1, |
135 | }, | 135 | }, |
136 | { | 136 | { |
137 | .errno = ECONNREFUSED, /* ICMP_PORT_UNREACH */ | 137 | .errno = ECONNREFUSED, /* ICMP_PORT_UNREACH */ |
138 | .fatal = 1, | 138 | .fatal = 1, |
139 | }, | 139 | }, |
140 | { | 140 | { |
141 | .errno = EMSGSIZE, /* ICMP_FRAG_NEEDED */ | 141 | .errno = EMSGSIZE, /* ICMP_FRAG_NEEDED */ |
142 | .fatal = 0, | 142 | .fatal = 0, |
143 | }, | 143 | }, |
144 | { | 144 | { |
145 | .errno = EOPNOTSUPP, /* ICMP_SR_FAILED */ | 145 | .errno = EOPNOTSUPP, /* ICMP_SR_FAILED */ |
146 | .fatal = 0, | 146 | .fatal = 0, |
147 | }, | 147 | }, |
148 | { | 148 | { |
149 | .errno = ENETUNREACH, /* ICMP_NET_UNKNOWN */ | 149 | .errno = ENETUNREACH, /* ICMP_NET_UNKNOWN */ |
150 | .fatal = 1, | 150 | .fatal = 1, |
151 | }, | 151 | }, |
152 | { | 152 | { |
153 | .errno = EHOSTDOWN, /* ICMP_HOST_UNKNOWN */ | 153 | .errno = EHOSTDOWN, /* ICMP_HOST_UNKNOWN */ |
154 | .fatal = 1, | 154 | .fatal = 1, |
155 | }, | 155 | }, |
156 | { | 156 | { |
157 | .errno = ENONET, /* ICMP_HOST_ISOLATED */ | 157 | .errno = ENONET, /* ICMP_HOST_ISOLATED */ |
158 | .fatal = 1, | 158 | .fatal = 1, |
159 | }, | 159 | }, |
160 | { | 160 | { |
161 | .errno = ENETUNREACH, /* ICMP_NET_ANO */ | 161 | .errno = ENETUNREACH, /* ICMP_NET_ANO */ |
162 | .fatal = 1, | 162 | .fatal = 1, |
163 | }, | 163 | }, |
164 | { | 164 | { |
165 | .errno = EHOSTUNREACH, /* ICMP_HOST_ANO */ | 165 | .errno = EHOSTUNREACH, /* ICMP_HOST_ANO */ |
166 | .fatal = 1, | 166 | .fatal = 1, |
167 | }, | 167 | }, |
168 | { | 168 | { |
169 | .errno = ENETUNREACH, /* ICMP_NET_UNR_TOS */ | 169 | .errno = ENETUNREACH, /* ICMP_NET_UNR_TOS */ |
170 | .fatal = 0, | 170 | .fatal = 0, |
171 | }, | 171 | }, |
172 | { | 172 | { |
173 | .errno = EHOSTUNREACH, /* ICMP_HOST_UNR_TOS */ | 173 | .errno = EHOSTUNREACH, /* ICMP_HOST_UNR_TOS */ |
174 | .fatal = 0, | 174 | .fatal = 0, |
175 | }, | 175 | }, |
176 | { | 176 | { |
177 | .errno = EHOSTUNREACH, /* ICMP_PKT_FILTERED */ | 177 | .errno = EHOSTUNREACH, /* ICMP_PKT_FILTERED */ |
178 | .fatal = 1, | 178 | .fatal = 1, |
179 | }, | 179 | }, |
180 | { | 180 | { |
181 | .errno = EHOSTUNREACH, /* ICMP_PREC_VIOLATION */ | 181 | .errno = EHOSTUNREACH, /* ICMP_PREC_VIOLATION */ |
182 | .fatal = 1, | 182 | .fatal = 1, |
183 | }, | 183 | }, |
184 | { | 184 | { |
185 | .errno = EHOSTUNREACH, /* ICMP_PREC_CUTOFF */ | 185 | .errno = EHOSTUNREACH, /* ICMP_PREC_CUTOFF */ |
186 | .fatal = 1, | 186 | .fatal = 1, |
187 | }, | 187 | }, |
188 | }; | 188 | }; |
189 | 189 | ||
190 | /* Control parameters for ECHO replies. */ | 190 | /* Control parameters for ECHO replies. */ |
191 | int sysctl_icmp_echo_ignore_all __read_mostly; | 191 | int sysctl_icmp_echo_ignore_all __read_mostly; |
192 | int sysctl_icmp_echo_ignore_broadcasts __read_mostly = 1; | 192 | int sysctl_icmp_echo_ignore_broadcasts __read_mostly = 1; |
193 | 193 | ||
194 | /* Control parameter - ignore bogus broadcast responses? */ | 194 | /* Control parameter - ignore bogus broadcast responses? */ |
195 | int sysctl_icmp_ignore_bogus_error_responses __read_mostly = 1; | 195 | int sysctl_icmp_ignore_bogus_error_responses __read_mostly = 1; |
196 | 196 | ||
197 | /* | 197 | /* |
198 | * Configurable global rate limit. | 198 | * Configurable global rate limit. |
199 | * | 199 | * |
200 | * ratelimit defines tokens/packet consumed for dst->rate_token bucket | 200 | * ratelimit defines tokens/packet consumed for dst->rate_token bucket |
201 | * ratemask defines which icmp types are ratelimited by setting | 201 | * ratemask defines which icmp types are ratelimited by setting |
202 | * it's bit position. | 202 | * it's bit position. |
203 | * | 203 | * |
204 | * default: | 204 | * default: |
205 | * dest unreachable (3), source quench (4), | 205 | * dest unreachable (3), source quench (4), |
206 | * time exceeded (11), parameter problem (12) | 206 | * time exceeded (11), parameter problem (12) |
207 | */ | 207 | */ |
208 | 208 | ||
209 | int sysctl_icmp_ratelimit __read_mostly = 1 * HZ; | 209 | int sysctl_icmp_ratelimit __read_mostly = 1 * HZ; |
210 | int sysctl_icmp_ratemask __read_mostly = 0x1818; | 210 | int sysctl_icmp_ratemask __read_mostly = 0x1818; |
211 | int sysctl_icmp_errors_use_inbound_ifaddr __read_mostly; | 211 | int sysctl_icmp_errors_use_inbound_ifaddr __read_mostly; |
212 | 212 | ||
213 | /* | 213 | /* |
214 | * ICMP control array. This specifies what to do with each ICMP. | 214 | * ICMP control array. This specifies what to do with each ICMP. |
215 | */ | 215 | */ |
216 | 216 | ||
217 | struct icmp_control { | 217 | struct icmp_control { |
218 | void (*handler)(struct sk_buff *skb); | 218 | void (*handler)(struct sk_buff *skb); |
219 | short error; /* This ICMP is classed as an error message */ | 219 | short error; /* This ICMP is classed as an error message */ |
220 | }; | 220 | }; |
221 | 221 | ||
222 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; | 222 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES+1]; |
223 | 223 | ||
224 | /* | 224 | /* |
225 | * The ICMP socket(s). This is the most convenient way to flow control | 225 | * The ICMP socket(s). This is the most convenient way to flow control |
226 | * our ICMP output as well as maintain a clean interface throughout | 226 | * our ICMP output as well as maintain a clean interface throughout |
227 | * all layers. All Socketless IP sends will soon be gone. | 227 | * all layers. All Socketless IP sends will soon be gone. |
228 | * | 228 | * |
229 | * On SMP we have one ICMP socket per-cpu. | 229 | * On SMP we have one ICMP socket per-cpu. |
230 | */ | 230 | */ |
231 | static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; | 231 | static DEFINE_PER_CPU(struct socket *, __icmp_socket) = NULL; |
232 | #define icmp_socket __get_cpu_var(__icmp_socket) | 232 | #define icmp_socket __get_cpu_var(__icmp_socket) |
233 | 233 | ||
234 | static __inline__ int icmp_xmit_lock(void) | 234 | static __inline__ int icmp_xmit_lock(void) |
235 | { | 235 | { |
236 | local_bh_disable(); | 236 | local_bh_disable(); |
237 | 237 | ||
238 | if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) { | 238 | if (unlikely(!spin_trylock(&icmp_socket->sk->sk_lock.slock))) { |
239 | /* This can happen if the output path signals a | 239 | /* This can happen if the output path signals a |
240 | * dst_link_failure() for an outgoing ICMP packet. | 240 | * dst_link_failure() for an outgoing ICMP packet. |
241 | */ | 241 | */ |
242 | local_bh_enable(); | 242 | local_bh_enable(); |
243 | return 1; | 243 | return 1; |
244 | } | 244 | } |
245 | return 0; | 245 | return 0; |
246 | } | 246 | } |
247 | 247 | ||
248 | static void icmp_xmit_unlock(void) | 248 | static void icmp_xmit_unlock(void) |
249 | { | 249 | { |
250 | spin_unlock_bh(&icmp_socket->sk->sk_lock.slock); | 250 | spin_unlock_bh(&icmp_socket->sk->sk_lock.slock); |
251 | } | 251 | } |
252 | 252 | ||
253 | /* | 253 | /* |
254 | * Send an ICMP frame. | 254 | * Send an ICMP frame. |
255 | */ | 255 | */ |
256 | 256 | ||
257 | /* | 257 | /* |
258 | * Check transmit rate limitation for given message. | 258 | * Check transmit rate limitation for given message. |
259 | * The rate information is held in the destination cache now. | 259 | * The rate information is held in the destination cache now. |
260 | * This function is generic and could be used for other purposes | 260 | * This function is generic and could be used for other purposes |
261 | * too. It uses a Token bucket filter as suggested by Alexey Kuznetsov. | 261 | * too. It uses a Token bucket filter as suggested by Alexey Kuznetsov. |
262 | * | 262 | * |
263 | * Note that the same dst_entry fields are modified by functions in | 263 | * Note that the same dst_entry fields are modified by functions in |
264 | * route.c too, but these work for packet destinations while xrlim_allow | 264 | * route.c too, but these work for packet destinations while xrlim_allow |
265 | * works for icmp destinations. This means the rate limiting information | 265 | * works for icmp destinations. This means the rate limiting information |
266 | * for one "ip object" is shared - and these ICMPs are twice limited: | 266 | * for one "ip object" is shared - and these ICMPs are twice limited: |
267 | * by source and by destination. | 267 | * by source and by destination. |
268 | * | 268 | * |
269 | * RFC 1812: 4.3.2.8 SHOULD be able to limit error message rate | 269 | * RFC 1812: 4.3.2.8 SHOULD be able to limit error message rate |
270 | * SHOULD allow setting of rate limits | 270 | * SHOULD allow setting of rate limits |
271 | * | 271 | * |
272 | * Shared between ICMPv4 and ICMPv6. | 272 | * Shared between ICMPv4 and ICMPv6. |
273 | */ | 273 | */ |
274 | #define XRLIM_BURST_FACTOR 6 | 274 | #define XRLIM_BURST_FACTOR 6 |
275 | int xrlim_allow(struct dst_entry *dst, int timeout) | 275 | int xrlim_allow(struct dst_entry *dst, int timeout) |
276 | { | 276 | { |
277 | unsigned long now; | 277 | unsigned long now; |
278 | int rc = 0; | 278 | int rc = 0; |
279 | 279 | ||
280 | now = jiffies; | 280 | now = jiffies; |
281 | dst->rate_tokens += now - dst->rate_last; | 281 | dst->rate_tokens += now - dst->rate_last; |
282 | dst->rate_last = now; | 282 | dst->rate_last = now; |
283 | if (dst->rate_tokens > XRLIM_BURST_FACTOR * timeout) | 283 | if (dst->rate_tokens > XRLIM_BURST_FACTOR * timeout) |
284 | dst->rate_tokens = XRLIM_BURST_FACTOR * timeout; | 284 | dst->rate_tokens = XRLIM_BURST_FACTOR * timeout; |
285 | if (dst->rate_tokens >= timeout) { | 285 | if (dst->rate_tokens >= timeout) { |
286 | dst->rate_tokens -= timeout; | 286 | dst->rate_tokens -= timeout; |
287 | rc = 1; | 287 | rc = 1; |
288 | } | 288 | } |
289 | return rc; | 289 | return rc; |
290 | } | 290 | } |
291 | 291 | ||
292 | static inline int icmpv4_xrlim_allow(struct rtable *rt, int type, int code) | 292 | static inline int icmpv4_xrlim_allow(struct rtable *rt, int type, int code) |
293 | { | 293 | { |
294 | struct dst_entry *dst = &rt->u.dst; | 294 | struct dst_entry *dst = &rt->u.dst; |
295 | int rc = 1; | 295 | int rc = 1; |
296 | 296 | ||
297 | if (type > NR_ICMP_TYPES) | 297 | if (type > NR_ICMP_TYPES) |
298 | goto out; | 298 | goto out; |
299 | 299 | ||
300 | /* Don't limit PMTU discovery. */ | 300 | /* Don't limit PMTU discovery. */ |
301 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) | 301 | if (type == ICMP_DEST_UNREACH && code == ICMP_FRAG_NEEDED) |
302 | goto out; | 302 | goto out; |
303 | 303 | ||
304 | /* No rate limit on loopback */ | 304 | /* No rate limit on loopback */ |
305 | if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) | 305 | if (dst->dev && (dst->dev->flags&IFF_LOOPBACK)) |
306 | goto out; | 306 | goto out; |
307 | 307 | ||
308 | /* Limit if icmp type is enabled in ratemask. */ | 308 | /* Limit if icmp type is enabled in ratemask. */ |
309 | if ((1 << type) & sysctl_icmp_ratemask) | 309 | if ((1 << type) & sysctl_icmp_ratemask) |
310 | rc = xrlim_allow(dst, sysctl_icmp_ratelimit); | 310 | rc = xrlim_allow(dst, sysctl_icmp_ratelimit); |
311 | out: | 311 | out: |
312 | return rc; | 312 | return rc; |
313 | } | 313 | } |
314 | 314 | ||
315 | /* | 315 | /* |
316 | * Maintain the counters used in the SNMP statistics for outgoing ICMP | 316 | * Maintain the counters used in the SNMP statistics for outgoing ICMP |
317 | */ | 317 | */ |
318 | void icmp_out_count(unsigned char type) | 318 | void icmp_out_count(unsigned char type) |
319 | { | 319 | { |
320 | ICMPMSGOUT_INC_STATS(type); | 320 | ICMPMSGOUT_INC_STATS(type); |
321 | ICMP_INC_STATS(ICMP_MIB_OUTMSGS); | 321 | ICMP_INC_STATS(ICMP_MIB_OUTMSGS); |
322 | } | 322 | } |
323 | 323 | ||
324 | /* | 324 | /* |
325 | * Checksum each fragment, and on the first include the headers and final | 325 | * Checksum each fragment, and on the first include the headers and final |
326 | * checksum. | 326 | * checksum. |
327 | */ | 327 | */ |
328 | static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, | 328 | static int icmp_glue_bits(void *from, char *to, int offset, int len, int odd, |
329 | struct sk_buff *skb) | 329 | struct sk_buff *skb) |
330 | { | 330 | { |
331 | struct icmp_bxm *icmp_param = (struct icmp_bxm *)from; | 331 | struct icmp_bxm *icmp_param = (struct icmp_bxm *)from; |
332 | __wsum csum; | 332 | __wsum csum; |
333 | 333 | ||
334 | csum = skb_copy_and_csum_bits(icmp_param->skb, | 334 | csum = skb_copy_and_csum_bits(icmp_param->skb, |
335 | icmp_param->offset + offset, | 335 | icmp_param->offset + offset, |
336 | to, len, 0); | 336 | to, len, 0); |
337 | 337 | ||
338 | skb->csum = csum_block_add(skb->csum, csum, odd); | 338 | skb->csum = csum_block_add(skb->csum, csum, odd); |
339 | if (icmp_pointers[icmp_param->data.icmph.type].error) | 339 | if (icmp_pointers[icmp_param->data.icmph.type].error) |
340 | nf_ct_attach(skb, icmp_param->skb); | 340 | nf_ct_attach(skb, icmp_param->skb); |
341 | return 0; | 341 | return 0; |
342 | } | 342 | } |
343 | 343 | ||
344 | static void icmp_push_reply(struct icmp_bxm *icmp_param, | 344 | static void icmp_push_reply(struct icmp_bxm *icmp_param, |
345 | struct ipcm_cookie *ipc, struct rtable *rt) | 345 | struct ipcm_cookie *ipc, struct rtable *rt) |
346 | { | 346 | { |
347 | struct sk_buff *skb; | 347 | struct sk_buff *skb; |
348 | 348 | ||
349 | if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, | 349 | if (ip_append_data(icmp_socket->sk, icmp_glue_bits, icmp_param, |
350 | icmp_param->data_len+icmp_param->head_len, | 350 | icmp_param->data_len+icmp_param->head_len, |
351 | icmp_param->head_len, | 351 | icmp_param->head_len, |
352 | ipc, rt, MSG_DONTWAIT) < 0) | 352 | ipc, rt, MSG_DONTWAIT) < 0) |
353 | ip_flush_pending_frames(icmp_socket->sk); | 353 | ip_flush_pending_frames(icmp_socket->sk); |
354 | else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { | 354 | else if ((skb = skb_peek(&icmp_socket->sk->sk_write_queue)) != NULL) { |
355 | struct icmphdr *icmph = icmp_hdr(skb); | 355 | struct icmphdr *icmph = icmp_hdr(skb); |
356 | __wsum csum = 0; | 356 | __wsum csum = 0; |
357 | struct sk_buff *skb1; | 357 | struct sk_buff *skb1; |
358 | 358 | ||
359 | skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) { | 359 | skb_queue_walk(&icmp_socket->sk->sk_write_queue, skb1) { |
360 | csum = csum_add(csum, skb1->csum); | 360 | csum = csum_add(csum, skb1->csum); |
361 | } | 361 | } |
362 | csum = csum_partial_copy_nocheck((void *)&icmp_param->data, | 362 | csum = csum_partial_copy_nocheck((void *)&icmp_param->data, |
363 | (char *)icmph, | 363 | (char *)icmph, |
364 | icmp_param->head_len, csum); | 364 | icmp_param->head_len, csum); |
365 | icmph->checksum = csum_fold(csum); | 365 | icmph->checksum = csum_fold(csum); |
366 | skb->ip_summed = CHECKSUM_NONE; | 366 | skb->ip_summed = CHECKSUM_NONE; |
367 | ip_push_pending_frames(icmp_socket->sk); | 367 | ip_push_pending_frames(icmp_socket->sk); |
368 | } | 368 | } |
369 | } | 369 | } |
370 | 370 | ||
371 | /* | 371 | /* |
372 | * Driving logic for building and sending ICMP messages. | 372 | * Driving logic for building and sending ICMP messages. |
373 | */ | 373 | */ |
374 | 374 | ||
375 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) | 375 | static void icmp_reply(struct icmp_bxm *icmp_param, struct sk_buff *skb) |
376 | { | 376 | { |
377 | struct sock *sk = icmp_socket->sk; | 377 | struct sock *sk = icmp_socket->sk; |
378 | struct inet_sock *inet = inet_sk(sk); | 378 | struct inet_sock *inet = inet_sk(sk); |
379 | struct ipcm_cookie ipc; | 379 | struct ipcm_cookie ipc; |
380 | struct rtable *rt = (struct rtable *)skb->dst; | 380 | struct rtable *rt = (struct rtable *)skb->dst; |
381 | __be32 daddr; | 381 | __be32 daddr; |
382 | 382 | ||
383 | if (ip_options_echo(&icmp_param->replyopts, skb)) | 383 | if (ip_options_echo(&icmp_param->replyopts, skb)) |
384 | return; | 384 | return; |
385 | 385 | ||
386 | if (icmp_xmit_lock()) | 386 | if (icmp_xmit_lock()) |
387 | return; | 387 | return; |
388 | 388 | ||
389 | icmp_param->data.icmph.checksum = 0; | 389 | icmp_param->data.icmph.checksum = 0; |
390 | 390 | ||
391 | inet->tos = ip_hdr(skb)->tos; | 391 | inet->tos = ip_hdr(skb)->tos; |
392 | daddr = ipc.addr = rt->rt_src; | 392 | daddr = ipc.addr = rt->rt_src; |
393 | ipc.opt = NULL; | 393 | ipc.opt = NULL; |
394 | if (icmp_param->replyopts.optlen) { | 394 | if (icmp_param->replyopts.optlen) { |
395 | ipc.opt = &icmp_param->replyopts; | 395 | ipc.opt = &icmp_param->replyopts; |
396 | if (ipc.opt->srr) | 396 | if (ipc.opt->srr) |
397 | daddr = icmp_param->replyopts.faddr; | 397 | daddr = icmp_param->replyopts.faddr; |
398 | } | 398 | } |
399 | { | 399 | { |
400 | struct flowi fl = { .nl_u = { .ip4_u = | 400 | struct flowi fl = { .nl_u = { .ip4_u = |
401 | { .daddr = daddr, | 401 | { .daddr = daddr, |
402 | .saddr = rt->rt_spec_dst, | 402 | .saddr = rt->rt_spec_dst, |
403 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, | 403 | .tos = RT_TOS(ip_hdr(skb)->tos) } }, |
404 | .proto = IPPROTO_ICMP }; | 404 | .proto = IPPROTO_ICMP }; |
405 | security_skb_classify_flow(skb, &fl); | 405 | security_skb_classify_flow(skb, &fl); |
406 | if (ip_route_output_key(&rt, &fl)) | 406 | if (ip_route_output_key(&rt, &fl)) |
407 | goto out_unlock; | 407 | goto out_unlock; |
408 | } | 408 | } |
409 | if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, | 409 | if (icmpv4_xrlim_allow(rt, icmp_param->data.icmph.type, |
410 | icmp_param->data.icmph.code)) | 410 | icmp_param->data.icmph.code)) |
411 | icmp_push_reply(icmp_param, &ipc, rt); | 411 | icmp_push_reply(icmp_param, &ipc, rt); |
412 | ip_rt_put(rt); | 412 | ip_rt_put(rt); |
413 | out_unlock: | 413 | out_unlock: |
414 | icmp_xmit_unlock(); | 414 | icmp_xmit_unlock(); |
415 | } | 415 | } |
416 | 416 | ||
417 | 417 | ||
418 | /* | 418 | /* |
419 | * Send an ICMP message in response to a situation | 419 | * Send an ICMP message in response to a situation |
420 | * | 420 | * |
421 | * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. | 421 | * RFC 1122: 3.2.2 MUST send at least the IP header and 8 bytes of header. |
422 | * MAY send more (we do). | 422 | * MAY send more (we do). |
423 | * MUST NOT change this header information. | 423 | * MUST NOT change this header information. |
424 | * MUST NOT reply to a multicast/broadcast IP address. | 424 | * MUST NOT reply to a multicast/broadcast IP address. |
425 | * MUST NOT reply to a multicast/broadcast MAC address. | 425 | * MUST NOT reply to a multicast/broadcast MAC address. |
426 | * MUST reply to only the first fragment. | 426 | * MUST reply to only the first fragment. |
427 | */ | 427 | */ |
428 | 428 | ||
429 | void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) | 429 | void icmp_send(struct sk_buff *skb_in, int type, int code, __be32 info) |
430 | { | 430 | { |
431 | struct iphdr *iph; | 431 | struct iphdr *iph; |
432 | int room; | 432 | int room; |
433 | struct icmp_bxm icmp_param; | 433 | struct icmp_bxm icmp_param; |
434 | struct rtable *rt = (struct rtable *)skb_in->dst; | 434 | struct rtable *rt = (struct rtable *)skb_in->dst; |
435 | struct ipcm_cookie ipc; | 435 | struct ipcm_cookie ipc; |
436 | __be32 saddr; | 436 | __be32 saddr; |
437 | u8 tos; | 437 | u8 tos; |
438 | 438 | ||
439 | if (!rt) | 439 | if (!rt) |
440 | goto out; | 440 | goto out; |
441 | 441 | ||
442 | /* | 442 | /* |
443 | * Find the original header. It is expected to be valid, of course. | 443 | * Find the original header. It is expected to be valid, of course. |
444 | * Check this, icmp_send is called from the most obscure devices | 444 | * Check this, icmp_send is called from the most obscure devices |
445 | * sometimes. | 445 | * sometimes. |
446 | */ | 446 | */ |
447 | iph = ip_hdr(skb_in); | 447 | iph = ip_hdr(skb_in); |
448 | 448 | ||
449 | if ((u8 *)iph < skb_in->head || | 449 | if ((u8 *)iph < skb_in->head || |
450 | (skb_in->network_header + sizeof(*iph)) > skb_in->tail) | 450 | (skb_in->network_header + sizeof(*iph)) > skb_in->tail) |
451 | goto out; | 451 | goto out; |
452 | 452 | ||
453 | /* | 453 | /* |
454 | * No replies to physical multicast/broadcast | 454 | * No replies to physical multicast/broadcast |
455 | */ | 455 | */ |
456 | if (skb_in->pkt_type != PACKET_HOST) | 456 | if (skb_in->pkt_type != PACKET_HOST) |
457 | goto out; | 457 | goto out; |
458 | 458 | ||
459 | /* | 459 | /* |
460 | * Now check at the protocol level | 460 | * Now check at the protocol level |
461 | */ | 461 | */ |
462 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) | 462 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) |
463 | goto out; | 463 | goto out; |
464 | 464 | ||
465 | /* | 465 | /* |
466 | * Only reply to fragment 0. We byte re-order the constant | 466 | * Only reply to fragment 0. We byte re-order the constant |
467 | * mask for efficiency. | 467 | * mask for efficiency. |
468 | */ | 468 | */ |
469 | if (iph->frag_off & htons(IP_OFFSET)) | 469 | if (iph->frag_off & htons(IP_OFFSET)) |
470 | goto out; | 470 | goto out; |
471 | 471 | ||
472 | /* | 472 | /* |
473 | * If we send an ICMP error to an ICMP error a mess would result.. | 473 | * If we send an ICMP error to an ICMP error a mess would result.. |
474 | */ | 474 | */ |
475 | if (icmp_pointers[type].error) { | 475 | if (icmp_pointers[type].error) { |
476 | /* | 476 | /* |
477 | * We are an error, check if we are replying to an | 477 | * We are an error, check if we are replying to an |
478 | * ICMP error | 478 | * ICMP error |
479 | */ | 479 | */ |
480 | if (iph->protocol == IPPROTO_ICMP) { | 480 | if (iph->protocol == IPPROTO_ICMP) { |
481 | u8 _inner_type, *itp; | 481 | u8 _inner_type, *itp; |
482 | 482 | ||
483 | itp = skb_header_pointer(skb_in, | 483 | itp = skb_header_pointer(skb_in, |
484 | skb_network_header(skb_in) + | 484 | skb_network_header(skb_in) + |
485 | (iph->ihl << 2) + | 485 | (iph->ihl << 2) + |
486 | offsetof(struct icmphdr, | 486 | offsetof(struct icmphdr, |
487 | type) - | 487 | type) - |
488 | skb_in->data, | 488 | skb_in->data, |
489 | sizeof(_inner_type), | 489 | sizeof(_inner_type), |
490 | &_inner_type); | 490 | &_inner_type); |
491 | if (itp == NULL) | 491 | if (itp == NULL) |
492 | goto out; | 492 | goto out; |
493 | 493 | ||
494 | /* | 494 | /* |
495 | * Assume any unknown ICMP type is an error. This | 495 | * Assume any unknown ICMP type is an error. This |
496 | * isn't specified by the RFC, but think about it.. | 496 | * isn't specified by the RFC, but think about it.. |
497 | */ | 497 | */ |
498 | if (*itp > NR_ICMP_TYPES || | 498 | if (*itp > NR_ICMP_TYPES || |
499 | icmp_pointers[*itp].error) | 499 | icmp_pointers[*itp].error) |
500 | goto out; | 500 | goto out; |
501 | } | 501 | } |
502 | } | 502 | } |
503 | 503 | ||
504 | if (icmp_xmit_lock()) | 504 | if (icmp_xmit_lock()) |
505 | return; | 505 | return; |
506 | 506 | ||
507 | /* | 507 | /* |
508 | * Construct source address and options. | 508 | * Construct source address and options. |
509 | */ | 509 | */ |
510 | 510 | ||
511 | saddr = iph->daddr; | 511 | saddr = iph->daddr; |
512 | if (!(rt->rt_flags & RTCF_LOCAL)) { | 512 | if (!(rt->rt_flags & RTCF_LOCAL)) { |
513 | struct net_device *dev = NULL; | 513 | struct net_device *dev = NULL; |
514 | 514 | ||
515 | if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr) | 515 | if (rt->fl.iif && sysctl_icmp_errors_use_inbound_ifaddr) |
516 | dev = dev_get_by_index(&init_net, rt->fl.iif); | 516 | dev = dev_get_by_index(&init_net, rt->fl.iif); |
517 | 517 | ||
518 | if (dev) { | 518 | if (dev) { |
519 | saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK); | 519 | saddr = inet_select_addr(dev, 0, RT_SCOPE_LINK); |
520 | dev_put(dev); | 520 | dev_put(dev); |
521 | } else | 521 | } else |
522 | saddr = 0; | 522 | saddr = 0; |
523 | } | 523 | } |
524 | 524 | ||
525 | tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) | | 525 | tos = icmp_pointers[type].error ? ((iph->tos & IPTOS_TOS_MASK) | |
526 | IPTOS_PREC_INTERNETCONTROL) : | 526 | IPTOS_PREC_INTERNETCONTROL) : |
527 | iph->tos; | 527 | iph->tos; |
528 | 528 | ||
529 | if (ip_options_echo(&icmp_param.replyopts, skb_in)) | 529 | if (ip_options_echo(&icmp_param.replyopts, skb_in)) |
530 | goto out_unlock; | 530 | goto out_unlock; |
531 | 531 | ||
532 | 532 | ||
533 | /* | 533 | /* |
534 | * Prepare data for ICMP header. | 534 | * Prepare data for ICMP header. |
535 | */ | 535 | */ |
536 | 536 | ||
537 | icmp_param.data.icmph.type = type; | 537 | icmp_param.data.icmph.type = type; |
538 | icmp_param.data.icmph.code = code; | 538 | icmp_param.data.icmph.code = code; |
539 | icmp_param.data.icmph.un.gateway = info; | 539 | icmp_param.data.icmph.un.gateway = info; |
540 | icmp_param.data.icmph.checksum = 0; | 540 | icmp_param.data.icmph.checksum = 0; |
541 | icmp_param.skb = skb_in; | 541 | icmp_param.skb = skb_in; |
542 | icmp_param.offset = skb_network_offset(skb_in); | 542 | icmp_param.offset = skb_network_offset(skb_in); |
543 | icmp_out_count(icmp_param.data.icmph.type); | ||
544 | inet_sk(icmp_socket->sk)->tos = tos; | 543 | inet_sk(icmp_socket->sk)->tos = tos; |
545 | ipc.addr = iph->saddr; | 544 | ipc.addr = iph->saddr; |
546 | ipc.opt = &icmp_param.replyopts; | 545 | ipc.opt = &icmp_param.replyopts; |
547 | 546 | ||
548 | { | 547 | { |
549 | struct flowi fl = { | 548 | struct flowi fl = { |
550 | .nl_u = { | 549 | .nl_u = { |
551 | .ip4_u = { | 550 | .ip4_u = { |
552 | .daddr = icmp_param.replyopts.srr ? | 551 | .daddr = icmp_param.replyopts.srr ? |
553 | icmp_param.replyopts.faddr : | 552 | icmp_param.replyopts.faddr : |
554 | iph->saddr, | 553 | iph->saddr, |
555 | .saddr = saddr, | 554 | .saddr = saddr, |
556 | .tos = RT_TOS(tos) | 555 | .tos = RT_TOS(tos) |
557 | } | 556 | } |
558 | }, | 557 | }, |
559 | .proto = IPPROTO_ICMP, | 558 | .proto = IPPROTO_ICMP, |
560 | .uli_u = { | 559 | .uli_u = { |
561 | .icmpt = { | 560 | .icmpt = { |
562 | .type = type, | 561 | .type = type, |
563 | .code = code | 562 | .code = code |
564 | } | 563 | } |
565 | } | 564 | } |
566 | }; | 565 | }; |
567 | security_skb_classify_flow(skb_in, &fl); | 566 | security_skb_classify_flow(skb_in, &fl); |
568 | if (ip_route_output_key(&rt, &fl)) | 567 | if (ip_route_output_key(&rt, &fl)) |
569 | goto out_unlock; | 568 | goto out_unlock; |
570 | } | 569 | } |
571 | 570 | ||
572 | if (!icmpv4_xrlim_allow(rt, type, code)) | 571 | if (!icmpv4_xrlim_allow(rt, type, code)) |
573 | goto ende; | 572 | goto ende; |
574 | 573 | ||
575 | /* RFC says return as much as we can without exceeding 576 bytes. */ | 574 | /* RFC says return as much as we can without exceeding 576 bytes. */ |
576 | 575 | ||
577 | room = dst_mtu(&rt->u.dst); | 576 | room = dst_mtu(&rt->u.dst); |
578 | if (room > 576) | 577 | if (room > 576) |
579 | room = 576; | 578 | room = 576; |
580 | room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen; | 579 | room -= sizeof(struct iphdr) + icmp_param.replyopts.optlen; |
581 | room -= sizeof(struct icmphdr); | 580 | room -= sizeof(struct icmphdr); |
582 | 581 | ||
583 | icmp_param.data_len = skb_in->len - icmp_param.offset; | 582 | icmp_param.data_len = skb_in->len - icmp_param.offset; |
584 | if (icmp_param.data_len > room) | 583 | if (icmp_param.data_len > room) |
585 | icmp_param.data_len = room; | 584 | icmp_param.data_len = room; |
586 | icmp_param.head_len = sizeof(struct icmphdr); | 585 | icmp_param.head_len = sizeof(struct icmphdr); |
587 | 586 | ||
588 | icmp_push_reply(&icmp_param, &ipc, rt); | 587 | icmp_push_reply(&icmp_param, &ipc, rt); |
589 | ende: | 588 | ende: |
590 | ip_rt_put(rt); | 589 | ip_rt_put(rt); |
591 | out_unlock: | 590 | out_unlock: |
592 | icmp_xmit_unlock(); | 591 | icmp_xmit_unlock(); |
593 | out:; | 592 | out:; |
594 | } | 593 | } |
595 | 594 | ||
596 | 595 | ||
597 | /* | 596 | /* |
598 | * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, and ICMP_QUENCH. | 597 | * Handle ICMP_DEST_UNREACH, ICMP_TIME_EXCEED, and ICMP_QUENCH. |
599 | */ | 598 | */ |
600 | 599 | ||
601 | static void icmp_unreach(struct sk_buff *skb) | 600 | static void icmp_unreach(struct sk_buff *skb) |
602 | { | 601 | { |
603 | struct iphdr *iph; | 602 | struct iphdr *iph; |
604 | struct icmphdr *icmph; | 603 | struct icmphdr *icmph; |
605 | int hash, protocol; | 604 | int hash, protocol; |
606 | struct net_protocol *ipprot; | 605 | struct net_protocol *ipprot; |
607 | struct sock *raw_sk; | 606 | struct sock *raw_sk; |
608 | u32 info = 0; | 607 | u32 info = 0; |
609 | 608 | ||
610 | /* | 609 | /* |
611 | * Incomplete header ? | 610 | * Incomplete header ? |
612 | * Only checks for the IP header, there should be an | 611 | * Only checks for the IP header, there should be an |
613 | * additional check for longer headers in upper levels. | 612 | * additional check for longer headers in upper levels. |
614 | */ | 613 | */ |
615 | 614 | ||
616 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 615 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
617 | goto out_err; | 616 | goto out_err; |
618 | 617 | ||
619 | icmph = icmp_hdr(skb); | 618 | icmph = icmp_hdr(skb); |
620 | iph = (struct iphdr *)skb->data; | 619 | iph = (struct iphdr *)skb->data; |
621 | 620 | ||
622 | if (iph->ihl < 5) /* Mangled header, drop. */ | 621 | if (iph->ihl < 5) /* Mangled header, drop. */ |
623 | goto out_err; | 622 | goto out_err; |
624 | 623 | ||
625 | if (icmph->type == ICMP_DEST_UNREACH) { | 624 | if (icmph->type == ICMP_DEST_UNREACH) { |
626 | switch (icmph->code & 15) { | 625 | switch (icmph->code & 15) { |
627 | case ICMP_NET_UNREACH: | 626 | case ICMP_NET_UNREACH: |
628 | case ICMP_HOST_UNREACH: | 627 | case ICMP_HOST_UNREACH: |
629 | case ICMP_PROT_UNREACH: | 628 | case ICMP_PROT_UNREACH: |
630 | case ICMP_PORT_UNREACH: | 629 | case ICMP_PORT_UNREACH: |
631 | break; | 630 | break; |
632 | case ICMP_FRAG_NEEDED: | 631 | case ICMP_FRAG_NEEDED: |
633 | if (ipv4_config.no_pmtu_disc) { | 632 | if (ipv4_config.no_pmtu_disc) { |
634 | LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: " | 633 | LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: " |
635 | "fragmentation needed " | 634 | "fragmentation needed " |
636 | "and DF set.\n", | 635 | "and DF set.\n", |
637 | NIPQUAD(iph->daddr)); | 636 | NIPQUAD(iph->daddr)); |
638 | } else { | 637 | } else { |
639 | info = ip_rt_frag_needed(iph, | 638 | info = ip_rt_frag_needed(iph, |
640 | ntohs(icmph->un.frag.mtu)); | 639 | ntohs(icmph->un.frag.mtu)); |
641 | if (!info) | 640 | if (!info) |
642 | goto out; | 641 | goto out; |
643 | } | 642 | } |
644 | break; | 643 | break; |
645 | case ICMP_SR_FAILED: | 644 | case ICMP_SR_FAILED: |
646 | LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: Source " | 645 | LIMIT_NETDEBUG(KERN_INFO "ICMP: %u.%u.%u.%u: Source " |
647 | "Route Failed.\n", | 646 | "Route Failed.\n", |
648 | NIPQUAD(iph->daddr)); | 647 | NIPQUAD(iph->daddr)); |
649 | break; | 648 | break; |
650 | default: | 649 | default: |
651 | break; | 650 | break; |
652 | } | 651 | } |
653 | if (icmph->code > NR_ICMP_UNREACH) | 652 | if (icmph->code > NR_ICMP_UNREACH) |
654 | goto out; | 653 | goto out; |
655 | } else if (icmph->type == ICMP_PARAMETERPROB) | 654 | } else if (icmph->type == ICMP_PARAMETERPROB) |
656 | info = ntohl(icmph->un.gateway) >> 24; | 655 | info = ntohl(icmph->un.gateway) >> 24; |
657 | 656 | ||
658 | /* | 657 | /* |
659 | * Throw it at our lower layers | 658 | * Throw it at our lower layers |
660 | * | 659 | * |
661 | * RFC 1122: 3.2.2 MUST extract the protocol ID from the passed | 660 | * RFC 1122: 3.2.2 MUST extract the protocol ID from the passed |
662 | * header. | 661 | * header. |
663 | * RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the | 662 | * RFC 1122: 3.2.2.1 MUST pass ICMP unreach messages to the |
664 | * transport layer. | 663 | * transport layer. |
665 | * RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to | 664 | * RFC 1122: 3.2.2.2 MUST pass ICMP time expired messages to |
666 | * transport layer. | 665 | * transport layer. |
667 | */ | 666 | */ |
668 | 667 | ||
669 | /* | 668 | /* |
670 | * Check the other end isnt violating RFC 1122. Some routers send | 669 | * Check the other end isnt violating RFC 1122. Some routers send |
671 | * bogus responses to broadcast frames. If you see this message | 670 | * bogus responses to broadcast frames. If you see this message |
672 | * first check your netmask matches at both ends, if it does then | 671 | * first check your netmask matches at both ends, if it does then |
673 | * get the other vendor to fix their kit. | 672 | * get the other vendor to fix their kit. |
674 | */ | 673 | */ |
675 | 674 | ||
676 | if (!sysctl_icmp_ignore_bogus_error_responses && | 675 | if (!sysctl_icmp_ignore_bogus_error_responses && |
677 | inet_addr_type(iph->daddr) == RTN_BROADCAST) { | 676 | inet_addr_type(iph->daddr) == RTN_BROADCAST) { |
678 | if (net_ratelimit()) | 677 | if (net_ratelimit()) |
679 | printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP " | 678 | printk(KERN_WARNING "%u.%u.%u.%u sent an invalid ICMP " |
680 | "type %u, code %u " | 679 | "type %u, code %u " |
681 | "error to a broadcast: %u.%u.%u.%u on %s\n", | 680 | "error to a broadcast: %u.%u.%u.%u on %s\n", |
682 | NIPQUAD(ip_hdr(skb)->saddr), | 681 | NIPQUAD(ip_hdr(skb)->saddr), |
683 | icmph->type, icmph->code, | 682 | icmph->type, icmph->code, |
684 | NIPQUAD(iph->daddr), | 683 | NIPQUAD(iph->daddr), |
685 | skb->dev->name); | 684 | skb->dev->name); |
686 | goto out; | 685 | goto out; |
687 | } | 686 | } |
688 | 687 | ||
689 | /* Checkin full IP header plus 8 bytes of protocol to | 688 | /* Checkin full IP header plus 8 bytes of protocol to |
690 | * avoid additional coding at protocol handlers. | 689 | * avoid additional coding at protocol handlers. |
691 | */ | 690 | */ |
692 | if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) | 691 | if (!pskb_may_pull(skb, iph->ihl * 4 + 8)) |
693 | goto out; | 692 | goto out; |
694 | 693 | ||
695 | iph = (struct iphdr *)skb->data; | 694 | iph = (struct iphdr *)skb->data; |
696 | protocol = iph->protocol; | 695 | protocol = iph->protocol; |
697 | 696 | ||
698 | /* | 697 | /* |
699 | * Deliver ICMP message to raw sockets. Pretty useless feature? | 698 | * Deliver ICMP message to raw sockets. Pretty useless feature? |
700 | */ | 699 | */ |
701 | 700 | ||
702 | /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */ | 701 | /* Note: See raw.c and net/raw.h, RAWV4_HTABLE_SIZE==MAX_INET_PROTOS */ |
703 | hash = protocol & (MAX_INET_PROTOS - 1); | 702 | hash = protocol & (MAX_INET_PROTOS - 1); |
704 | read_lock(&raw_v4_lock); | 703 | read_lock(&raw_v4_lock); |
705 | if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) { | 704 | if ((raw_sk = sk_head(&raw_v4_htable[hash])) != NULL) { |
706 | while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, | 705 | while ((raw_sk = __raw_v4_lookup(raw_sk, protocol, iph->daddr, |
707 | iph->saddr, | 706 | iph->saddr, |
708 | skb->dev->ifindex)) != NULL) { | 707 | skb->dev->ifindex)) != NULL) { |
709 | raw_err(raw_sk, skb, info); | 708 | raw_err(raw_sk, skb, info); |
710 | raw_sk = sk_next(raw_sk); | 709 | raw_sk = sk_next(raw_sk); |
711 | iph = (struct iphdr *)skb->data; | 710 | iph = (struct iphdr *)skb->data; |
712 | } | 711 | } |
713 | } | 712 | } |
714 | read_unlock(&raw_v4_lock); | 713 | read_unlock(&raw_v4_lock); |
715 | 714 | ||
716 | rcu_read_lock(); | 715 | rcu_read_lock(); |
717 | ipprot = rcu_dereference(inet_protos[hash]); | 716 | ipprot = rcu_dereference(inet_protos[hash]); |
718 | if (ipprot && ipprot->err_handler) | 717 | if (ipprot && ipprot->err_handler) |
719 | ipprot->err_handler(skb, info); | 718 | ipprot->err_handler(skb, info); |
720 | rcu_read_unlock(); | 719 | rcu_read_unlock(); |
721 | 720 | ||
722 | out: | 721 | out: |
723 | return; | 722 | return; |
724 | out_err: | 723 | out_err: |
725 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 724 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
726 | goto out; | 725 | goto out; |
727 | } | 726 | } |
728 | 727 | ||
729 | 728 | ||
730 | /* | 729 | /* |
731 | * Handle ICMP_REDIRECT. | 730 | * Handle ICMP_REDIRECT. |
732 | */ | 731 | */ |
733 | 732 | ||
734 | static void icmp_redirect(struct sk_buff *skb) | 733 | static void icmp_redirect(struct sk_buff *skb) |
735 | { | 734 | { |
736 | struct iphdr *iph; | 735 | struct iphdr *iph; |
737 | 736 | ||
738 | if (skb->len < sizeof(struct iphdr)) | 737 | if (skb->len < sizeof(struct iphdr)) |
739 | goto out_err; | 738 | goto out_err; |
740 | 739 | ||
741 | /* | 740 | /* |
742 | * Get the copied header of the packet that caused the redirect | 741 | * Get the copied header of the packet that caused the redirect |
743 | */ | 742 | */ |
744 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) | 743 | if (!pskb_may_pull(skb, sizeof(struct iphdr))) |
745 | goto out; | 744 | goto out; |
746 | 745 | ||
747 | iph = (struct iphdr *)skb->data; | 746 | iph = (struct iphdr *)skb->data; |
748 | 747 | ||
749 | switch (icmp_hdr(skb)->code & 7) { | 748 | switch (icmp_hdr(skb)->code & 7) { |
750 | case ICMP_REDIR_NET: | 749 | case ICMP_REDIR_NET: |
751 | case ICMP_REDIR_NETTOS: | 750 | case ICMP_REDIR_NETTOS: |
752 | /* | 751 | /* |
753 | * As per RFC recommendations now handle it as a host redirect. | 752 | * As per RFC recommendations now handle it as a host redirect. |
754 | */ | 753 | */ |
755 | case ICMP_REDIR_HOST: | 754 | case ICMP_REDIR_HOST: |
756 | case ICMP_REDIR_HOSTTOS: | 755 | case ICMP_REDIR_HOSTTOS: |
757 | ip_rt_redirect(ip_hdr(skb)->saddr, iph->daddr, | 756 | ip_rt_redirect(ip_hdr(skb)->saddr, iph->daddr, |
758 | icmp_hdr(skb)->un.gateway, | 757 | icmp_hdr(skb)->un.gateway, |
759 | iph->saddr, skb->dev); | 758 | iph->saddr, skb->dev); |
760 | break; | 759 | break; |
761 | } | 760 | } |
762 | out: | 761 | out: |
763 | return; | 762 | return; |
764 | out_err: | 763 | out_err: |
765 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 764 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
766 | goto out; | 765 | goto out; |
767 | } | 766 | } |
768 | 767 | ||
769 | /* | 768 | /* |
770 | * Handle ICMP_ECHO ("ping") requests. | 769 | * Handle ICMP_ECHO ("ping") requests. |
771 | * | 770 | * |
772 | * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo | 771 | * RFC 1122: 3.2.2.6 MUST have an echo server that answers ICMP echo |
773 | * requests. | 772 | * requests. |
774 | * RFC 1122: 3.2.2.6 Data received in the ICMP_ECHO request MUST be | 773 | * RFC 1122: 3.2.2.6 Data received in the ICMP_ECHO request MUST be |
775 | * included in the reply. | 774 | * included in the reply. |
776 | * RFC 1812: 4.3.3.6 SHOULD have a config option for silently ignoring | 775 | * RFC 1812: 4.3.3.6 SHOULD have a config option for silently ignoring |
777 | * echo requests, MUST have default=NOT. | 776 | * echo requests, MUST have default=NOT. |
778 | * See also WRT handling of options once they are done and working. | 777 | * See also WRT handling of options once they are done and working. |
779 | */ | 778 | */ |
780 | 779 | ||
781 | static void icmp_echo(struct sk_buff *skb) | 780 | static void icmp_echo(struct sk_buff *skb) |
782 | { | 781 | { |
783 | if (!sysctl_icmp_echo_ignore_all) { | 782 | if (!sysctl_icmp_echo_ignore_all) { |
784 | struct icmp_bxm icmp_param; | 783 | struct icmp_bxm icmp_param; |
785 | 784 | ||
786 | icmp_param.data.icmph = *icmp_hdr(skb); | 785 | icmp_param.data.icmph = *icmp_hdr(skb); |
787 | icmp_param.data.icmph.type = ICMP_ECHOREPLY; | 786 | icmp_param.data.icmph.type = ICMP_ECHOREPLY; |
788 | icmp_param.skb = skb; | 787 | icmp_param.skb = skb; |
789 | icmp_param.offset = 0; | 788 | icmp_param.offset = 0; |
790 | icmp_param.data_len = skb->len; | 789 | icmp_param.data_len = skb->len; |
791 | icmp_param.head_len = sizeof(struct icmphdr); | 790 | icmp_param.head_len = sizeof(struct icmphdr); |
792 | icmp_reply(&icmp_param, skb); | 791 | icmp_reply(&icmp_param, skb); |
793 | } | 792 | } |
794 | } | 793 | } |
795 | 794 | ||
796 | /* | 795 | /* |
797 | * Handle ICMP Timestamp requests. | 796 | * Handle ICMP Timestamp requests. |
798 | * RFC 1122: 3.2.2.8 MAY implement ICMP timestamp requests. | 797 | * RFC 1122: 3.2.2.8 MAY implement ICMP timestamp requests. |
799 | * SHOULD be in the kernel for minimum random latency. | 798 | * SHOULD be in the kernel for minimum random latency. |
800 | * MUST be accurate to a few minutes. | 799 | * MUST be accurate to a few minutes. |
801 | * MUST be updated at least at 15Hz. | 800 | * MUST be updated at least at 15Hz. |
802 | */ | 801 | */ |
803 | static void icmp_timestamp(struct sk_buff *skb) | 802 | static void icmp_timestamp(struct sk_buff *skb) |
804 | { | 803 | { |
805 | struct timeval tv; | 804 | struct timeval tv; |
806 | struct icmp_bxm icmp_param; | 805 | struct icmp_bxm icmp_param; |
807 | /* | 806 | /* |
808 | * Too short. | 807 | * Too short. |
809 | */ | 808 | */ |
810 | if (skb->len < 4) | 809 | if (skb->len < 4) |
811 | goto out_err; | 810 | goto out_err; |
812 | 811 | ||
813 | /* | 812 | /* |
814 | * Fill in the current time as ms since midnight UT: | 813 | * Fill in the current time as ms since midnight UT: |
815 | */ | 814 | */ |
816 | do_gettimeofday(&tv); | 815 | do_gettimeofday(&tv); |
817 | icmp_param.data.times[1] = htonl((tv.tv_sec % 86400) * 1000 + | 816 | icmp_param.data.times[1] = htonl((tv.tv_sec % 86400) * 1000 + |
818 | tv.tv_usec / 1000); | 817 | tv.tv_usec / 1000); |
819 | icmp_param.data.times[2] = icmp_param.data.times[1]; | 818 | icmp_param.data.times[2] = icmp_param.data.times[1]; |
820 | if (skb_copy_bits(skb, 0, &icmp_param.data.times[0], 4)) | 819 | if (skb_copy_bits(skb, 0, &icmp_param.data.times[0], 4)) |
821 | BUG(); | 820 | BUG(); |
822 | icmp_param.data.icmph = *icmp_hdr(skb); | 821 | icmp_param.data.icmph = *icmp_hdr(skb); |
823 | icmp_param.data.icmph.type = ICMP_TIMESTAMPREPLY; | 822 | icmp_param.data.icmph.type = ICMP_TIMESTAMPREPLY; |
824 | icmp_param.data.icmph.code = 0; | 823 | icmp_param.data.icmph.code = 0; |
825 | icmp_param.skb = skb; | 824 | icmp_param.skb = skb; |
826 | icmp_param.offset = 0; | 825 | icmp_param.offset = 0; |
827 | icmp_param.data_len = 0; | 826 | icmp_param.data_len = 0; |
828 | icmp_param.head_len = sizeof(struct icmphdr) + 12; | 827 | icmp_param.head_len = sizeof(struct icmphdr) + 12; |
829 | icmp_reply(&icmp_param, skb); | 828 | icmp_reply(&icmp_param, skb); |
830 | out: | 829 | out: |
831 | return; | 830 | return; |
832 | out_err: | 831 | out_err: |
833 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 832 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
834 | goto out; | 833 | goto out; |
835 | } | 834 | } |
836 | 835 | ||
837 | 836 | ||
838 | /* | 837 | /* |
839 | * Handle ICMP_ADDRESS_MASK requests. (RFC950) | 838 | * Handle ICMP_ADDRESS_MASK requests. (RFC950) |
840 | * | 839 | * |
841 | * RFC1122 (3.2.2.9). A host MUST only send replies to | 840 | * RFC1122 (3.2.2.9). A host MUST only send replies to |
842 | * ADDRESS_MASK requests if it's been configured as an address mask | 841 | * ADDRESS_MASK requests if it's been configured as an address mask |
843 | * agent. Receiving a request doesn't constitute implicit permission to | 842 | * agent. Receiving a request doesn't constitute implicit permission to |
844 | * act as one. Of course, implementing this correctly requires (SHOULD) | 843 | * act as one. Of course, implementing this correctly requires (SHOULD) |
845 | * a way to turn the functionality on and off. Another one for sysctl(), | 844 | * a way to turn the functionality on and off. Another one for sysctl(), |
846 | * I guess. -- MS | 845 | * I guess. -- MS |
847 | * | 846 | * |
848 | * RFC1812 (4.3.3.9). A router MUST implement it. | 847 | * RFC1812 (4.3.3.9). A router MUST implement it. |
849 | * A router SHOULD have switch turning it on/off. | 848 | * A router SHOULD have switch turning it on/off. |
850 | * This switch MUST be ON by default. | 849 | * This switch MUST be ON by default. |
851 | * | 850 | * |
852 | * Gratuitous replies, zero-source replies are not implemented, | 851 | * Gratuitous replies, zero-source replies are not implemented, |
853 | * that complies with RFC. DO NOT implement them!!! All the idea | 852 | * that complies with RFC. DO NOT implement them!!! All the idea |
854 | * of broadcast addrmask replies as specified in RFC950 is broken. | 853 | * of broadcast addrmask replies as specified in RFC950 is broken. |
855 | * The problem is that it is not uncommon to have several prefixes | 854 | * The problem is that it is not uncommon to have several prefixes |
856 | * on one physical interface. Moreover, addrmask agent can even be | 855 | * on one physical interface. Moreover, addrmask agent can even be |
857 | * not aware of existing another prefixes. | 856 | * not aware of existing another prefixes. |
858 | * If source is zero, addrmask agent cannot choose correct prefix. | 857 | * If source is zero, addrmask agent cannot choose correct prefix. |
859 | * Gratuitous mask announcements suffer from the same problem. | 858 | * Gratuitous mask announcements suffer from the same problem. |
860 | * RFC1812 explains it, but still allows to use ADDRMASK, | 859 | * RFC1812 explains it, but still allows to use ADDRMASK, |
861 | * that is pretty silly. --ANK | 860 | * that is pretty silly. --ANK |
862 | * | 861 | * |
863 | * All these rules are so bizarre, that I removed kernel addrmask | 862 | * All these rules are so bizarre, that I removed kernel addrmask |
864 | * support at all. It is wrong, it is obsolete, nobody uses it in | 863 | * support at all. It is wrong, it is obsolete, nobody uses it in |
865 | * any case. --ANK | 864 | * any case. --ANK |
866 | * | 865 | * |
867 | * Furthermore you can do it with a usermode address agent program | 866 | * Furthermore you can do it with a usermode address agent program |
868 | * anyway... | 867 | * anyway... |
869 | */ | 868 | */ |
870 | 869 | ||
871 | static void icmp_address(struct sk_buff *skb) | 870 | static void icmp_address(struct sk_buff *skb) |
872 | { | 871 | { |
873 | #if 0 | 872 | #if 0 |
874 | if (net_ratelimit()) | 873 | if (net_ratelimit()) |
875 | printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n"); | 874 | printk(KERN_DEBUG "a guy asks for address mask. Who is it?\n"); |
876 | #endif | 875 | #endif |
877 | } | 876 | } |
878 | 877 | ||
879 | /* | 878 | /* |
880 | * RFC1812 (4.3.3.9). A router SHOULD listen all replies, and complain | 879 | * RFC1812 (4.3.3.9). A router SHOULD listen all replies, and complain |
881 | * loudly if an inconsistency is found. | 880 | * loudly if an inconsistency is found. |
882 | */ | 881 | */ |
883 | 882 | ||
884 | static void icmp_address_reply(struct sk_buff *skb) | 883 | static void icmp_address_reply(struct sk_buff *skb) |
885 | { | 884 | { |
886 | struct rtable *rt = (struct rtable *)skb->dst; | 885 | struct rtable *rt = (struct rtable *)skb->dst; |
887 | struct net_device *dev = skb->dev; | 886 | struct net_device *dev = skb->dev; |
888 | struct in_device *in_dev; | 887 | struct in_device *in_dev; |
889 | struct in_ifaddr *ifa; | 888 | struct in_ifaddr *ifa; |
890 | 889 | ||
891 | if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) | 890 | if (skb->len < 4 || !(rt->rt_flags&RTCF_DIRECTSRC)) |
892 | goto out; | 891 | goto out; |
893 | 892 | ||
894 | in_dev = in_dev_get(dev); | 893 | in_dev = in_dev_get(dev); |
895 | if (!in_dev) | 894 | if (!in_dev) |
896 | goto out; | 895 | goto out; |
897 | rcu_read_lock(); | 896 | rcu_read_lock(); |
898 | if (in_dev->ifa_list && | 897 | if (in_dev->ifa_list && |
899 | IN_DEV_LOG_MARTIANS(in_dev) && | 898 | IN_DEV_LOG_MARTIANS(in_dev) && |
900 | IN_DEV_FORWARD(in_dev)) { | 899 | IN_DEV_FORWARD(in_dev)) { |
901 | __be32 _mask, *mp; | 900 | __be32 _mask, *mp; |
902 | 901 | ||
903 | mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask); | 902 | mp = skb_header_pointer(skb, 0, sizeof(_mask), &_mask); |
904 | BUG_ON(mp == NULL); | 903 | BUG_ON(mp == NULL); |
905 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { | 904 | for (ifa = in_dev->ifa_list; ifa; ifa = ifa->ifa_next) { |
906 | if (*mp == ifa->ifa_mask && | 905 | if (*mp == ifa->ifa_mask && |
907 | inet_ifa_match(rt->rt_src, ifa)) | 906 | inet_ifa_match(rt->rt_src, ifa)) |
908 | break; | 907 | break; |
909 | } | 908 | } |
910 | if (!ifa && net_ratelimit()) { | 909 | if (!ifa && net_ratelimit()) { |
911 | printk(KERN_INFO "Wrong address mask %u.%u.%u.%u from " | 910 | printk(KERN_INFO "Wrong address mask %u.%u.%u.%u from " |
912 | "%s/%u.%u.%u.%u\n", | 911 | "%s/%u.%u.%u.%u\n", |
913 | NIPQUAD(*mp), dev->name, NIPQUAD(rt->rt_src)); | 912 | NIPQUAD(*mp), dev->name, NIPQUAD(rt->rt_src)); |
914 | } | 913 | } |
915 | } | 914 | } |
916 | rcu_read_unlock(); | 915 | rcu_read_unlock(); |
917 | in_dev_put(in_dev); | 916 | in_dev_put(in_dev); |
918 | out:; | 917 | out:; |
919 | } | 918 | } |
920 | 919 | ||
921 | static void icmp_discard(struct sk_buff *skb) | 920 | static void icmp_discard(struct sk_buff *skb) |
922 | { | 921 | { |
923 | } | 922 | } |
924 | 923 | ||
925 | /* | 924 | /* |
926 | * Deal with incoming ICMP packets. | 925 | * Deal with incoming ICMP packets. |
927 | */ | 926 | */ |
928 | int icmp_rcv(struct sk_buff *skb) | 927 | int icmp_rcv(struct sk_buff *skb) |
929 | { | 928 | { |
930 | struct icmphdr *icmph; | 929 | struct icmphdr *icmph; |
931 | struct rtable *rt = (struct rtable *)skb->dst; | 930 | struct rtable *rt = (struct rtable *)skb->dst; |
932 | 931 | ||
933 | ICMP_INC_STATS_BH(ICMP_MIB_INMSGS); | 932 | ICMP_INC_STATS_BH(ICMP_MIB_INMSGS); |
934 | 933 | ||
935 | switch (skb->ip_summed) { | 934 | switch (skb->ip_summed) { |
936 | case CHECKSUM_COMPLETE: | 935 | case CHECKSUM_COMPLETE: |
937 | if (!csum_fold(skb->csum)) | 936 | if (!csum_fold(skb->csum)) |
938 | break; | 937 | break; |
939 | /* fall through */ | 938 | /* fall through */ |
940 | case CHECKSUM_NONE: | 939 | case CHECKSUM_NONE: |
941 | skb->csum = 0; | 940 | skb->csum = 0; |
942 | if (__skb_checksum_complete(skb)) | 941 | if (__skb_checksum_complete(skb)) |
943 | goto error; | 942 | goto error; |
944 | } | 943 | } |
945 | 944 | ||
946 | if (!pskb_pull(skb, sizeof(struct icmphdr))) | 945 | if (!pskb_pull(skb, sizeof(struct icmphdr))) |
947 | goto error; | 946 | goto error; |
948 | 947 | ||
949 | icmph = icmp_hdr(skb); | 948 | icmph = icmp_hdr(skb); |
950 | 949 | ||
951 | ICMPMSGIN_INC_STATS_BH(icmph->type); | 950 | ICMPMSGIN_INC_STATS_BH(icmph->type); |
952 | /* | 951 | /* |
953 | * 18 is the highest 'known' ICMP type. Anything else is a mystery | 952 | * 18 is the highest 'known' ICMP type. Anything else is a mystery |
954 | * | 953 | * |
955 | * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently | 954 | * RFC 1122: 3.2.2 Unknown ICMP messages types MUST be silently |
956 | * discarded. | 955 | * discarded. |
957 | */ | 956 | */ |
958 | if (icmph->type > NR_ICMP_TYPES) | 957 | if (icmph->type > NR_ICMP_TYPES) |
959 | goto error; | 958 | goto error; |
960 | 959 | ||
961 | 960 | ||
962 | /* | 961 | /* |
963 | * Parse the ICMP message | 962 | * Parse the ICMP message |
964 | */ | 963 | */ |
965 | 964 | ||
966 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { | 965 | if (rt->rt_flags & (RTCF_BROADCAST | RTCF_MULTICAST)) { |
967 | /* | 966 | /* |
968 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be | 967 | * RFC 1122: 3.2.2.6 An ICMP_ECHO to broadcast MAY be |
969 | * silently ignored (we let user decide with a sysctl). | 968 | * silently ignored (we let user decide with a sysctl). |
970 | * RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently | 969 | * RFC 1122: 3.2.2.8 An ICMP_TIMESTAMP MAY be silently |
971 | * discarded if to broadcast/multicast. | 970 | * discarded if to broadcast/multicast. |
972 | */ | 971 | */ |
973 | if ((icmph->type == ICMP_ECHO || | 972 | if ((icmph->type == ICMP_ECHO || |
974 | icmph->type == ICMP_TIMESTAMP) && | 973 | icmph->type == ICMP_TIMESTAMP) && |
975 | sysctl_icmp_echo_ignore_broadcasts) { | 974 | sysctl_icmp_echo_ignore_broadcasts) { |
976 | goto error; | 975 | goto error; |
977 | } | 976 | } |
978 | if (icmph->type != ICMP_ECHO && | 977 | if (icmph->type != ICMP_ECHO && |
979 | icmph->type != ICMP_TIMESTAMP && | 978 | icmph->type != ICMP_TIMESTAMP && |
980 | icmph->type != ICMP_ADDRESS && | 979 | icmph->type != ICMP_ADDRESS && |
981 | icmph->type != ICMP_ADDRESSREPLY) { | 980 | icmph->type != ICMP_ADDRESSREPLY) { |
982 | goto error; | 981 | goto error; |
983 | } | 982 | } |
984 | } | 983 | } |
985 | 984 | ||
986 | icmp_pointers[icmph->type].handler(skb); | 985 | icmp_pointers[icmph->type].handler(skb); |
987 | 986 | ||
988 | drop: | 987 | drop: |
989 | kfree_skb(skb); | 988 | kfree_skb(skb); |
990 | return 0; | 989 | return 0; |
991 | error: | 990 | error: |
992 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); | 991 | ICMP_INC_STATS_BH(ICMP_MIB_INERRORS); |
993 | goto drop; | 992 | goto drop; |
994 | } | 993 | } |
995 | 994 | ||
996 | /* | 995 | /* |
997 | * This table is the definition of how we handle ICMP. | 996 | * This table is the definition of how we handle ICMP. |
998 | */ | 997 | */ |
999 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { | 998 | static const struct icmp_control icmp_pointers[NR_ICMP_TYPES + 1] = { |
1000 | [ICMP_ECHOREPLY] = { | 999 | [ICMP_ECHOREPLY] = { |
1001 | .handler = icmp_discard, | 1000 | .handler = icmp_discard, |
1002 | }, | 1001 | }, |
1003 | [1] = { | 1002 | [1] = { |
1004 | .handler = icmp_discard, | 1003 | .handler = icmp_discard, |
1005 | .error = 1, | 1004 | .error = 1, |
1006 | }, | 1005 | }, |
1007 | [2] = { | 1006 | [2] = { |
1008 | .handler = icmp_discard, | 1007 | .handler = icmp_discard, |
1009 | .error = 1, | 1008 | .error = 1, |
1010 | }, | 1009 | }, |
1011 | [ICMP_DEST_UNREACH] = { | 1010 | [ICMP_DEST_UNREACH] = { |
1012 | .handler = icmp_unreach, | 1011 | .handler = icmp_unreach, |
1013 | .error = 1, | 1012 | .error = 1, |
1014 | }, | 1013 | }, |
1015 | [ICMP_SOURCE_QUENCH] = { | 1014 | [ICMP_SOURCE_QUENCH] = { |
1016 | .handler = icmp_unreach, | 1015 | .handler = icmp_unreach, |
1017 | .error = 1, | 1016 | .error = 1, |
1018 | }, | 1017 | }, |
1019 | [ICMP_REDIRECT] = { | 1018 | [ICMP_REDIRECT] = { |
1020 | .handler = icmp_redirect, | 1019 | .handler = icmp_redirect, |
1021 | .error = 1, | 1020 | .error = 1, |
1022 | }, | 1021 | }, |
1023 | [6] = { | 1022 | [6] = { |
1024 | .handler = icmp_discard, | 1023 | .handler = icmp_discard, |
1025 | .error = 1, | 1024 | .error = 1, |
1026 | }, | 1025 | }, |
1027 | [7] = { | 1026 | [7] = { |
1028 | .handler = icmp_discard, | 1027 | .handler = icmp_discard, |
1029 | .error = 1, | 1028 | .error = 1, |
1030 | }, | 1029 | }, |
1031 | [ICMP_ECHO] = { | 1030 | [ICMP_ECHO] = { |
1032 | .handler = icmp_echo, | 1031 | .handler = icmp_echo, |
1033 | }, | 1032 | }, |
1034 | [9] = { | 1033 | [9] = { |
1035 | .handler = icmp_discard, | 1034 | .handler = icmp_discard, |
1036 | .error = 1, | 1035 | .error = 1, |
1037 | }, | 1036 | }, |
1038 | [10] = { | 1037 | [10] = { |
1039 | .handler = icmp_discard, | 1038 | .handler = icmp_discard, |
1040 | .error = 1, | 1039 | .error = 1, |
1041 | }, | 1040 | }, |
1042 | [ICMP_TIME_EXCEEDED] = { | 1041 | [ICMP_TIME_EXCEEDED] = { |
1043 | .handler = icmp_unreach, | 1042 | .handler = icmp_unreach, |
1044 | .error = 1, | 1043 | .error = 1, |
1045 | }, | 1044 | }, |
1046 | [ICMP_PARAMETERPROB] = { | 1045 | [ICMP_PARAMETERPROB] = { |
1047 | .handler = icmp_unreach, | 1046 | .handler = icmp_unreach, |
1048 | .error = 1, | 1047 | .error = 1, |
1049 | }, | 1048 | }, |
1050 | [ICMP_TIMESTAMP] = { | 1049 | [ICMP_TIMESTAMP] = { |
1051 | .handler = icmp_timestamp, | 1050 | .handler = icmp_timestamp, |
1052 | }, | 1051 | }, |
1053 | [ICMP_TIMESTAMPREPLY] = { | 1052 | [ICMP_TIMESTAMPREPLY] = { |
1054 | .handler = icmp_discard, | 1053 | .handler = icmp_discard, |
1055 | }, | 1054 | }, |
1056 | [ICMP_INFO_REQUEST] = { | 1055 | [ICMP_INFO_REQUEST] = { |
1057 | .handler = icmp_discard, | 1056 | .handler = icmp_discard, |
1058 | }, | 1057 | }, |
1059 | [ICMP_INFO_REPLY] = { | 1058 | [ICMP_INFO_REPLY] = { |
1060 | .handler = icmp_discard, | 1059 | .handler = icmp_discard, |
1061 | }, | 1060 | }, |
1062 | [ICMP_ADDRESS] = { | 1061 | [ICMP_ADDRESS] = { |
1063 | .handler = icmp_address, | 1062 | .handler = icmp_address, |
1064 | }, | 1063 | }, |
1065 | [ICMP_ADDRESSREPLY] = { | 1064 | [ICMP_ADDRESSREPLY] = { |
1066 | .handler = icmp_address_reply, | 1065 | .handler = icmp_address_reply, |
1067 | }, | 1066 | }, |
1068 | }; | 1067 | }; |
1069 | 1068 | ||
1070 | void __init icmp_init(struct net_proto_family *ops) | 1069 | void __init icmp_init(struct net_proto_family *ops) |
1071 | { | 1070 | { |
1072 | struct inet_sock *inet; | 1071 | struct inet_sock *inet; |
1073 | int i; | 1072 | int i; |
1074 | 1073 | ||
1075 | for_each_possible_cpu(i) { | 1074 | for_each_possible_cpu(i) { |
1076 | int err; | 1075 | int err; |
1077 | 1076 | ||
1078 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, | 1077 | err = sock_create_kern(PF_INET, SOCK_RAW, IPPROTO_ICMP, |
1079 | &per_cpu(__icmp_socket, i)); | 1078 | &per_cpu(__icmp_socket, i)); |
1080 | 1079 | ||
1081 | if (err < 0) | 1080 | if (err < 0) |
1082 | panic("Failed to create the ICMP control socket.\n"); | 1081 | panic("Failed to create the ICMP control socket.\n"); |
1083 | 1082 | ||
1084 | per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC; | 1083 | per_cpu(__icmp_socket, i)->sk->sk_allocation = GFP_ATOMIC; |
1085 | 1084 | ||
1086 | /* Enough space for 2 64K ICMP packets, including | 1085 | /* Enough space for 2 64K ICMP packets, including |
1087 | * sk_buff struct overhead. | 1086 | * sk_buff struct overhead. |
1088 | */ | 1087 | */ |
1089 | per_cpu(__icmp_socket, i)->sk->sk_sndbuf = | 1088 | per_cpu(__icmp_socket, i)->sk->sk_sndbuf = |
1090 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); | 1089 | (2 * ((64 * 1024) + sizeof(struct sk_buff))); |
1091 | 1090 | ||
1092 | inet = inet_sk(per_cpu(__icmp_socket, i)->sk); | 1091 | inet = inet_sk(per_cpu(__icmp_socket, i)->sk); |
1093 | inet->uc_ttl = -1; | 1092 | inet->uc_ttl = -1; |
1094 | inet->pmtudisc = IP_PMTUDISC_DONT; | 1093 | inet->pmtudisc = IP_PMTUDISC_DONT; |
1095 | 1094 | ||
1096 | /* Unhash it so that IP input processing does not even | 1095 | /* Unhash it so that IP input processing does not even |
1097 | * see it, we do not wish this socket to see incoming | 1096 | * see it, we do not wish this socket to see incoming |
1098 | * packets. | 1097 | * packets. |
1099 | */ | 1098 | */ |
1100 | per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk); | 1099 | per_cpu(__icmp_socket, i)->sk->sk_prot->unhash(per_cpu(__icmp_socket, i)->sk); |
1101 | } | 1100 | } |
1102 | } | 1101 | } |
1103 | 1102 | ||
1104 | EXPORT_SYMBOL(icmp_err_convert); | 1103 | EXPORT_SYMBOL(icmp_err_convert); |
1105 | EXPORT_SYMBOL(icmp_send); | 1104 | EXPORT_SYMBOL(icmp_send); |
1106 | EXPORT_SYMBOL(icmp_statistics); | 1105 | EXPORT_SYMBOL(icmp_statistics); |
1107 | EXPORT_SYMBOL(xrlim_allow); | 1106 | EXPORT_SYMBOL(xrlim_allow); |
1108 | 1107 |