{
        struct ctl_table_header *sysctl_header;
        ctl_table addrconf_vars[DEVCONF_MAX+1];
-       char *dev_name;
 } addrconf_sysctl __read_mostly = {
        .sysctl_header = NULL,
        .addrconf_vars = {
 {
        int i;
        struct addrconf_sysctl_table *t;
-
-#define ADDRCONF_CTL_PATH_DEV  3
-
-       struct ctl_path addrconf_ctl_path[] = {
-               { .procname = "net", },
-               { .procname = "ipv6", },
-               { .procname = "conf", },
-               { /* to be set */ },
-               { },
-       };
-
+       char path[sizeof("net/ipv6/conf/") + IFNAMSIZ];
 
        t = kmemdup(&addrconf_sysctl, sizeof(*t), GFP_KERNEL);
        if (t == NULL)
                t->addrconf_vars[i].extra2 = net;
        }
 
-       /*
-        * Make a copy of dev_name, because '.procname' is regarded as const
-        * by sysctl and we wouldn't want anyone to change it under our feet
-        * (see SIOCSIFNAME).
-        */
-       t->dev_name = kstrdup(dev_name, GFP_KERNEL);
-       if (!t->dev_name)
-               goto free;
+       snprintf(path, sizeof(path), "net/ipv6/conf/%s", dev_name);
 
-       addrconf_ctl_path[ADDRCONF_CTL_PATH_DEV].procname = t->dev_name;
-
-       t->sysctl_header = register_net_sysctl_table(net, addrconf_ctl_path,
-                       t->addrconf_vars);
+       t->sysctl_header = register_net_sysctl(net, path, t->addrconf_vars);
        if (t->sysctl_header == NULL)
-               goto free_procname;
+               goto free;
 
        p->sysctl = t;
        return 0;
 
-free_procname:
-       kfree(t->dev_name);
 free:
        kfree(t);
 out:
        t = p->sysctl;
        p->sysctl = NULL;
        unregister_net_sysctl_table(t->sysctl_header);
-       kfree(t->dev_name);
        kfree(t);
 }