kernels/linux-2.4.0/drivers/net/pppoe.c
/***************************************************************************
 *
 *  Handler for device events.
 *  Certain device events require that sockets be unconnected.
 *
 **************************************************************************/
Handler for device events.
Certain device events require that sockets be unconnected.
Handler for device events . Certain device events require that sockets be unconnected .
static int pppoe_device_event(struct notifier_block *this,
			      unsigned long event, void *ptr)
{
	int error = NOTIFY_DONE;
	struct net_device *dev = (struct net_device *) ptr;
	struct pppox_opt *po = NULL;
	int hash = 0;
	switch (event) {
	case NETDEV_CHANGEMTU:
	case NETDEV_GOING_DOWN:
	case NETDEV_DOWN:
		read_lock_bh(&pppoe_hash_lock);
		while (!po && hash < PPPOE_HASH_SIZE){
			po = item_hash_table[hash];
			++hash;
		}
		while (po && hash < PPPOE_HASH_SIZE){
			if(po->pppoe_dev == dev){
				lock_sock(po->sk);
				if (po->sk->state & (PPPOX_CONNECTED|PPPOX_BOUND)){
					pppox_unbind_sock(po->sk);
					dev_put(po->pppoe_dev);
					po->pppoe_dev = NULL;
					po->sk->state = PPPOX_DEAD;
					po->sk->state_change(po->sk);
				}
 				release_sock(po->sk);
			}
			if (po->next) {
				po = po->next;
			} else {
				po = NULL;
				while (!po && hash < PPPOE_HASH_SIZE){
					po = item_hash_table[hash];
					++hash;
				}
			}
		}
		read_unlock_bh(&pppoe_hash_lock);
		break;
	default:
		break;
	};
	return error;
}
static int pppoe_device_event ( struct notifier_block * this , unsigned long event , void * ptr ) { int error = NOTIFY_DONE ; struct net_device * dev = ( struct net_device * ) ptr ; struct pppox_opt * po = NULL ; int hash = 0 ; switch ( event ) { case NETDEV_CHANGEMTU : case NETDEV_GOING_DOWN : case NETDEV_DOWN : read_lock_bh ( & pppoe_hash_lock ) ; while ( ! po && hash < PPPOE_HASH_SIZE ) { po = item_hash_table [ hash ] ; ++ hash ; } while ( po && hash < PPPOE_HASH_SIZE ) { if ( po -> pppoe_dev == dev ) { lock_sock ( po -> sk ) ; if ( po -> sk -> state & ( PPPOX_CONNECTED | PPPOX_BOUND ) ) { pppox_unbind_sock ( po -> sk ) ; dev_put ( po -> pppoe_dev ) ; po -> pppoe_dev = NULL ; po -> sk -> state = PPPOX_DEAD ; po -> sk -> state_change ( po -> sk ) ; } release_sock ( po -> sk ) ; } if ( po -> next ) { po = po -> next ; } else { po = NULL ; while ( ! po && hash < PPPOE_HASH_SIZE ) { po = item_hash_table [ hash ] ; ++ hash ; } } } read_unlock_bh ( & pppoe_hash_lock ) ; break ; default : break ; } ; return error ; }
Handler for device events.
Handler for device events .
/* Only look at sockets that are using this specific device. */ /* A change in mtu is a bad thing, requiring
	     * LCP re-negotiation.
	     */ /* Find every socket on this device and kill it. */