From: Patrick McHardy Date: Mon, 6 Jan 2014 18:09:49 +0000 (+0000) Subject: netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET X-Git-Tag: v3.14-rc1~94^2~245^2~15 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=9638f33ecf7e1b7eb844603c1137bc3468902c17;p=platform%2Fkernel%2Flinux-exynos.git netfilter: nft_ct: load both IPv4 and IPv6 conntrack modules for NFPROTO_INET The ct expression can currently not be used in the inet family since we don't have a conntrack module for NFPROTO_INET, so nf_ct_l3proto_try_module_get() fails. Add some manual handling to load the modules for both NFPROTO_IPV4 and NFPROTO_IPV6 if the ct expression is used in the inet family. Signed-off-by: Patrick McHardy Signed-off-by: Pablo Neira Ayuso --- diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 955f4e6..3727a32 100644 --- a/net/netfilter/nft_ct.c +++ b/net/netfilter/nft_ct.c @@ -129,6 +129,39 @@ static const struct nla_policy nft_ct_policy[NFTA_CT_MAX + 1] = { [NFTA_CT_DIRECTION] = { .type = NLA_U8 }, }; +static int nft_ct_l3proto_try_module_get(uint8_t family) +{ + int err; + + if (family == NFPROTO_INET) { + err = nf_ct_l3proto_try_module_get(NFPROTO_IPV4); + if (err < 0) + goto err1; + err = nf_ct_l3proto_try_module_get(NFPROTO_IPV6); + if (err < 0) + goto err2; + } else { + err = nf_ct_l3proto_try_module_get(family); + if (err < 0) + goto err1; + } + return 0; + +err2: + nf_ct_l3proto_module_put(NFPROTO_IPV4); +err1: + return err; +} + +static void nft_ct_l3proto_module_put(uint8_t family) +{ + if (family == NFPROTO_INET) { + nf_ct_l3proto_module_put(NFPROTO_IPV4); + nf_ct_l3proto_module_put(NFPROTO_IPV6); + } else + nf_ct_l3proto_module_put(family); +} + static int nft_ct_init(const struct nft_ctx *ctx, const struct nft_expr *expr, const struct nlattr * const tb[]) @@ -179,7 +212,7 @@ static int nft_ct_init(const struct nft_ctx *ctx, return -EOPNOTSUPP; } - err = nf_ct_l3proto_try_module_get(ctx->afi->family); + err = nft_ct_l3proto_try_module_get(ctx->afi->family); if (err < 0) return err; priv->family = ctx->afi->family; @@ -195,7 +228,7 @@ static int nft_ct_init(const struct nft_ctx *ctx, return 0; err1: - nf_ct_l3proto_module_put(ctx->afi->family); + nft_ct_l3proto_module_put(ctx->afi->family); return err; } @@ -203,7 +236,7 @@ static void nft_ct_destroy(const struct nft_expr *expr) { struct nft_ct *priv = nft_expr_priv(expr); - nf_ct_l3proto_module_put(priv->family); + nft_ct_l3proto_module_put(priv->family); } static int nft_ct_dump(struct sk_buff *skb, const struct nft_expr *expr)