|
@@ -98,31 +98,28 @@ static int cttimeout_new_timeout(struct net *net, struct sock *ctnl,
|
|
|
break;
|
|
|
}
|
|
|
|
|
|
- l4proto = nf_ct_l4proto_find_get(l3num, l4num);
|
|
|
-
|
|
|
- /* This protocol is not supportted, skip. */
|
|
|
- if (l4proto->l4proto != l4num) {
|
|
|
- ret = -EOPNOTSUPP;
|
|
|
- goto err_proto_put;
|
|
|
- }
|
|
|
-
|
|
|
if (matching) {
|
|
|
if (nlh->nlmsg_flags & NLM_F_REPLACE) {
|
|
|
/* You cannot replace one timeout policy by another of
|
|
|
* different kind, sorry.
|
|
|
*/
|
|
|
if (matching->l3num != l3num ||
|
|
|
- matching->l4proto->l4proto != l4num) {
|
|
|
- ret = -EINVAL;
|
|
|
- goto err_proto_put;
|
|
|
- }
|
|
|
-
|
|
|
- ret = ctnl_timeout_parse_policy(&matching->data,
|
|
|
- l4proto, net,
|
|
|
- cda[CTA_TIMEOUT_DATA]);
|
|
|
- return ret;
|
|
|
+ matching->l4proto->l4proto != l4num)
|
|
|
+ return -EINVAL;
|
|
|
+
|
|
|
+ return ctnl_timeout_parse_policy(&matching->data,
|
|
|
+ matching->l4proto, net,
|
|
|
+ cda[CTA_TIMEOUT_DATA]);
|
|
|
}
|
|
|
- ret = -EBUSY;
|
|
|
+
|
|
|
+ return -EBUSY;
|
|
|
+ }
|
|
|
+
|
|
|
+ l4proto = nf_ct_l4proto_find_get(l3num, l4num);
|
|
|
+
|
|
|
+ /* This protocol is not supportted, skip. */
|
|
|
+ if (l4proto->l4proto != l4num) {
|
|
|
+ ret = -EOPNOTSUPP;
|
|
|
goto err_proto_put;
|
|
|
}
|
|
|
|
|
@@ -305,7 +302,16 @@ static void ctnl_untimeout(struct net *net, struct ctnl_timeout *timeout)
|
|
|
const struct hlist_nulls_node *nn;
|
|
|
unsigned int last_hsize;
|
|
|
spinlock_t *lock;
|
|
|
- int i;
|
|
|
+ int i, cpu;
|
|
|
+
|
|
|
+ for_each_possible_cpu(cpu) {
|
|
|
+ struct ct_pcpu *pcpu = per_cpu_ptr(net->ct.pcpu_lists, cpu);
|
|
|
+
|
|
|
+ spin_lock_bh(&pcpu->lock);
|
|
|
+ hlist_nulls_for_each_entry(h, nn, &pcpu->unconfirmed, hnnode)
|
|
|
+ untimeout(h, timeout);
|
|
|
+ spin_unlock_bh(&pcpu->lock);
|
|
|
+ }
|
|
|
|
|
|
local_bh_disable();
|
|
|
restart:
|
|
@@ -350,12 +356,13 @@ static int cttimeout_del_timeout(struct net *net, struct sock *ctnl,
|
|
|
const struct nlmsghdr *nlh,
|
|
|
const struct nlattr * const cda[])
|
|
|
{
|
|
|
- struct ctnl_timeout *cur;
|
|
|
+ struct ctnl_timeout *cur, *tmp;
|
|
|
int ret = -ENOENT;
|
|
|
char *name;
|
|
|
|
|
|
if (!cda[CTA_TIMEOUT_NAME]) {
|
|
|
- list_for_each_entry(cur, &net->nfct_timeout_list, head)
|
|
|
+ list_for_each_entry_safe(cur, tmp, &net->nfct_timeout_list,
|
|
|
+ head)
|
|
|
ctnl_timeout_try_del(net, cur);
|
|
|
|
|
|
return 0;
|