summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--acinclude.m44
-rw-r--r--datapath/linux/compat/nf_conntrack_reasm.c52
2 files changed, 53 insertions, 3 deletions
diff --git a/acinclude.m4 b/acinclude.m4
index 55d2784b6..d52974ccf 100644
--- a/acinclude.m4
+++ b/acinclude.m4
@@ -694,7 +694,9 @@ AC_DEFUN([OVS_CHECK_LINUX_COMPAT], [
OVS_FIND_PARAM_IFELSE([$KSRC/include/net/protocol.h],
[udp_add_offload], [net],
[OVS_DEFINE([HAVE_UDP_ADD_OFFLOAD_TAKES_NET])])
-
+ OVS_FIND_FIELD_IFELSE([$KSRC/include/net/inet_frag.h], [inet_frags],
+ [rnd],
+ [OVS_DEFINE([HAVE_INET_FRAGS_RND])])
if cmp -s datapath/linux/kcompat.h.new \
datapath/linux/kcompat.h >/dev/null 2>&1; then
diff --git a/datapath/linux/compat/nf_conntrack_reasm.c b/datapath/linux/compat/nf_conntrack_reasm.c
index fb0a746ee..dffab9aae 100644
--- a/datapath/linux/compat/nf_conntrack_reasm.c
+++ b/datapath/linux/compat/nf_conntrack_reasm.c
@@ -73,6 +73,7 @@ static inline u8 ip6_frag_ecn(const struct ipv6hdr *ipv6h)
return 1 << (ipv6_get_dsfield(ipv6h) & INET_ECN_MASK);
}
+#ifdef HAVE_INET_FRAGS_RND
static unsigned int nf_hash_frag(__be32 id, const struct in6_addr *saddr,
const struct in6_addr *daddr)
{
@@ -99,6 +100,7 @@ static unsigned int nf_hashfn(struct inet_frag_queue *q)
return nf_hash_frag(nq->id, &nq->saddr, &nq->daddr);
}
+#endif /* HAVE_INET_FRAGS_RND */
static void nf_ct_frag6_expire(unsigned long data)
{
struct frag_queue *fq;
@@ -107,9 +109,14 @@ static void nf_ct_frag6_expire(unsigned long data)
fq = container_of((struct inet_frag_queue *)data, struct frag_queue, q);
net = container_of(fq->q.net, struct net, nf_frag.frags);
+#ifdef HAVE_INET_FRAGS_RND
ip6_expire_frag_queue(net, fq, &nf_frags);
+#else
+ ip6_expire_frag_queue(net, fq);
+#endif
}
+#ifdef HAVE_INET_FRAGS_RND
/* Creation primitives. */
static inline struct frag_queue *fq_find(struct net *net, __be32 id,
u32 user, struct in6_addr *src,
@@ -140,7 +147,27 @@ static inline struct frag_queue *fq_find(struct net *net, __be32 id,
}
return container_of(q, struct frag_queue, q);
}
+#else
+static struct frag_queue *fq_find(struct net *net, __be32 id, u32 user,
+ const struct ipv6hdr *hdr, int iif)
+{
+ struct frag_v6_compare_key key = {
+ .id = id,
+ .saddr = hdr->saddr,
+ .daddr = hdr->daddr,
+ .user = user,
+ .iif = iif,
+ };
+ struct inet_frag_queue *q;
+ q = inet_frag_find(&net->nf_frag.frags, &key);
+ if (!q)
+ return NULL;
+
+ return container_of(q, struct frag_queue, q);
+}
+
+#endif /* HAVE_INET_FRAGS_RND */
static int nf_ct_frag6_queue(struct frag_queue *fq, struct sk_buff *skb,
const struct frag_hdr *fhdr, int nhoff)
@@ -289,7 +316,11 @@ found:
return 0;
discard_fq:
+#ifdef HAVE_INET_FRAGS_RND
inet_frag_kill(&fq->q, &nf_frags);
+#else
+ inet_frag_kill(&fq->q);
+#endif
err:
return -1;
}
@@ -311,7 +342,11 @@ nf_ct_frag6_reasm(struct frag_queue *fq, struct sk_buff *prev, struct net_devic
int payload_len;
u8 ecn;
+#ifdef HAVE_INET_FRAGS_RND
inet_frag_kill(&fq->q, &nf_frags);
+#else
+ inet_frag_kill(&fq->q);
+#endif
WARN_ON(head == NULL);
WARN_ON(NFCT_FRAG6_CB(head)->offset != 0);
@@ -530,8 +565,13 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
local_bh_enable();
#endif
+#ifdef HAVE_INET_FRAGS_RND
fq = fq_find(net, fhdr->identification, user, &hdr->saddr, &hdr->daddr,
ip6_frag_ecn(hdr));
+#else
+ fq = fq_find(net, fhdr->identification, user, hdr,
+ skb->dev ? skb->dev->ifindex : 0);
+#endif
if (fq == NULL)
return -ENOMEM;
@@ -553,7 +593,11 @@ int nf_ct_frag6_gather(struct net *net, struct sk_buff *skb, u32 user)
out_unlock:
spin_unlock_bh(&fq->q.lock);
+#ifdef HAVE_INET_FRAGS_RND
inet_frag_put(&fq->q, &nf_frags);
+#else
+ inet_frag_put(&fq->q);
+#endif
return ret;
}
@@ -571,13 +615,17 @@ int rpl_nf_ct_frag6_init(void)
int ret = 0;
nf_defrag_ipv6_enable();
+#ifdef HAVE_INET_FRAGS_RND
nf_frags.hashfn = nf_hashfn;
+ nf_frags.match = ip6_frag_match;
+#else
+ nf_frags.rhash_params = ip6_rhash_params;
+#endif
nf_frags.constructor = ip6_frag_init;
nf_frags.destructor = NULL;
nf_frags.qsize = sizeof(struct frag_queue);
- nf_frags.match = ip6_frag_match;
nf_frags.frag_expire = nf_ct_frag6_expire;
-#ifdef HAVE_INET_FRAGS_WITH_FRAGS_WORK
+#if defined(HAVE_INET_FRAGS_WITH_FRAGS_WORK) || !defined(HAVE_INET_FRAGS_RND)
nf_frags.frags_cache_name = nf_frags_cache_name;
#endif
#if RHEL_RELEASE_CODE < RHEL_RELEASE_VERSION(8,0)