netfilter: ctnetlink: refactor ctnetlink_create_expect
This patch refactors ctnetlink_create_expect by spliting it in two chunks. As a result, we have a new function ctnetlink_alloc_expect to allocate and to setup the expectation from ctnetlink. Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
This commit is contained in:
parent
c655bc6896
commit
0ef71ee1a5
@ -2735,76 +2735,26 @@ ctnetlink_parse_expect_nat(const struct nlattr *attr,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static struct nf_conntrack_expect *
|
||||||
ctnetlink_create_expect(struct net *net, u16 zone,
|
ctnetlink_alloc_expect(const struct nlattr * const cda[], struct nf_conn *ct,
|
||||||
const struct nlattr * const cda[],
|
struct nf_conntrack_helper *helper,
|
||||||
u_int8_t u3,
|
struct nf_conntrack_tuple *tuple,
|
||||||
u32 portid, int report)
|
struct nf_conntrack_tuple *mask)
|
||||||
{
|
{
|
||||||
struct nf_conntrack_tuple tuple, mask, master_tuple;
|
|
||||||
struct nf_conntrack_tuple_hash *h = NULL;
|
|
||||||
struct nf_conntrack_expect *exp;
|
|
||||||
struct nf_conn *ct;
|
|
||||||
struct nf_conn_help *help;
|
|
||||||
struct nf_conntrack_helper *helper = NULL;
|
|
||||||
u_int32_t class = 0;
|
u_int32_t class = 0;
|
||||||
int err = 0;
|
struct nf_conntrack_expect *exp;
|
||||||
|
struct nf_conn_help *help;
|
||||||
/* caller guarantees that those three CTA_EXPECT_* exist */
|
int err;
|
||||||
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
/* Look for master conntrack of this expectation */
|
|
||||||
h = nf_conntrack_find_get(net, zone, &master_tuple);
|
|
||||||
if (!h)
|
|
||||||
return -ENOENT;
|
|
||||||
ct = nf_ct_tuplehash_to_ctrack(h);
|
|
||||||
|
|
||||||
/* Look for helper of this expectation */
|
|
||||||
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) {
|
|
||||||
#ifdef CONFIG_MODULES
|
|
||||||
if (request_module("nfct-helper-%s", helpname) < 0) {
|
|
||||||
err = -EOPNOTSUPP;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
helper = __nf_conntrack_helper_find(helpname,
|
|
||||||
nf_ct_l3num(ct),
|
|
||||||
nf_ct_protonum(ct));
|
|
||||||
if (helper) {
|
|
||||||
err = -EAGAIN;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
err = -EOPNOTSUPP;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (cda[CTA_EXPECT_CLASS] && helper) {
|
if (cda[CTA_EXPECT_CLASS] && helper) {
|
||||||
class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
|
class = ntohl(nla_get_be32(cda[CTA_EXPECT_CLASS]));
|
||||||
if (class > helper->expect_class_max) {
|
if (class > helper->expect_class_max)
|
||||||
err = -EINVAL;
|
return ERR_PTR(-EINVAL);
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
exp = nf_ct_expect_alloc(ct);
|
exp = nf_ct_expect_alloc(ct);
|
||||||
if (!exp) {
|
if (!exp)
|
||||||
err = -ENOMEM;
|
return ERR_PTR(-ENOMEM);
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
help = nfct_help(ct);
|
help = nfct_help(ct);
|
||||||
if (!help) {
|
if (!help) {
|
||||||
if (!cda[CTA_EXPECT_TIMEOUT]) {
|
if (!cda[CTA_EXPECT_TIMEOUT]) {
|
||||||
@ -2842,21 +2792,89 @@ ctnetlink_create_expect(struct net *net, u16 zone,
|
|||||||
exp->class = class;
|
exp->class = class;
|
||||||
exp->master = ct;
|
exp->master = ct;
|
||||||
exp->helper = helper;
|
exp->helper = helper;
|
||||||
memcpy(&exp->tuple, &tuple, sizeof(struct nf_conntrack_tuple));
|
exp->tuple = *tuple;
|
||||||
memcpy(&exp->mask.src.u3, &mask.src.u3, sizeof(exp->mask.src.u3));
|
exp->mask.src.u3 = mask->src.u3;
|
||||||
exp->mask.src.u.all = mask.src.u.all;
|
exp->mask.src.u.all = mask->src.u.all;
|
||||||
|
|
||||||
if (cda[CTA_EXPECT_NAT]) {
|
if (cda[CTA_EXPECT_NAT]) {
|
||||||
err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT],
|
err = ctnetlink_parse_expect_nat(cda[CTA_EXPECT_NAT],
|
||||||
exp, u3);
|
exp, nf_ct_l3num(ct));
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
err = nf_ct_expect_related_report(exp, portid, report);
|
return exp;
|
||||||
err_out:
|
err_out:
|
||||||
nf_ct_expect_put(exp);
|
nf_ct_expect_put(exp);
|
||||||
out:
|
return ERR_PTR(err);
|
||||||
nf_ct_put(nf_ct_tuplehash_to_ctrack(h));
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
ctnetlink_create_expect(struct net *net, u16 zone,
|
||||||
|
const struct nlattr * const cda[],
|
||||||
|
u_int8_t u3, u32 portid, int report)
|
||||||
|
{
|
||||||
|
struct nf_conntrack_tuple tuple, mask, master_tuple;
|
||||||
|
struct nf_conntrack_tuple_hash *h = NULL;
|
||||||
|
struct nf_conntrack_helper *helper = NULL;
|
||||||
|
struct nf_conntrack_expect *exp;
|
||||||
|
struct nf_conn *ct;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
/* caller guarantees that those three CTA_EXPECT_* exist */
|
||||||
|
err = ctnetlink_parse_tuple(cda, &tuple, CTA_EXPECT_TUPLE, u3);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = ctnetlink_parse_tuple(cda, &mask, CTA_EXPECT_MASK, u3);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = ctnetlink_parse_tuple(cda, &master_tuple, CTA_EXPECT_MASTER, u3);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
/* Look for master conntrack of this expectation */
|
||||||
|
h = nf_conntrack_find_get(net, zone, &master_tuple);
|
||||||
|
if (!h)
|
||||||
|
return -ENOENT;
|
||||||
|
ct = nf_ct_tuplehash_to_ctrack(h);
|
||||||
|
|
||||||
|
if (cda[CTA_EXPECT_HELP_NAME]) {
|
||||||
|
const char *helpname = nla_data(cda[CTA_EXPECT_HELP_NAME]);
|
||||||
|
|
||||||
|
helper = __nf_conntrack_helper_find(helpname, u3,
|
||||||
|
nf_ct_protonum(ct));
|
||||||
|
if (helper == NULL) {
|
||||||
|
#ifdef CONFIG_MODULES
|
||||||
|
if (request_module("nfct-helper-%s", helpname) < 0) {
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
goto err_ct;
|
||||||
|
}
|
||||||
|
helper = __nf_conntrack_helper_find(helpname, u3,
|
||||||
|
nf_ct_protonum(ct));
|
||||||
|
if (helper) {
|
||||||
|
err = -EAGAIN;
|
||||||
|
goto err_ct;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
err = -EOPNOTSUPP;
|
||||||
|
goto err_ct;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
exp = ctnetlink_alloc_expect(cda, ct, helper, &tuple, &mask);
|
||||||
|
if (IS_ERR(exp)) {
|
||||||
|
err = PTR_ERR(exp);
|
||||||
|
goto err_ct;
|
||||||
|
}
|
||||||
|
|
||||||
|
err = nf_ct_expect_related_report(exp, portid, report);
|
||||||
|
if (err < 0)
|
||||||
|
goto err_exp;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
err_exp:
|
||||||
|
nf_ct_expect_put(exp);
|
||||||
|
err_ct:
|
||||||
|
nf_ct_put(ct);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user