Commit dfc0a507 authored by Michal Ostrowski's avatar Michal Ostrowski Committed by David S. Miller

[PPPOE]: Fix connect handling.

parent 27114580
...@@ -2028,9 +2028,11 @@ config PPPOE ...@@ -2028,9 +2028,11 @@ config PPPOE
help help
Support for PPP over Ethernet. Support for PPP over Ethernet.
This driver requires a specially patched pppd daemon. The patch to This driver requires the latest version of pppd from the CVS
pppd, along with binaries of a patched pppd package can be found at: repository at cvs.samba.org. Alternatively, see the
<http://www.shoshin.uwaterloo.ca/~mostrows/>. RoaringPenguin package (http://www.roaringpenguin.com/pppoe)
which contains instruction on how to use this driver (under
the heading "Kernel mode PPPoE").
config PPPOATM config PPPOATM
tristate "PPP over ATM" tristate "PPP over ATM"
......
...@@ -5,15 +5,15 @@ ...@@ -5,15 +5,15 @@
* PPPoE --- PPP over Ethernet (RFC 2516) * PPPoE --- PPP over Ethernet (RFC 2516)
* *
* *
* Version: 0.6.11 * Version: 0.7.0
* *
* 220102 : Fix module use count on failure in pppoe_create, pppox_sk -acme * 220102 : Fix module use count on failure in pppoe_create, pppox_sk -acme
* 030700 : Fixed connect logic to allow for disconnect. * 030700 : Fixed connect logic to allow for disconnect.
* 270700 : Fixed potential SMP problems; we must protect against * 270700 : Fixed potential SMP problems; we must protect against
* simultaneous invocation of ppp_input * simultaneous invocation of ppp_input
* and ppp_unregister_channel. * and ppp_unregister_channel.
* 040800 : Respect reference count mechanisms on net-devices. * 040800 : Respect reference count mechanisms on net-devices.
* 200800 : fix kfree(skb) in pppoe_rcv (acme) * 200800 : fix kfree(skb) in pppoe_rcv (acme)
* Module reference count is decremented in the right spot now, * Module reference count is decremented in the right spot now,
* guards against sock_put not actually freeing the sk * guards against sock_put not actually freeing the sk
* in pppoe_release. * in pppoe_release.
...@@ -30,13 +30,14 @@ ...@@ -30,13 +30,14 @@
* the original skb that was passed in on success, never on * the original skb that was passed in on success, never on
* failure. Delete the copy of the skb on failure to avoid * failure. Delete the copy of the skb on failure to avoid
* a memory leak. * a memory leak.
* 081001 : Misc. cleanup (licence string, non-blocking, prevent * 081001 : Misc. cleanup (licence string, non-blocking, prevent
* reference of device on close). * reference of device on close).
* 121301 : New ppp channels interface; cannot unregister a channel * 121301 : New ppp channels interface; cannot unregister a channel
* from interrupts. Thus, we mark the socket as a ZOMBIE * from interrupts. Thus, we mark the socket as a ZOMBIE
* and do the unregistration later. * and do the unregistration later.
* 081002 : seq_file support for proc stuff -acme * 081002 : seq_file support for proc stuff -acme
* * 111602 : Merge all 2.4 fixes into 2.5/2.6 tree. Label 2.5/2.6
* as version 0.7. Spacing cleanup.
* Author: Michal Ostrowski <mostrows@speakeasy.net> * Author: Michal Ostrowski <mostrows@speakeasy.net>
* Contributors: * Contributors:
* Arnaldo Carvalho de Melo <acme@conectiva.com.br> * Arnaldo Carvalho de Melo <acme@conectiva.com.br>
...@@ -381,8 +382,8 @@ int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb) ...@@ -381,8 +382,8 @@ int pppoe_rcv_core(struct sock *sk, struct sk_buff *skb)
* *
***********************************************************************/ ***********************************************************************/
static int pppoe_rcv(struct sk_buff *skb, static int pppoe_rcv(struct sk_buff *skb,
struct net_device *dev, struct net_device *dev,
struct packet_type *pt) struct packet_type *pt)
{ {
struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw; struct pppoe_hdr *ph = (struct pppoe_hdr *) skb->nh.raw;
...@@ -398,7 +399,7 @@ static int pppoe_rcv(struct sk_buff *skb, ...@@ -398,7 +399,7 @@ static int pppoe_rcv(struct sk_buff *skb,
} }
sk = po->sk; sk = po->sk;
bh_lock_sock(sk); bh_lock_sock(sk);
/* Socket state is unknown, must put skb into backlog. */ /* Socket state is unknown, must put skb into backlog. */
if (sock_owned_by_user(sk) != 0) { if (sock_owned_by_user(sk) != 0) {
...@@ -443,8 +444,10 @@ static int pppoe_disc_rcv(struct sk_buff *skb, ...@@ -443,8 +444,10 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
* what kind of SKB it is during backlog rcv. * what kind of SKB it is during backlog rcv.
*/ */
if (sock_owned_by_user(sk) == 0) { if (sock_owned_by_user(sk) == 0) {
/* We're no longer connect at the PPPOE layer,
* and must wait for ppp channel to disconnect us.
*/
sk->state = PPPOX_ZOMBIE; sk->state = PPPOX_ZOMBIE;
pppox_unbind_sock(sk);
} }
bh_unlock_sock(sk); bh_unlock_sock(sk);
...@@ -583,8 +586,7 @@ int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, ...@@ -583,8 +586,7 @@ int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
if ((sk->state & PPPOX_CONNECTED) && sp->sa_addr.pppoe.sid) if ((sk->state & PPPOX_CONNECTED) && sp->sa_addr.pppoe.sid)
goto end; goto end;
/* Check for already disconnected sockets, /* Check for already disconnected sockets, on attempts to disconnect */
on attempts to disconnect */
error = -EALREADY; error = -EALREADY;
if((sk->state & PPPOX_DEAD) && !sp->sa_addr.pppoe.sid ) if((sk->state & PPPOX_DEAD) && !sp->sa_addr.pppoe.sid )
goto end; goto end;
...@@ -596,7 +598,8 @@ int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, ...@@ -596,7 +598,8 @@ int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
/* Delete the old binding */ /* Delete the old binding */
delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote); delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote);
dev_put(po->pppoe_dev); if(po->pppoe_dev)
dev_put(po->pppoe_dev);
memset(po, 0, sizeof(struct pppox_opt)); memset(po, 0, sizeof(struct pppox_opt));
po->sk = sk; po->sk = sk;
...@@ -994,7 +997,7 @@ static int pppoe_seq_show(struct seq_file *seq, void *v) ...@@ -994,7 +997,7 @@ static int pppoe_seq_show(struct seq_file *seq, void *v)
po->pppoe_pa.remote[2], po->pppoe_pa.remote[3], po->pppoe_pa.remote[2], po->pppoe_pa.remote[3],
po->pppoe_pa.remote[4], po->pppoe_pa.remote[5], dev_name); po->pppoe_pa.remote[4], po->pppoe_pa.remote[5], dev_name);
out: out:
return 0; return 0;
} }
static __inline__ struct pppox_opt *pppoe_get_idx(loff_t pos) static __inline__ struct pppox_opt *pppoe_get_idx(loff_t pos)
...@@ -1064,10 +1067,10 @@ static int pppoe_seq_open(struct inode *inode, struct file *file) ...@@ -1064,10 +1067,10 @@ static int pppoe_seq_open(struct inode *inode, struct file *file)
} }
static struct file_operations pppoe_seq_fops = { static struct file_operations pppoe_seq_fops = {
.open = pppoe_seq_open, .open = pppoe_seq_open,
.read = seq_read, .read = seq_read,
.llseek = seq_lseek, .llseek = seq_lseek,
.release = seq_release, .release = seq_release,
}; };
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
......
...@@ -5,9 +5,9 @@ ...@@ -5,9 +5,9 @@
* PPPoE --- PPP over Ethernet (RFC 2516) * PPPoE --- PPP over Ethernet (RFC 2516)
* *
* *
* Version: 0.5.1 * Version: 0.5.2
* *
* Author: Michal Ostrowski <mostrows@styx.uwaterloo.ca> * Author: Michal Ostrowski <mostrows@speakeasy.net>
* *
* 051000 : Initialization cleanup * 051000 : Initialization cleanup
* *
...@@ -56,8 +56,8 @@ int register_pppox_proto(int proto_num, struct pppox_proto *pp) ...@@ -56,8 +56,8 @@ int register_pppox_proto(int proto_num, struct pppox_proto *pp)
void unregister_pppox_proto(int proto_num) void unregister_pppox_proto(int proto_num)
{ {
if (proto_num >= 0 && proto_num <= PX_MAX_PROTO) { if (proto_num >= 0 && proto_num <= PX_MAX_PROTO) {
proto[proto_num] = NULL; proto[proto_num] = NULL;
MOD_DEC_USE_COUNT; MOD_DEC_USE_COUNT;
} }
} }
...@@ -65,9 +65,9 @@ void pppox_unbind_sock(struct sock *sk) ...@@ -65,9 +65,9 @@ void pppox_unbind_sock(struct sock *sk)
{ {
/* Clear connection to ppp device, if attached. */ /* Clear connection to ppp device, if attached. */
if (sk->state & PPPOX_BOUND) { if (sk->state & (PPPOX_BOUND|PPPOX_ZOMBIE)) {
ppp_unregister_channel(&pppox_sk(sk)->chan); ppp_unregister_channel(&pppox_sk(sk)->chan);
sk->state &= ~PPPOX_BOUND; sk->state = PPPOX_DEAD;
} }
} }
...@@ -75,7 +75,7 @@ EXPORT_SYMBOL(register_pppox_proto); ...@@ -75,7 +75,7 @@ EXPORT_SYMBOL(register_pppox_proto);
EXPORT_SYMBOL(unregister_pppox_proto); EXPORT_SYMBOL(unregister_pppox_proto);
EXPORT_SYMBOL(pppox_unbind_sock); EXPORT_SYMBOL(pppox_unbind_sock);
static int pppox_ioctl(struct socket* sock, unsigned int cmd, static int pppox_ioctl(struct socket* sock, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
struct sock *sk = sock->sk; struct sock *sk = sock->sk;
...@@ -117,10 +117,10 @@ static int pppox_create(struct socket *sock, int protocol) ...@@ -117,10 +117,10 @@ static int pppox_create(struct socket *sock, int protocol)
int err = 0; int err = 0;
if (protocol < 0 || protocol > PX_MAX_PROTO) if (protocol < 0 || protocol > PX_MAX_PROTO)
return -EPROTOTYPE; return -EPROTOTYPE;
if (proto[protocol] == NULL) if (proto[protocol] == NULL)
return -EPROTONOSUPPORT; return -EPROTONOSUPPORT;
err = (*proto[protocol]->create)(sock); err = (*proto[protocol]->create)(sock);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment