linux/include/net/netfilter/nf_queue.h
<<
>>
Prefs
   1#ifndef _NF_QUEUE_H
   2#define _NF_QUEUE_H
   3
   4#include <linux/ip.h>
   5#include <linux/ipv6.h>
   6#include <linux/jhash.h>
   7
   8/* Each queued (to userspace) skbuff has one of these. */
   9struct nf_queue_entry {
  10        struct list_head        list;
  11        struct sk_buff          *skb;
  12        unsigned int            id;
  13
  14        struct nf_hook_ops      *elem;
  15        u_int8_t                pf;
  16        u16                     size; /* sizeof(entry) + saved route keys */
  17        unsigned int            hook;
  18        struct net_device       *indev;
  19        struct net_device       *outdev;
  20        int                     (*okfn)(struct sk_buff *);
  21
  22        /* extra space to store route keys */
  23};
  24
  25#define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
  26
  27/* Packet queuing */
  28struct nf_queue_handler {
  29        int                     (*outfn)(struct nf_queue_entry *entry,
  30                                         unsigned int queuenum);
  31};
  32
  33void nf_register_queue_handler(const struct nf_queue_handler *qh);
  34void nf_unregister_queue_handler(void);
  35void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
  36
  37bool nf_queue_entry_get_refs(struct nf_queue_entry *entry);
  38void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
  39
  40static inline void init_hashrandom(u32 *jhash_initval)
  41{
  42        while (*jhash_initval == 0)
  43                *jhash_initval = prandom_u32();
  44}
  45
  46static 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)
  60static 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
  84static inline u32
  85nfqueue_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
  98#endif /* _NF_QUEUE_H */
  99