Commit 8fa508b5 authored by David S. Miller's avatar David S. Miller

Merge bk://kernel.bkbits.net/acme/net-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents f31ab861 9614c538
...@@ -471,16 +471,15 @@ struct packet_type pppoed_ptype = { ...@@ -471,16 +471,15 @@ struct packet_type pppoed_ptype = {
/*********************************************************************** /***********************************************************************
* *
* Really kill the socket. (Called from sock_put if refcnt == 0.) * Really kill the socket. (Called from pppox_sk_free if refcnt == 0.)
* *
**********************************************************************/ **********************************************************************/
void pppoe_sock_destruct(struct sock *sk) static void pppoe_sk_free(struct sock *sk)
{ {
struct pppox_opt *po = pppox_sk(sk); struct pppox_opt *po = pppox_sk(sk);
if (po) if (po)
kfree(po); kfree(po);
MOD_DEC_USE_COUNT;
} }
...@@ -495,26 +494,16 @@ static int pppoe_create(struct socket *sock) ...@@ -495,26 +494,16 @@ static int pppoe_create(struct socket *sock)
struct sock *sk; struct sock *sk;
struct pppox_opt *po; struct pppox_opt *po;
MOD_INC_USE_COUNT; sk = pppox_sk_alloc(sock, PX_PROTO_OE, GFP_KERNEL, 1, NULL);
sk = sk_alloc(PF_PPPOX, GFP_KERNEL, 1, NULL);
if (!sk) if (!sk)
goto decmod; goto out;
sock_init_data(sock, sk);
sock->state = SS_UNCONNECTED; sock->state = SS_UNCONNECTED;
sock->ops = &pppoe_ops; sock->ops = &pppoe_ops;
sk->protocol = PX_PROTO_OE;
sk->family = PF_PPPOX;
sk->backlog_rcv = pppoe_rcv_core; sk->backlog_rcv = pppoe_rcv_core;
sk->next = NULL;
sk->pprev = NULL;
sk->state = PPPOX_NONE; sk->state = PPPOX_NONE;
sk->type = SOCK_STREAM; sk->type = SOCK_STREAM;
sk->destruct = pppoe_sock_destruct;
po = pppox_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL); po = pppox_sk(sk) = kmalloc(sizeof(*po), GFP_KERNEL);
if (!po) if (!po)
...@@ -522,10 +511,8 @@ static int pppoe_create(struct socket *sock) ...@@ -522,10 +511,8 @@ static int pppoe_create(struct socket *sock)
memset(po, 0, sizeof(*po)); memset(po, 0, sizeof(*po));
po->sk = sk; po->sk = sk;
error = 0; error = 0;
sock->sk = sk;
out: return error; out: return error;
frees: sk_free(sk); frees: sk_free(sk);
decmod: MOD_DEC_USE_COUNT;
goto out; goto out;
} }
...@@ -1075,16 +1062,16 @@ static struct file_operations pppoe_seq_fops = { ...@@ -1075,16 +1062,16 @@ static struct file_operations pppoe_seq_fops = {
}; };
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
/* ->release and ->ioctl are set at pppox_create */
struct proto_ops pppoe_ops = { struct proto_ops pppoe_ops = {
.family = AF_PPPOX, .family = AF_PPPOX,
.release = pppoe_release,
.bind = sock_no_bind, .bind = sock_no_bind,
.connect = pppoe_connect, .connect = pppoe_connect,
.socketpair = sock_no_socketpair, .socketpair = sock_no_socketpair,
.accept = sock_no_accept, .accept = sock_no_accept,
.getname = pppoe_getname, .getname = pppoe_getname,
.poll = datagram_poll, .poll = datagram_poll,
.ioctl = pppoe_ioctl,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = sock_no_shutdown, .shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt, .setsockopt = sock_no_setsockopt,
...@@ -1096,7 +1083,10 @@ struct proto_ops pppoe_ops = { ...@@ -1096,7 +1083,10 @@ struct proto_ops pppoe_ops = {
struct pppox_proto pppoe_proto = { struct pppox_proto pppoe_proto = {
.create = pppoe_create, .create = pppoe_create,
.ioctl = pppoe_ioctl .ioctl = pppoe_ioctl,
.release = pppoe_release,
.sk_free = pppoe_sk_free,
.owner = THIS_MODULE,
}; };
......
...@@ -64,9 +64,45 @@ void pppox_unbind_sock(struct sock *sk) ...@@ -64,9 +64,45 @@ void pppox_unbind_sock(struct sock *sk)
} }
} }
static int pppox_release(struct socket *sock)
{
struct sock *sk = sock->sk;
int rc = pppox_protos[sk->protocol]->release(sock);
module_put(pppox_protos[sk->protocol]->owner);
return rc;
}
static void pppox_sk_free(struct sock *sk)
{
pppox_protos[sk->protocol]->sk_free(sk);
module_put(pppox_protos[sk->protocol]->owner);
}
struct sock *pppox_sk_alloc(struct socket *sock, int protocol, int priority,
int zero_it, kmem_cache_t *slab)
{
struct sock *sk = NULL;
if (!try_module_get(pppox_protos[protocol]->owner))
goto out;
sk = sk_alloc(PF_PPPOX, priority, zero_it, slab);
if (sk) {
sock_init_data(sock, sk);
sk->family = PF_PPPOX;
sk->protocol = protocol;
sk->destruct = pppox_sk_free;
} else
module_put(pppox_protos[protocol]->owner);
out:
return sk;
}
EXPORT_SYMBOL(register_pppox_proto); 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);
EXPORT_SYMBOL(pppox_sk_alloc);
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)
...@@ -116,11 +152,19 @@ static int pppox_create(struct socket *sock, int protocol) ...@@ -116,11 +152,19 @@ static int pppox_create(struct socket *sock, int protocol)
if (!pppox_protos[protocol]) if (!pppox_protos[protocol])
goto out; goto out;
rc = -EBUSY;
if (!try_module_get(pppox_protos[protocol]->owner))
goto out;
rc = pppox_protos[protocol]->create(sock); rc = pppox_protos[protocol]->create(sock);
if (!rc) if (!rc) {
/* We get to set the ioctl handler. */ /* We get to set the ioctl handler. */
/* And the release handler, for module refcounting */
/* For everything else, pppox is just a shell. */ /* For everything else, pppox is just a shell. */
sock->ops->ioctl = pppox_ioctl; sock->ops->ioctl = pppox_ioctl;
sock->ops->release = pppox_release;
} else
module_put(pppox_protos[protocol]->owner);
out: out:
return rc; return rc;
} }
...@@ -128,6 +172,7 @@ static int pppox_create(struct socket *sock, int protocol) ...@@ -128,6 +172,7 @@ static int pppox_create(struct socket *sock, int protocol)
static struct net_proto_family pppox_proto_family = { static struct net_proto_family pppox_proto_family = {
.family = PF_PPPOX, .family = PF_PPPOX,
.create = pppox_create, .create = pppox_create,
.owner = THIS_MODULE,
}; };
static int __init pppox_init(void) static int __init pppox_init(void)
......
...@@ -134,10 +134,15 @@ struct pppox_opt { ...@@ -134,10 +134,15 @@ struct pppox_opt {
#define pppox_sk(__sk) ((struct pppox_opt *)(__sk)->protinfo) #define pppox_sk(__sk) ((struct pppox_opt *)(__sk)->protinfo)
struct module;
struct pppox_proto { struct pppox_proto {
int (*create)(struct socket *sock); int (*create)(struct socket *sock);
int (*ioctl)(struct socket *sock, unsigned int cmd, int (*ioctl)(struct socket *sock, unsigned int cmd,
unsigned long arg); unsigned long arg);
int (*release)(struct socket *sock);
void (*sk_free)(struct sock *sk);
struct module *owner;
}; };
extern int register_pppox_proto(int proto_num, struct pppox_proto *pp); extern int register_pppox_proto(int proto_num, struct pppox_proto *pp);
...@@ -145,6 +150,9 @@ extern void unregister_pppox_proto(int proto_num); ...@@ -145,6 +150,9 @@ extern void unregister_pppox_proto(int proto_num);
extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */ extern void pppox_unbind_sock(struct sock *sk);/* delete ppp-channel binding */
extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd, extern int pppox_channel_ioctl(struct ppp_channel *pc, unsigned int cmd,
unsigned long arg); unsigned long arg);
extern struct sock *pppox_sk_alloc(struct socket *sock, int protocol,
int priority, int zero_it,
kmem_cache_t *slab);
/* PPPoX socket states */ /* PPPoX socket states */
enum { enum {
......
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