Beispiel #1
0
void ssh_interceptor_iface_uninit(SshInterceptor interceptor)
{
  /* Clear interface table and release net_device references. */
  ssh_interceptor_clear_ifaces(interceptor);

  if (interceptor->nf->iface_notifiers_installed == FALSE)
    return;

  SSH_ASSERT(in_softirq());
  local_bh_enable();
  SSH_ASSERT(!in_softirq());

  /* Unregister notifier callback */
  unregister_netdevice_notifier(&interceptor->nf->notifier_netdev);
  unregister_inetaddr_notifier(&interceptor->nf->notifier_inetaddr);
#ifdef SSH_LINUX_INTERCEPTOR_IPV6
  unregister_inet6addr_notifier(&interceptor->nf->notifier_inet6addr);
#endif /* SSH_LINUX_INTERCEPTOR_IPV6 */

  local_bh_disable();

  /* Due to lack of proper locking in linux kernel notifier code, 
     the unregister_*_notifier functions might leave the notifier 
     blocks out of sync, resulting in that the kernel may call an
     unregistered notifier function.

     Sleep for a while to decrease the possibility of the bug causing
     trouble (crash during module unloading). */
  mdelay(500);
  
  interceptor->nf->iface_notifiers_installed = FALSE;
}
Beispiel #2
0
Datei: core.c Projekt: gxt/linux
void brcmf_detach(struct device *dev)
{
	s32 i;
	struct brcmf_bus *bus_if = dev_get_drvdata(dev);
	struct brcmf_pub *drvr = bus_if->drvr;

	brcmf_dbg(TRACE, "Enter\n");

	if (drvr == NULL)
		return;

#ifdef CONFIG_INET
	unregister_inetaddr_notifier(&drvr->inetaddr_notifier);
#endif

#if IS_ENABLED(CONFIG_IPV6)
	unregister_inet6addr_notifier(&drvr->inet6addr_notifier);
#endif

	/* stop firmware event handling */
	brcmf_fweh_detach(drvr);
	if (drvr->config)
		brcmf_p2p_detach(&drvr->config->p2p);

	brcmf_bus_change_state(bus_if, BRCMF_BUS_DOWN);

	/* make sure primary interface removed last */
	for (i = BRCMF_MAX_IFS-1; i > -1; i--)
		brcmf_remove_interface(drvr->iflist[i], false);

	brcmf_cfg80211_detach(drvr->config);

	brcmf_fws_deinit(drvr);

	brcmf_bus_detach(drvr);

	brcmf_proto_detach(drvr);

	brcmf_debug_detach(drvr);
	bus_if->drvr = NULL;
	kfree(drvr);
}