diff options
| author | Eric Leblond <eric@regit.org> | 2013-12-05 18:24:12 -0500 |
|---|---|---|
| committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2013-12-07 17:20:45 -0500 |
| commit | 97a2d41c47a2246c3387a937c62126c9faefe875 (patch) | |
| tree | 0c295ac10edb37c0e441666a84b6f3ff37fc077e /include/net | |
| parent | e569bdab35fd0d31cecb6b072e95af1834991f9d (diff) | |
netfilter: xt_NFQUEUE: separate reusable code
This patch prepares the addition of nft_queue module by moving
reusable code into a header file.
This patch also converts NFQUEUE to use prandom_u32 to initialize
the random jhash seed as suggested by Florian Westphal.
Signed-off-by: Eric Leblond <eric@regit.org>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Diffstat (limited to 'include/net')
| -rw-r--r-- | include/net/netfilter/nf_queue.h | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/include/net/netfilter/nf_queue.h b/include/net/netfilter/nf_queue.h index c1d5b3e34a21..84a53d780306 100644 --- a/include/net/netfilter/nf_queue.h +++ b/include/net/netfilter/nf_queue.h | |||
| @@ -1,6 +1,10 @@ | |||
| 1 | #ifndef _NF_QUEUE_H | 1 | #ifndef _NF_QUEUE_H |
| 2 | #define _NF_QUEUE_H | 2 | #define _NF_QUEUE_H |
| 3 | 3 | ||
| 4 | #include <linux/ip.h> | ||
| 5 | #include <linux/ipv6.h> | ||
| 6 | #include <linux/jhash.h> | ||
| 7 | |||
| 4 | /* Each queued (to userspace) skbuff has one of these. */ | 8 | /* Each queued (to userspace) skbuff has one of these. */ |
| 5 | struct nf_queue_entry { | 9 | struct nf_queue_entry { |
| 6 | struct list_head list; | 10 | struct list_head list; |
| @@ -33,4 +37,62 @@ void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict); | |||
| 33 | bool nf_queue_entry_get_refs(struct nf_queue_entry *entry); | 37 | bool nf_queue_entry_get_refs(struct nf_queue_entry *entry); |
| 34 | void nf_queue_entry_release_refs(struct nf_queue_entry *entry); | 38 | void nf_queue_entry_release_refs(struct nf_queue_entry *entry); |
| 35 | 39 | ||
| 40 | static inline void init_hashrandom(u32 *jhash_initval) | ||
| 41 | { | ||
| 42 | while (*jhash_initval == 0) | ||
| 43 | *jhash_initval = prandom_u32(); | ||
| 44 | } | ||
| 45 | |||
| 46 | static inline u32 hash_v4(const struct sk_buff *skb, u32 jhash_initval) | ||
| 47 | { | ||
| 48 | const struct iphdr *iph = ip_hdr(skb); | ||
| 49 | |||
| 50 | /* packets in either direction go into same queue */ | ||
| 51 | if ((__force u32)iph->saddr < (__force u32)iph->daddr) | ||
| 52 | return jhash_3words((__force u32)iph->saddr, | ||
| 53 | (__force u32)iph->daddr, iph->protocol, jhash_initval); | ||
| 54 | |||
| 55 | return jhash_3words((__force u32)iph->daddr, | ||
| 56 | (__force u32)iph->saddr, iph->protocol, jhash_initval); | ||
| 57 | } | ||
| 58 | |||
| 59 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | ||
| 60 | static inline u32 hash_v6(const struct sk_buff *skb, u32 jhash_initval) | ||
| 61 | { | ||
| 62 | const struct ipv6hdr *ip6h = ipv6_hdr(skb); | ||
| 63 | u32 a, b, c; | ||
| 64 | |||
| 65 | if ((__force u32)ip6h->saddr.s6_addr32[3] < | ||
| 66 | (__force u32)ip6h->daddr.s6_addr32[3]) { | ||
| 67 | a = (__force u32) ip6h->saddr.s6_addr32[3]; | ||
| 68 | b = (__force u32) ip6h->daddr.s6_addr32[3]; | ||
| 69 | } else { | ||
| 70 | b = (__force u32) ip6h->saddr.s6_addr32[3]; | ||
| 71 | a = (__force u32) ip6h->daddr.s6_addr32[3]; | ||
| 72 | } | ||
| 73 | |||
| 74 | if ((__force u32)ip6h->saddr.s6_addr32[1] < | ||
| 75 | (__force u32)ip6h->daddr.s6_addr32[1]) | ||
| 76 | c = (__force u32) ip6h->saddr.s6_addr32[1]; | ||
| 77 | else | ||
| 78 | c = (__force u32) ip6h->daddr.s6_addr32[1]; | ||
| 79 | |||
| 80 | return jhash_3words(a, b, c, jhash_initval); | ||
| 81 | } | ||
| 82 | #endif | ||
| 83 | |||
| 84 | static inline u32 | ||
| 85 | nfqueue_hash(const struct sk_buff *skb, u16 queue, u16 queues_total, u8 family, | ||
| 86 | u32 jhash_initval) | ||
| 87 | { | ||
| 88 | if (family == NFPROTO_IPV4) | ||
| 89 | queue += ((u64) hash_v4(skb, jhash_initval) * queues_total) >> 32; | ||
| 90 | #if IS_ENABLED(CONFIG_IP6_NF_IPTABLES) | ||
| 91 | else if (family == NFPROTO_IPV6) | ||
| 92 | queue += ((u64) hash_v6(skb, jhash_initval) * queues_total) >> 32; | ||
| 93 | #endif | ||
| 94 | |||
| 95 | return queue; | ||
| 96 | } | ||
| 97 | |||
| 36 | #endif /* _NF_QUEUE_H */ | 98 | #endif /* _NF_QUEUE_H */ |
