sch_tbf.c (20fea08b5fb639c4c175b5c74a2bb346c5c5bc2e) | sch_tbf.c (1e90474c377e92db7262a8968a45c1dd980ca9e5) |
---|---|
1/* 2 * net/sched/sch_tbf.c Token Bucket Filter queue. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * --- 231 unchanged lines hidden (view full) --- 240 q->tokens = q->buffer; 241 q->ptokens = q->mtu; 242 qdisc_watchdog_cancel(&q->watchdog); 243} 244 245static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) 246{ 247 struct Qdisc *q; | 1/* 2 * net/sched/sch_tbf.c Token Bucket Filter queue. 3 * 4 * This program is free software; you can redistribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * --- 231 unchanged lines hidden (view full) --- 240 q->tokens = q->buffer; 241 q->ptokens = q->mtu; 242 qdisc_watchdog_cancel(&q->watchdog); 243} 244 245static struct Qdisc *tbf_create_dflt_qdisc(struct Qdisc *sch, u32 limit) 246{ 247 struct Qdisc *q; |
248 struct rtattr *rta; | 248 struct nlattr *nla; |
249 int ret; 250 251 q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops, 252 TC_H_MAKE(sch->handle, 1)); 253 if (q) { | 249 int ret; 250 251 q = qdisc_create_dflt(sch->dev, &bfifo_qdisc_ops, 252 TC_H_MAKE(sch->handle, 1)); 253 if (q) { |
254 rta = kmalloc(RTA_LENGTH(sizeof(struct tc_fifo_qopt)), GFP_KERNEL); 255 if (rta) { 256 rta->rta_type = RTM_NEWQDISC; 257 rta->rta_len = RTA_LENGTH(sizeof(struct tc_fifo_qopt)); 258 ((struct tc_fifo_qopt *)RTA_DATA(rta))->limit = limit; | 254 nla = kmalloc(nla_attr_size(sizeof(struct tc_fifo_qopt)), 255 GFP_KERNEL); 256 if (nla) { 257 nla->nla_type = RTM_NEWQDISC; 258 nla->nla_len = nla_attr_size(sizeof(struct tc_fifo_qopt)); 259 ((struct tc_fifo_qopt *)nla_data(nla))->limit = limit; |
259 | 260 |
260 ret = q->ops->change(q, rta); 261 kfree(rta); | 261 ret = q->ops->change(q, nla); 262 kfree(nla); |
262 263 if (ret == 0) 264 return q; 265 } 266 qdisc_destroy(q); 267 } 268 269 return NULL; 270} 271 | 263 264 if (ret == 0) 265 return q; 266 } 267 qdisc_destroy(q); 268 } 269 270 return NULL; 271} 272 |
272static int tbf_change(struct Qdisc* sch, struct rtattr *opt) | 273static int tbf_change(struct Qdisc* sch, struct nlattr *opt) |
273{ 274 int err = -EINVAL; 275 struct tbf_sched_data *q = qdisc_priv(sch); | 274{ 275 int err = -EINVAL; 276 struct tbf_sched_data *q = qdisc_priv(sch); |
276 struct rtattr *tb[TCA_TBF_PTAB]; | 277 struct nlattr *tb[TCA_TBF_PTAB + 1]; |
277 struct tc_tbf_qopt *qopt; 278 struct qdisc_rate_table *rtab = NULL; 279 struct qdisc_rate_table *ptab = NULL; 280 struct Qdisc *child = NULL; 281 int max_size,n; 282 | 278 struct tc_tbf_qopt *qopt; 279 struct qdisc_rate_table *rtab = NULL; 280 struct qdisc_rate_table *ptab = NULL; 281 struct Qdisc *child = NULL; 282 int max_size,n; 283 |
283 if (rtattr_parse_nested(tb, TCA_TBF_PTAB, opt) || 284 tb[TCA_TBF_PARMS-1] == NULL || 285 RTA_PAYLOAD(tb[TCA_TBF_PARMS-1]) < sizeof(*qopt)) | 284 if (nla_parse_nested(tb, TCA_TBF_PTAB, opt, NULL) || 285 tb[TCA_TBF_PARMS] == NULL || 286 nla_len(tb[TCA_TBF_PARMS]) < sizeof(*qopt)) |
286 goto done; 287 | 287 goto done; 288 |
288 qopt = RTA_DATA(tb[TCA_TBF_PARMS-1]); 289 rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB-1]); | 289 qopt = nla_data(tb[TCA_TBF_PARMS]); 290 rtab = qdisc_get_rtab(&qopt->rate, tb[TCA_TBF_RTAB]); |
290 if (rtab == NULL) 291 goto done; 292 293 if (qopt->peakrate.rate) { 294 if (qopt->peakrate.rate > qopt->rate.rate) | 291 if (rtab == NULL) 292 goto done; 293 294 if (qopt->peakrate.rate) { 295 if (qopt->peakrate.rate > qopt->rate.rate) |
295 ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB-1]); | 296 ptab = qdisc_get_rtab(&qopt->peakrate, tb[TCA_TBF_PTAB]); |
296 if (ptab == NULL) 297 goto done; 298 } 299 300 for (n = 0; n < 256; n++) 301 if (rtab->data[n] > qopt->buffer) break; 302 max_size = (n << qopt->rate.cell_log)-1; 303 if (ptab) { --- 30 unchanged lines hidden (view full) --- 334done: 335 if (rtab) 336 qdisc_put_rtab(rtab); 337 if (ptab) 338 qdisc_put_rtab(ptab); 339 return err; 340} 341 | 297 if (ptab == NULL) 298 goto done; 299 } 300 301 for (n = 0; n < 256; n++) 302 if (rtab->data[n] > qopt->buffer) break; 303 max_size = (n << qopt->rate.cell_log)-1; 304 if (ptab) { --- 30 unchanged lines hidden (view full) --- 335done: 336 if (rtab) 337 qdisc_put_rtab(rtab); 338 if (ptab) 339 qdisc_put_rtab(ptab); 340 return err; 341} 342 |
342static int tbf_init(struct Qdisc* sch, struct rtattr *opt) | 343static int tbf_init(struct Qdisc* sch, struct nlattr *opt) |
343{ 344 struct tbf_sched_data *q = qdisc_priv(sch); 345 346 if (opt == NULL) 347 return -EINVAL; 348 349 q->t_c = psched_get_time(); 350 qdisc_watchdog_init(&q->watchdog, sch); --- 15 unchanged lines hidden (view full) --- 366 367 qdisc_destroy(q->qdisc); 368} 369 370static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) 371{ 372 struct tbf_sched_data *q = qdisc_priv(sch); 373 unsigned char *b = skb_tail_pointer(skb); | 344{ 345 struct tbf_sched_data *q = qdisc_priv(sch); 346 347 if (opt == NULL) 348 return -EINVAL; 349 350 q->t_c = psched_get_time(); 351 qdisc_watchdog_init(&q->watchdog, sch); --- 15 unchanged lines hidden (view full) --- 367 368 qdisc_destroy(q->qdisc); 369} 370 371static int tbf_dump(struct Qdisc *sch, struct sk_buff *skb) 372{ 373 struct tbf_sched_data *q = qdisc_priv(sch); 374 unsigned char *b = skb_tail_pointer(skb); |
374 struct rtattr *rta; | 375 struct nlattr *nla; |
375 struct tc_tbf_qopt opt; 376 | 376 struct tc_tbf_qopt opt; 377 |
377 rta = (struct rtattr*)b; 378 RTA_PUT(skb, TCA_OPTIONS, 0, NULL); | 378 nla = (struct nlattr*)b; 379 NLA_PUT(skb, TCA_OPTIONS, 0, NULL); |
379 380 opt.limit = q->limit; 381 opt.rate = q->R_tab->rate; 382 if (q->P_tab) 383 opt.peakrate = q->P_tab->rate; 384 else 385 memset(&opt.peakrate, 0, sizeof(opt.peakrate)); 386 opt.mtu = q->mtu; 387 opt.buffer = q->buffer; | 380 381 opt.limit = q->limit; 382 opt.rate = q->R_tab->rate; 383 if (q->P_tab) 384 opt.peakrate = q->P_tab->rate; 385 else 386 memset(&opt.peakrate, 0, sizeof(opt.peakrate)); 387 opt.mtu = q->mtu; 388 opt.buffer = q->buffer; |
388 RTA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt); 389 rta->rta_len = skb_tail_pointer(skb) - b; | 389 NLA_PUT(skb, TCA_TBF_PARMS, sizeof(opt), &opt); 390 nla->nla_len = skb_tail_pointer(skb) - b; |
390 391 return skb->len; 392 | 391 392 return skb->len; 393 |
393rtattr_failure: | 394nla_put_failure: |
394 nlmsg_trim(skb, b); 395 return -1; 396} 397 398static int tbf_dump_class(struct Qdisc *sch, unsigned long cl, 399 struct sk_buff *skb, struct tcmsg *tcm) 400{ 401 struct tbf_sched_data *q = qdisc_priv(sch); --- 35 unchanged lines hidden (view full) --- 437 return 1; 438} 439 440static void tbf_put(struct Qdisc *sch, unsigned long arg) 441{ 442} 443 444static int tbf_change_class(struct Qdisc *sch, u32 classid, u32 parentid, | 395 nlmsg_trim(skb, b); 396 return -1; 397} 398 399static int tbf_dump_class(struct Qdisc *sch, unsigned long cl, 400 struct sk_buff *skb, struct tcmsg *tcm) 401{ 402 struct tbf_sched_data *q = qdisc_priv(sch); --- 35 unchanged lines hidden (view full) --- 438 return 1; 439} 440 441static void tbf_put(struct Qdisc *sch, unsigned long arg) 442{ 443} 444 445static int tbf_change_class(struct Qdisc *sch, u32 classid, u32 parentid, |
445 struct rtattr **tca, unsigned long *arg) | 446 struct nlattr **tca, unsigned long *arg) |
446{ 447 return -ENOSYS; 448} 449 450static int tbf_delete(struct Qdisc *sch, unsigned long arg) 451{ 452 return -ENOSYS; 453} --- 60 unchanged lines hidden --- | 447{ 448 return -ENOSYS; 449} 450 451static int tbf_delete(struct Qdisc *sch, unsigned long arg) 452{ 453 return -ENOSYS; 454} --- 60 unchanged lines hidden --- |