Mon, Jul 08, 2019 at 06:06:09PM CEST, pa...@netfilter.org wrote:
>This patch adds tcf_block_setup() which uses the flow block API.
>
>This infrastructure takes the flow block callbacks coming from the
>driver and register/unregister to/from the cls_api core.
>
>Signed-off-by: Pablo Neira Ayuso <pa...@netfilter.org>

[...]


>+static int tcf_block_bind(struct tcf_block *block,
>+                        struct flow_block_offload *bo)
>+{
>+      struct flow_block_cb *block_cb, *next;
>+      int err, i = 0;
>+
>+      list_for_each_entry(block_cb, &bo->cb_list, driver_list) {
>+              err = tcf_block_playback_offloads(block, block_cb->cb,
>+                                                block_cb->cb_priv, true,
>+                                                
>tcf_block_offload_in_use(block),
>+                                                bo->extack);
>+              if (err)
>+                      goto err_unroll;
>+
>+              list_add(&block_cb->list, &block->cb_list);
>+              i++;
>+      }
>+      list_splice(&bo->cb_list, bo->driver_block_list);

This cl/driver_block list magic is really very hard to follow. Could you
please make it more clear?



>+
>+      return 0;
>+
>+err_unroll:
>+      list_for_each_entry_safe(block_cb, next, &bo->cb_list, driver_list) {
>+              if (i-- > 0) {
>+                      list_del(&block_cb->list);
>+                      tcf_block_playback_offloads(block, block_cb->cb,
>+                                                  block_cb->cb_priv, false,
>+                                                  
>tcf_block_offload_in_use(block),
>+                                                  NULL);
>+              }
>+              flow_block_cb_free(block_cb);
>+      }
>+
>+      return err;
>+}
>+
>+static void tcf_block_unbind(struct tcf_block *block,
>+                           struct flow_block_offload *bo)
>+{
>+      struct flow_block_cb *block_cb, *next;
>+
>+      list_for_each_entry_safe(block_cb, next, &bo->cb_list, driver_list) {
>+              list_del(&block_cb->driver_list);
>+              tcf_block_playback_offloads(block, block_cb->cb,
>+                                          block_cb->cb_priv, false,
>+                                          tcf_block_offload_in_use(block),
>+                                          NULL);
>+              list_del(&block_cb->list);
>+              flow_block_cb_free(block_cb);
>+      }
>+}

[...]

Reply via email to