debugfs_remove_recursive(nsim_dev_port->ddir);
 }
 
-static struct net *nsim_devlink_net(struct devlink *devlink)
-{
-       return &init_net;
-}
-
-static u64 nsim_dev_ipv4_fib_resource_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, false);
-}
-
-static u64 nsim_dev_ipv4_fib_rules_res_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, false);
-}
-
-static u64 nsim_dev_ipv6_fib_resource_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, false);
-}
-
-static u64 nsim_dev_ipv6_fib_rules_res_occ_get(void *priv)
-{
-       struct net *net = priv;
-
-       return nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, false);
-}
-
 static int nsim_dev_resources_register(struct devlink *devlink)
 {
        struct devlink_resource_size_params params = {
                .size_granularity = 1,
                .unit = DEVLINK_RESOURCE_UNIT_ENTRY
        };
-       struct net *net = nsim_devlink_net(devlink);
        int err;
-       u64 n;
 
        /* Resources for IPv4 */
        err = devlink_resource_register(devlink, "IPv4", (u64)-1,
                goto out;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB, true);
-       err = devlink_resource_register(devlink, "fib", n,
+       err = devlink_resource_register(devlink, "fib", (u64)-1,
                                        NSIM_RESOURCE_IPV4_FIB,
                                        NSIM_RESOURCE_IPV4, ¶ms);
        if (err) {
                return err;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV4_FIB_RULES, true);
-       err = devlink_resource_register(devlink, "fib-rules", n,
+       err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
                                        NSIM_RESOURCE_IPV4_FIB_RULES,
                                        NSIM_RESOURCE_IPV4, ¶ms);
        if (err) {
                goto out;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB, true);
-       err = devlink_resource_register(devlink, "fib", n,
+       err = devlink_resource_register(devlink, "fib", (u64)-1,
                                        NSIM_RESOURCE_IPV6_FIB,
                                        NSIM_RESOURCE_IPV6, ¶ms);
        if (err) {
                return err;
        }
 
-       n = nsim_fib_get_val(net, NSIM_RESOURCE_IPV6_FIB_RULES, true);
-       err = devlink_resource_register(devlink, "fib-rules", n,
+       err = devlink_resource_register(devlink, "fib-rules", (u64)-1,
                                        NSIM_RESOURCE_IPV6_FIB_RULES,
                                        NSIM_RESOURCE_IPV6, ¶ms);
        if (err) {
                return err;
        }
 
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV4_FIB,
-                                         nsim_dev_ipv4_fib_resource_occ_get,
-                                         net);
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV4_FIB_RULES,
-                                         nsim_dev_ipv4_fib_rules_res_occ_get,
-                                         net);
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV6_FIB,
-                                         nsim_dev_ipv6_fib_resource_occ_get,
-                                         net);
-       devlink_resource_occ_get_register(devlink,
-                                         NSIM_RESOURCE_IPV6_FIB_RULES,
-                                         nsim_dev_ipv6_fib_rules_res_occ_get,
-                                         net);
 out:
        return err;
 }
 static int nsim_dev_reload_up(struct devlink *devlink,
                              struct netlink_ext_ack *extack)
 {
+       struct nsim_dev *nsim_dev = devlink_priv(devlink);
        enum nsim_resource_id res_ids[] = {
                NSIM_RESOURCE_IPV4_FIB, NSIM_RESOURCE_IPV4_FIB_RULES,
                NSIM_RESOURCE_IPV6_FIB, NSIM_RESOURCE_IPV6_FIB_RULES
        };
-       struct net *net = nsim_devlink_net(devlink);
        int i;
 
        for (i = 0; i < ARRAY_SIZE(res_ids); ++i) {
 
                err = devlink_resource_size_get(devlink, res_ids[i], &val);
                if (!err) {
-                       err = nsim_fib_set_max(net, res_ids[i], val, extack);
+                       err = nsim_fib_set_max(nsim_dev->fib_data,
+                                              res_ids[i], val, extack);
                        if (err)
                                return err;
                }
        if (err)
                goto err_devlink_free;
 
+       nsim_dev->fib_data = nsim_fib_create(devlink);
+       if (IS_ERR(nsim_dev->fib_data)) {
+               err = PTR_ERR(nsim_dev->fib_data);
+               goto err_resources_unregister;
+       }
+
        err = devlink_register(devlink, &nsim_bus_dev->dev);
        if (err)
-               goto err_resources_unregister;
+               goto err_fib_destroy;
 
        err = devlink_params_register(devlink, nsim_devlink_params,
                                      ARRAY_SIZE(nsim_devlink_params));
                                  ARRAY_SIZE(nsim_devlink_params));
 err_dl_unregister:
        devlink_unregister(devlink);
+err_fib_destroy:
+       nsim_fib_destroy(devlink, nsim_dev->fib_data);
 err_resources_unregister:
        devlink_resources_unregister(devlink, NULL);
 err_devlink_free:
        devlink_params_unregister(devlink, nsim_devlink_params,
                                  ARRAY_SIZE(nsim_devlink_params));
        devlink_unregister(devlink);
+       nsim_fib_destroy(devlink, nsim_dev->fib_data);
        devlink_resources_unregister(devlink, NULL);
        mutex_destroy(&nsim_dev->port_list_lock);
        devlink_free(devlink);
 
 #include <net/ip_fib.h>
 #include <net/ip6_fib.h>
 #include <net/fib_rules.h>
-#include <net/netns/generic.h>
+#include <net/net_namespace.h>
 
 #include "netdevsim.h"
 
 };
 
 struct nsim_fib_data {
+       struct notifier_block fib_nb;
        struct nsim_per_fib_data ipv4;
        struct nsim_per_fib_data ipv6;
 };
 
-static unsigned int nsim_fib_net_id;
-
-u64 nsim_fib_get_val(struct net *net, enum nsim_resource_id res_id, bool max)
+u64 nsim_fib_get_val(struct nsim_fib_data *fib_data,
+                    enum nsim_resource_id res_id, bool max)
 {
-       struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id);
        struct nsim_fib_entry *entry;
 
        switch (res_id) {
        return max ? entry->max : entry->num;
 }
 
-int nsim_fib_set_max(struct net *net, enum nsim_resource_id res_id, u64 val,
+int nsim_fib_set_max(struct nsim_fib_data *fib_data,
+                    enum nsim_resource_id res_id, u64 val,
                     struct netlink_ext_ack *extack)
 {
-       struct nsim_fib_data *fib_data = net_generic(net, nsim_fib_net_id);
        struct nsim_fib_entry *entry;
        int err = 0;
 
        return err;
 }
 
-static int nsim_fib_rule_event(struct fib_notifier_info *info, bool add)
+static int nsim_fib_rule_event(struct nsim_fib_data *data,
+                              struct fib_notifier_info *info, bool add)
 {
-       struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id);
        struct netlink_ext_ack *extack = info->extack;
        int err = 0;
 
        return err;
 }
 
-static int nsim_fib_event(struct fib_notifier_info *info, bool add)
+static int nsim_fib_event(struct nsim_fib_data *data,
+                         struct fib_notifier_info *info, bool add)
 {
-       struct nsim_fib_data *data = net_generic(info->net, nsim_fib_net_id);
        struct netlink_ext_ack *extack = info->extack;
        int err = 0;
 
 static int nsim_fib_event_nb(struct notifier_block *nb, unsigned long event,
                             void *ptr)
 {
+       struct nsim_fib_data *data = container_of(nb, struct nsim_fib_data,
+                                                 fib_nb);
        struct fib_notifier_info *info = ptr;
        int err = 0;
 
+       if (!net_eq(info->net, &init_net))
+               return NOTIFY_DONE;
+
        switch (event) {
        case FIB_EVENT_RULE_ADD: /* fall through */
        case FIB_EVENT_RULE_DEL:
-               err = nsim_fib_rule_event(info, event == FIB_EVENT_RULE_ADD);
+               err = nsim_fib_rule_event(data, info,
+                                         event == FIB_EVENT_RULE_ADD);
                break;
 
        case FIB_EVENT_ENTRY_ADD:  /* fall through */
        case FIB_EVENT_ENTRY_DEL:
-               err = nsim_fib_event(info, event == FIB_EVENT_ENTRY_ADD);
+               err = nsim_fib_event(data, info,
+                                    event == FIB_EVENT_ENTRY_ADD);
                break;
        }
 
 /* inconsistent dump, trying again */
 static void nsim_fib_dump_inconsistent(struct notifier_block *nb)
 {
-       struct nsim_fib_data *data;
-       struct net *net;
+       struct nsim_fib_data *data = container_of(nb, struct nsim_fib_data,
+                                                 fib_nb);
 
-       rcu_read_lock();
-       for_each_net_rcu(net) {
-               data = net_generic(net, nsim_fib_net_id);
+       data->ipv4.fib.num = 0ULL;
+       data->ipv4.rules.num = 0ULL;
+       data->ipv6.fib.num = 0ULL;
+       data->ipv6.rules.num = 0ULL;
+}
 
-               data->ipv4.fib.num = 0ULL;
-               data->ipv4.rules.num = 0ULL;
+static u64 nsim_fib_ipv4_resource_occ_get(void *priv)
+{
+       struct nsim_fib_data *data = priv;
 
-               data->ipv6.fib.num = 0ULL;
-               data->ipv6.rules.num = 0ULL;
-       }
-       rcu_read_unlock();
+       return nsim_fib_get_val(data, NSIM_RESOURCE_IPV4_FIB, false);
 }
 
-static struct notifier_block nsim_fib_nb = {
-       .notifier_call = nsim_fib_event_nb,
-};
-
-/* Initialize per network namespace state */
-static int __net_init nsim_fib_netns_init(struct net *net)
+static u64 nsim_fib_ipv4_rules_res_occ_get(void *priv)
 {
-       struct nsim_fib_data *data = net_generic(net, nsim_fib_net_id);
+       struct nsim_fib_data *data = priv;
 
-       data->ipv4.fib.max = (u64)-1;
-       data->ipv4.rules.max = (u64)-1;
+       return nsim_fib_get_val(data, NSIM_RESOURCE_IPV4_FIB_RULES, false);
+}
 
-       data->ipv6.fib.max = (u64)-1;
-       data->ipv6.rules.max = (u64)-1;
+static u64 nsim_fib_ipv6_resource_occ_get(void *priv)
+{
+       struct nsim_fib_data *data = priv;
 
-       return 0;
+       return nsim_fib_get_val(data, NSIM_RESOURCE_IPV6_FIB, false);
 }
 
-static struct pernet_operations nsim_fib_net_ops = {
-       .init = nsim_fib_netns_init,
-       .id   = &nsim_fib_net_id,
-       .size = sizeof(struct nsim_fib_data),
-};
-
-void nsim_fib_exit(void)
+static u64 nsim_fib_ipv6_rules_res_occ_get(void *priv)
 {
-       unregister_pernet_subsys(&nsim_fib_net_ops);
-       unregister_fib_notifier(&nsim_fib_nb);
+       struct nsim_fib_data *data = priv;
+
+       return nsim_fib_get_val(data, NSIM_RESOURCE_IPV6_FIB_RULES, false);
 }
 
-int nsim_fib_init(void)
+struct nsim_fib_data *nsim_fib_create(struct devlink *devlink)
 {
+       struct nsim_fib_data *data;
        int err;
 
-       err = register_pernet_subsys(&nsim_fib_net_ops);
-       if (err < 0) {
-               pr_err("Failed to register pernet subsystem\n");
-               goto err_out;
-       }
+       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return ERR_PTR(-ENOMEM);
 
-       err = register_fib_notifier(&nsim_fib_nb, nsim_fib_dump_inconsistent);
-       if (err < 0) {
+       data->ipv4.fib.max = (u64)-1;
+       data->ipv4.rules.max = (u64)-1;
+
+       data->ipv6.fib.max = (u64)-1;
+       data->ipv6.rules.max = (u64)-1;
+
+       data->fib_nb.notifier_call = nsim_fib_event_nb;
+       err = register_fib_notifier(&data->fib_nb, nsim_fib_dump_inconsistent);
+       if (err) {
                pr_err("Failed to register fib notifier\n");
                goto err_out;
        }
 
+       devlink_resource_occ_get_register(devlink,
+                                         NSIM_RESOURCE_IPV4_FIB,
+                                         nsim_fib_ipv4_resource_occ_get,
+                                         data);
+       devlink_resource_occ_get_register(devlink,
+                                         NSIM_RESOURCE_IPV4_FIB_RULES,
+                                         nsim_fib_ipv4_rules_res_occ_get,
+                                         data);
+       devlink_resource_occ_get_register(devlink,
+                                         NSIM_RESOURCE_IPV6_FIB,
+                                         nsim_fib_ipv6_resource_occ_get,
+                                         data);
+       devlink_resource_occ_get_register(devlink,
+                                         NSIM_RESOURCE_IPV6_FIB_RULES,
+                                         nsim_fib_ipv6_rules_res_occ_get,
+                                         data);
+       return data;
+
 err_out:
-       return err;
+       kfree(data);
+       return ERR_PTR(err);
+}
+
+void nsim_fib_destroy(struct devlink *devlink, struct nsim_fib_data *data)
+{
+       devlink_resource_occ_get_unregister(devlink,
+                                           NSIM_RESOURCE_IPV6_FIB_RULES);
+       devlink_resource_occ_get_unregister(devlink,
+                                           NSIM_RESOURCE_IPV6_FIB);
+       devlink_resource_occ_get_unregister(devlink,
+                                           NSIM_RESOURCE_IPV4_FIB_RULES);
+       devlink_resource_occ_get_unregister(devlink,
+                                           NSIM_RESOURCE_IPV4_FIB);
+       unregister_fib_notifier(&data->fib_nb);
+       kfree(data);
 }