root/include/net/netfilter/nf_queue.h

/* [<][>][^][v][top][bottom][index][help] */

INCLUDED FROM


DEFINITIONS

This source file includes following definitions.
  1. init_hashrandom
  2. hash_v4
  3. hash_v6
  4. hash_bridge
  5. nfqueue_hash

   1 /* SPDX-License-Identifier: GPL-2.0 */
   2 #ifndef _NF_QUEUE_H
   3 #define _NF_QUEUE_H
   4 
   5 #include <linux/ip.h>
   6 #include <linux/ipv6.h>
   7 #include <linux/jhash.h>
   8 #include <linux/netfilter.h>
   9 #include <linux/skbuff.h>
  10 
  11 /* Each queued (to userspace) skbuff has one of these. */
  12 struct nf_queue_entry {
  13         struct list_head        list;
  14         struct sk_buff          *skb;
  15         unsigned int            id;
  16         unsigned int            hook_index;     /* index in hook_entries->hook[] */
  17 
  18         struct nf_hook_state    state;
  19         u16                     size; /* sizeof(entry) + saved route keys */
  20 
  21         /* extra space to store route keys */
  22 };
  23 
  24 #define nf_queue_entry_reroute(x) ((void *)x + sizeof(struct nf_queue_entry))
  25 
  26 /* Packet queuing */
  27 struct nf_queue_handler {
  28         int             (*outfn)(struct nf_queue_entry *entry,
  29                                  unsigned int queuenum);
  30         void            (*nf_hook_drop)(struct net *net);
  31 };
  32 
  33 void nf_register_queue_handler(struct net *net, const struct nf_queue_handler *qh);
  34 void nf_unregister_queue_handler(struct net *net);
  35 void nf_reinject(struct nf_queue_entry *entry, unsigned int verdict);
  36 
  37 void nf_queue_entry_get_refs(struct nf_queue_entry *entry);
  38 void nf_queue_entry_release_refs(struct nf_queue_entry *entry);
  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 iphdr *iph, u32 initval)
  47 {
  48         /* packets in either direction go into same queue */
  49         if ((__force u32)iph->saddr < (__force u32)iph->daddr)
  50                 return jhash_3words((__force u32)iph->saddr,
  51                         (__force u32)iph->daddr, iph->protocol, initval);
  52 
  53         return jhash_3words((__force u32)iph->daddr,
  54                         (__force u32)iph->saddr, iph->protocol, initval);
  55 }
  56 
  57 static inline u32 hash_v6(const struct ipv6hdr *ip6h, u32 initval)
  58 {
  59         u32 a, b, c;
  60 
  61         if ((__force u32)ip6h->saddr.s6_addr32[3] <
  62             (__force u32)ip6h->daddr.s6_addr32[3]) {
  63                 a = (__force u32) ip6h->saddr.s6_addr32[3];
  64                 b = (__force u32) ip6h->daddr.s6_addr32[3];
  65         } else {
  66                 b = (__force u32) ip6h->saddr.s6_addr32[3];
  67                 a = (__force u32) ip6h->daddr.s6_addr32[3];
  68         }
  69 
  70         if ((__force u32)ip6h->saddr.s6_addr32[1] <
  71             (__force u32)ip6h->daddr.s6_addr32[1])
  72                 c = (__force u32) ip6h->saddr.s6_addr32[1];
  73         else
  74                 c = (__force u32) ip6h->daddr.s6_addr32[1];
  75 
  76         return jhash_3words(a, b, c, initval);
  77 }
  78 
  79 static inline u32 hash_bridge(const struct sk_buff *skb, u32 initval)
  80 {
  81         struct ipv6hdr *ip6h, _ip6h;
  82         struct iphdr *iph, _iph;
  83 
  84         switch (eth_hdr(skb)->h_proto) {
  85         case htons(ETH_P_IP):
  86                 iph = skb_header_pointer(skb, skb_network_offset(skb),
  87                                          sizeof(*iph), &_iph);
  88                 if (iph)
  89                         return hash_v4(iph, initval);
  90                 break;
  91         case htons(ETH_P_IPV6):
  92                 ip6h = skb_header_pointer(skb, skb_network_offset(skb),
  93                                           sizeof(*ip6h), &_ip6h);
  94                 if (ip6h)
  95                         return hash_v6(ip6h, initval);
  96                 break;
  97         }
  98 
  99         return 0;
 100 }
 101 
 102 static inline u32
 103 nfqueue_hash(const struct sk_buff *skb, u16 queue, u16 queues_total, u8 family,
 104              u32 initval)
 105 {
 106         switch (family) {
 107         case NFPROTO_IPV4:
 108                 queue += reciprocal_scale(hash_v4(ip_hdr(skb), initval),
 109                                           queues_total);
 110                 break;
 111         case NFPROTO_IPV6:
 112                 queue += reciprocal_scale(hash_v6(ipv6_hdr(skb), initval),
 113                                           queues_total);
 114                 break;
 115         case NFPROTO_BRIDGE:
 116                 queue += reciprocal_scale(hash_bridge(skb, initval),
 117                                           queues_total);
 118                 break;
 119         }
 120 
 121         return queue;
 122 }
 123 
 124 int nf_queue(struct sk_buff *skb, struct nf_hook_state *state,
 125              unsigned int index, unsigned int verdict);
 126 
 127 #endif /* _NF_QUEUE_H */

/* [<][>][^][v][top][bottom][index][help] */