net: pppoe - code cleanup and helpers

- Introduce PPPOE_HASH_MASK.
- Remove redundant declaration of pppoe_chan_ops.
- Introduce stage_session helper.
- Tabs, space, long-line-split cleanup.

Signed-off-by: Cyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: David S. Miller <davem@davemloft.net>
This commit is contained in:
Cyrill Gorcunov 2009-01-21 15:54:15 -08:00 committed by David S. Miller
parent e287880622
commit 6aba915881
1 changed files with 87 additions and 82 deletions

View File

@ -84,32 +84,43 @@
#include <asm/uaccess.h> #include <asm/uaccess.h>
#define PPPOE_HASH_BITS 4 #define PPPOE_HASH_BITS 4
#define PPPOE_HASH_SIZE (1<<PPPOE_HASH_BITS) #define PPPOE_HASH_SIZE (1 << PPPOE_HASH_BITS)
#define PPPOE_HASH_MASK (PPPOE_HASH_SIZE - 1)
static struct ppp_channel_ops pppoe_chan_ops;
static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg); static int pppoe_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb); static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb);
static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb); static int __pppoe_xmit(struct sock *sk, struct sk_buff *skb);
static const struct proto_ops pppoe_ops; static const struct proto_ops pppoe_ops;
static struct ppp_channel_ops pppoe_chan_ops;
static DEFINE_RWLOCK(pppoe_hash_lock); static DEFINE_RWLOCK(pppoe_hash_lock);
static struct ppp_channel_ops pppoe_chan_ops; /*
* PPPoE could be in the following stages:
* 1) Discovery stage (to obtain remote MAC and Session ID)
* 2) Session stage (MAC and SID are known)
*
* Ethernet frames have a special tag for this but
* we use simplier approach based on session id
*/
static inline bool stage_session(__be16 sid)
{
return sid != 0;
}
static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b) static inline int cmp_2_addr(struct pppoe_addr *a, struct pppoe_addr *b)
{ {
return (a->sid == b->sid && return a->sid == b->sid &&
(memcmp(a->remote, b->remote, ETH_ALEN) == 0)); (memcmp(a->remote, b->remote, ETH_ALEN) == 0);
} }
static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr) static inline int cmp_addr(struct pppoe_addr *a, __be16 sid, char *addr)
{ {
return (a->sid == sid && return a->sid == sid &&
(memcmp(a->remote,addr,ETH_ALEN) == 0)); (memcmp(a->remote, addr, ETH_ALEN) == 0);
} }
#if 8%PPPOE_HASH_BITS #if 8 % PPPOE_HASH_BITS
#error 8 must be a multiple of PPPOE_HASH_BITS #error 8 must be a multiple of PPPOE_HASH_BITS
#endif #endif
@ -118,17 +129,14 @@ static int hash_item(__be16 sid, unsigned char *addr)
unsigned char hash = 0; unsigned char hash = 0;
unsigned int i; unsigned int i;
for (i = 0 ; i < ETH_ALEN ; i++) { for (i = 0; i < ETH_ALEN; i++)
hash ^= addr[i]; hash ^= addr[i];
} for (i = 0; i < sizeof(sid_t) * 8; i += 8)
for (i = 0 ; i < sizeof(sid_t)*8 ; i += 8 ){ hash ^= (__force __u32)sid >> i;
hash ^= (__force __u32)sid>>i; for (i = 8; (i >>= 1) >= PPPOE_HASH_BITS;)
} hash ^= hash >> i;
for (i = 8 ; (i>>=1) >= PPPOE_HASH_BITS ; ) {
hash ^= hash>>i;
}
return hash & ( PPPOE_HASH_SIZE - 1 ); return hash & PPPOE_HASH_MASK;
} }
/* zeroed because its in .bss */ /* zeroed because its in .bss */
@ -146,10 +154,15 @@ static struct pppox_sock *__get_item(__be16 sid, unsigned char *addr, int ifinde
ret = item_hash_table[hash]; ret = item_hash_table[hash];
while (ret && !(cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex)) while (ret) {
ret = ret->next; if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
ret->pppoe_ifindex == ifindex)
return ret;
return ret; ret = ret->next;
}
return NULL;
} }
static int __set_item(struct pppox_sock *po) static int __set_item(struct pppox_sock *po)
@ -159,7 +172,8 @@ static int __set_item(struct pppox_sock *po)
ret = item_hash_table[hash]; ret = item_hash_table[hash];
while (ret) { while (ret) {
if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) && ret->pppoe_ifindex == po->pppoe_ifindex) if (cmp_2_addr(&ret->pppoe_pa, &po->pppoe_pa) &&
ret->pppoe_ifindex == po->pppoe_ifindex)
return -EALREADY; return -EALREADY;
ret = ret->next; ret = ret->next;
@ -180,7 +194,8 @@ static struct pppox_sock *__delete_item(__be16 sid, char *addr, int ifindex)
src = &item_hash_table[hash]; src = &item_hash_table[hash];
while (ret) { while (ret) {
if (cmp_addr(&ret->pppoe_pa, sid, addr) && ret->pppoe_ifindex == ifindex) { if (cmp_addr(&ret->pppoe_pa, sid, addr) &&
ret->pppoe_ifindex == ifindex) {
*src = ret->next; *src = ret->next;
break; break;
} }
@ -217,7 +232,7 @@ static inline struct pppox_sock *get_item_by_addr(struct sockaddr_pppox *sp)
int ifindex; int ifindex;
dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev); dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
if(!dev) if (!dev)
return NULL; return NULL;
ifindex = dev->ifindex; ifindex = dev->ifindex;
dev_put(dev); dev_put(dev);
@ -329,7 +344,6 @@ static struct notifier_block pppoe_notifier = {
.notifier_call = pppoe_device_event, .notifier_call = pppoe_device_event,
}; };
/************************************************************************ /************************************************************************
* *
* Do the real work of receiving a PPPoE Session frame. * Do the real work of receiving a PPPoE Session frame.
@ -383,7 +397,8 @@ static int pppoe_rcv(struct sk_buff *skb,
struct pppox_sock *po; struct pppox_sock *po;
int len; int len;
if (!(skb = skb_share_check(skb, GFP_ATOMIC))) skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb)
goto out; goto out;
if (dev_net(dev) != &init_net) if (dev_net(dev) != &init_net)
@ -432,7 +447,8 @@ static int pppoe_disc_rcv(struct sk_buff *skb,
if (dev_net(dev) != &init_net) if (dev_net(dev) != &init_net)
goto abort; goto abort;
if (!(skb = skb_share_check(skb, GFP_ATOMIC))) skb = skb_share_check(skb, GFP_ATOMIC);
if (!skb)
goto out; goto out;
if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr))) if (!pskb_may_pull(skb, sizeof(struct pppoe_hdr)))
@ -493,12 +509,11 @@ static struct proto pppoe_sk_proto = {
**********************************************************************/ **********************************************************************/
static int pppoe_create(struct net *net, struct socket *sock) static int pppoe_create(struct net *net, struct socket *sock)
{ {
int error = -ENOMEM;
struct sock *sk; struct sock *sk;
sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto); sk = sk_alloc(net, PF_PPPOX, GFP_KERNEL, &pppoe_sk_proto);
if (!sk) if (!sk)
goto out; return -ENOMEM;
sock_init_data(sock, sk); sock_init_data(sock, sk);
@ -511,8 +526,7 @@ static int pppoe_create(struct net *net, struct socket *sock)
sk->sk_family = PF_PPPOX; sk->sk_family = PF_PPPOX;
sk->sk_protocol = PX_PROTO_OE; sk->sk_protocol = PX_PROTO_OE;
error = 0; return 0;
out: return error;
} }
static int pppoe_release(struct socket *sock) static int pppoe_release(struct socket *sock)
@ -524,7 +538,7 @@ static int pppoe_release(struct socket *sock)
return 0; return 0;
lock_sock(sk); lock_sock(sk);
if (sock_flag(sk, SOCK_DEAD)){ if (sock_flag(sk, SOCK_DEAD)) {
release_sock(sk); release_sock(sk);
return -EBADF; return -EBADF;
} }
@ -542,7 +556,7 @@ static int pppoe_release(struct socket *sock)
write_lock_bh(&pppoe_hash_lock); write_lock_bh(&pppoe_hash_lock);
po = pppox_sk(sk); po = pppox_sk(sk);
if (po->pppoe_pa.sid) { if (stage_session(po->pppoe_pa.sid)) {
__delete_item(po->pppoe_pa.sid, __delete_item(po->pppoe_pa.sid,
po->pppoe_pa.remote, po->pppoe_ifindex); po->pppoe_pa.remote, po->pppoe_ifindex);
} }
@ -564,7 +578,6 @@ static int pppoe_release(struct socket *sock)
return 0; return 0;
} }
static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr, static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
int sockaddr_len, int flags) int sockaddr_len, int flags)
{ {
@ -582,32 +595,31 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
/* Check for already bound sockets */ /* Check for already bound sockets */
error = -EBUSY; error = -EBUSY;
if ((sk->sk_state & PPPOX_CONNECTED) && sp->sa_addr.pppoe.sid) if ((sk->sk_state & PPPOX_CONNECTED) &&
stage_session(sp->sa_addr.pppoe.sid))
goto end; goto end;
/* Check for already disconnected sockets, on attempts to disconnect */ /* Check for already disconnected sockets, on attempts to disconnect */
error = -EALREADY; error = -EALREADY;
if ((sk->sk_state & PPPOX_DEAD) && !sp->sa_addr.pppoe.sid ) if ((sk->sk_state & PPPOX_DEAD) &&
!stage_session(sp->sa_addr.pppoe.sid))
goto end; goto end;
error = 0; error = 0;
if (po->pppoe_pa.sid) {
/* Delete the old binding */
if (stage_session(po->pppoe_pa.sid)) {
pppox_unbind_sock(sk); pppox_unbind_sock(sk);
delete_item(po->pppoe_pa.sid, po->pppoe_pa.remote, po->pppoe_ifindex);
/* Delete the old binding */ if (po->pppoe_dev)
delete_item(po->pppoe_pa.sid,po->pppoe_pa.remote,po->pppoe_ifindex);
if(po->pppoe_dev)
dev_put(po->pppoe_dev); dev_put(po->pppoe_dev);
memset(sk_pppox(po) + 1, 0, memset(sk_pppox(po) + 1, 0,
sizeof(struct pppox_sock) - sizeof(struct sock)); sizeof(struct pppox_sock) - sizeof(struct sock));
sk->sk_state = PPPOX_NONE; sk->sk_state = PPPOX_NONE;
} }
/* Don't re-bind if sid==0 */ /* Re-bind in session stage only */
if (sp->sa_addr.pppoe.sid != 0) { if (stage_session(sp->sa_addr.pppoe.sid)) {
dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev); dev = dev_get_by_name(&init_net, sp->sa_addr.pppoe.dev);
error = -ENODEV; error = -ENODEV;
@ -618,7 +630,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->pppoe_ifindex = dev->ifindex; po->pppoe_ifindex = dev->ifindex;
write_lock_bh(&pppoe_hash_lock); write_lock_bh(&pppoe_hash_lock);
if (!(dev->flags & IFF_UP)){ if (!(dev->flags & IFF_UP)) {
write_unlock_bh(&pppoe_hash_lock); write_unlock_bh(&pppoe_hash_lock);
goto err_put; goto err_put;
} }
@ -648,7 +660,7 @@ static int pppoe_connect(struct socket *sock, struct sockaddr *uservaddr,
po->num = sp->sa_addr.pppoe.sid; po->num = sp->sa_addr.pppoe.sid;
end: end:
release_sock(sk); release_sock(sk);
return error; return error;
err_put: err_put:
@ -659,7 +671,6 @@ err_put:
goto end; goto end;
} }
static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr, static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
int *usockaddr_len, int peer) int *usockaddr_len, int peer)
{ {
@ -678,7 +689,6 @@ static int pppoe_getname(struct socket *sock, struct sockaddr *uaddr,
return 0; return 0;
} }
static int pppoe_ioctl(struct socket *sock, unsigned int cmd, static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
unsigned long arg) unsigned long arg)
{ {
@ -709,7 +719,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
break; break;
err = -EFAULT; err = -EFAULT;
if (get_user(val,(int __user *) arg)) if (get_user(val, (int __user *)arg))
break; break;
if (val < (po->pppoe_dev->mtu if (val < (po->pppoe_dev->mtu
@ -722,7 +732,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
case PPPIOCSFLAGS: case PPPIOCSFLAGS:
err = -EFAULT; err = -EFAULT;
if (get_user(val, (int __user *) arg)) if (get_user(val, (int __user *)arg))
break; break;
err = 0; err = 0;
break; break;
@ -749,7 +759,7 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
err = -EINVAL; err = -EINVAL;
if (po->pppoe_relay.sa_family != AF_PPPOX || if (po->pppoe_relay.sa_family != AF_PPPOX ||
po->pppoe_relay.sa_protocol!= PX_PROTO_OE) po->pppoe_relay.sa_protocol != PX_PROTO_OE)
break; break;
/* Check that the socket referenced by the address /* Check that the socket referenced by the address
@ -781,7 +791,6 @@ static int pppoe_ioctl(struct socket *sock, unsigned int cmd,
return err; return err;
} }
static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock, static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
struct msghdr *m, size_t total_len) struct msghdr *m, size_t total_len)
{ {
@ -808,7 +817,7 @@ static int pppoe_sendmsg(struct kiocb *iocb, struct socket *sock,
dev = po->pppoe_dev; dev = po->pppoe_dev;
error = -EMSGSIZE; error = -EMSGSIZE;
if (total_len > (dev->mtu + dev->hard_header_len)) if (total_len > (dev->mtu + dev->hard_header_len))
goto end; goto end;
@ -853,7 +862,6 @@ end:
return error; return error;
} }
/************************************************************************ /************************************************************************
* *
* xmit function for internal use. * xmit function for internal use.
@ -903,7 +911,6 @@ abort:
return 1; return 1;
} }
/************************************************************************ /************************************************************************
* *
* xmit function called by generic PPP driver * xmit function called by generic PPP driver
@ -916,7 +923,6 @@ static int pppoe_xmit(struct ppp_channel *chan, struct sk_buff *skb)
return __pppoe_xmit(sk, skb); return __pppoe_xmit(sk, skb);
} }
static struct ppp_channel_ops pppoe_chan_ops = { static struct ppp_channel_ops pppoe_chan_ops = {
.start_xmit = pppoe_xmit, .start_xmit = pppoe_xmit,
}; };
@ -976,9 +982,9 @@ out:
static __inline__ struct pppox_sock *pppoe_get_idx(loff_t pos) static __inline__ struct pppox_sock *pppoe_get_idx(loff_t pos)
{ {
struct pppox_sock *po; struct pppox_sock *po;
int i = 0; int i;
for (; i < PPPOE_HASH_SIZE; i++) { for (i = 0; i < PPPOE_HASH_SIZE; i++) {
po = item_hash_table[i]; po = item_hash_table[i];
while (po) { while (po) {
if (!pos--) if (!pos--)
@ -1064,32 +1070,31 @@ static inline int pppoe_proc_init(void) { return 0; }
#endif /* CONFIG_PROC_FS */ #endif /* CONFIG_PROC_FS */
static const struct proto_ops pppoe_ops = { static const struct proto_ops pppoe_ops = {
.family = AF_PPPOX, .family = AF_PPPOX,
.owner = THIS_MODULE, .owner = THIS_MODULE,
.release = pppoe_release, .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,
.listen = sock_no_listen, .listen = sock_no_listen,
.shutdown = sock_no_shutdown, .shutdown = sock_no_shutdown,
.setsockopt = sock_no_setsockopt, .setsockopt = sock_no_setsockopt,
.getsockopt = sock_no_getsockopt, .getsockopt = sock_no_getsockopt,
.sendmsg = pppoe_sendmsg, .sendmsg = pppoe_sendmsg,
.recvmsg = pppoe_recvmsg, .recvmsg = pppoe_recvmsg,
.mmap = sock_no_mmap, .mmap = sock_no_mmap,
.ioctl = pppox_ioctl, .ioctl = pppox_ioctl,
}; };
static struct pppox_proto pppoe_proto = { static struct pppox_proto pppoe_proto = {
.create = pppoe_create, .create = pppoe_create,
.ioctl = pppoe_ioctl, .ioctl = pppoe_ioctl,
.owner = THIS_MODULE, .owner = THIS_MODULE,
}; };
static int __init pppoe_init(void) static int __init pppoe_init(void)
{ {
int err = proto_register(&pppoe_sk_proto, 0); int err = proto_register(&pppoe_sk_proto, 0);
@ -1097,7 +1102,7 @@ static int __init pppoe_init(void)
if (err) if (err)
goto out; goto out;
err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto); err = register_pppox_proto(PX_PROTO_OE, &pppoe_proto);
if (err) if (err)
goto out_unregister_pppoe_proto; goto out_unregister_pppoe_proto;