u32 pid);
 static void neigh_update_notify(struct neighbour *neigh, u32 nlmsg_pid);
 static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
-                                   struct net_device *dev);
+                                   struct net_device *dev,
+                                   bool skip_perm);
 
 #ifdef CONFIG_PROC_FS
 static const struct seq_operations neigh_stat_seq_ops;
 {
        write_lock_bh(&tbl->lock);
        neigh_flush_dev(tbl, dev, skip_perm);
-       pneigh_ifdown_and_unlock(tbl, dev);
+       pneigh_ifdown_and_unlock(tbl, dev, skip_perm);
        pneigh_queue_purge(&tbl->proxy_queue, dev ? dev_net(dev) : NULL,
                           tbl->family);
        if (skb_queue_empty_lockless(&tbl->proxy_queue))
 }
 
 static int pneigh_ifdown_and_unlock(struct neigh_table *tbl,
-                                   struct net_device *dev)
+                                   struct net_device *dev,
+                                   bool skip_perm)
 {
        struct pneigh_entry *n, **np, *freelist = NULL;
        u32 h;
        for (h = 0; h <= PNEIGH_HASHMASK; h++) {
                np = &tbl->phash_buckets[h];
                while ((n = *np) != NULL) {
+                       if (skip_perm && n->permanent)
+                               goto skip;
                        if (!dev || n->dev == dev) {
                                *np = n->next;
                                n->next = freelist;
                                freelist = n;
                                continue;
                        }
+skip:
                        np = &n->next;
                }
        }
                pn = pneigh_lookup(tbl, net, dst, dev, 1);
                if (pn) {
                        pn->flags = ndm_flags;
+                       pn->permanent = !!(ndm->ndm_state & NUD_PERMANENT);
                        if (protocol)
                                pn->protocol = protocol;
                        err = 0;