diff options
author | Jamal Hadi Salim <jhs@mojatatu.com> | 2016-05-10 16:49:27 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2016-05-10 23:50:15 -0400 |
commit | a57f19d30b2d5fb632b73729b39d05bae188eaed (patch) | |
tree | 2b81da449cdb8dac334ac027c6c0149a6a209e8b | |
parent | 5026c9b1bafcb309bf467b60494b3bcd6364b99c (diff) |
net sched: ipt action fix late binding
This was broken and is fixed with this patch.
//add an ipt action and give it an instance id of 1
sudo tc actions add action ipt -j mark --set-mark 2 index 1
//create a filter which binds to ipt 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 ipt index 1
Message before bug 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_ipt.c | 19 |
1 files changed, 12 insertions, 7 deletions
diff --git a/net/sched/act_ipt.c b/net/sched/act_ipt.c index 350e134cffb3..8b5270008a6e 100644 --- a/net/sched/act_ipt.c +++ b/net/sched/act_ipt.c | |||
@@ -96,7 +96,7 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, | |||
96 | struct tcf_ipt *ipt; | 96 | struct tcf_ipt *ipt; |
97 | struct xt_entry_target *td, *t; | 97 | struct xt_entry_target *td, *t; |
98 | char *tname; | 98 | char *tname; |
99 | int ret = 0, err; | 99 | int ret = 0, err, exists = 0; |
100 | u32 hook = 0; | 100 | u32 hook = 0; |
101 | u32 index = 0; | 101 | u32 index = 0; |
102 | 102 | ||
@@ -107,18 +107,23 @@ static int __tcf_ipt_init(struct tc_action_net *tn, struct nlattr *nla, | |||
107 | if (err < 0) | 107 | if (err < 0) |
108 | return err; | 108 | return err; |
109 | 109 | ||
110 | if (tb[TCA_IPT_HOOK] == NULL) | 110 | if (tb[TCA_IPT_INDEX] != NULL) |
111 | return -EINVAL; | 111 | index = nla_get_u32(tb[TCA_IPT_INDEX]); |
112 | if (tb[TCA_IPT_TARG] == NULL) | 112 | |
113 | exists = tcf_hash_check(tn, index, a, bind); | ||
114 | if (exists && bind) | ||
115 | return 0; | ||
116 | |||
117 | if (tb[TCA_IPT_HOOK] == NULL || tb[TCA_IPT_TARG] == NULL) { | ||
118 | if (exists) | ||
119 | tcf_hash_release(a, bind); | ||
113 | return -EINVAL; | 120 | return -EINVAL; |
121 | } | ||
114 | 122 | ||
115 | td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]); | 123 | td = (struct xt_entry_target *)nla_data(tb[TCA_IPT_TARG]); |
116 | if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) | 124 | if (nla_len(tb[TCA_IPT_TARG]) < td->u.target_size) |
117 | return -EINVAL; | 125 | return -EINVAL; |
118 | 126 | ||
119 | if (tb[TCA_IPT_INDEX] != NULL) | ||
120 | index = nla_get_u32(tb[TCA_IPT_INDEX]); | ||
121 | |||
122 | if (!tcf_hash_check(tn, index, a, bind)) { | 127 | if (!tcf_hash_check(tn, index, a, bind)) { |
123 | ret = tcf_hash_create(tn, index, est, a, sizeof(*ipt), bind, | 128 | ret = tcf_hash_create(tn, index, est, a, sizeof(*ipt), bind, |
124 | false); | 129 | false); |