diff options
| -rw-r--r-- | net/netfilter/xt_CT.c | 24 |
1 files changed, 19 insertions, 5 deletions
diff --git a/net/netfilter/xt_CT.c b/net/netfilter/xt_CT.c index 4babb278e41..59530e93fa5 100644 --- a/net/netfilter/xt_CT.c +++ b/net/netfilter/xt_CT.c | |||
| @@ -150,6 +150,17 @@ err1: | |||
| 150 | return ret; | 150 | return ret; |
| 151 | } | 151 | } |
| 152 | 152 | ||
| 153 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT | ||
| 154 | static void __xt_ct_tg_timeout_put(struct ctnl_timeout *timeout) | ||
| 155 | { | ||
| 156 | typeof(nf_ct_timeout_put_hook) timeout_put; | ||
| 157 | |||
| 158 | timeout_put = rcu_dereference(nf_ct_timeout_put_hook); | ||
| 159 | if (timeout_put) | ||
| 160 | timeout_put(timeout); | ||
| 161 | } | ||
| 162 | #endif | ||
| 163 | |||
| 153 | static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | 164 | static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) |
| 154 | { | 165 | { |
| 155 | struct xt_ct_target_info_v1 *info = par->targinfo; | 166 | struct xt_ct_target_info_v1 *info = par->targinfo; |
| @@ -158,7 +169,9 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
| 158 | struct nf_conn *ct; | 169 | struct nf_conn *ct; |
| 159 | int ret = 0; | 170 | int ret = 0; |
| 160 | u8 proto; | 171 | u8 proto; |
| 161 | 172 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT | |
| 173 | struct ctnl_timeout *timeout; | ||
| 174 | #endif | ||
| 162 | if (info->flags & ~XT_CT_NOTRACK) | 175 | if (info->flags & ~XT_CT_NOTRACK) |
| 163 | return -EINVAL; | 176 | return -EINVAL; |
| 164 | 177 | ||
| @@ -216,7 +229,6 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
| 216 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT | 229 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT |
| 217 | if (info->timeout) { | 230 | if (info->timeout) { |
| 218 | typeof(nf_ct_timeout_find_get_hook) timeout_find_get; | 231 | typeof(nf_ct_timeout_find_get_hook) timeout_find_get; |
| 219 | struct ctnl_timeout *timeout; | ||
| 220 | struct nf_conn_timeout *timeout_ext; | 232 | struct nf_conn_timeout *timeout_ext; |
| 221 | 233 | ||
| 222 | rcu_read_lock(); | 234 | rcu_read_lock(); |
| @@ -245,7 +257,7 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
| 245 | pr_info("Timeout policy `%s' can only be " | 257 | pr_info("Timeout policy `%s' can only be " |
| 246 | "used by L3 protocol number %d\n", | 258 | "used by L3 protocol number %d\n", |
| 247 | info->timeout, timeout->l3num); | 259 | info->timeout, timeout->l3num); |
| 248 | goto err4; | 260 | goto err5; |
| 249 | } | 261 | } |
| 250 | /* Make sure the timeout policy matches any existing | 262 | /* Make sure the timeout policy matches any existing |
| 251 | * protocol tracker, otherwise default to generic. | 263 | * protocol tracker, otherwise default to generic. |
| @@ -258,13 +270,13 @@ static int xt_ct_tg_check_v1(const struct xt_tgchk_param *par) | |||
| 258 | "used by L4 protocol number %d\n", | 270 | "used by L4 protocol number %d\n", |
| 259 | info->timeout, | 271 | info->timeout, |
| 260 | timeout->l4proto->l4proto); | 272 | timeout->l4proto->l4proto); |
| 261 | goto err4; | 273 | goto err5; |
| 262 | } | 274 | } |
| 263 | timeout_ext = nf_ct_timeout_ext_add(ct, timeout, | 275 | timeout_ext = nf_ct_timeout_ext_add(ct, timeout, |
| 264 | GFP_ATOMIC); | 276 | GFP_ATOMIC); |
| 265 | if (timeout_ext == NULL) { | 277 | if (timeout_ext == NULL) { |
| 266 | ret = -ENOMEM; | 278 | ret = -ENOMEM; |
| 267 | goto err4; | 279 | goto err5; |
| 268 | } | 280 | } |
| 269 | } else { | 281 | } else { |
| 270 | ret = -ENOENT; | 282 | ret = -ENOENT; |
| @@ -282,6 +294,8 @@ out: | |||
| 282 | return 0; | 294 | return 0; |
| 283 | 295 | ||
| 284 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT | 296 | #ifdef CONFIG_NF_CONNTRACK_TIMEOUT |
| 297 | err5: | ||
| 298 | __xt_ct_tg_timeout_put(timeout); | ||
| 285 | err4: | 299 | err4: |
| 286 | rcu_read_unlock(); | 300 | rcu_read_unlock(); |
| 287 | #endif | 301 | #endif |
