/* 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);
 
 
 
 /* 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];
 /* 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;
 
        /* 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;
 
        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))