File: output_core.c

package info (click to toggle)
linux 3.2.78-1
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 693,024 kB
  • sloc: ansic: 9,721,346; asm: 244,047; xml: 40,377; makefile: 23,845; perl: 16,079; python: 4,929; sh: 4,425; cpp: 3,598; yacc: 2,979; lex: 1,726; awk: 708; pascal: 231; lisp: 218; sed: 30
file content (38 lines) | stat: -rw-r--r-- 1,107 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
#include <linux/export.h>
#include <linux/skbuff.h>
#include <net/ip.h>
#include <net/ipv6.h>

/* This function exists only for tap drivers that must support broken
 * clients requesting UFO without specifying an IPv6 fragment ID.
 *
 * This is similar to ipv6_select_ident() but we use an independent hash
 * seed to limit information leakage.
 */
void ipv6_proxy_select_ident(struct sk_buff *skb)
{
	static u32 ip6_proxy_idents_hashrnd __read_mostly;
	static bool hashrnd_initialized = false;
	struct in6_addr buf[2];
	struct in6_addr *addrs;
	u32 hash, id;

	addrs = skb_header_pointer(skb,
				   skb_network_offset(skb) +
				   offsetof(struct ipv6hdr, saddr),
				   sizeof(buf), buf);
	if (!addrs)
		return;

	if (unlikely(!hashrnd_initialized)) {
		hashrnd_initialized = true;
		get_random_bytes(&ip6_proxy_idents_hashrnd,
				 sizeof(ip6_proxy_idents_hashrnd));
	}
	hash = __ipv6_addr_jhash(&addrs[1], ip6_proxy_idents_hashrnd);
	hash = __ipv6_addr_jhash(&addrs[0], hash);

	id = ip_idents_reserve(hash, 1);
	skb_shinfo(skb)->ip6_frag_id = htonl(id);
}
EXPORT_SYMBOL_GPL(ipv6_proxy_select_ident);