]> git.proxmox.com Git - mirror_ovs.git/blob - datapath/linux/compat/nf_conntrack_proto.c
datapath: Handle removal of nf_conntrack_l3proto.h
[mirror_ovs.git] / datapath / linux / compat / nf_conntrack_proto.c
1 #include <linux/types.h>
2
3 #include <net/netfilter/nf_conntrack.h>
4 #ifdef HAVE_NF_CONNTRACK_L3PROATO_H
5 #include <net/netfilter/nf_conntrack_l3proto.h>
6 #endif
7
8 /*
9 * Upstream net-next commmit 7e35ec0e8044
10 * ("netfilter: conntrack: move nf_ct_netns_{get,put}() to core")
11 * is introduced in v4.15, and it supports NFPROTO_INET in
12 * nf_ct_netns_{get,put}() that OVS conntrack uses this feature.
13 *
14 * However, we only need this feature if the underlying nf_conntrack_l3proto
15 * supports net_ns_get/put. Thus, we just mock the functions if
16 * HAVE_NET_NS_GET is false.
17 */
18 #if LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0)
19 #ifdef HAVE_NET_NS_GET
20 static int nf_ct_netns_do_get(struct net *net, u8 nfproto)
21 {
22 const struct nf_conntrack_l3proto *l3proto;
23 int ret;
24
25 might_sleep();
26
27 ret = nf_ct_l3proto_try_module_get(nfproto);
28 if (ret < 0)
29 return ret;
30
31 /* we already have a reference, can't fail */
32 rcu_read_lock();
33 l3proto = __nf_ct_l3proto_find(nfproto);
34 rcu_read_unlock();
35
36 if (!l3proto->net_ns_get)
37 return 0;
38
39 ret = l3proto->net_ns_get(net);
40 if (ret < 0)
41 nf_ct_l3proto_module_put(nfproto);
42
43 return ret;
44 }
45
46 int rpl_nf_ct_netns_get(struct net *net, u8 nfproto)
47 {
48 int err;
49
50 if (nfproto == NFPROTO_INET) {
51 err = nf_ct_netns_do_get(net, NFPROTO_IPV4);
52 if (err < 0)
53 goto err1;
54 err = nf_ct_netns_do_get(net, NFPROTO_IPV6);
55 if (err < 0)
56 goto err2;
57 } else {
58 err = nf_ct_netns_do_get(net, nfproto);
59 if (err < 0)
60 goto err1;
61 }
62 return 0;
63
64 err2:
65 nf_ct_netns_put(net, NFPROTO_IPV4);
66 err1:
67 return err;
68 }
69 EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_get);
70
71 static void nf_ct_netns_do_put(struct net *net, u8 nfproto)
72 {
73 const struct nf_conntrack_l3proto *l3proto;
74
75 might_sleep();
76
77 /* same as nf_conntrack_netns_get(), reference assumed */
78 rcu_read_lock();
79 l3proto = __nf_ct_l3proto_find(nfproto);
80 rcu_read_unlock();
81
82 if (WARN_ON(!l3proto))
83 return;
84
85 if (l3proto->net_ns_put)
86 l3proto->net_ns_put(net);
87
88 nf_ct_l3proto_module_put(nfproto);
89 }
90
91 void rpl_nf_ct_netns_put(struct net *net, uint8_t nfproto)
92 {
93 if (nfproto == NFPROTO_INET) {
94 nf_ct_netns_do_put(net, NFPROTO_IPV4);
95 nf_ct_netns_do_put(net, NFPROTO_IPV6);
96 } else
97 nf_ct_netns_do_put(net, nfproto);
98 }
99 EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_put);
100
101 #else /* !HAVE_NET_NS_GET */
102 void rpl_nf_ct_netns_put(struct net *net, uint8_t nfproto)
103 {
104 }
105 EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_put);
106
107 int rpl_nf_ct_netns_get(struct net *net, u8 nfproto)
108 {
109 return 0;
110 }
111 EXPORT_SYMBOL_GPL(rpl_nf_ct_netns_get);
112
113 #endif /* HAVE_NET_NS_GET */
114 #endif /* LINUX_VERSION_CODE < KERNEL_VERSION(4,15,0) */