Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89cee8b1 authored by Herbert Xu's avatar Herbert Xu Committed by David S. Miller
Browse files

[IPV4]: Safer reassembly

Another spin of Herbert Xu's "safer ip reassembly" patch
for 2.6.16.

(The original patch is here:
http://marc.theaimsgroup.com/?l=linux-netdev&m=112281936522415&w=2


and my only contribution is to have tested it.)

This patch (optionally) does additional checks before accepting IP
fragments, which can greatly reduce the possibility of reassembling
fragments which originated from different IP datagrams.

Signed-off-by: default avatarHerbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: default avatarArthur Kepner <akepner@sgi.com>
Signed-off-by: default avatarDavid S. Miller <davem@davemloft.net>
parent d5228a4f
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -46,6 +46,29 @@ ipfrag_secret_interval - INTEGER
	for the hash secret) for IP fragments.
	Default: 600

ipfrag_max_dist - INTEGER
	ipfrag_max_dist is a non-negative integer value which defines the 
	maximum "disorder" which is allowed among fragments which share a 
	common IP source address. Note that reordering of packets is 
	not unusual, but if a large number of fragments arrive from a source 
	IP address while a particular fragment queue remains incomplete, it 
	probably indicates that one or more fragments belonging to that queue 
	have been lost. When ipfrag_max_dist is positive, an additional check 
	is done on fragments before they are added to a reassembly queue - if 
	ipfrag_max_dist (or more) fragments have arrived from a particular IP 
	address between additions to any IP fragment queue using that source 
	address, it's presumed that one or more fragments in the queue are 
	lost. The existing fragment queue will be dropped, and a new one 
	started. An ipfrag_max_dist value of zero disables this check.

	Using a very small value, e.g. 1 or 2, for ipfrag_max_dist can
	result in unnecessarily dropping fragment queues when normal
	reordering of packets occurs, which could lead to poor application 
	performance. Using a very large value, e.g. 50000, increases the 
	likelihood of incorrectly reassembling IP fragments that originate 
	from different IP datagrams, which could result in data corruption.
	Default: 64

INET peer storage:

inet_peer_threshold - INTEGER
+1 −0
Original line number Diff line number Diff line
@@ -390,6 +390,7 @@ enum
	NET_IPV4_ICMP_ERRORS_USE_INBOUND_IFADDR=109,
	NET_TCP_CONG_CONTROL=110,
	NET_TCP_ABC=111,
	NET_IPV4_IPFRAG_MAX_DIST=112,
};

enum {
+1 −0
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ struct inet_peer
	__u32			v4daddr;	/* peer's address */
	__u16			avl_height;
	__u16			ip_id_count;	/* IP ID for the next packet */
	atomic_t		rid;		/* Frag reception counter */
	__u32			tcp_ts;
	unsigned long		tcp_ts_stamp;
};
+2 −0
Original line number Diff line number Diff line
@@ -45,6 +45,7 @@ struct inet_skb_parm
#define IPSKB_TRANSLATED	2
#define IPSKB_FORWARDED		4
#define IPSKB_XFRM_TUNNEL_SIZE	8
#define IPSKB_FRAG_COMPLETE	16
};

struct ipcm_cookie
@@ -168,6 +169,7 @@ extern int sysctl_ipfrag_high_thresh;
extern int sysctl_ipfrag_low_thresh;
extern int sysctl_ipfrag_time;
extern int sysctl_ipfrag_secret_interval;
extern int sysctl_ipfrag_max_dist;

/* From inetpeer.c */
extern int inet_peer_threshold;
+1 −0
Original line number Diff line number Diff line
@@ -401,6 +401,7 @@ struct inet_peer *inet_getpeer(__u32 daddr, int create)
		return NULL;
	n->v4daddr = daddr;
	atomic_set(&n->refcnt, 1);
	atomic_set(&n->rid, 0);
	n->ip_id_count = secure_ip_id(daddr);
	n->tcp_ts_stamp = 0;

Loading