compat: Detect and use upstream ip_fragment().
[cascardo/ovs.git] / datapath / linux / compat / include / net / inet_frag.h
1 #ifndef __NET_INET_FRAG_WRAPPER_H
2 #define __NET_INET_FRAG_WRAPPER_H 1
3
4 #include <linux/version.h>
5 #include_next <net/inet_frag.h>
6
7 #if LINUX_VERSION_CODE < KERNEL_VERSION(3,7,0)
8 #define inet_frag_evictor(nf, f, force)                                 \
9         do {                                                            \
10                 if (force || atomic_read(&nf->mem) > nf->high_thresh) { \
11                         inet_frag_evictor(nf, f);                       \
12                 }                                                       \
13         } while (0)
14 #endif
15
16 #ifdef OVS_FRAGMENT_BACKPORT
17 #ifdef HAVE_INET_FRAGS_LAST_IN
18 #define q_flags(q) (q->last_in)
19 #define qp_flags(qp) (qp->q.last_in)
20 #else
21 #define q_flags(q) (q->flags)
22 #define qp_flags(qp) (qp->q.flags)
23 #endif
24
25 #ifndef HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR
26 /**
27  * struct ovs_inet_frag_queue - fragment queue
28  *
29  * Wrap the system inet_frag_queue to provide a list evictor.
30  *
31  * @list_evictor: list of queues to forcefully evict (e.g. due to low memory)
32  */
33 struct ovs_inet_frag_queue {
34         struct inet_frag_queue  fq;
35         struct hlist_node       list_evictor;
36 };
37
38 static inline bool rpl_inet_frag_evicting(struct inet_frag_queue *q)
39 {
40 #ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
41         struct ovs_inet_frag_queue *ofq = (struct ovs_inet_frag_queue *)q;
42         return !hlist_unhashed(&ofq->list_evictor);
43 #else
44         return (q_flags(q) & INET_FRAG_FIRST_IN) && q->fragments != NULL;
45 #endif
46 }
47 #define inet_frag_evicting rpl_inet_frag_evicting
48 #else /* HAVE_INET_FRAG_QUEUE_WITH_LIST_EVICTOR */
49 #ifndef HAVE_INET_FRAG_EVICTING
50 static inline bool rpl_inet_frag_evicting(struct inet_frag_queue *q)
51 {
52         return !hlist_unhashed(&q->list_evictor);
53 }
54 #define inet_frag_evicting rpl_inet_frag_evicting
55 #endif
56 #endif
57
58 #ifndef HAVE_CORRECT_MRU_HANDLING
59 static unsigned int rpl_frag_percpu_counter_batch = 130000;
60 #define frag_percpu_counter_batch rpl_frag_percpu_counter_batch
61
62 static inline void rpl_sub_frag_mem_limit(struct netns_frags *nf, int i)
63 {
64         __percpu_counter_add(&nf->mem, -i, frag_percpu_counter_batch);
65 }
66 #define sub_frag_mem_limit rpl_sub_frag_mem_limit
67
68 static inline void rpl_add_frag_mem_limit(struct netns_frags *nf, int i)
69 {
70         __percpu_counter_add(&nf->mem, i, frag_percpu_counter_batch);
71 }
72 #define add_frag_mem_limit rpl_add_frag_mem_limit
73
74 int rpl_inet_frags_init(struct inet_frags *f);
75 #define inet_frags_init rpl_inet_frags_init
76
77 void rpl_inet_frags_exit_net(struct netns_frags *nf, struct inet_frags *f);
78 #define inet_frags_exit_net rpl_inet_frags_exit_net
79
80 void rpl_inet_frag_destroy(struct inet_frag_queue *q, struct inet_frags *f);
81 #define inet_frag_destroy(q, f, work) rpl_inet_frag_destroy(q, f)
82 #endif /* !HAVE_CORRECT_MRU_HANDLING */
83 #endif /* OVS_FRAGMENT_BACKPORT */
84
85 #endif /* inet_frag.h */