Exemple #1
0
static void pppoe_flush_dev(struct net_device *dev)
{
	int hash;

	BUG_ON(dev == NULL);

	read_lock_bh(&pppoe_hash_lock);
	for (hash = 0; hash < PPPOE_HASH_SIZE; hash++) {
		struct pppox_sock *po = item_hash_table[hash];

		while (po != NULL) {
			if (po->pppoe_dev == dev) {
				struct sock *sk = sk_pppox(po);

				sock_hold(sk);
				po->pppoe_dev = NULL;

				/* We hold a reference to SK, now drop the
				 * hash table lock so that we may attempt
				 * to lock the socket (which can sleep).
				 */
				read_unlock_bh(&pppoe_hash_lock);

				lock_sock(sk);

				if (sk->sk_state &
				    (PPPOX_CONNECTED | PPPOX_BOUND)) {
					pppox_unbind_sock(sk);
					dev_put(dev);
					sk->sk_state = PPPOX_ZOMBIE;
					sk->sk_state_change(sk);
				}

				release_sock(sk);

				sock_put(sk);

				read_lock_bh(&pppoe_hash_lock);

				/* Now restart from the beginning of this
				 * hash chain.  We always NULL out pppoe_dev
				 * so we are guaranteed to make forward
				 * progress.
				 */
				po = item_hash_table[hash];
				continue;
			}
			po = po->next;
		}
	}
	read_unlock_bh(&pppoe_hash_lock);
}
Exemple #2
0
/**********************************************************************
 *
 *  Set/get/delete/rehash items
 *
 **********************************************************************/
static inline struct pppox_sock *get_item(unsigned long sid,
					 unsigned char *addr)
{
	struct pppox_sock *po;

	read_lock_bh(&pppoe_hash_lock);
	po = __get_item(sid, addr);
	if (po)
		sock_hold(sk_pppox(po));
	read_unlock_bh(&pppoe_hash_lock);

	return po;
}
Exemple #3
0
static inline struct pppox_sock *dzc_get_item(struct pppoe_net *pn, __be16 sid,
					unsigned char *addr, int ifindex)
{
	struct pppox_sock *po;

	read_lock_bh(&pn->hash_lock);
	po = __get_item(pn, sid, addr, ifindex);
	if (po)
		sock_hold(sk_pppox(po));
	read_unlock_bh(&pn->hash_lock);

	return po;
}
static struct pppox_sock *lookup_chan(u16 call_id, __be32 s_addr)
{
	struct pppox_sock *sock;
	struct pptp_opt *opt;

	rcu_read_lock();
	sock = rcu_dereference(callid_sock[call_id]);
	if (sock) {
		opt = &sock->proto.pptp;
		if (opt->dst_addr.sin_addr.s_addr != s_addr)
			sock = NULL;
		else
			sock_hold(sk_pppox(sock));
	}
	rcu_read_unlock();

	return sock;
}
Exemple #5
0
static void pppoe_dzc_flush_dev(struct net_device *dev)
{
	struct pppoe_net *pn;
	int i;

	pn = dzc_pppoe_pernet(dev_net(dev));
	write_lock_bh(&pn->hash_lock);
	for (i = 0; i < (1 << 4); i++) {
		struct pppox_sock *po = pn->hash_table[i];
		struct sock *sk;

		while (po) {
			while (po && po->pppoe_dev != dev) {
				po = po->next;
			}

			if (!po)
				break;

			sk = sk_pppox(po);
			
			sock_hold(sk);
			write_unlock_bh(&pn->hash_lock);
			lock_sock(sk);

			if (po->pppoe_dev == dev &&
			    sk->sk_state & (PPPOX_CONNECTED | PPPOX_BOUND | PPPOX_ZOMBIE)) {
				pppox_unbind_sock(sk);
				sk->sk_state = PPPOX_ZOMBIE;
				sk->sk_state_change(sk);
				po->pppoe_dev = NULL;
				dev_put(dev);
			}

			release_sock(sk);
			sock_put(sk);

			BUG_ON(dzc_pppoe_pernet(dev_net(dev)) == NULL);
			write_lock_bh(&pn->hash_lock);
			po = pn->hash_table[i];
		}
	}
	write_unlock_bh(&pn->hash_lock);
}