aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJamal Hadi Salim <jhs@mojatatu.com>2016-05-10 16:49:30 -0400
committerDavid S. Miller <davem@davemloft.net>2016-05-10 23:50:15 -0400
commit5e1567aeb7fe0ca478bfad5d17791cce3ddd45c9 (patch)
tree5b3b2762410bcf2dd7ffd5157f4f6c4a07fee739
parent0e5538ab2b59ec205411949d839de6dbab663730 (diff)
net sched: skbedit action fix late binding
The process below was broken and is fixed with this patch. //add a skbedit action and give it an instance id of 1 sudo tc actions add action skbedit mark 10 index 1 //create a filter which binds to skbedit action id 1 sudo tc filter add dev $DEV parent ffff: protocol ip prio 1 u32\ match ip dst 17.0.0.1/32 flowid 1:10 action skbedit index 1 Message before fix was: RTNETLINK answers: Invalid argument We have an error talking to the kernel Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com> Reviewed-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: David S. Miller <davem@davemloft.net>
-rw-r--r--net/sched/act_skbedit.c18
1 files changed, 11 insertions, 7 deletions
diff --git a/net/sched/act_skbedit.c b/net/sched/act_skbedit.c
index cfcdbdc00c9b..69da5a8f0034 100644
--- a/net/sched/act_skbedit.c
+++ b/net/sched/act_skbedit.c
@@ -69,7 +69,7 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
69 struct tcf_skbedit *d; 69 struct tcf_skbedit *d;
70 u32 flags = 0, *priority = NULL, *mark = NULL; 70 u32 flags = 0, *priority = NULL, *mark = NULL;
71 u16 *queue_mapping = NULL; 71 u16 *queue_mapping = NULL;
72 int ret = 0, err; 72 int ret = 0, err, exists = 0;
73 73
74 if (nla == NULL) 74 if (nla == NULL)
75 return -EINVAL; 75 return -EINVAL;
@@ -96,12 +96,18 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
96 mark = nla_data(tb[TCA_SKBEDIT_MARK]); 96 mark = nla_data(tb[TCA_SKBEDIT_MARK]);
97 } 97 }
98 98
99 if (!flags)
100 return -EINVAL;
101
102 parm = nla_data(tb[TCA_SKBEDIT_PARMS]); 99 parm = nla_data(tb[TCA_SKBEDIT_PARMS]);
103 100
104 if (!tcf_hash_check(tn, parm->index, a, bind)) { 101 exists = tcf_hash_check(tn, parm->index, a, bind);
102 if (exists && bind)
103 return 0;
104
105 if (!flags) {
106 tcf_hash_release(a, bind);
107 return -EINVAL;
108 }
109
110 if (!exists) {
105 ret = tcf_hash_create(tn, parm->index, est, a, 111 ret = tcf_hash_create(tn, parm->index, est, a,
106 sizeof(*d), bind, false); 112 sizeof(*d), bind, false);
107 if (ret) 113 if (ret)
@@ -111,8 +117,6 @@ static int tcf_skbedit_init(struct net *net, struct nlattr *nla,
111 ret = ACT_P_CREATED; 117 ret = ACT_P_CREATED;
112 } else { 118 } else {
113 d = to_skbedit(a); 119 d = to_skbedit(a);
114 if (bind)
115 return 0;
116 tcf_hash_release(a, bind); 120 tcf_hash_release(a, bind);
117 if (!ovr) 121 if (!ovr)
118 return -EEXIST; 122 return -EEXIST;