* Due Credit:
* Wanpipe socket layer is based on Packet and
* the X25 socket layers. The above sockets were
-* used for the specific use of Sangoma Technoloiges
+* used for the specific use of Sangoma Technologies
* API programs.
* Packet socket Authors: Ross Biro, Fred N. van Kempen and
* Alan Cox.
* Apr 25, 2000 Nenad Corbic o Added the ability to send zero length packets.
* Mar 13, 2000 Nenad Corbic o Added a tx buffer check via ioctl call.
* Mar 06, 2000 Nenad Corbic o Fixed the corrupt sock lcn problem.
-* Server and client applicaton can run
+* Server and client application can run
* simultaneously without conflicts.
* Feb 29, 2000 Nenad Corbic o Added support for PVC protocols, such as
* CHDLC, Frame Relay and HDLC API.
*
******************************************************************************/
-#include <linux/config.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <linux/mm.h>
+#include <linux/capability.h>
#include <linux/fcntl.h>
#include <linux/socket.h>
#include <linux/in.h>
#include <asm/uaccess.h>
#include <linux/module.h>
#include <linux/init.h>
-#include <linux/wanpipe.h>
#include <linux/if_wanpipe.h>
#include <linux/pkt_sched.h>
-#include <linux/tcp.h>
+#include <linux/tcp_states.h>
#include <linux/if_wanpipe_common.h>
-#include <linux/sdla_x25.h>
#ifdef CONFIG_INET
#include <net/inet_common.h>
/* List of all wanpipe sockets. */
HLIST_HEAD(wanpipe_sklist);
-static rwlock_t wanpipe_sklist_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(wanpipe_sklist_lock);
atomic_t wanpipe_socks_nr;
static unsigned long wanpipe_tx_critical;
#endif
static int sk_count;
-extern struct proto_ops wanpipe_ops;
+extern const struct proto_ops wanpipe_ops;
static unsigned long find_free_critical;
static void wanpipe_unlink_driver(struct sock *sk);
* used by the ioctl call to read call information
* and to execute commands.
*/
- if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) {
+ if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL) {
wanpipe_kill_sock_irq (newsk);
release_device(dev);
return -ENOMEM;
}
- memset(mbox_ptr, 0, sizeof(mbox_cmd_t));
memcpy(mbox_ptr,skb->data,skb->len);
/* Register the lcn on which incoming call came
chan->lcn = mbox_ptr->cmd.lcn;
card->u.x.svc_to_dev_map[(chan->lcn%MAX_X25_LCN)] = dev;
- newsk->sk_zapped = 0;
+ sock_reset_flag(newsk, SOCK_ZAPPED);
newwp->num = htons(X25_PROT);
if (wanpipe_do_bind(newsk, dev, newwp->num)) {
wp_sk(sk)->num = wp_sk(osk)->num;
sk->sk_rcvbuf = osk->sk_rcvbuf;
sk->sk_sndbuf = osk->sk_sndbuf;
- sk->sk_debug = osk->sk_debug;
sk->sk_state = WANSOCK_CONNECTING;
sk->sk_sleep = osk->sk_sleep;
+ if (sock_flag(osk, SOCK_DBG))
+ sock_set_flag(sk, SOCK_DBG);
+
return sk;
}
+/*
+ * FIXME: wanpipe_opt has to include a sock in its definition and stop using
+ * sk_protinfo, but this code is not even compilable now, so lets leave it for
+ * later.
+ */
+static struct proto wanpipe_proto = {
+ .name = "WANPIPE",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct sock),
+};
+
/*============================================================
* wanpipe_make_new
*
struct sock *sk;
struct wanpipe_opt *wan_opt;
- if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, 1, NULL)) == NULL)
+ if ((sk = sk_alloc(PF_WANPIPE, GFP_ATOMIC, &wanpipe_proto, 1)) == NULL)
return NULL;
- if ((wan_opt = kmalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) {
+ if ((wan_opt = kzalloc(sizeof(struct wanpipe_opt), GFP_ATOMIC)) == NULL) {
sk_free(sk);
return NULL;
}
- memset(wan_opt, 0x00, sizeof(struct wanpipe_opt));
wp_sk(sk) = wan_opt;
int ifindex, err, reserve = 0;
- if (!sk->sk_zapped)
+ if (!sock_flag(sk, SOCK_ZAPPED))
return -ENETDOWN;
if (sk->sk_state != WANSOCK_CONNECTED)
return -ENOTCONN;
- if (msg->msg_flags&~MSG_DONTWAIT)
+ if (msg->msg_flags & ~(MSG_DONTWAIT|MSG_CMSG_COMPAT))
return(-EINVAL);
/* it was <=, now one can send
return;
}
- if (sk->sk_state != WANSOCK_CONNECTED || !sk->sk_zapped) {
+ if (sk->sk_state != WANSOCK_CONNECTED || !sock_flag(sk, SOCK_ZAPPED)) {
clear_bit(0, &wp->timer);
DBG_PRINTK(KERN_INFO "wansock: Tx Timer, State not CONNECTED\n");
return;
struct net_device *dev;
wanpipe_common_t *chan=NULL;
- sk->sk_zapped = 0;
+ sock_reset_flag(sk, SOCK_ZAPPED);
sk->sk_state = WANSOCK_DISCONNECTED;
wp_sk(sk)->dev = NULL;
chan->mbox = wp->mbox;
chan->tx_timer = &wp->tx_timer;
wp->dev = dev;
- sk->sk_zapped = 1;
+ sock_set_flag(sk, SOCK_ZAPPED);
clear_bit(0,&chan->common_critical);
}
*/
if (wp->num == htons(X25_PROT) &&
- sk->sk_state != WANSOCK_DISCONNECTED && sk->sk_zapped) {
+ sk->sk_state != WANSOCK_DISCONNECTED && sock_flag(sk, SOCK_ZAPPED)) {
struct net_device *dev = dev_get_by_index(sk->sk_bound_dev_if);
wanpipe_common_t *chan;
if (dev){
}
kfree_skb(skb);
}
- if (sk->sk_zapped)
+ if (sock_flag(sk, SOCK_ZAPPED))
wanpipe_unlink_card(sk);
}else{
- if (sk->sk_zapped)
+ if (sock_flag(sk, SOCK_ZAPPED))
wanpipe_unlink_driver(sk);
}
sk->sk_state = WANSOCK_DISCONNECTED;
sk->sk_bound_dev_if = 0;
- sk->sk_zapped = 0;
+ sock_reset_flag(sk, SOCK_ZAPPED);
wp = wp_sk(sk);
- if (wp && wp->mbox) {
+ if (wp) {
kfree(wp->mbox);
wp->mbox = NULL;
}
return;
}
- if (wp_sk(sk)) {
- kfree(wp_sk(sk));
- wp_sk(sk) = NULL;
- }
+ kfree(wp_sk(sk));
+ wp_sk(sk) = NULL;
if (atomic_read(&sk->sk_refcnt) != 1) {
atomic_set(&sk->sk_refcnt, 1);
sk->sk_socket = NULL;
- if (wp_sk(sk)) {
- kfree(wp_sk(sk));
- wp_sk(sk) = NULL;
- }
+ kfree(wp_sk(sk));
+ wp_sk(sk) = NULL;
if (atomic_read(&sk->sk_refcnt) != 1) {
atomic_set(&sk->sk_refcnt, 1);
sk->sk_socket = NULL;
- if (wp_sk(sk)) {
- kfree(wp_sk(sk));
- wp_sk(sk) = NULL;
- }
+ kfree(wp_sk(sk));
+ wp_sk(sk) = NULL;
if (atomic_read(&sk->sk_refcnt) != 1) {
atomic_set(&sk->sk_refcnt, 1);
wanpipe_common_t *chan=NULL;
int err=0;
- if (sk->sk_zapped) {
+ if (sock_flag(sk, SOCK_ZAPPED)) {
err = -EALREADY;
goto bind_unlock_exit;
}
sock->ops = &wanpipe_ops;
sock_init_data(sock,sk);
- sk->sk_zapped = 0;
+ sock_reset_flag(sk, SOCK_ZAPPED);
sk->sk_family = PF_WANPIPE;
wp_sk(sk)->num = protocol;
sk->sk_state = WANSOCK_DISCONNECTED;
case NETDEV_UNREGISTER:
if (dev->ifindex == sk->sk_bound_dev_if) {
printk(KERN_INFO "wansock: Device down %s\n",dev->name);
- if (sk->sk_zapped) {
+ if (sock_flag(sk, SOCK_ZAPPED)) {
wanpipe_unlink_driver(sk);
sk->sk_err = ENETDOWN;
sk->sk_error_report(sk);
break;
case NETDEV_UP:
if (dev->ifindex == sk->sk_bound_dev_if &&
- po->num && !sk->sk_zapped) {
+ po->num && !sock_flag(sk, SOCK_ZAPPED)) {
printk(KERN_INFO "wansock: Registering Device: %s\n",
dev->name);
wanpipe_link_driver(dev,sk);
#endif
default:
- return dev_ioctl(cmd,(void __user *) arg);
+ return -ENOIOCTLCMD;
}
/*NOTREACHED*/
}
dev_put(dev);
- if ((mbox_ptr = kmalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL)
+ if ((mbox_ptr = kzalloc(sizeof(mbox_cmd_t), GFP_ATOMIC)) == NULL)
return -ENOMEM;
- memset(mbox_ptr, 0, sizeof(mbox_cmd_t));
wp_sk(sk)->mbox = mbox_ptr;
wanpipe_link_driver(dev,sk);
card->sk=sk;
card->func=wanpipe_listen_rcv;
- sk->sk_zapped = 1;
+ sock_set_flag(sk, SOCK_ZAPPED);
return 0;
}
write_unlock(&wanpipe_sklist_lock);
clear_bit(1,&wanpipe_tx_critical);
- newsk->sk_pair = NULL;
newsk->sk_socket = newsock;
newsk->sk_sleep = &newsock->wait;
dev_put(dev);
- if (!sk->sk_zapped) /* Must bind first - autobinding does not work */
+ if (!sock_flag(sk, SOCK_ZAPPED)) /* Must bind first - autobinding does not work */
return -EINVAL;
sock->state = SS_CONNECTING;
return 0;
}
-struct proto_ops wanpipe_ops = {
+const struct proto_ops wanpipe_ops = {
.family = PF_WANPIPE,
.owner = THIS_MODULE,
.release = wanpipe_release,
printk(KERN_INFO "wansock: Cleaning up \n");
unregister_netdevice_notifier(&wanpipe_netdev_notifier);
sock_unregister(PF_WANPIPE);
- return;
+ proto_unregister(&wanpipe_proto);
}
-
int init_module(void)
{
+ int rc;
printk(KERN_INFO "wansock: Registering Socket \n");
+
+ rc = proto_register(&wanpipe_proto, 0);
+ if (rc != 0)
+ goto out;
+
sock_register(&wanpipe_family_ops);
register_netdevice_notifier(&wanpipe_netdev_notifier);
- return 0;
+out:
+ return rc;
}
#endif
MODULE_LICENSE("GPL");