return err == -EAGAIN ? -ENOBUFS : err;
 }
 
+static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
+       [CTA_EXPECT_MASTER]     = { .type = NLA_NESTED },
+       [CTA_EXPECT_TUPLE]      = { .type = NLA_NESTED },
+       [CTA_EXPECT_MASK]       = { .type = NLA_NESTED },
+       [CTA_EXPECT_TIMEOUT]    = { .type = NLA_U32 },
+       [CTA_EXPECT_ID]         = { .type = NLA_U32 },
+       [CTA_EXPECT_HELP_NAME]  = { .type = NLA_NUL_STRING,
+                                   .len = NF_CT_HELPER_NAME_LEN - 1 },
+       [CTA_EXPECT_ZONE]       = { .type = NLA_U16 },
+       [CTA_EXPECT_FLAGS]      = { .type = NLA_U32 },
+       [CTA_EXPECT_CLASS]      = { .type = NLA_U32 },
+       [CTA_EXPECT_NAT]        = { .type = NLA_NESTED },
+       [CTA_EXPECT_FN]         = { .type = NLA_NUL_STRING },
+};
+
+static struct nf_conntrack_expect *
+ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct,
+                      struct nf_conntrack_helper *helper,
+                      struct nf_conntrack_tuple *tuple,
+                      struct nf_conntrack_tuple *mask);
+
 #ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT
 static size_t
 ctnetlink_nfqueue_build_size(const struct nf_conn *ct)
        return ret;
 }
 
+static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda,
+                                      const struct nf_conn *ct,
+                                      struct nf_conntrack_tuple *tuple,
+                                      struct nf_conntrack_tuple *mask)
+{
+       int err;
+
+       err = ctnetlink_parse_tuple(cda, tuple, CTA_EXPECT_TUPLE,
+                                   nf_ct_l3num(ct));
+       if (err < 0)
+               return err;
+
+       return ctnetlink_parse_tuple(cda, mask, CTA_EXPECT_MASK,
+                                    nf_ct_l3num(ct));
+}
+
+static int
+ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct,
+                               u32 portid, u32 report)
+{
+       struct nlattr *cda[CTA_EXPECT_MAX+1];
+       struct nf_conntrack_tuple tuple, mask;
+       struct nf_conntrack_helper *helper;
+       struct nf_conntrack_expect *exp;
+       int err;
+
+       err = nla_parse_nested(cda, CTA_EXPECT_MAX, attr, exp_nla_policy);
+       if (err < 0)
+               return err;
+
+       err = ctnetlink_nfqueue_exp_parse((const struct nlattr * const *)cda,
+                                         ct, &tuple, &mask);
+       if (err < 0)
+               return err;
+
+       if (cda[CTA_EXPECT_HELP_NAME]) {
+               const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
+
+               helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct),
+                                                   nf_ct_protonum(ct));
+               if (helper == NULL)
+                       return -EOPNOTSUPP;
+       }
+
+       exp = ctnetlink_alloc_expect((const struct nlattr * const *)cda, ct,
+                                    helper, &tuple, &mask);
+       if (IS_ERR(exp))
+               return PTR_ERR(exp);
+
+       err = nf_ct_expect_related_report(exp, portid, report);
+       if (err < 0) {
+               nf_ct_expect_put(exp);
+               return err;
+       }
+
+       return 0;
+}
+
 static struct nfq_ct_hook ctnetlink_nfqueue_hook = {
        .build_size     = ctnetlink_nfqueue_build_size,
        .build          = ctnetlink_nfqueue_build,
        .parse          = ctnetlink_nfqueue_parse,
+       .attach_expect  = ctnetlink_nfqueue_attach_expect,
 };
 #endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */
 
        return err;
 }
 
-static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = {
-       [CTA_EXPECT_MASTER]     = { .type = NLA_NESTED },
-       [CTA_EXPECT_TUPLE]      = { .type = NLA_NESTED },
-       [CTA_EXPECT_MASK]       = { .type = NLA_NESTED },
-       [CTA_EXPECT_TIMEOUT]    = { .type = NLA_U32 },
-       [CTA_EXPECT_ID]         = { .type = NLA_U32 },
-       [CTA_EXPECT_HELP_NAME]  = { .type = NLA_NUL_STRING,
-                                   .len = NF_CT_HELPER_NAME_LEN - 1 },
-       [CTA_EXPECT_ZONE]       = { .type = NLA_U16 },
-       [CTA_EXPECT_FLAGS]      = { .type = NLA_U32 },
-       [CTA_EXPECT_CLASS]      = { .type = NLA_U32 },
-       [CTA_EXPECT_NAT]        = { .type = NLA_NESTED },
-       [CTA_EXPECT_FN]         = { .type = NLA_NUL_STRING },
-};
-
 static int
 ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb,
                     const struct nlmsghdr *nlh,