struct ax25_dev         *next;
        struct net_device       *dev;
        struct net_device       *forward;
-       struct ctl_table        *systable;
+       struct ctl_table_header *sysheader;
        int                     values[AX25_MAX_VALUES];
 #if defined(CONFIG_AX25_DAMA_SLAVE) || defined(CONFIG_AX25_DAMA_MASTER)
        ax25_dama_info          dama;
 
 /* sysctl_net_ax25.c */
 #ifdef CONFIG_SYSCTL
-extern void ax25_register_sysctl(void);
-extern void ax25_unregister_sysctl(void);
+extern int ax25_register_dev_sysctl(ax25_dev *ax25_dev);
+extern void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev);
 #else
-static inline void ax25_register_sysctl(void) {};
-static inline void ax25_unregister_sysctl(void) {};
+static inline int ax25_register_dev_sysctl(ax25_dev *ax25_dev) { return 0 };
+static inline void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev) {};
 #endif /* CONFIG_SYSCTL */
 
 #endif
 
        sock_register(&ax25_family_ops);
        dev_add_pack(&ax25_packet_type);
        register_netdevice_notifier(&ax25_dev_notifier);
-       ax25_register_sysctl();
 
        proc_net_fops_create(&init_net, "ax25_route", S_IRUGO, &ax25_route_fops);
        proc_net_fops_create(&init_net, "ax25", S_IRUGO, &ax25_info_fops);
        ax25_uid_free();
        ax25_dev_free();
 
-       ax25_unregister_sysctl();
        unregister_netdevice_notifier(&ax25_dev_notifier);
 
        dev_remove_pack(&ax25_packet_type);
 
                return;
        }
 
-       ax25_unregister_sysctl();
-
        dev->ax25_ptr     = ax25_dev;
        ax25_dev->dev     = dev;
        dev_hold(dev);
        ax25_dev_list  = ax25_dev;
        spin_unlock_bh(&ax25_dev_lock);
 
-       ax25_register_sysctl();
+       ax25_register_dev_sysctl(ax25_dev);
 }
 
 void ax25_dev_device_down(struct net_device *dev)
        if ((ax25_dev = ax25_dev_ax25dev(dev)) == NULL)
                return;
 
-       ax25_unregister_sysctl();
+       ax25_unregister_dev_sysctl(ax25_dev);
 
        spin_lock_bh(&ax25_dev_lock);
 
                spin_unlock_bh(&ax25_dev_lock);
                dev_put(dev);
                kfree(ax25_dev);
-               ax25_register_sysctl();
                return;
        }
 
                        spin_unlock_bh(&ax25_dev_lock);
                        dev_put(dev);
                        kfree(ax25_dev);
-                       ax25_register_sysctl();
                        return;
                }
 
        }
        spin_unlock_bh(&ax25_dev_lock);
        dev->ax25_ptr = NULL;
-
-       ax25_register_sysctl();
 }
 
 int ax25_fwd_ioctl(unsigned int cmd, struct ax25_fwd_struct *fwd)
 
 static int min_ds_timeout[1],          max_ds_timeout[] = {65535000};
 #endif
 
-static struct ctl_table_header *ax25_table_header;
-
-static ctl_table *ax25_table;
-static int ax25_table_size;
-
-static struct ctl_path ax25_path[] = {
-       { .procname = "net", },
-       { .procname = "ax25", },
-       { }
-};
-
 static const ctl_table ax25_param_table[] = {
        {
                .procname       = "ip_default_mode",
        { }     /* that's all, folks! */
 };
 
-void ax25_register_sysctl(void)
+int ax25_register_dev_sysctl(ax25_dev *ax25_dev)
 {
-       ax25_dev *ax25_dev;
-       int n, k;
-
-       spin_lock_bh(&ax25_dev_lock);
-       for (ax25_table_size = sizeof(ctl_table), ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next)
-               ax25_table_size += sizeof(ctl_table);
-
-       if ((ax25_table = kzalloc(ax25_table_size, GFP_ATOMIC)) == NULL) {
-               spin_unlock_bh(&ax25_dev_lock);
-               return;
-       }
-
-       for (n = 0, ax25_dev = ax25_dev_list; ax25_dev != NULL; ax25_dev = ax25_dev->next) {
-               struct ctl_table *child = kmemdup(ax25_param_table,
-                                                 sizeof(ax25_param_table),
-                                                 GFP_ATOMIC);
-               if (!child) {
-                       while (n--)
-                               kfree(ax25_table[n].child);
-                       kfree(ax25_table);
-                       spin_unlock_bh(&ax25_dev_lock);
-                       return;
-               }
-               ax25_table[n].child = ax25_dev->systable = child;
-               ax25_table[n].procname     = ax25_dev->dev->name;
-               ax25_table[n].mode         = 0555;
-
-
-               for (k = 0; k < AX25_MAX_VALUES; k++)
-                       child[k].data = &ax25_dev->values[k];
-
-               n++;
+       char path[sizeof("net/ax25/") + IFNAMSIZ];
+       int k;
+       struct ctl_table *table;
+
+       table = kmemdup(ax25_param_table, sizeof(ax25_param_table), GFP_KERNEL);
+       if (!table)
+               return -ENOMEM;
+
+       for (k = 0; k < AX25_MAX_VALUES; k++)
+               table[k].data = &ax25_dev->values[k];
+
+       snprintf(path, sizeof(path), "net/ax25/%s", ax25_dev->dev->name);
+       ax25_dev->sysheader = register_net_sysctl(&init_net, path, table);
+       if (!ax25_dev->sysheader) {
+               kfree(table);
+               return -ENOMEM;
        }
-       spin_unlock_bh(&ax25_dev_lock);
-
-       ax25_table_header = register_net_sysctl_table(&init_net, ax25_path, ax25_table);
+       return 0;
 }
 
-void ax25_unregister_sysctl(void)
+void ax25_unregister_dev_sysctl(ax25_dev *ax25_dev)
 {
-       ctl_table *p;
-       unregister_net_sysctl_table(ax25_table_header);
-
-       for (p = ax25_table; p->procname; p++)
-               kfree(p->child);
-       kfree(ax25_table);
+       struct ctl_table_header *header = ax25_dev->sysheader;
+       struct ctl_table *table;
+
+       if (header) {
+               ax25_dev->sysheader = NULL;
+               table = header->ctl_table_arg;
+               unregister_net_sysctl_table(header);
+               kfree(table);
+       }
 }