diff options
Diffstat (limited to 'net/sched/sch_api.c')
-rw-r--r-- | net/sched/sch_api.c | 22 |
1 files changed, 17 insertions, 5 deletions
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c index b9e8c3b7d406..408eea7086aa 100644 --- a/net/sched/sch_api.c +++ b/net/sched/sch_api.c | |||
@@ -150,22 +150,34 @@ int register_qdisc(struct Qdisc_ops *qops) | |||
150 | if (qops->enqueue == NULL) | 150 | if (qops->enqueue == NULL) |
151 | qops->enqueue = noop_qdisc_ops.enqueue; | 151 | qops->enqueue = noop_qdisc_ops.enqueue; |
152 | if (qops->peek == NULL) { | 152 | if (qops->peek == NULL) { |
153 | if (qops->dequeue == NULL) { | 153 | if (qops->dequeue == NULL) |
154 | qops->peek = noop_qdisc_ops.peek; | 154 | qops->peek = noop_qdisc_ops.peek; |
155 | } else { | 155 | else |
156 | rc = -EINVAL; | 156 | goto out_einval; |
157 | goto out; | ||
158 | } | ||
159 | } | 157 | } |
160 | if (qops->dequeue == NULL) | 158 | if (qops->dequeue == NULL) |
161 | qops->dequeue = noop_qdisc_ops.dequeue; | 159 | qops->dequeue = noop_qdisc_ops.dequeue; |
162 | 160 | ||
161 | if (qops->cl_ops) { | ||
162 | const struct Qdisc_class_ops *cops = qops->cl_ops; | ||
163 | |||
164 | if (!(cops->get && cops->put && cops->walk && cops->leaf)) | ||
165 | goto out_einval; | ||
166 | |||
167 | if (cops->tcf_chain && !(cops->bind_tcf && cops->unbind_tcf)) | ||
168 | goto out_einval; | ||
169 | } | ||
170 | |||
163 | qops->next = NULL; | 171 | qops->next = NULL; |
164 | *qp = qops; | 172 | *qp = qops; |
165 | rc = 0; | 173 | rc = 0; |
166 | out: | 174 | out: |
167 | write_unlock(&qdisc_mod_lock); | 175 | write_unlock(&qdisc_mod_lock); |
168 | return rc; | 176 | return rc; |
177 | |||
178 | out_einval: | ||
179 | rc = -EINVAL; | ||
180 | goto out; | ||
169 | } | 181 | } |
170 | EXPORT_SYMBOL(register_qdisc); | 182 | EXPORT_SYMBOL(register_qdisc); |
171 | 183 | ||