net: flow_offload: fix flow_indr_dev_unregister path
[linux-2.6-microblaze.git] / net / netfilter / nf_tables_offload.c
index 2bb2848..c7cf1cd 100644 (file)
@@ -285,40 +285,42 @@ static int nft_block_offload_cmd(struct nft_base_chain *chain,
        return nft_block_setup(chain, &bo, cmd);
 }
 
-static void nft_indr_block_ing_cmd(struct net_device *dev,
-                                  struct nft_base_chain *chain,
-                                  flow_indr_block_bind_cb_t *cb,
-                                  void *cb_priv,
-                                  enum flow_block_command cmd)
+static void nft_indr_block_cleanup(struct flow_block_cb *block_cb)
 {
+       struct nft_base_chain *basechain = block_cb->indr.data;
+       struct net_device *dev = block_cb->indr.dev;
        struct netlink_ext_ack extack = {};
+       struct net *net = dev_net(dev);
        struct flow_block_offload bo;
 
-       if (!chain)
-               return;
-
-       nft_flow_block_offload_init(&bo, dev_net(dev), cmd, chain, &extack);
-
-       cb(dev, cb_priv, TC_SETUP_BLOCK, &bo);
-
-       nft_block_setup(chain, &bo, cmd);
+       nft_flow_block_offload_init(&bo, dev_net(dev), FLOW_BLOCK_UNBIND,
+                                   basechain, &extack);
+       mutex_lock(&net->nft.commit_mutex);
+       list_del(&block_cb->driver_list);
+       list_move(&block_cb->list, &bo.cb_list);
+       nft_flow_offload_unbind(&bo, basechain);
+       mutex_unlock(&net->nft.commit_mutex);
 }
 
-static int nft_indr_block_offload_cmd(struct nft_base_chain *chain,
+static int nft_indr_block_offload_cmd(struct nft_base_chain *basechain,
                                      struct net_device *dev,
                                      enum flow_block_command cmd)
 {
        struct netlink_ext_ack extack = {};
        struct flow_block_offload bo;
+       int err;
 
-       nft_flow_block_offload_init(&bo, dev_net(dev), cmd, chain, &extack);
+       nft_flow_block_offload_init(&bo, dev_net(dev), cmd, basechain, &extack);
 
-       flow_indr_block_call(dev, &bo, cmd);
+       err = flow_indr_dev_setup_offload(dev, TC_SETUP_BLOCK, basechain, &bo,
+                                         nft_indr_block_cleanup);
+       if (err < 0)
+               return err;
 
        if (list_empty(&bo.cb_list))
                return -EOPNOTSUPP;
 
-       return nft_block_setup(chain, &bo, cmd);
+       return nft_block_setup(basechain, &bo, cmd);
 }
 
 #define FLOW_SETUP_BLOCK TC_SETUP_BLOCK
@@ -555,24 +557,6 @@ static struct nft_chain *__nft_offload_get_chain(struct net_device *dev)
        return NULL;
 }
 
-static void nft_indr_block_cb(struct net_device *dev,
-                             flow_indr_block_bind_cb_t *cb, void *cb_priv,
-                             enum flow_block_command cmd)
-{
-       struct net *net = dev_net(dev);
-       struct nft_chain *chain;
-
-       mutex_lock(&net->nft.commit_mutex);
-       chain = __nft_offload_get_chain(dev);
-       if (chain && chain->flags & NFT_CHAIN_HW_OFFLOAD) {
-               struct nft_base_chain *basechain;
-
-               basechain = nft_base_chain(chain);
-               nft_indr_block_ing_cmd(dev, basechain, cb, cb_priv, cmd);
-       }
-       mutex_unlock(&net->nft.commit_mutex);
-}
-
 static int nft_offload_netdev_event(struct notifier_block *this,
                                    unsigned long event, void *ptr)
 {
@@ -594,30 +578,16 @@ static int nft_offload_netdev_event(struct notifier_block *this,
        return NOTIFY_DONE;
 }
 
-static struct flow_indr_block_entry block_ing_entry = {
-       .cb     = nft_indr_block_cb,
-       .list   = LIST_HEAD_INIT(block_ing_entry.list),
-};
-
 static struct notifier_block nft_offload_netdev_notifier = {
        .notifier_call  = nft_offload_netdev_event,
 };
 
 int nft_offload_init(void)
 {
-       int err;
-
-       err = register_netdevice_notifier(&nft_offload_netdev_notifier);
-       if (err < 0)
-               return err;
-
-       flow_indr_add_block_cb(&block_ing_entry);
-
-       return 0;
+       return register_netdevice_notifier(&nft_offload_netdev_notifier);
 }
 
 void nft_offload_exit(void)
 {
-       flow_indr_del_block_cb(&block_ing_entry);
        unregister_netdevice_notifier(&nft_offload_netdev_notifier);
 }