diff options
Diffstat (limited to 'net/sched/cls_api.c')
-rw-r--r-- | net/sched/cls_api.c | 33 |
1 files changed, 18 insertions, 15 deletions
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c index 2bc1bc23d42e..247b7cc20c13 100644 --- a/net/sched/cls_api.c +++ b/net/sched/cls_api.c | |||
@@ -376,17 +376,12 @@ struct tcf_net { | |||
376 | static unsigned int tcf_net_id; | 376 | static unsigned int tcf_net_id; |
377 | 377 | ||
378 | static int tcf_block_insert(struct tcf_block *block, struct net *net, | 378 | static int tcf_block_insert(struct tcf_block *block, struct net *net, |
379 | u32 block_index, struct netlink_ext_ack *extack) | 379 | struct netlink_ext_ack *extack) |
380 | { | 380 | { |
381 | struct tcf_net *tn = net_generic(net, tcf_net_id); | 381 | struct tcf_net *tn = net_generic(net, tcf_net_id); |
382 | int err; | ||
383 | 382 | ||
384 | err = idr_alloc_u32(&tn->idr, block, &block_index, block_index, | 383 | return idr_alloc_u32(&tn->idr, block, &block->index, block->index, |
385 | GFP_KERNEL); | 384 | GFP_KERNEL); |
386 | if (err) | ||
387 | return err; | ||
388 | block->index = block_index; | ||
389 | return 0; | ||
390 | } | 385 | } |
391 | 386 | ||
392 | static void tcf_block_remove(struct tcf_block *block, struct net *net) | 387 | static void tcf_block_remove(struct tcf_block *block, struct net *net) |
@@ -397,6 +392,7 @@ static void tcf_block_remove(struct tcf_block *block, struct net *net) | |||
397 | } | 392 | } |
398 | 393 | ||
399 | static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, | 394 | static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, |
395 | u32 block_index, | ||
400 | struct netlink_ext_ack *extack) | 396 | struct netlink_ext_ack *extack) |
401 | { | 397 | { |
402 | struct tcf_block *block; | 398 | struct tcf_block *block; |
@@ -419,10 +415,13 @@ static struct tcf_block *tcf_block_create(struct net *net, struct Qdisc *q, | |||
419 | err = -ENOMEM; | 415 | err = -ENOMEM; |
420 | goto err_chain_create; | 416 | goto err_chain_create; |
421 | } | 417 | } |
422 | block->net = qdisc_net(q); | ||
423 | block->refcnt = 1; | 418 | block->refcnt = 1; |
424 | block->net = net; | 419 | block->net = net; |
425 | block->q = q; | 420 | block->index = block_index; |
421 | |||
422 | /* Don't store q pointer for blocks which are shared */ | ||
423 | if (!tcf_block_shared(block)) | ||
424 | block->q = q; | ||
426 | return block; | 425 | return block; |
427 | 426 | ||
428 | err_chain_create: | 427 | err_chain_create: |
@@ -518,13 +517,12 @@ int tcf_block_get_ext(struct tcf_block **p_block, struct Qdisc *q, | |||
518 | } | 517 | } |
519 | 518 | ||
520 | if (!block) { | 519 | if (!block) { |
521 | block = tcf_block_create(net, q, extack); | 520 | block = tcf_block_create(net, q, ei->block_index, extack); |
522 | if (IS_ERR(block)) | 521 | if (IS_ERR(block)) |
523 | return PTR_ERR(block); | 522 | return PTR_ERR(block); |
524 | created = true; | 523 | created = true; |
525 | if (ei->block_index) { | 524 | if (tcf_block_shared(block)) { |
526 | err = tcf_block_insert(block, net, | 525 | err = tcf_block_insert(block, net, extack); |
527 | ei->block_index, extack); | ||
528 | if (err) | 526 | if (err) |
529 | goto err_block_insert; | 527 | goto err_block_insert; |
530 | } | 528 | } |
@@ -1399,13 +1397,18 @@ static int tc_dump_tfilter(struct sk_buff *skb, struct netlink_callback *cb) | |||
1399 | nla_get_u32(tca[TCA_CHAIN]) != chain->index) | 1397 | nla_get_u32(tca[TCA_CHAIN]) != chain->index) |
1400 | continue; | 1398 | continue; |
1401 | if (!tcf_chain_dump(chain, q, parent, skb, cb, | 1399 | if (!tcf_chain_dump(chain, q, parent, skb, cb, |
1402 | index_start, &index)) | 1400 | index_start, &index)) { |
1401 | err = -EMSGSIZE; | ||
1403 | break; | 1402 | break; |
1403 | } | ||
1404 | } | 1404 | } |
1405 | 1405 | ||
1406 | cb->args[0] = index; | 1406 | cb->args[0] = index; |
1407 | 1407 | ||
1408 | out: | 1408 | out: |
1409 | /* If we did no progress, the error (EMSGSIZE) is real */ | ||
1410 | if (skb->len == 0 && err) | ||
1411 | return err; | ||
1409 | return skb->len; | 1412 | return skb->len; |
1410 | } | 1413 | } |
1411 | 1414 | ||