extern void ip_rt_redirect(__be32 old_gw, __be32 dst, __be32 new_gw,
__be32 src, struct net_device *dev);
extern void rt_cache_flush(struct net *net, int how);
+extern void rt_cache_flush_batch(void);
extern int __ip_route_output_key(struct net *, struct rtable **, const struct flowi *flp);
extern int ip_route_output_key(struct net *, struct rtable **, struct flowi *flp);
extern int ip_route_output_flow(struct net *, struct rtable **rp, struct flowi *flp, struct sock *sk, int flags);
nb->notifier_call(nb, NETDEV_DOWN, dev);
}
nb->notifier_call(nb, NETDEV_UNREGISTER, dev);
- nb->notifier_call(nb, NETDEV_UNREGISTER_PERNET, dev);
+ nb->notifier_call(nb, NETDEV_UNREGISTER_BATCH, dev);
}
}
static void rollback_registered_many(struct list_head *head)
{
- struct net_device *dev, *aux, *fdev;
- LIST_HEAD(pernet_list);
+ struct net_device *dev;
BUG_ON(dev_boot_phase);
ASSERT_RTNL();
netdev_unregister_kobject(dev);
}
- synchronize_net();
+ /* Process any work delayed until the end of the batch */
+ dev = list_entry(head->next, struct net_device, unreg_list);
+ call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
- list_for_each_entry_safe(dev, aux, head, unreg_list) {
- int new_net = 1;
- list_for_each_entry(fdev, &pernet_list, unreg_list) {
- if (net_eq(dev_net(dev), dev_net(fdev))) {
- new_net = 0;
- dev_put(dev);
- break;
- }
- }
- if (new_net)
- list_move(&dev->unreg_list, &pernet_list);
- }
+ synchronize_net();
- list_for_each_entry_safe(dev, aux, &pernet_list, unreg_list) {
- call_netdevice_notifiers(NETDEV_UNREGISTER_PERNET, dev);
- list_move(&dev->unreg_list, head);
+ list_for_each_entry(dev, head, unreg_list)
dev_put(dev);
- }
}
static void rollback_registered(struct net_device *dev)
/* Rebroadcast unregister notification */
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
- /* don't resend NETDEV_UNREGISTER_PERNET, _PERNET users
+ /* don't resend NETDEV_UNREGISTER_BATCH, _BATCH users
* should have already handle it the first time */
if (test_bit(__LINK_STATE_LINKWATCH_PENDING,
/**
* unregister_netdevice_many - unregister many devices
* @head: list of devices
- *
- * WARNING: Calling this modifies the given list
- * (in rollback_registered_many). It may change the order of the elements
- * in the list. However, you can assume it does not add or delete elements
- * to/from the list.
*/
void unregister_netdevice_many(struct list_head *head)
{
this device. They should clean all the things.
*/
call_netdevice_notifiers(NETDEV_UNREGISTER, dev);
- call_netdevice_notifiers(NETDEV_UNREGISTER_PERNET, dev);
+ call_netdevice_notifiers(NETDEV_UNREGISTER_BATCH, dev);
/*
* Flush the unicast and multicast chains