diff --git a/include/net/netfilter/nf_conntrack_expect.h b/include/net/netfilter/nf_conntrack_expect.h
index b969c430b36a4ee70e646d93deccf4f2335c3801..54a3d038beaa2d138672fbc9890fd78f8306236d 100644
--- a/include/net/netfilter/nf_conntrack_expect.h
+++ b/include/net/netfilter/nf_conntrack_expect.h
@@ -68,6 +68,10 @@ void nf_conntrack_unexpect_related(struct nf_conntrack_expect *exp);
 /* Allocate space for an expectation: this is mandatory before calling
    nf_conntrack_expect_related.  You will have to call put afterwards. */
 struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me);
+void nf_conntrack_expect_init(struct nf_conntrack_expect *, int,
+			      union nf_conntrack_address *,
+			      union nf_conntrack_address *,
+			      u_int8_t, __be16 *, __be16 *);
 void nf_conntrack_expect_put(struct nf_conntrack_expect *exp);
 int nf_conntrack_expect_related(struct nf_conntrack_expect *expect);
 
diff --git a/include/net/netfilter/nf_conntrack_tuple.h b/include/net/netfilter/nf_conntrack_tuple.h
index be9dc9a0eb77cf260dd53e9be038ff5defa93dff..c96a9c576736428b67351dcb642210b4727e237a 100644
--- a/include/net/netfilter/nf_conntrack_tuple.h
+++ b/include/net/netfilter/nf_conntrack_tuple.h
@@ -24,7 +24,7 @@
 
 /* The l3 protocol-specific manipulable parts of the tuple: always in
    network order! */
-union nf_conntrack_man_l3proto {
+union nf_conntrack_address {
 	u_int32_t all[NF_CT_TUPLE_L3SIZE];
 	__be32 ip;
 	__be32 ip6[4];
@@ -54,7 +54,7 @@ union nf_conntrack_man_proto
 /* The manipulable part of the tuple. */
 struct nf_conntrack_man
 {
-	union nf_conntrack_man_l3proto u3;
+	union nf_conntrack_address u3;
 	union nf_conntrack_man_proto u;
 	/* Layer 3 protocol */
 	u_int16_t l3num;
@@ -67,11 +67,7 @@ struct nf_conntrack_tuple
 
 	/* These are the parts of the tuple which are fixed. */
 	struct {
-		union {
-			u_int32_t all[NF_CT_TUPLE_L3SIZE];
-			u_int32_t ip;
-			u_int32_t ip6[4];
-		} u3;
+		union nf_conntrack_address u3;
 		union {
 			/* Add other protocols here. */
 			u_int16_t all;
diff --git a/net/netfilter/nf_conntrack_expect.c b/net/netfilter/nf_conntrack_expect.c
index aa5903e4da11a92ab983113341682e3611fe8faf..68623ae778c8d919ff70f6fa469c3402d9d23159 100644
--- a/net/netfilter/nf_conntrack_expect.c
+++ b/net/netfilter/nf_conntrack_expect.c
@@ -196,6 +196,74 @@ struct nf_conntrack_expect *nf_conntrack_expect_alloc(struct nf_conn *me)
 	return new;
 }
 
+void nf_conntrack_expect_init(struct nf_conntrack_expect *exp, int family,
+			      union nf_conntrack_address *saddr,
+			      union nf_conntrack_address *daddr,
+			      u_int8_t proto, __be16 *src, __be16 *dst)
+{
+	int len;
+
+	if (family == AF_INET)
+		len = 4;
+	else
+		len = 16;
+
+	exp->flags = 0;
+	exp->expectfn = NULL;
+	exp->helper = NULL;
+	exp->tuple.src.l3num = family;
+	exp->tuple.dst.protonum = proto;
+	exp->mask.src.l3num = 0xFFFF;
+	exp->mask.dst.protonum = 0xFF;
+
+	if (saddr) {
+		memcpy(&exp->tuple.src.u3, saddr, len);
+		if (sizeof(exp->tuple.src.u3) > len)
+			/* address needs to be cleared for nf_ct_tuple_equal */
+			memset((void *)&exp->tuple.src.u3 + len, 0x00,
+			       sizeof(exp->tuple.src.u3) - len);
+		memset(&exp->mask.src.u3, 0xFF, len);
+		if (sizeof(exp->mask.src.u3) > len)
+			memset((void *)&exp->mask.src.u3 + len, 0x00,
+			       sizeof(exp->mask.src.u3) - len);
+	} else {
+		memset(&exp->tuple.src.u3, 0x00, sizeof(exp->tuple.src.u3));
+		memset(&exp->mask.src.u3, 0x00, sizeof(exp->mask.src.u3));
+	}
+
+	if (daddr) {
+		memcpy(&exp->tuple.dst.u3, daddr, len);
+		if (sizeof(exp->tuple.dst.u3) > len)
+			/* address needs to be cleared for nf_ct_tuple_equal */
+			memset((void *)&exp->tuple.dst.u3 + len, 0x00,
+			       sizeof(exp->tuple.dst.u3) - len);
+		memset(&exp->mask.dst.u3, 0xFF, len);
+		if (sizeof(exp->mask.dst.u3) > len)
+			memset((void *)&exp->mask.dst.u3 + len, 0x00,
+			       sizeof(exp->mask.dst.u3) - len);
+	} else {
+		memset(&exp->tuple.dst.u3, 0x00, sizeof(exp->tuple.dst.u3));
+		memset(&exp->mask.dst.u3, 0x00, sizeof(exp->mask.dst.u3));
+	}
+
+	if (src) {
+		exp->tuple.src.u.all = (__force u16)*src;
+		exp->mask.src.u.all = 0xFFFF;
+	} else {
+		exp->tuple.src.u.all = 0;
+		exp->mask.src.u.all = 0;
+	}
+
+	if (dst) {
+		exp->tuple.dst.u.all = (__force u16)*dst;
+		exp->mask.dst.u.all = 0xFFFF;
+	} else {
+		exp->tuple.dst.u.all = 0;
+		exp->mask.dst.u.all = 0;
+	}
+}
+EXPORT_SYMBOL_GPL(nf_conntrack_expect_init);
+
 void nf_conntrack_expect_put(struct nf_conntrack_expect *exp)
 {
 	if (atomic_dec_and_test(&exp->use))