| @@ -1987,6 +1987,27 @@ out: · 1986 unmodified lines |
| 1987 | 1987 | return err == -EAGAIN ? -ENOBUFS : err; |
| 1988 | 1988 | } |
| 1989 | 1989 | |
| 1990 | +static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { |
| 1991 | + [CTA_EXPECT_MASTER] = { .type = NLA_NESTED }, |
| 1992 | + [CTA_EXPECT_TUPLE] = { .type = NLA_NESTED }, |
| 1993 | + [CTA_EXPECT_MASK] = { .type = NLA_NESTED }, |
| 1994 | + [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 }, |
| 1995 | + [CTA_EXPECT_ID] = { .type = NLA_U32 }, |
| 1996 | + [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING, |
| 1997 | + .len = NF_CT_HELPER_NAME_LEN - 1 }, |
| 1998 | + [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, |
| 1999 | + [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, |
| 2000 | + [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, |
| 2001 | + [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, |
| 2002 | + [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING }, |
| 2003 | +}; |
| 2004 | + |
| 2005 | +static struct nf_conntrack_expect * |
| 2006 | +ctnetlink_alloc_expect(const struct nlattr *const cda[], struct nf_conn *ct, |
| 2007 | + struct nf_conntrack_helper *helper, |
| 2008 | + struct nf_conntrack_tuple *tuple, |
| 2009 | + struct nf_conntrack_tuple *mask); |
| 2010 | + |
| 1990 | 2011 | #ifdef CONFIG_NETFILTER_NETLINK_QUEUE_CT |
| 1991 | 2012 | static size_t |
| 1992 | 2013 | ctnetlink_nfqueue_build_size(const struct nf_conn *ct) |
| @@ -2127,10 +2148,69 @@ ctnetlink_nfqueue_parse(const struct nlattr *attr, struct nf_conn *ct) · 134 unmodified lines |
| 2127 | 2148 | return ret; |
| 2128 | 2149 | } |
| 2129 | 2150 | |
| 2151 | +static int ctnetlink_nfqueue_exp_parse(const struct nlattr * const *cda, |
| 2152 | + const struct nf_conn *ct, |
| 2153 | + struct nf_conntrack_tuple *tuple, |
| 2154 | + struct nf_conntrack_tuple *mask) |
| 2155 | +{ |
| 2156 | + int err; |
| 2157 | + |
| 2158 | + err = ctnetlink_parse_tuple(cda, tuple, CTA_EXPECT_TUPLE, |
| 2159 | + nf_ct_l3num(ct)); |
| 2160 | + if (err < 0) |
| 2161 | + return err; |
| 2162 | + |
| 2163 | + return ctnetlink_parse_tuple(cda, mask, CTA_EXPECT_MASK, |
| 2164 | + nf_ct_l3num(ct)); |
| 2165 | +} |
| 2166 | + |
| 2167 | +static int |
| 2168 | +ctnetlink_nfqueue_attach_expect(const struct nlattr *attr, struct nf_conn *ct, |
| 2169 | + u32 portid, u32 report) |
| 2170 | +{ |
| 2171 | + struct nlattr *cda[CTA_EXPECT_MAX+1]; |
| 2172 | + struct nf_conntrack_tuple tuple, mask; |
| 2173 | + struct nf_conntrack_helper *helper; |
| 2174 | + struct nf_conntrack_expect *exp; |
| 2175 | + int err; |
| 2176 | + |
| 2177 | + err = nla_parse_nested(cda, CTA_EXPECT_MAX, attr, exp_nla_policy); |
| 2178 | + if (err < 0) |
| 2179 | + return err; |
| 2180 | + |
| 2181 | + err = ctnetlink_nfqueue_exp_parse((const struct nlattr * const *)cda, |
| 2182 | + ct, &tuple, &mask); |
| 2183 | + if (err < 0) |
| 2184 | + return err; |
| 2185 | + |
| 2186 | + if (cda[CTA_EXPECT_HELP_NAME]) { |
| 2187 | + const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]); |
| 2188 | + |
| 2189 | + helper = __nf_conntrack_helper_find(helpname, nf_ct_l3num(ct), |
| 2190 | + nf_ct_protonum(ct)); |
| 2191 | + if (helper == NULL) |
| 2192 | + return -EOPNOTSUPP; |
| 2193 | + } |
| 2194 | + |
| 2195 | + exp = ctnetlink_alloc_expect((const struct nlattr * const *)cda, ct, |
| 2196 | + helper, &tuple, &mask); |
| 2197 | + if (IS_ERR(exp)) |
| 2198 | + return PTR_ERR(exp); |
| 2199 | + |
| 2200 | + err = nf_ct_expect_related_report(exp, portid, report); |
| 2201 | + if (err < 0) { |
| 2202 | + nf_ct_expect_put(exp); |
| 2203 | + return err; |
| 2204 | + } |
| 2205 | + |
| 2206 | + return 0; |
| 2207 | +} |
| 2208 | + |
| 2130 | 2209 | static struct nfq_ct_hook ctnetlink_nfqueue_hook = { |
| 2131 | 2210 | .build_size = ctnetlink_nfqueue_build_size, |
| 2132 | 2211 | .build = ctnetlink_nfqueue_build, |
| 2133 | 2212 | .parse = ctnetlink_nfqueue_parse, |
| 2213 | + .attach_expect = ctnetlink_nfqueue_attach_expect, |
| 2134 | 2214 | }; |
| 2135 | 2215 | #endif /* CONFIG_NETFILTER_NETLINK_QUEUE_CT */ |
| 2136 | 2216 | |
| @@ -2498,21 +2578,6 @@ static int ctnetlink_dump_exp_ct(struct sock *ctnl, struct sk_buff *skb, · 361 unmodified lines |
| 2498 | 2578 | return err; |
| 2499 | 2579 | } |
| 2500 | 2580 | |
| 2501 | | −static const struct nla_policy exp_nla_policy[CTA_EXPECT_MAX+1] = { |
| 2502 | | − [CTA_EXPECT_MASTER] = { .type = NLA_NESTED }, |
| 2503 | | − [CTA_EXPECT_TUPLE] = { .type = NLA_NESTED }, |
| 2504 | | − [CTA_EXPECT_MASK] = { .type = NLA_NESTED }, |
| 2505 | | − [CTA_EXPECT_TIMEOUT] = { .type = NLA_U32 }, |
| 2506 | | − [CTA_EXPECT_ID] = { .type = NLA_U32 }, |
| 2507 | | − [CTA_EXPECT_HELP_NAME] = { .type = NLA_NUL_STRING, |
| 2508 | | − .len = NF_CT_HELPER_NAME_LEN - 1 }, |
| 2509 | | − [CTA_EXPECT_ZONE] = { .type = NLA_U16 }, |
| 2510 | | − [CTA_EXPECT_FLAGS] = { .type = NLA_U32 }, |
| 2511 | | − [CTA_EXPECT_CLASS] = { .type = NLA_U32 }, |
| 2512 | | − [CTA_EXPECT_NAT] = { .type = NLA_NESTED }, |
| 2513 | | − [CTA_EXPECT_FN] = { .type = NLA_NUL_STRING }, |
| 2514 | | −}; |
| 2515 | | − |
| 2516 | 2581 | static int |
| 2517 | 2582 | ctnetlink_get_expect(struct sock *ctnl, struct sk_buff *skb, |
| 2518 | 2583 | const struct nlmsghdr *nlh, |