#include <linux/if_arp.h>
#include <linux/wireless.h>
#include <linux/skbuff.h>
+#include <linux/udp.h>
#include <net/sock.h>
#include <net/inet_common.h>
#include <linux/stat.h>
#include <net/ip.h>
#include <linux/spinlock.h>
#include <linux/rcupdate.h>
+#include <linux/bitops.h>
#include <asm/uaccess.h>
#include <asm/system.h>
-#include <asm/bitops.h>
-static struct proto_ops econet_ops;
+static const struct proto_ops econet_ops;
static struct hlist_head econet_sklist;
-static rwlock_t econet_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(econet_lock);
/* Since there are only 256 possible network numbers (or fewer, depends
how you count) it makes sense to use a simple lookup table. */
#define EC_PORT_IP 0xd2
#ifdef CONFIG_ECONET_AUNUDP
-static spinlock_t aun_queue_lock;
+static DEFINE_SPINLOCK(aun_queue_lock);
static struct socket *udpsock;
#define AUN_PORT 0x8000
err = memcpy_toiovec(msg->msg_iov, skb->data, copied);
if (err)
goto out_free;
- sk->sk_stamp = skb->stamp;
+ skb_get_timestamp(skb, &sk->sk_stamp);
if (msg->msg_name)
memcpy(msg->msg_name, skb->cb, msg->msg_namelen);
{
struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
struct sock *sk=sock->sk;
- struct econet_opt *eo = ec_sk(sk);
+ struct econet_sock *eo = ec_sk(sk);
/*
* Check legality
*/
if (saddr == NULL) {
- struct econet_opt *eo = ec_sk(sk);
+ struct econet_sock *eo = ec_sk(sk);
addr.station = eo->station;
addr.net = eo->net;
unsigned long network = 0;
rcu_read_lock();
- idev = __in_dev_get(dev);
+ idev = __in_dev_get_rcu(dev);
if (idev) {
if (idev->ifa_list)
network = ntohl(idev->ifa_list->ifa_address) &
void __user *base = msg->msg_iov[i].iov_base;
size_t len = msg->msg_iov[i].iov_len;
/* Check it now since we switch to KERNEL_DS later. */
- if ((err = verify_area(VERIFY_READ, base, len)) < 0)
- return err;
+ if (!access_ok(VERIFY_READ, base, len))
+ return -EFAULT;
iov[i+1].iov_base = base;
iov[i+1].iov_len = len;
size += len;
int *uaddr_len, int peer)
{
struct sock *sk = sock->sk;
- struct econet_opt *eo = ec_sk(sk);
+ struct econet_sock *eo = ec_sk(sk);
struct sockaddr_ec *sec = (struct sockaddr_ec *)uaddr;
if (peer)
return 0;
}
+static struct proto econet_proto = {
+ .name = "ECONET",
+ .owner = THIS_MODULE,
+ .obj_size = sizeof(struct econet_sock),
+};
+
/*
* Create an Econet socket
*/
static int econet_create(struct socket *sock, int protocol)
{
struct sock *sk;
- struct econet_opt *eo;
+ struct econet_sock *eo;
int err;
/* Econet only provides datagram services. */
sock->state = SS_UNCONNECTED;
err = -ENOBUFS;
- sk = sk_alloc(PF_ECONET, GFP_KERNEL, 1, NULL);
+ sk = sk_alloc(PF_ECONET, GFP_KERNEL, &econet_proto, 1);
if (sk == NULL)
goto out;
sk->sk_reuse = 1;
sock->ops = &econet_ops;
- sock_init_data(sock,sk);
- sk_set_owner(sk, THIS_MODULE);
+ sock_init_data(sock, sk);
- eo = sk->sk_protinfo = kmalloc(sizeof(*eo), GFP_KERNEL);
- if (!eo)
- goto out_free;
- memset(eo, 0, sizeof(*eo));
- sk->sk_zapped = 0;
+ eo = ec_sk(sk);
+ sock_reset_flag(sk, SOCK_ZAPPED);
sk->sk_family = PF_ECONET;
eo->num = protocol;
econet_insert_socket(&econet_sklist, sk);
return(0);
-
-out_free:
- sk_free(sk);
out:
return err;
}
break;
default:
- return dev_ioctl(cmd, argp);
+ return -ENOIOCTLCMD;
}
/*NOTREACHED*/
return 0;
.owner = THIS_MODULE,
};
-static struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
+static const struct proto_ops SOCKOPS_WRAPPED(econet_ops) = {
.family = PF_ECONET,
.owner = THIS_MODULE,
.release = econet_release,
struct hlist_node *node;
sk_for_each(sk, node, &econet_sklist) {
- struct econet_opt *opt = ec_sk(sk);
+ struct econet_sock *opt = ec_sk(sk);
if ((opt->port == port || opt->port == 0) &&
(opt->station == station || opt->station == 0) &&
(opt->net == net || opt->net == 0))
foundit:
tx_result(skb->sk, eb->cookie, result);
- skb_unlink(skb);
+ skb_unlink(skb, &aun_queue);
spin_unlock_irqrestore(&aun_queue_lock, flags);
kfree_skb(skb);
}
{
tx_result(skb->sk, eb->cookie,
ECTYPE_TRANSMIT_NOT_PRESENT);
- skb_unlink(skb);
+ skb_unlink(skb, &aun_queue);
kfree_skb(skb);
}
skb = newskb;
* Receive an Econet frame from a device.
*/
-static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt)
+static int econet_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *pt, struct net_device *orig_dev)
{
struct ec_framehdr *hdr;
struct sock *sk;
#endif
unregister_netdevice_notifier(&econet_netdev_notifier);
sock_unregister(econet_family_ops.family);
+ proto_unregister(&econet_proto);
}
static int __init econet_proto_init(void)
{
+ int err = proto_register(&econet_proto, 0);
+
+ if (err != 0)
+ goto out;
sock_register(&econet_family_ops);
#ifdef CONFIG_ECONET_AUNUDP
spin_lock_init(&aun_queue_lock);
econet_hw_initialise();
#endif
register_netdevice_notifier(&econet_netdev_notifier);
- return 0;
+out:
+ return err;
}
module_init(econet_proto_init);