*     Multicast router control variables
  */
 
-static struct vif_device vif_table[MAXVIFS];           /* Devices              */
-static int maxvif;
-
-#define VIF_EXISTS(idx) (vif_table[idx].dev != NULL)
+#define VIF_EXISTS(_net, _idx) ((_net)->ipv4.vif_table[_idx].dev != NULL)
 
 static int mroute_do_assert;                           /* Set in PIM assert    */
 static int mroute_do_pim;
        struct net_device *dev;
        struct in_device *in_dev;
 
-       if (vifi < 0 || vifi >= maxvif)
+       if (vifi < 0 || vifi >= init_net.ipv4.maxvif)
                return -EADDRNOTAVAIL;
 
-       v = &vif_table[vifi];
+       v = &init_net.ipv4.vif_table[vifi];
 
        write_lock_bh(&mrt_lock);
        dev = v->dev;
                reg_vif_num = -1;
 #endif
 
-       if (vifi+1 == maxvif) {
+       if (vifi+1 == init_net.ipv4.maxvif) {
                int tmp;
                for (tmp=vifi-1; tmp>=0; tmp--) {
-                       if (VIF_EXISTS(tmp))
+                       if (VIF_EXISTS(&init_net, tmp))
                                break;
                }
-               maxvif = tmp+1;
+               init_net.ipv4.maxvif = tmp+1;
        }
 
        write_unlock_bh(&mrt_lock);
        cache->mfc_un.res.maxvif = 0;
        memset(cache->mfc_un.res.ttls, 255, MAXVIFS);
 
-       for (vifi=0; vifi<maxvif; vifi++) {
-               if (VIF_EXISTS(vifi) && ttls[vifi] && ttls[vifi] < 255) {
+       for (vifi = 0; vifi < init_net.ipv4.maxvif; vifi++) {
+               if (VIF_EXISTS(&init_net, vifi) &&
+                   ttls[vifi] && ttls[vifi] < 255) {
                        cache->mfc_un.res.ttls[vifi] = ttls[vifi];
                        if (cache->mfc_un.res.minvif > vifi)
                                cache->mfc_un.res.minvif = vifi;
 static int vif_add(struct vifctl *vifc, int mrtsock)
 {
        int vifi = vifc->vifc_vifi;
-       struct vif_device *v = &vif_table[vifi];
+       struct vif_device *v = &init_net.ipv4.vif_table[vifi];
        struct net_device *dev;
        struct in_device *in_dev;
        int err;
 
        /* Is vif busy ? */
-       if (VIF_EXISTS(vifi))
+       if (VIF_EXISTS(&init_net, vifi))
                return -EADDRINUSE;
 
        switch (vifc->vifc_flags) {
        if (v->flags&VIFF_REGISTER)
                reg_vif_num = vifi;
 #endif
-       if (vifi+1 > maxvif)
-               maxvif = vifi+1;
+       if (vifi+1 > init_net.ipv4.maxvif)
+               init_net.ipv4.maxvif = vifi+1;
        write_unlock_bh(&mrt_lock);
        return 0;
 }
        /*
         *      Shut down all active vif entries
         */
-       for (i=0; i<maxvif; i++) {
-               if (!(vif_table[i].flags&VIFF_STATIC))
+       for (i = 0; i < init_net.ipv4.maxvif; i++) {
+               if (!(init_net.ipv4.vif_table[i].flags&VIFF_STATIC))
                        vif_delete(i, 0);
        }
 
        case SIOCGETVIFCNT:
                if (copy_from_user(&vr, arg, sizeof(vr)))
                        return -EFAULT;
-               if (vr.vifi >= maxvif)
+               if (vr.vifi >= init_net.ipv4.maxvif)
                        return -EINVAL;
                read_lock(&mrt_lock);
-               vif=&vif_table[vr.vifi];
-               if (VIF_EXISTS(vr.vifi))        {
+               vif = &init_net.ipv4.vif_table[vr.vifi];
+               if (VIF_EXISTS(&init_net, vr.vifi)) {
                        vr.icount = vif->pkt_in;
                        vr.ocount = vif->pkt_out;
                        vr.ibytes = vif->bytes_in;
 
        if (event != NETDEV_UNREGISTER)
                return NOTIFY_DONE;
-       v=&vif_table[0];
-       for (ct=0; ct<maxvif; ct++,v++) {
+       v = &init_net.ipv4.vif_table[0];
+       for (ct = 0; ct < init_net.ipv4.maxvif; ct++, v++) {
                if (v->dev == dev)
                        vif_delete(ct, 1);
        }
 static void ipmr_queue_xmit(struct sk_buff *skb, struct mfc_cache *c, int vifi)
 {
        const struct iphdr *iph = ip_hdr(skb);
-       struct vif_device *vif = &vif_table[vifi];
+       struct vif_device *vif = &init_net.ipv4.vif_table[vifi];
        struct net_device *dev;
        struct rtable *rt;
        int    encap = 0;
 static int ipmr_find_vif(struct net_device *dev)
 {
        int ct;
-       for (ct=maxvif-1; ct>=0; ct--) {
-               if (vif_table[ct].dev == dev)
+       for (ct = init_net.ipv4.maxvif-1; ct >= 0; ct--) {
+               if (init_net.ipv4.vif_table[ct].dev == dev)
                        break;
        }
        return ct;
        /*
         * Wrong interface: drop packet and (maybe) send PIM assert.
         */
-       if (vif_table[vif].dev != skb->dev) {
+       if (init_net.ipv4.vif_table[vif].dev != skb->dev) {
                int true_vifi;
 
                if (skb->rtable->fl.iif == 0) {
                goto dont_forward;
        }
 
-       vif_table[vif].pkt_in++;
-       vif_table[vif].bytes_in += skb->len;
+       init_net.ipv4.vif_table[vif].pkt_in++;
+       init_net.ipv4.vif_table[vif].bytes_in += skb->len;
 
        /*
         *      Forward the frame
 
        read_lock(&mrt_lock);
        if (reg_vif_num >= 0)
-               reg_dev = vif_table[reg_vif_num].dev;
+               reg_dev = init_net.ipv4.vif_table[reg_vif_num].dev;
        if (reg_dev)
                dev_hold(reg_dev);
        read_unlock(&mrt_lock);
 {
        int ct;
        struct rtnexthop *nhp;
-       struct net_device *dev = vif_table[c->mfc_parent].dev;
+       struct net_device *dev = init_net.ipv4.vif_table[c->mfc_parent].dev;
        u8 *b = skb_tail_pointer(skb);
        struct rtattr *mp_head;
 
                        nhp = (struct rtnexthop *)skb_put(skb, RTA_ALIGN(sizeof(*nhp)));
                        nhp->rtnh_flags = 0;
                        nhp->rtnh_hops = c->mfc_un.res.ttls[ct];
-                       nhp->rtnh_ifindex = vif_table[ct].dev->ifindex;
+                       nhp->rtnh_ifindex = init_net.ipv4.vif_table[ct].dev->ifindex;
                        nhp->rtnh_len = sizeof(*nhp);
                }
        }
 static struct vif_device *ipmr_vif_seq_idx(struct ipmr_vif_iter *iter,
                                           loff_t pos)
 {
-       for (iter->ct = 0; iter->ct < maxvif; ++iter->ct) {
-               if (!VIF_EXISTS(iter->ct))
+       for (iter->ct = 0; iter->ct < init_net.ipv4.maxvif; ++iter->ct) {
+               if (!VIF_EXISTS(&init_net, iter->ct))
                        continue;
                if (pos-- == 0)
-                       return &vif_table[iter->ct];
+                       return &init_net.ipv4.vif_table[iter->ct];
        }
        return NULL;
 }
        if (v == SEQ_START_TOKEN)
                return ipmr_vif_seq_idx(iter, 0);
 
-       while (++iter->ct < maxvif) {
-               if (!VIF_EXISTS(iter->ct))
+       while (++iter->ct < init_net.ipv4.maxvif) {
+               if (!VIF_EXISTS(&init_net, iter->ct))
                        continue;
-               return &vif_table[iter->ct];
+               return &init_net.ipv4.vif_table[iter->ct];
        }
        return NULL;
 }
 
                seq_printf(seq,
                           "%2Zd %-10s %8ld %7ld  %8ld %7ld %05X %08X %08X\n",
-                          vif - vif_table,
+                          vif - init_net.ipv4.vif_table,
                           name, vif->bytes_in, vif->pkt_in,
                           vif->bytes_out, vif->pkt_out,
                           vif->flags, vif->local, vif->remote);
                                   mfc->mfc_un.res.wrong_if);
                        for (n = mfc->mfc_un.res.minvif;
                             n < mfc->mfc_un.res.maxvif; n++ ) {
-                               if (VIF_EXISTS(n)
-                                  && mfc->mfc_un.res.ttls[n] < 255)
-                               seq_printf(seq,
+                               if (VIF_EXISTS(&init_net, n) &&
+                                   mfc->mfc_un.res.ttls[n] < 255)
+                                       seq_printf(seq,
                                           " %2d:%-3d",
                                           n, mfc->mfc_un.res.ttls[n]);
                        }
 /*
  *     Setup for IP multicast routing
  */
+static int __net_init ipmr_net_init(struct net *net)
+{
+       int err = 0;
+
+       net->ipv4.vif_table = kcalloc(MAXVIFS, sizeof(struct vif_device),
+                                     GFP_KERNEL);
+       if (!net->ipv4.vif_table) {
+               err = -ENOMEM;
+               goto fail;
+       }
+fail:
+       return err;
+}
+
+static void __net_exit ipmr_net_exit(struct net *net)
+{
+       kfree(net->ipv4.vif_table);
+}
+
+static struct pernet_operations ipmr_net_ops = {
+       .init = ipmr_net_init,
+       .exit = ipmr_net_exit,
+};
 
 int __init ip_mr_init(void)
 {
        if (!mrt_cachep)
                return -ENOMEM;
 
+       err = register_pernet_subsys(&ipmr_net_ops);
+       if (err)
+               goto reg_pernet_fail;
+
        setup_timer(&ipmr_expire_timer, ipmr_expire_process, 0);
        err = register_netdevice_notifier(&ip_mr_notifier);
        if (err)
 #endif
 reg_notif_fail:
        del_timer(&ipmr_expire_timer);
+       unregister_pernet_subsys(&ipmr_net_ops);
+reg_pernet_fail:
        kmem_cache_destroy(mrt_cachep);
        return err;
 }