kernel: fix crash in act_connmark in 3.9 and 3.10 (fixes #13916, #13876)

Signed-off-by: Felix Fietkau <nbd@openwrt.org>

SVN-Revision: 37493
This commit is contained in:
Felix Fietkau 2013-07-21 13:53:54 +00:00
parent a1ec175d7b
commit a50c18c632
2 changed files with 40 additions and 18 deletions

View File

@ -1,6 +1,6 @@
--- /dev/null --- /dev/null
+++ b/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c
@@ -0,0 +1,137 @@ @@ -0,0 +1,148 @@
+/* +/*
+ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> + * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
+ * + *
@ -81,19 +81,30 @@
+ return TC_ACT_PIPE; + return TC_ACT_PIPE;
+} +}
+ +
+static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, +static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+ struct tc_action *a, int ovr, int bind) + struct nlattr *est, struct tc_action *a,
+ int ovr, int bind)
+{ +{
+ struct tcf_common *pc; + struct tcf_common *pc;
+ int ret = 0;
+ +
+ pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, + pc = tcf_hash_check(0, a, bind, &connmark_hash_info);
+ &connmark_idx_gen, &connmark_hash_info); + if (!pc) {
+ if (IS_ERR(pc)) + pc = tcf_hash_create(0, est, a, sizeof(*pc), bind,
+ return PTR_ERR(pc); + &connmark_idx_gen, &connmark_hash_info);
+ if (IS_ERR(pc))
+ return PTR_ERR(pc);
+ +
+ tcf_hash_insert(pc, &connmark_hash_info); + tcf_hash_insert(pc, &connmark_hash_info);
+ ret = ACT_P_CREATED;
+ } else {
+ if (!ovr) {
+ tcf_hash_release(pc, bind, &connmark_hash_info);
+ return -EEXIST;
+ }
+ }
+ +
+ return ACT_P_CREATED; + return ret;
+} +}
+ +
+static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) +static inline int tcf_connmark_cleanup(struct tc_action *a, int bind)

View File

@ -1,6 +1,6 @@
--- /dev/null --- /dev/null
+++ b/net/sched/act_connmark.c +++ b/net/sched/act_connmark.c
@@ -0,0 +1,137 @@ @@ -0,0 +1,148 @@
+/* +/*
+ * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org> + * Copyright (c) 2011 Felix Fietkau <nbd@openwrt.org>
+ * + *
@ -81,19 +81,30 @@
+ return TC_ACT_PIPE; + return TC_ACT_PIPE;
+} +}
+ +
+static int tcf_connmark_init(struct nlattr *nla, struct nlattr *est, +static int tcf_connmark_init(struct net *net, struct nlattr *nla,
+ struct tc_action *a, int ovr, int bind) + struct nlattr *est, struct tc_action *a,
+ int ovr, int bind)
+{ +{
+ struct tcf_common *pc; + struct tcf_common *pc;
+ int ret = 0;
+ +
+ pc = tcf_hash_create(0, est, a, sizeof(*pc), bind, + pc = tcf_hash_check(0, a, bind, &connmark_hash_info);
+ &connmark_idx_gen, &connmark_hash_info); + if (!pc) {
+ if (IS_ERR(pc)) + pc = tcf_hash_create(0, est, a, sizeof(*pc), bind,
+ return PTR_ERR(pc); + &connmark_idx_gen, &connmark_hash_info);
+ if (IS_ERR(pc))
+ return PTR_ERR(pc);
+ +
+ tcf_hash_insert(pc, &connmark_hash_info); + tcf_hash_insert(pc, &connmark_hash_info);
+ ret = ACT_P_CREATED;
+ } else {
+ if (!ovr) {
+ tcf_hash_release(pc, bind, &connmark_hash_info);
+ return -EEXIST;
+ }
+ }
+ +
+ return ACT_P_CREATED; + return ret;
+} +}
+ +
+static inline int tcf_connmark_cleanup(struct tc_action *a, int bind) +static inline int tcf_connmark_cleanup(struct tc_action *a, int bind)