__be32 clusterip;                       /* the IP address */
        u_int8_t clustermac[ETH_ALEN];          /* the MAC address */
-       struct net_device *dev;                 /* device */
+       int ifindex;                            /* device ifindex */
        u_int16_t num_total_nodes;              /* total number of nodes */
        unsigned long local_nodes;              /* node number array */
 
        enum clusterip_hashmode hash_mode;      /* which hashing mode */
        u_int32_t hash_initval;                 /* hash initialization */
        struct rcu_head rcu;
+
+       char ifname[IFNAMSIZ];                  /* device ifname */
+       struct notifier_block notifier;         /* refresh c->ifindex in it */
 };
 
 #ifdef CONFIG_PROC_FS
  * entry(rule) is removed, remove the config from lists, but don't free it
  * yet, since proc-files could still be holding references */
 static inline void
-clusterip_config_entry_put(struct clusterip_config *c)
+clusterip_config_entry_put(struct net *net, struct clusterip_config *c)
 {
-       struct net *net = dev_net(c->dev);
        struct clusterip_net *cn = net_generic(net, clusterip_net_id);
 
        local_bh_disable();
                spin_unlock(&cn->lock);
                local_bh_enable();
 
-               dev_mc_del(c->dev, c->clustermac);
-               dev_put(c->dev);
+               unregister_netdevice_notifier(&c->notifier);
 
                /* In case anyone still accesses the file, the open/close
                 * functions are also incrementing the refcount on their own,
                set_bit(i->local_nodes[n] - 1, &c->local_nodes);
 }
 
-static struct clusterip_config *
-clusterip_config_init(const struct ipt_clusterip_tgt_info *i, __be32 ip,
-                     struct net_device *dev)
+static int
+clusterip_netdev_event(struct notifier_block *this, unsigned long event,
+                      void *ptr)
 {
-       struct net *net = dev_net(dev);
+       struct net_device *dev = netdev_notifier_info_to_dev(ptr);
        struct clusterip_config *c;
+
+       c = container_of(this, struct clusterip_config, notifier);
+       switch (event) {
+       case NETDEV_REGISTER:
+               if (!strcmp(dev->name, c->ifname)) {
+                       c->ifindex = dev->ifindex;
+                       dev_mc_add(dev, c->clustermac);
+               }
+               break;
+       case NETDEV_UNREGISTER:
+               if (dev->ifindex == c->ifindex) {
+                       dev_mc_del(dev, c->clustermac);
+                       c->ifindex = -1;
+               }
+               break;
+       case NETDEV_CHANGENAME:
+               if (!strcmp(dev->name, c->ifname)) {
+                       c->ifindex = dev->ifindex;
+                       dev_mc_add(dev, c->clustermac);
+               } else if (dev->ifindex == c->ifindex) {
+                       dev_mc_del(dev, c->clustermac);
+                       c->ifindex = -1;
+               }
+               break;
+       }
+
+       return NOTIFY_DONE;
+}
+
+static struct clusterip_config *
+clusterip_config_init(struct net *net, const struct ipt_clusterip_tgt_info *i,
+                     __be32 ip, const char *iniface)
+{
        struct clusterip_net *cn = net_generic(net, clusterip_net_id);
+       struct clusterip_config *c;
+       int err;
 
        c = kzalloc(sizeof(*c), GFP_ATOMIC);
        if (!c)
                return ERR_PTR(-ENOMEM);
 
-       c->dev = dev;
+       strcpy(c->ifname, iniface);
+       c->ifindex = -1;
        c->clusterip = ip;
        memcpy(&c->clustermac, &i->clustermac, ETH_ALEN);
        c->num_total_nodes = i->num_total_nodes;
                                          cn->procdir,
                                          &clusterip_proc_fops, c);
                if (!c->pde) {
-                       spin_lock_bh(&cn->lock);
-                       list_del_rcu(&c->list);
-                       spin_unlock_bh(&cn->lock);
-                       kfree(c);
-
-                       return ERR_PTR(-ENOMEM);
+                       err = -ENOMEM;
+                       goto err;
                }
        }
 #endif
 
-       return c;
+       c->notifier.notifier_call = clusterip_netdev_event;
+       err = register_netdevice_notifier(&c->notifier);
+       if (!err)
+               return c;
+
+#ifdef CONFIG_PROC_FS
+       proc_remove(c->pde);
+err:
+#endif
+       spin_lock_bh(&cn->lock);
+       list_del_rcu(&c->list);
+       spin_unlock_bh(&cn->lock);
+       kfree(c);
+
+       return ERR_PTR(err);
 }
 
 #ifdef CONFIG_PROC_FS
                                        e->ip.iniface);
                                return -ENOENT;
                        }
+                       dev_put(dev);
 
-                       config = clusterip_config_init(cipinfo,
-                                                       e->ip.dst.s_addr, dev);
-                       if (IS_ERR(config)) {
-                               dev_put(dev);
+                       config = clusterip_config_init(par->net, cipinfo,
+                                                      e->ip.dst.s_addr,
+                                                      e->ip.iniface);
+                       if (IS_ERR(config))
                                return PTR_ERR(config);
-                       }
-                       dev_mc_add(config->dev, config->clustermac);
                }
        }
        cipinfo->config = config;
 
        /* if no more entries are referencing the config, remove it
         * from the list and destroy the proc entry */
-       clusterip_config_entry_put(cipinfo->config);
+       clusterip_config_entry_put(par->net, cipinfo->config);
 
        clusterip_config_put(cipinfo->config);
 
         * addresses on different interfacs.  However, in the CLUSTERIP case
         * this wouldn't work, since we didn't subscribe the mcast group on
         * other interfaces */
-       if (c->dev != state->out) {
-               pr_debug("not mangling arp reply on different "
-                        "interface: cip'%s'-skb'%s'\n",
-                        c->dev->name, state->out->name);
+       if (c->ifindex != state->out->ifindex) {
+               pr_debug("not mangling arp reply on different interface: cip'%d'-skb'%d'\n",
+                        c->ifindex, state->out->ifindex);
                clusterip_config_put(c);
                return NF_ACCEPT;
        }