diff options
author | Patrick McHardy <kaber@trash.net> | 2014-01-06 13:09:49 -0500 |
---|---|---|
committer | Pablo Neira Ayuso <pablo@netfilter.org> | 2014-01-07 17:57:32 -0500 |
commit | 9638f33ecf7e1b7eb844603c1137bc3468902c17 (patch) | |
tree | 3d9372689c382af60fd1a2aa26dd3bb1f5140dd3 | |
parent | 4566bf27069b7780e453cffb24ea5f5323059885 (diff) |
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 <kaber@trash.net>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
-rw-r--r-- | net/netfilter/nft_ct.c | 39 |
1 files changed, 36 insertions, 3 deletions
diff --git a/net/netfilter/nft_ct.c b/net/netfilter/nft_ct.c index 955f4e6e7089..3727a321c9a7 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] = { | |||
129 | [NFTA_CT_DIRECTION] = { .type = NLA_U8 }, | 129 | [NFTA_CT_DIRECTION] = { .type = NLA_U8 }, |
130 | }; | 130 | }; |
131 | 131 | ||
132 | static int nft_ct_l3proto_try_module_get(uint8_t family) | ||
133 | { | ||
134 | int err; | ||
135 | |||
136 | if (family == NFPROTO_INET) { | ||
137 | err = nf_ct_l3proto_try_module_get(NFPROTO_IPV4); | ||
138 | if (err < 0) | ||
139 | goto err1; | ||
140 | err = nf_ct_l3proto_try_module_get(NFPROTO_IPV6); | ||
141 | if (err < 0) | ||
142 | goto err2; | ||
143 | } else { | ||
144 | err = nf_ct_l3proto_try_module_get(family); | ||
145 | if (err < 0) | ||
146 | goto err1; | ||
147 | } | ||
148 | return 0; | ||
149 | |||
150 | err2: | ||
151 | nf_ct_l3proto_module_put(NFPROTO_IPV4); | ||
152 | err1: | ||
153 | return err; | ||
154 | } | ||
155 | |||
156 | static void nft_ct_l3proto_module_put(uint8_t family) | ||
157 | { | ||
158 | if (family == NFPROTO_INET) { | ||
159 | nf_ct_l3proto_module_put(NFPROTO_IPV4); | ||
160 | nf_ct_l3proto_module_put(NFPROTO_IPV6); | ||
161 | } else | ||
162 | nf_ct_l3proto_module_put(family); | ||
163 | } | ||
164 | |||
132 | static int nft_ct_init(const struct nft_ctx *ctx, | 165 | static int nft_ct_init(const struct nft_ctx *ctx, |
133 | const struct nft_expr *expr, | 166 | const struct nft_expr *expr, |
134 | const struct nlattr * const tb[]) | 167 | const struct nlattr * const tb[]) |
@@ -179,7 +212,7 @@ static int nft_ct_init(const struct nft_ctx *ctx, | |||
179 | return -EOPNOTSUPP; | 212 | return -EOPNOTSUPP; |
180 | } | 213 | } |
181 | 214 | ||
182 | err = nf_ct_l3proto_try_module_get(ctx->afi->family); | 215 | err = nft_ct_l3proto_try_module_get(ctx->afi->family); |
183 | if (err < 0) | 216 | if (err < 0) |
184 | return err; | 217 | return err; |
185 | priv->family = ctx->afi->family; | 218 | priv->family = ctx->afi->family; |
@@ -195,7 +228,7 @@ static int nft_ct_init(const struct nft_ctx *ctx, | |||
195 | return 0; | 228 | return 0; |
196 | 229 | ||
197 | err1: | 230 | err1: |
198 | nf_ct_l3proto_module_put(ctx->afi->family); | 231 | nft_ct_l3proto_module_put(ctx->afi->family); |
199 | return err; | 232 | return err; |
200 | } | 233 | } |
201 | 234 | ||
@@ -203,7 +236,7 @@ static void nft_ct_destroy(const struct nft_expr *expr) | |||
203 | { | 236 | { |
204 | struct nft_ct *priv = nft_expr_priv(expr); | 237 | struct nft_ct *priv = nft_expr_priv(expr); |
205 | 238 | ||
206 | nf_ct_l3proto_module_put(priv->family); | 239 | nft_ct_l3proto_module_put(priv->family); |
207 | } | 240 | } |
208 | 241 | ||
209 | static int nft_ct_dump(struct sk_buff *skb, const struct nft_expr *expr) | 242 | static int nft_ct_dump(struct sk_buff *skb, const struct nft_expr *expr) |