Blame view

net/ipv4/ip_input.c 14.7 KB
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
1
2
3
4
5
6
7
  /*
   * INET		An implementation of the TCP/IP protocol suite for the LINUX
   *		operating system.  INET is implemented using the  BSD Socket
   *		interface as the means of communication with the user level.
   *
   *		The Internet Protocol (IP) module.
   *
02c30a84e   Jesper Juhl   [PATCH] update Ro...
8
   * Authors:	Ross Biro
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
9
10
   *		Fred N. van Kempen, <waltje@uWalt.NL.Mugnet.ORG>
   *		Donald Becker, <becker@super.org>
113aa838e   Alan Cox   net: Rationalise ...
11
   *		Alan Cox, <alan@lxorguk.ukuu.org.uk>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
12
13
14
15
   *		Richard Underwood
   *		Stefan Becker, <stefanb@yello.ping.de>
   *		Jorge Cwik, <jorge@laser.satlink.net>
   *		Arnt Gulbrandsen, <agulbra@nvg.unit.no>
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
16
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
   *
   * Fixes:
   *		Alan Cox	:	Commented a couple of minor bits of surplus code
   *		Alan Cox	:	Undefining IP_FORWARD doesn't include the code
   *					(just stops a compiler warning).
   *		Alan Cox	:	Frames with >=MAX_ROUTE record routes, strict routes or loose routes
   *					are junked rather than corrupting things.
   *		Alan Cox	:	Frames to bad broadcast subnets are dumped
   *					We used to process them non broadcast and
   *					boy could that cause havoc.
   *		Alan Cox	:	ip_forward sets the free flag on the
   *					new frame it queues. Still crap because
   *					it copies the frame but at least it
   *					doesn't eat memory too.
   *		Alan Cox	:	Generic queue code and memory fixes.
   *		Fred Van Kempen :	IP fragment support (borrowed from NET2E)
   *		Gerhard Koerting:	Forward fragmented frames correctly.
   *		Gerhard Koerting: 	Fixes to my fix of the above 8-).
   *		Gerhard Koerting:	IP interface addressing fix.
   *		Linus Torvalds	:	More robustness checks
   *		Alan Cox	:	Even more checks: Still not as robust as it ought to be
   *		Alan Cox	:	Save IP header pointer for later
   *		Alan Cox	:	ip option setting
   *		Alan Cox	:	Use ip_tos/ip_ttl settings
   *		Alan Cox	:	Fragmentation bogosity removed
   *					(Thanks to Mark.Bush@prg.ox.ac.uk)
   *		Dmitry Gorodchanin :	Send of a raw packet crash fix.
   *		Alan Cox	:	Silly ip bug when an overlength
   *					fragment turns up. Now frees the
   *					queue.
   *		Linus Torvalds/ :	Memory leakage on fragmentation
   *		Alan Cox	:	handling.
   *		Gerhard Koerting:	Forwarding uses IP priority hints
   *		Teemu Rantanen	:	Fragment problems.
   *		Alan Cox	:	General cleanup, comments and reformat
   *		Alan Cox	:	SNMP statistics
   *		Alan Cox	:	BSD address rule semantics. Also see
   *					UDP as there is a nasty checksum issue
   *					if you do things the wrong way.
   *		Alan Cox	:	Always defrag, moved IP_FORWARD to the config.in file
   *		Alan Cox	: 	IP options adjust sk->priority.
   *		Pedro Roque	:	Fix mtu/length error in ip_forward.
   *		Alan Cox	:	Avoid ip_chk_addr when possible.
   *	Richard Underwood	:	IP multicasting.
   *		Alan Cox	:	Cleaned up multicast handlers.
   *		Alan Cox	:	RAW sockets demultiplex in the BSD style.
   *		Gunther Mayer	:	Fix the SNMP reporting typo
   *		Alan Cox	:	Always in group 224.0.0.1
   *	Pauline Middelink	:	Fast ip_checksum update when forwarding
   *					Masquerading support.
   *		Alan Cox	:	Multicast loopback error for 224.0.0.1
   *		Alan Cox	:	IP_MULTICAST_LOOP option.
   *		Alan Cox	:	Use notifiers.
   *		Bjorn Ekwall	:	Removed ip_csum (from slhc.c too)
   *		Bjorn Ekwall	:	Moved ip_fast_csum to ip.h (inline!)
   *		Stefan Becker   :       Send out ICMP HOST REDIRECT
   *	Arnt Gulbrandsen	:	ip_build_xmit
   *		Alan Cox	:	Per socket routing cache
   *		Alan Cox	:	Fixed routing cache, added header cache.
   *		Alan Cox	:	Loopback didn't work right in original ip_build_xmit - fixed it.
   *		Alan Cox	:	Only send ICMP_REDIRECT if src/dest are the same net.
   *		Alan Cox	:	Incoming IP option handling.
   *		Alan Cox	:	Set saddr on raw output frames as per BSD.
   *		Alan Cox	:	Stopped broadcast source route explosions.
   *		Alan Cox	:	Can disable source routing
   *		Takeshi Sone    :	Masquerading didn't work.
   *	Dave Bonn,Alan Cox	:	Faster IP forwarding whenever possible.
   *		Alan Cox	:	Memory leaks, tramples, misc debugging.
   *		Alan Cox	:	Fixed multicast (by popular demand 8))
   *		Alan Cox	:	Fixed forwarding (by even more popular demand 8))
   *		Alan Cox	:	Fixed SNMP statistics [I think]
   *	Gerhard Koerting	:	IP fragmentation forwarding fix
   *		Alan Cox	:	Device lock against page fault.
   *		Alan Cox	:	IP_HDRINCL facility.
   *	Werner Almesberger	:	Zero fragment bug
   *		Alan Cox	:	RAW IP frame length bug
   *		Alan Cox	:	Outgoing firewall on build_xmit
   *		A.N.Kuznetsov	:	IP_OPTIONS support throughout the kernel
   *		Alan Cox	:	Multicast routing hooks
   *		Jos Vos		:	Do accounting *before* call_in_firewall
   *	Willy Konynenberg	:	Transparent proxying support
   *
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
99
   *
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
100
101
102
103
104
   *
   * To Fix:
   *		IP fragmentation wants rewriting cleanly. The RFC815 algorithm is much more efficient
   *		and could be made very efficient with the addition of some virtual memory hacks to permit
   *		the allocation of a buffer that can then be 'grown' by twiddling page tables.
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
105
   *		Output fragmentation wants updating along with the buffer management to use a single
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
106
107
108
109
110
111
112
113
114
   *		interleaved copy algorithm so that fragmenting has a one copy overhead. Actual packet
   *		output should probably do its own fragmentation at the UDP/RAW layer. TCP shouldn't cause
   *		fragmentation anyway.
   *
   *		This program is free software; you can redistribute it and/or
   *		modify it under the terms of the GNU General Public License
   *		as published by the Free Software Foundation; either version
   *		2 of the License, or (at your option) any later version.
   */
afd465030   Joe Perches   net: ipv4: Standa...
115
  #define pr_fmt(fmt) "IPv4: " fmt
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
116
117
118
119
120
  #include <linux/module.h>
  #include <linux/types.h>
  #include <linux/kernel.h>
  #include <linux/string.h>
  #include <linux/errno.h>
5a0e3ad6a   Tejun Heo   include cleanup: ...
121
  #include <linux/slab.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
122
123
124
125
126
127
  
  #include <linux/net.h>
  #include <linux/socket.h>
  #include <linux/sockios.h>
  #include <linux/in.h>
  #include <linux/inet.h>
14c850212   Arnaldo Carvalho de Melo   [INET_SOCK]: Move...
128
  #include <linux/inetdevice.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
129
130
131
132
133
134
135
136
137
138
139
140
141
  #include <linux/netdevice.h>
  #include <linux/etherdevice.h>
  
  #include <net/snmp.h>
  #include <net/ip.h>
  #include <net/protocol.h>
  #include <net/route.h>
  #include <linux/skbuff.h>
  #include <net/sock.h>
  #include <net/arp.h>
  #include <net/icmp.h>
  #include <net/raw.h>
  #include <net/checksum.h>
1f07d03e2   Eric Dumazet   net: add SNMP cou...
142
  #include <net/inet_ecn.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
143
144
145
146
  #include <linux/netfilter_ipv4.h>
  #include <net/xfrm.h>
  #include <linux/mroute.h>
  #include <linux/netlink.h>
f38a9eb1f   Thomas Graf   dst: Metadata des...
147
  #include <net/dst_metadata.h>
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
148
149
  
  /*
66018506e   Eric Dumazet   ip: Router Alert ...
150
   *	Process Router Attention IP option (RFC 2113)
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
151
   */
ba57b4db2   David S. Miller   ipv4: Make ip_cal...
152
  bool ip_call_ra_chain(struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
153
154
  {
  	struct ip_ra_chain *ra;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
155
  	u8 protocol = ip_hdr(skb)->protocol;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
156
  	struct sock *last = NULL;
cb84663e4   Denis V. Lunev   [NETNS]: Process ...
157
  	struct net_device *dev = skb->dev;
37fcbab61   Eric W. Biederman   ipv4: Only comput...
158
  	struct net *net = dev_net(dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
159

66018506e   Eric Dumazet   ip: Router Alert ...
160
  	for (ra = rcu_dereference(ip_ra_chain); ra; ra = rcu_dereference(ra->next)) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
161
162
163
164
165
  		struct sock *sk = ra->sk;
  
  		/* If socket is bound to an interface, only report
  		 * the packet if it came  from that interface.
  		 */
c720c7e83   Eric Dumazet   inet: rename some...
166
  		if (sk && inet_sk(sk)->inet_num == protocol &&
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
167
  		    (!sk->sk_bound_dev_if ||
cb84663e4   Denis V. Lunev   [NETNS]: Process ...
168
  		     sk->sk_bound_dev_if == dev->ifindex) &&
37fcbab61   Eric W. Biederman   ipv4: Only comput...
169
  		    net_eq(sock_net(sk), net)) {
56f8a75c1   Paul Gortmaker   ip: introduce ip_...
170
  			if (ip_is_fragment(ip_hdr(skb))) {
19bcf9f20   Eric W. Biederman   ipv4: Pass struct...
171
  				if (ip_defrag(net, skb, IP_DEFRAG_CALL_RA_CHAIN))
ba57b4db2   David S. Miller   ipv4: Make ip_cal...
172
  					return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
173
174
175
176
177
178
179
180
181
182
183
184
  			}
  			if (last) {
  				struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
  				if (skb2)
  					raw_rcv(last, skb2);
  			}
  			last = sk;
  		}
  	}
  
  	if (last) {
  		raw_rcv(last, skb);
ba57b4db2   David S. Miller   ipv4: Make ip_cal...
185
  		return true;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
186
  	}
ba57b4db2   David S. Miller   ipv4: Make ip_cal...
187
  	return false;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
188
  }
0c4b51f00   Eric W. Biederman   netfilter: Pass n...
189
  static int ip_local_deliver_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
190
  {
21d1196a3   Eric Dumazet   ipv4: set transpo...
191
  	__skb_pull(skb, skb_network_header_len(skb));
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
192
193
194
  
  	rcu_read_lock();
  	{
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
195
  		int protocol = ip_hdr(skb)->protocol;
32613090a   Alexey Dobriyan   net: constify str...
196
  		const struct net_protocol *ipprot;
f9242b6b2   David S. Miller   inet: Sanitize in...
197
  		int raw;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
198
199
  
  	resubmit:
7bc54c903   Pavel Emelyanov   [IPv4] RAW: Compa...
200
  		raw = raw_local_deliver(skb, protocol);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
201

f9242b6b2   David S. Miller   inet: Sanitize in...
202
  		ipprot = rcu_dereference(inet_protos[protocol]);
00db41243   Ian Morris   ipv4: coding styl...
203
  		if (ipprot) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
204
  			int ret;
b59c27010   Patrick McHardy   [NETFILTER]: Keep...
205
206
207
208
209
210
  			if (!ipprot->no_policy) {
  				if (!xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
  					kfree_skb(skb);
  					goto out;
  				}
  				nf_reset(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
211
212
213
214
215
216
  			}
  			ret = ipprot->handler(skb);
  			if (ret < 0) {
  				protocol = -ret;
  				goto resubmit;
  			}
b45386efa   Eric Dumazet   net: rename IP_IN...
217
  			__IP_INC_STATS(net, IPSTATS_MIB_INDELIVERS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
218
  		} else {
7bc54c903   Pavel Emelyanov   [IPv4] RAW: Compa...
219
  			if (!raw) {
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
220
  				if (xfrm4_policy_check(NULL, XFRM_POLICY_IN, skb)) {
b45386efa   Eric Dumazet   net: rename IP_IN...
221
  					__IP_INC_STATS(net, IPSTATS_MIB_INUNKNOWNPROTOS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
222
223
224
  					icmp_send(skb, ICMP_DEST_UNREACH,
  						  ICMP_PROT_UNREACH, 0);
  				}
d8c6f4b9b   Neil Horman   ipv[4|6]: correct...
225
226
  				kfree_skb(skb);
  			} else {
b45386efa   Eric Dumazet   net: rename IP_IN...
227
  				__IP_INC_STATS(net, IPSTATS_MIB_INDELIVERS);
d8c6f4b9b   Neil Horman   ipv[4|6]: correct...
228
229
  				consume_skb(skb);
  			}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
230
231
232
233
234
235
236
237
238
239
  		}
  	}
   out:
  	rcu_read_unlock();
  
  	return 0;
  }
  
  /*
   * 	Deliver IP Packets to the higher protocol layers.
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
240
   */
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
241
242
243
244
245
  int ip_local_deliver(struct sk_buff *skb)
  {
  	/*
  	 *	Reassemble IP fragments.
  	 */
19bcf9f20   Eric W. Biederman   ipv4: Pass struct...
246
  	struct net *net = dev_net(skb->dev);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
247

56f8a75c1   Paul Gortmaker   ip: introduce ip_...
248
  	if (ip_is_fragment(ip_hdr(skb))) {
19bcf9f20   Eric W. Biederman   ipv4: Pass struct...
249
  		if (ip_defrag(net, skb, IP_DEFRAG_LOCAL_DELIVER))
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
250
251
  			return 0;
  	}
29a26a568   Eric W. Biederman   netfilter: Pass s...
252
  	return NF_HOOK(NFPROTO_IPV4, NF_INET_LOCAL_IN,
19bcf9f20   Eric W. Biederman   ipv4: Pass struct...
253
  		       net, NULL, skb, skb->dev, NULL,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
254
255
  		       ip_local_deliver_finish);
  }
6a91395f2   David S. Miller   ipv4: Make ip_rcv...
256
  static inline bool ip_rcv_options(struct sk_buff *skb)
d245407e7   Thomas Graf   [IPV4]: Move ip o...
257
258
  {
  	struct ip_options *opt;
b71d1d426   Eric Dumazet   inet: constify ip...
259
  	const struct iphdr *iph;
d245407e7   Thomas Graf   [IPV4]: Move ip o...
260
261
262
263
264
265
266
267
268
269
  	struct net_device *dev = skb->dev;
  
  	/* It looks as overkill, because not all
  	   IP options require packet mangling.
  	   But it is the easiest for now, especially taking
  	   into account that combination of IP options
  	   and running sniffer is extremely rare condition.
  					      --ANK (980813)
  	*/
  	if (skb_cow(skb, skb_headroom(skb))) {
b45386efa   Eric Dumazet   net: rename IP_IN...
270
  		__IP_INC_STATS(dev_net(dev), IPSTATS_MIB_INDISCARDS);
d245407e7   Thomas Graf   [IPV4]: Move ip o...
271
272
  		goto drop;
  	}
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
273
  	iph = ip_hdr(skb);
22aba383c   Denis V. Lunev   [IPV4]: Always pa...
274
275
  	opt = &(IPCB(skb)->opt);
  	opt->optlen = iph->ihl*4 - sizeof(struct iphdr);
d245407e7   Thomas Graf   [IPV4]: Move ip o...
276

c346dca10   YOSHIFUJI Hideaki   [NET] NETNS: Omit...
277
  	if (ip_options_compile(dev_net(dev), opt, skb)) {
b45386efa   Eric Dumazet   net: rename IP_IN...
278
  		__IP_INC_STATS(dev_net(dev), IPSTATS_MIB_INHDRERRORS);
d245407e7   Thomas Graf   [IPV4]: Move ip o...
279
280
  		goto drop;
  	}
d245407e7   Thomas Graf   [IPV4]: Move ip o...
281
  	if (unlikely(opt->srr)) {
6e8b11b43   Eric Dumazet   net: avoid two at...
282
  		struct in_device *in_dev = __in_dev_get_rcu(dev);
d245407e7   Thomas Graf   [IPV4]: Move ip o...
283
284
  		if (in_dev) {
  			if (!IN_DEV_SOURCE_ROUTE(in_dev)) {
e87cc4728   Joe Perches   net: Convert net_...
285
286
287
288
289
  				if (IN_DEV_LOG_MARTIANS(in_dev))
  					net_info_ratelimited("source route option %pI4 -> %pI4
  ",
  							     &iph->saddr,
  							     &iph->daddr);
d245407e7   Thomas Graf   [IPV4]: Move ip o...
290
291
  				goto drop;
  			}
d245407e7   Thomas Graf   [IPV4]: Move ip o...
292
293
294
295
296
  		}
  
  		if (ip_options_rcv_srr(skb))
  			goto drop;
  	}
6a91395f2   David S. Miller   ipv4: Make ip_rcv...
297
  	return false;
d245407e7   Thomas Graf   [IPV4]: Move ip o...
298
  drop:
6a91395f2   David S. Miller   ipv4: Make ip_rcv...
299
  	return true;
d245407e7   Thomas Graf   [IPV4]: Move ip o...
300
  }
0c4b51f00   Eric W. Biederman   netfilter: Pass n...
301
  static int ip_rcv_finish(struct net *net, struct sock *sk, struct sk_buff *skb)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
302
  {
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
303
  	const struct iphdr *iph = ip_hdr(skb);
7487449c8   Paolo Abeni   IPv4: early demux...
304
  	int (*edemux)(struct sk_buff *skb);
d6f64d725   Mark Tomlinson   net: VRF: Pass or...
305
  	struct net_device *dev = skb->dev;
7487449c8   Paolo Abeni   IPv4: early demux...
306
307
  	struct rtable *rt;
  	int err;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
308

74b20582a   David Ahern   net: l3mdev: Add ...
309
310
311
312
313
314
  	/* if ingress device is enslaved to an L3 master device pass the
  	 * skb to its handler for processing
  	 */
  	skb = l3mdev_ip_rcv(skb);
  	if (!skb)
  		return NET_RX_SUCCESS;
e21145a98   Nikolay Borisov   ipv4: namespacify...
315
  	if (net->ipv4.sysctl_ip_early_demux &&
63e51b6a2   Eric Dumazet   ipv4: early demux...
316
317
318
  	    !skb_dst(skb) &&
  	    !skb->sk &&
  	    !ip_is_fragment(iph)) {
160eb5a6b   David S. Miller   ipv4: Kill early ...
319
320
  		const struct net_protocol *ipprot;
  		int protocol = iph->protocol;
160eb5a6b   David S. Miller   ipv4: Kill early ...
321
  		ipprot = rcu_dereference(inet_protos[protocol]);
dddb64bcb   subashab@codeaurora.org   net: Add sysctl t...
322
  		if (ipprot && (edemux = READ_ONCE(ipprot->early_demux))) {
7487449c8   Paolo Abeni   IPv4: early demux...
323
324
325
  			err = edemux(skb);
  			if (unlikely(err))
  				goto drop_error;
9cb429d69   Eric Dumazet   tcp: early_demux ...
326
327
328
  			/* must reload iph, skb->head might have changed */
  			iph = ip_hdr(skb);
  		}
160eb5a6b   David S. Miller   ipv4: Kill early ...
329
  	}
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
330
331
332
  	/*
  	 *	Initialise the virtual path cache for the packet. It describes
  	 *	how the packet travels inside Linux networking.
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
333
  	 */
f38a9eb1f   Thomas Graf   dst: Metadata des...
334
  	if (!skb_valid_dst(skb)) {
7487449c8   Paolo Abeni   IPv4: early demux...
335
336
337
338
  		err = ip_route_input_noref(skb, iph->daddr, iph->saddr,
  					   iph->tos, dev);
  		if (unlikely(err))
  			goto drop_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
339
  	}
c7066f70d   Patrick McHardy   netfilter: fix Kc...
340
  #ifdef CONFIG_IP_ROUTE_CLASSID
adf30907d   Eric Dumazet   net: skb->dst acc...
341
  	if (unlikely(skb_dst(skb)->tclassid)) {
7a9b2d595   Eric Dumazet   net: use this_cpu...
342
  		struct ip_rt_acct *st = this_cpu_ptr(ip_rt_acct);
adf30907d   Eric Dumazet   net: skb->dst acc...
343
  		u32 idx = skb_dst(skb)->tclassid;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
344
  		st[idx&0xFF].o_packets++;
fd3f8c4cb   Jianjun Kong   net: clean up net...
345
  		st[idx&0xFF].o_bytes += skb->len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
346
  		st[(idx>>16)&0xFF].i_packets++;
fd3f8c4cb   Jianjun Kong   net: clean up net...
347
  		st[(idx>>16)&0xFF].i_bytes += skb->len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
348
349
  	}
  #endif
d245407e7   Thomas Graf   [IPV4]: Move ip o...
350
351
  	if (iph->ihl > 5 && ip_rcv_options(skb))
  		goto drop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
352

511c3f92a   Eric Dumazet   net: skb->rtable ...
353
  	rt = skb_rtable(skb);
edf391ff1   Neil Horman   snmp: add missing...
354
  	if (rt->rt_type == RTN_MULTICAST) {
b15084ec7   Eric Dumazet   net: rename IP_UP...
355
  		__IP_UPD_PO_STATS(net, IPSTATS_MIB_INMCAST, skb->len);
12b74dfad   Johannes Berg   ipv4: add option ...
356
  	} else if (rt->rt_type == RTN_BROADCAST) {
b15084ec7   Eric Dumazet   net: rename IP_UP...
357
  		__IP_UPD_PO_STATS(net, IPSTATS_MIB_INBCAST, skb->len);
12b74dfad   Johannes Berg   ipv4: add option ...
358
359
  	} else if (skb->pkt_type == PACKET_BROADCAST ||
  		   skb->pkt_type == PACKET_MULTICAST) {
d6f64d725   Mark Tomlinson   net: VRF: Pass or...
360
  		struct in_device *in_dev = __in_dev_get_rcu(dev);
12b74dfad   Johannes Berg   ipv4: add option ...
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
  
  		/* RFC 1122 3.3.6:
  		 *
  		 *   When a host sends a datagram to a link-layer broadcast
  		 *   address, the IP destination address MUST be a legal IP
  		 *   broadcast or IP multicast address.
  		 *
  		 *   A host SHOULD silently discard a datagram that is received
  		 *   via a link-layer broadcast (see Section 2.4) but does not
  		 *   specify an IP multicast or broadcast destination address.
  		 *
  		 * This doesn't explicitly say L2 *broadcast*, but broadcast is
  		 * in a way a form of multicast and the most common use case for
  		 * this is 802.11 protecting against cross-station spoofing (the
  		 * so-called "hole-196" attack) so do it for both.
  		 */
  		if (in_dev &&
  		    IN_DEV_ORCONF(in_dev, DROP_UNICAST_IN_L2_MULTICAST))
  			goto drop;
  	}
5506b54b3   Mitsuru Chinen   [IPV4] SNMP: Supp...
381

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
382
  	return dst_input(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
383
  drop:
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
384
385
  	kfree_skb(skb);
  	return NET_RX_DROP;
7487449c8   Paolo Abeni   IPv4: early demux...
386
387
388
389
390
  
  drop_error:
  	if (err == -EXDEV)
  		__NET_INC_STATS(net, LINUX_MIB_IPRPFILTER);
  	goto drop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
391
392
393
394
  }
  
  /*
   * 	Main IP Receive routine.
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
395
   */
f2ccd8fa0   David S. Miller   [NET]: Kill skb->...
396
  int ip_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
397
  {
b71d1d426   Eric Dumazet   inet: constify ip...
398
  	const struct iphdr *iph;
e707766ce   Eric W. Biederman   ipv4: Compute net...
399
  	struct net *net;
586152424   Thomas Graf   [IPV4]: Consisten...
400
  	u32 len;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
401
402
403
404
405
406
  
  	/* When the interface is in promisc. mode, drop all the crap
  	 * that it receives, do not try to analyse it.
  	 */
  	if (skb->pkt_type == PACKET_OTHERHOST)
  		goto drop;
edf391ff1   Neil Horman   snmp: add missing...
407

e707766ce   Eric W. Biederman   ipv4: Compute net...
408
  	net = dev_net(dev);
b15084ec7   Eric Dumazet   net: rename IP_UP...
409
  	__IP_UPD_PO_STATS(net, IPSTATS_MIB_IN, skb->len);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
410

51456b291   Ian Morris   ipv4: coding styl...
411
412
  	skb = skb_share_check(skb, GFP_ATOMIC);
  	if (!skb) {
b45386efa   Eric Dumazet   net: rename IP_IN...
413
  		__IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
414
415
416
417
418
  		goto out;
  	}
  
  	if (!pskb_may_pull(skb, sizeof(struct iphdr)))
  		goto inhdr_error;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
419
  	iph = ip_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
420
421
  
  	/*
c67fa0279   J.H.M. Dassen (Ray)   net/ipv4: correct...
422
  	 *	RFC1122: 3.2.1.2 MUST silently discard any IP frame that fails the checksum.
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
423
424
425
426
427
428
429
430
431
432
  	 *
  	 *	Is the datagram acceptable?
  	 *
  	 *	1.	Length at least the size of an ip header
  	 *	2.	Version of 4
  	 *	3.	Checksums correctly. [Speed optimisation for later, skip loopback checksums]
  	 *	4.	Doesn't have a bogus length
  	 */
  
  	if (iph->ihl < 5 || iph->version != 4)
586152424   Thomas Graf   [IPV4]: Consisten...
433
  		goto inhdr_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
434

1f07d03e2   Eric Dumazet   net: add SNMP cou...
435
436
437
  	BUILD_BUG_ON(IPSTATS_MIB_ECT1PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_1);
  	BUILD_BUG_ON(IPSTATS_MIB_ECT0PKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_ECT_0);
  	BUILD_BUG_ON(IPSTATS_MIB_CEPKTS != IPSTATS_MIB_NOECTPKTS + INET_ECN_CE);
98f619957   Eric Dumazet   net: rename IP_AD...
438
439
440
  	__IP_ADD_STATS(net,
  		       IPSTATS_MIB_NOECTPKTS + (iph->tos & INET_ECN_MASK),
  		       max_t(unsigned short, 1, skb_shinfo(skb)->gso_segs));
1f07d03e2   Eric Dumazet   net: add SNMP cou...
441

1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
442
443
  	if (!pskb_may_pull(skb, iph->ihl*4))
  		goto inhdr_error;
eddc9ec53   Arnaldo Carvalho de Melo   [SK_BUFF]: Introd...
444
  	iph = ip_hdr(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
445

e9c604227   Thomas Graf   [IPV4]: Avoid com...
446
  	if (unlikely(ip_fast_csum((u8 *)iph, iph->ihl)))
6a5dc9e59   Eric Dumazet   net: Add MIB coun...
447
  		goto csum_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
448

586152424   Thomas Graf   [IPV4]: Consisten...
449
  	len = ntohs(iph->tot_len);
704aed53b   Mitsuru Chinen   [IPV4] SNMP: Supp...
450
  	if (skb->len < len) {
b45386efa   Eric Dumazet   net: rename IP_IN...
451
  		__IP_INC_STATS(net, IPSTATS_MIB_INTRUNCATEDPKTS);
704aed53b   Mitsuru Chinen   [IPV4] SNMP: Supp...
452
453
  		goto drop;
  	} else if (len < (iph->ihl*4))
586152424   Thomas Graf   [IPV4]: Consisten...
454
  		goto inhdr_error;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
455

586152424   Thomas Graf   [IPV4]: Consisten...
456
457
458
459
460
  	/* Our transport medium may have padded the buffer out. Now we know it
  	 * is IP we can trim to the true length of the frame.
  	 * Note this now means skb->len holds ntohs(iph->tot_len).
  	 */
  	if (pskb_trim_rcsum(skb, len)) {
b45386efa   Eric Dumazet   net: rename IP_IN...
461
  		__IP_INC_STATS(net, IPSTATS_MIB_INDISCARDS);
586152424   Thomas Graf   [IPV4]: Consisten...
462
  		goto drop;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
463
  	}
66a011d15   Ross Lagerwall   net: Fix usage of...
464
  	iph = ip_hdr(skb);
21d1196a3   Eric Dumazet   ipv4: set transpo...
465
  	skb->transport_header = skb->network_header + iph->ihl*4;
53602f92d   Stephen Hemminger   [IPV4]: Clear skb...
466
  	/* Remove any debris in the socket control block */
d569f1d72   Guillaume Chazarain   [IPV4]: Clear the...
467
  	memset(IPCB(skb), 0, sizeof(struct inet_skb_parm));
0b922b7a8   David Ahern   net: original ing...
468
  	IPCB(skb)->iif = skb->skb_iif;
53602f92d   Stephen Hemminger   [IPV4]: Clear skb...
469

71f9dacd2   Herbert Xu   inet: Call skb_or...
470
471
  	/* Must drop socket now because of tproxy. */
  	skb_orphan(skb);
29a26a568   Eric W. Biederman   netfilter: Pass s...
472
473
  	return NF_HOOK(NFPROTO_IPV4, NF_INET_PRE_ROUTING,
  		       net, NULL, skb, dev, NULL,
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
474
  		       ip_rcv_finish);
6a5dc9e59   Eric Dumazet   net: Add MIB coun...
475
  csum_error:
b45386efa   Eric Dumazet   net: rename IP_IN...
476
  	__IP_INC_STATS(net, IPSTATS_MIB_CSUMERRORS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
477
  inhdr_error:
b45386efa   Eric Dumazet   net: rename IP_IN...
478
  	__IP_INC_STATS(net, IPSTATS_MIB_INHDRERRORS);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
479
  drop:
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
480
  	kfree_skb(skb);
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
481
  out:
e905a9eda   YOSHIFUJI Hideaki   [NET] IPV4: Fix w...
482
  	return NET_RX_DROP;
1da177e4c   Linus Torvalds   Linux-2.6.12-rc2
483
  }