sh: convert /proc/cpu/aligmnent, /proc/cpu/kernel_alignment to seq_file
[safe/jmp/linux-2.6] / net / appletalk / ddp.c
index 32b8270..b1a4290 100644 (file)
@@ -2,7 +2,7 @@
  *     DDP:    An implementation of the AppleTalk DDP protocol for
  *             Ethernet 'ELAP'.
  *
- *             Alan Cox  <Alan.Cox@linux.org>
+ *             Alan Cox  <alan@lxorguk.ukuu.org.uk>
  *
  *             With more than a little assistance from
  *
@@ -54,6 +54,7 @@
 #include <linux/capability.h>
 #include <linux/module.h>
 #include <linux/if_arp.h>
+#include <linux/smp_lock.h>
 #include <linux/termios.h>     /* For TIOCOUTQ/INQ */
 #include <net/datalink.h>
 #include <net/psnap.h>
@@ -162,8 +163,7 @@ static void atalk_destroy_timer(unsigned long data)
 {
        struct sock *sk = (struct sock *)data;
 
-       if (atomic_read(&sk->sk_wmem_alloc) ||
-           atomic_read(&sk->sk_rmem_alloc)) {
+       if (sk_has_allocations(sk)) {
                sk->sk_timer.expires = jiffies + SOCK_DESTROY_TIME;
                add_timer(&sk->sk_timer);
        } else
@@ -175,12 +175,10 @@ static inline void atalk_destroy_socket(struct sock *sk)
        atalk_remove_socket(sk);
        skb_queue_purge(&sk->sk_receive_queue);
 
-       if (atomic_read(&sk->sk_wmem_alloc) ||
-           atomic_read(&sk->sk_rmem_alloc)) {
-               init_timer(&sk->sk_timer);
+       if (sk_has_allocations(sk)) {
+               setup_timer(&sk->sk_timer, atalk_destroy_timer,
+                               (unsigned long)sk);
                sk->sk_timer.expires    = jiffies + SOCK_DESTROY_TIME;
-               sk->sk_timer.function   = atalk_destroy_timer;
-               sk->sk_timer.data       = (unsigned long)sk;
                add_timer(&sk->sk_timer);
        } else
                sock_put(sk);
@@ -647,9 +645,14 @@ static inline void atalk_dev_down(struct net_device *dev)
 static int ddp_device_event(struct notifier_block *this, unsigned long event,
                            void *ptr)
 {
+       struct net_device *dev = ptr;
+
+       if (!net_eq(dev_net(dev), &init_net))
+               return NOTIFY_DONE;
+
        if (event == NETDEV_DOWN)
                /* Discard any use of this */
-               atalk_dev_down(ptr);
+               atalk_dev_down(dev);
 
        return NOTIFY_DONE;
 }
@@ -672,7 +675,7 @@ static int atif_ioctl(int cmd, void __user *arg)
        if (copy_from_user(&atreq, arg, sizeof(atreq)))
                return -EFAULT;
 
-       dev = __dev_get_by_name(atreq.ifr_name);
+       dev = __dev_get_by_name(&init_net, atreq.ifr_name);
        if (!dev)
                return -ENODEV;
 
@@ -811,9 +814,6 @@ static int atif_ioctl(int cmd, void __user *arg)
                                return -EPERM;
                        if (sa->sat_family != AF_APPLETALK)
                                return -EINVAL;
-                       if (!atif)
-                               return -EADDRNOTAVAIL;
-
                        /*
                         * for now, we only support proxy AARP on ELAP;
                         * we should be able to do it for LocalTalk, too.
@@ -896,7 +896,7 @@ static int atrtr_ioctl(unsigned int cmd, void __user *arg)
                                if (copy_from_user(name, rt.rt_dev, IFNAMSIZ-1))
                                        return -EFAULT;
                                name[IFNAMSIZ-1] = '\0';
-                               dev = __dev_get_by_name(name);
+                               dev = __dev_get_by_name(&init_net, name);
                                if (!dev)
                                        return -ENODEV;
                        }
@@ -938,6 +938,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
                                   int len, unsigned long sum)
 {
        int start = skb_headlen(skb);
+       struct sk_buff *frag_iter;
        int i, copy;
 
        /* checksum stuff in header space */
@@ -955,7 +956,7 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
        for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
                int end;
 
-               BUG_TRAP(start <= offset + len);
+               WARN_ON(start > offset + len);
 
                end = start + skb_shinfo(skb)->frags[i].size;
                if ((copy = end - offset) > 0) {
@@ -976,26 +977,22 @@ static unsigned long atalk_sum_skb(const struct sk_buff *skb, int offset,
                start = end;
        }
 
-       if (skb_shinfo(skb)->frag_list) {
-               struct sk_buff *list = skb_shinfo(skb)->frag_list;
-
-               for (; list; list = list->next) {
-                       int end;
+       skb_walk_frags(skb, frag_iter) {
+               int end;
 
-                       BUG_TRAP(start <= offset + len);
+               WARN_ON(start > offset + len);
 
-                       end = start + list->len;
-                       if ((copy = end - offset) > 0) {
-                               if (copy > len)
-                                       copy = len;
-                               sum = atalk_sum_skb(list, offset - start,
-                                                   copy, sum);
-                               if ((len -= copy) == 0)
-                                       return sum;
-                               offset += copy;
-                       }
-                       start = end;
+               end = start + frag_iter->len;
+               if ((copy = end - offset) > 0) {
+                       if (copy > len)
+                               copy = len;
+                       sum = atalk_sum_skb(frag_iter, offset - start,
+                                           copy, sum);
+                       if ((len -= copy) == 0)
+                               return sum;
+                       offset += copy;
                }
+               start = end;
        }
 
        BUG_ON(len > 0);
@@ -1024,11 +1021,14 @@ static struct proto ddp_proto = {
  * Create a socket. Initialise the socket, blank the addresses
  * set the state.
  */
-static int atalk_create(struct socket *sock, int protocol)
+static int atalk_create(struct net *net, struct socket *sock, int protocol)
 {
        struct sock *sk;
        int rc = -ESOCKTNOSUPPORT;
 
+       if (net != &init_net)
+               return -EAFNOSUPPORT;
+
        /*
         * We permit SOCK_DGRAM and RAW is an extension. It is trivial to do
         * and gives you the full ELAP frame. Should be handy for CAP 8)
@@ -1036,7 +1036,7 @@ static int atalk_create(struct socket *sock, int protocol)
        if (sock->type != SOCK_RAW && sock->type != SOCK_DGRAM)
                goto out;
        rc = -ENOMEM;
-       sk = sk_alloc(PF_APPLETALK, GFP_KERNEL, &ddp_proto, 1);
+       sk = sk_alloc(net, PF_APPLETALK, GFP_KERNEL, &ddp_proto);
        if (!sk)
                goto out;
        rc = 0;
@@ -1238,6 +1238,7 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
                        return -ENOBUFS;
 
        *uaddr_len = sizeof(struct sockaddr_at);
+       memset(&sat.sat_zero, 0, sizeof(sat.sat_zero));
 
        if (peer) {
                if (sk->sk_state != TCP_ESTABLISHED)
@@ -1265,23 +1266,24 @@ static __inline__ int is_ip_over_ddp(struct sk_buff *skb)
 
 static int handle_ip_over_ddp(struct sk_buff *skb)
 {
-       struct net_device *dev = __dev_get_by_name("ipddp0");
+       struct net_device *dev = __dev_get_by_name(&init_net, "ipddp0");
        struct net_device_stats *stats;
 
        /* This needs to be able to handle ipddp"N" devices */
-       if (!dev)
-               return -ENODEV;
+       if (!dev) {
+               kfree_skb(skb);
+               return NET_RX_DROP;
+       }
 
        skb->protocol = htons(ETH_P_IP);
        skb_pull(skb, 13);
        skb->dev   = dev;
-       skb->h.raw = skb->data;
+       skb_reset_transport_header(skb);
 
-       stats = dev->priv;
+       stats = netdev_priv(dev);
        stats->rx_packets++;
        stats->rx_bytes += skb->len + 13;
-       netif_rx(skb);  /* Send the SKB up to a higher place. */
-       return 0;
+       return netif_rx(skb);  /* Send the SKB up to a higher place. */
 }
 #else
 /* make it easy for gcc to optimize this test out, i.e. kill the code */
@@ -1289,9 +1291,8 @@ static int handle_ip_over_ddp(struct sk_buff *skb)
 #define handle_ip_over_ddp(skb) 0
 #endif
 
-static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
-                              struct ddpehdr *ddp, __u16 len_hops,
-                              int origlen)
+static int atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
+                             struct ddpehdr *ddp, __u16 len_hops, int origlen)
 {
        struct atalk_route *rt;
        struct atalk_addr ta;
@@ -1358,8 +1359,6 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
                /* 22 bytes - 12 ether, 2 len, 3 802.2 5 snap */
                struct sk_buff *nskb = skb_realloc_headroom(skb, 32);
                kfree_skb(skb);
-               if (!nskb)
-                       goto out;
                skb = nskb;
        } else
                skb = skb_unshare(skb, GFP_ATOMIC);
@@ -1368,12 +1367,16 @@ static void atalk_route_packet(struct sk_buff *skb, struct net_device *dev,
         * If the buffer didn't vanish into the lack of space bitbucket we can
         * send it.
         */
-       if (skb && aarp_send_ddp(rt->dev, skb, &ta, NULL) == -1)
-               goto free_it;
-out:
-       return;
+       if (skb == NULL)
+               goto drop;
+
+       if (aarp_send_ddp(rt->dev, skb, &ta, NULL) == NET_XMIT_DROP)
+               return NET_RX_DROP;
+       return NET_RX_SUCCESS;
 free_it:
        kfree_skb(skb);
+drop:
+       return NET_RX_DROP;
 }
 
 /**
@@ -1383,10 +1386,10 @@ free_it:
  *     @pt - packet type
  *
  *     Receive a packet (in skb) from device dev. This has come from the SNAP
- *     decoder, and on entry skb->h.raw is the DDP header, skb->len is the DDP
- *     header, skb->len is the DDP length. The physical headers have been
- *     extracted. PPP should probably pass frames marked as for this layer.
- *     [ie ARPHRD_ETHERTALK]
+ *     decoder, and on entry skb->transport_header is the DDP header, skb->len
+ *     is the DDP header, skb->len is the DDP length. The physical headers
+ *     have been extracted. PPP should probably pass frames marked as for this
+ *     layer.  [ie ARPHRD_ETHERTALK]
  */
 static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
                     struct packet_type *pt, struct net_device *orig_dev)
@@ -1398,13 +1401,16 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
        int origlen;
        __u16 len_hops;
 
+       if (!net_eq(dev_net(dev), &init_net))
+               goto drop;
+
        /* Don't mangle buffer if shared */
        if (!(skb = skb_share_check(skb, GFP_ATOMIC)))
                goto out;
 
        /* Size check and make sure header is contiguous */
        if (!pskb_may_pull(skb, sizeof(*ddp)))
-               goto freeit;
+               goto drop;
 
        ddp = ddp_hdr(skb);
 
@@ -1422,7 +1428,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
        if (skb->len < sizeof(*ddp) || skb->len < (len_hops & 1023)) {
                pr_debug("AppleTalk: dropping corrupted frame (deh_len=%u, "
                         "skb->len=%u)\n", len_hops & 1023, skb->len);
-               goto freeit;
+               goto drop;
        }
 
        /*
@@ -1432,7 +1438,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
        if (ddp->deh_sum &&
            atalk_checksum(skb, len_hops & 1023) != ddp->deh_sum)
                /* Not a valid AppleTalk frame - dustbin time */
-               goto freeit;
+               goto drop;
 
        /* Check the packet is aimed at us */
        if (!ddp->deh_dnet)     /* Net 0 is 'this network' */
@@ -1444,8 +1450,7 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
                /* Not ours, so we route the packet via the correct
                 * AppleTalk iface
                 */
-               atalk_route_packet(skb, dev, ddp, len_hops, origlen);
-               goto out;
+               return atalk_route_packet(skb, dev, ddp, len_hops, origlen);
        }
 
        /* if IP over DDP is not selected this code will be optimized out */
@@ -1461,18 +1466,21 @@ static int atalk_rcv(struct sk_buff *skb, struct net_device *dev,
 
        sock = atalk_search_socket(&tosat, atif);
        if (!sock) /* But not one of our sockets */
-               goto freeit;
+               goto drop;
 
        /* Queue packet (standard) */
        skb->sk = sock;
 
        if (sock_queue_rcv_skb(sock, skb) < 0)
-               goto freeit;
-out:
-       return 0;
-freeit:
+               goto drop;
+
+       return NET_RX_SUCCESS;
+
+drop:
        kfree_skb(skb);
-       goto out;
+out:
+       return NET_RX_DROP;
+
 }
 
 /*
@@ -1483,8 +1491,11 @@ freeit:
 static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
                     struct packet_type *pt, struct net_device *orig_dev)
 {
+       if (!net_eq(dev_net(dev), &init_net))
+               goto freeit;
+
        /* Expand any short form frames */
-       if (skb->mac.raw[2] == 1) {
+       if (skb_mac_header(skb)[2] == 1) {
                struct ddpehdr *ddp;
                /* Find our address */
                struct atalk_addr *ap = atalk_find_dev_addr(dev);
@@ -1510,8 +1521,8 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
                 * we write the network numbers !
                 */
 
-               ddp->deh_dnode = skb->mac.raw[0];     /* From physical header */
-               ddp->deh_snode = skb->mac.raw[1];     /* From physical header */
+               ddp->deh_dnode = skb_mac_header(skb)[0];     /* From physical header */
+               ddp->deh_snode = skb_mac_header(skb)[1];     /* From physical header */
 
                ddp->deh_dnet  = ap->s_net;     /* Network number */
                ddp->deh_snet  = ap->s_net;
@@ -1522,7 +1533,7 @@ static int ltalk_rcv(struct sk_buff *skb, struct net_device *dev,
                /* Non routable, so force a drop if we slip up later */
                ddp->deh_len_hops = htons(skb->len + (DDP_MAXHOPS << 10));
        }
-       skb->h.raw = skb->data;
+       skb_reset_transport_header(skb);
 
        return atalk_rcv(skb, dev, pt, orig_dev);
 freeit:
@@ -1561,14 +1572,10 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                    usat->sat_family != AF_APPLETALK)
                        return -EINVAL;
 
-               /* netatalk doesn't implement this check */
+               /* netatalk didn't implement this check */
                if (usat->sat_addr.s_node == ATADDR_BCAST &&
                    !sock_flag(sk, SOCK_BROADCAST)) {
-                       printk(KERN_INFO "SO_BROADCAST: Fix your netatalk as "
-                                        "it will break before 2.2\n");
-#if 0
                        return -EPERM;
-#endif
                }
        } else {
                if (sk->sk_state != TCP_ESTABLISHED)
@@ -1649,10 +1656,10 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                if (skb2) {
                        loopback = 1;
                        SOCK_DEBUG(sk, "SK %p: send out(copy).\n", sk);
-                       if (aarp_send_ddp(dev, skb2,
-                                         &usat->sat_addr, NULL) == -1)
-                               kfree_skb(skb2);
-                               /* else queued/sent above in the aarp queue */
+                       /*
+                        * If it fails it is queued/sent above in the aarp queue
+                        */
+                       aarp_send_ddp(dev, skb2, &usat->sat_addr, NULL);
                }
        }
 
@@ -1682,9 +1689,10 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
                    usat = &gsat;
                }
 
-               if (aarp_send_ddp(dev, skb, &usat->sat_addr, NULL) == -1)
-                       kfree_skb(skb);
-               /* else queued/sent above in the aarp queue */
+               /*
+                * If it fails it is queued/sent above in the aarp queue
+                */
+               aarp_send_ddp(dev, skb, &usat->sat_addr, NULL);
        }
        SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len);
 
@@ -1747,8 +1755,7 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
        switch (cmd) {
                /* Protocol layer */
                case TIOCOUTQ: {
-                       long amount = sk->sk_sndbuf -
-                                     atomic_read(&sk->sk_wmem_alloc);
+                       long amount = sk->sk_sndbuf - sk_wmem_alloc_get(sk);
 
                        if (amount < 0)
                                amount = 0;
@@ -1844,31 +1851,29 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
        .sendpage       = sock_no_sendpage,
 };
 
-#include <linux/smp_lock.h>
 SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK);
 
 static struct notifier_block ddp_notifier = {
        .notifier_call  = ddp_device_event,
 };
 
-static struct packet_type ltalk_packet_type = {
-       .type           = __constant_htons(ETH_P_LOCALTALK),
+static struct packet_type ltalk_packet_type __read_mostly = {
+       .type           = cpu_to_be16(ETH_P_LOCALTALK),
        .func           = ltalk_rcv,
 };
 
-static struct packet_type ppptalk_packet_type = {
-       .type           = __constant_htons(ETH_P_PPPTALK),
+static struct packet_type ppptalk_packet_type __read_mostly = {
+       .type           = cpu_to_be16(ETH_P_PPPTALK),
        .func           = atalk_rcv,
 };
 
 static unsigned char ddp_snap_id[] = { 0x08, 0x00, 0x07, 0x80, 0x9B };
 
 /* Export symbols for use by drivers when AppleTalk is a module */
-EXPORT_SYMBOL(aarp_send_ddp);
 EXPORT_SYMBOL(atrtr_get_dev);
 EXPORT_SYMBOL(atalk_find_dev_addr);
 
-static char atalk_err_snap[] __initdata =
+static const char atalk_err_snap[] __initconst =
        KERN_CRIT "Unable to register DDP with SNAP.\n";
 
 /* Called by proto.c on kernel start up */
@@ -1922,6 +1927,6 @@ static void __exit atalk_exit(void)
 module_exit(atalk_exit);
 
 MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Alan Cox <Alan.Cox@linux.org>");
+MODULE_AUTHOR("Alan Cox <alan@lxorguk.ukuu.org.uk>");
 MODULE_DESCRIPTION("AppleTalk 0.20\n");
 MODULE_ALIAS_NETPROTO(PF_APPLETALK);