aboutsummaryrefslogtreecommitdiffstats
path: root/net/appletalk/ddp.c
diff options
context:
space:
mode:
Diffstat (limited to 'net/appletalk/ddp.c')
-rw-r--r--net/appletalk/ddp.c135
1 files changed, 92 insertions, 43 deletions
diff --git a/net/appletalk/ddp.c b/net/appletalk/ddp.c
index b1a4290996b5..7b02967fbbe7 100644
--- a/net/appletalk/ddp.c
+++ b/net/appletalk/ddp.c
@@ -56,6 +56,8 @@
56#include <linux/if_arp.h> 56#include <linux/if_arp.h>
57#include <linux/smp_lock.h> 57#include <linux/smp_lock.h>
58#include <linux/termios.h> /* For TIOCOUTQ/INQ */ 58#include <linux/termios.h> /* For TIOCOUTQ/INQ */
59#include <linux/compat.h>
60#include <linux/slab.h>
59#include <net/datalink.h> 61#include <net/datalink.h>
60#include <net/psnap.h> 62#include <net/psnap.h>
61#include <net/sock.h> 63#include <net/sock.h>
@@ -922,13 +924,8 @@ static unsigned long atalk_sum_partial(const unsigned char *data,
922{ 924{
923 /* This ought to be unwrapped neatly. I'll trust gcc for now */ 925 /* This ought to be unwrapped neatly. I'll trust gcc for now */
924 while (len--) { 926 while (len--) {
925 sum += *data; 927 sum += *data++;
926 sum <<= 1; 928 sum = rol16(sum, 1);
927 if (sum & 0x10000) {
928 sum++;
929 sum &= 0xffff;
930 }
931 data++;
932 } 929 }
933 return sum; 930 return sum;
934} 931}
@@ -1021,12 +1018,13 @@ static struct proto ddp_proto = {
1021 * Create a socket. Initialise the socket, blank the addresses 1018 * Create a socket. Initialise the socket, blank the addresses
1022 * set the state. 1019 * set the state.
1023 */ 1020 */
1024static int atalk_create(struct net *net, struct socket *sock, int protocol) 1021static int atalk_create(struct net *net, struct socket *sock, int protocol,
1022 int kern)
1025{ 1023{
1026 struct sock *sk; 1024 struct sock *sk;
1027 int rc = -ESOCKTNOSUPPORT; 1025 int rc = -ESOCKTNOSUPPORT;
1028 1026
1029 if (net != &init_net) 1027 if (!net_eq(net, &init_net))
1030 return -EAFNOSUPPORT; 1028 return -EAFNOSUPPORT;
1031 1029
1032 /* 1030 /*
@@ -1054,11 +1052,13 @@ static int atalk_release(struct socket *sock)
1054{ 1052{
1055 struct sock *sk = sock->sk; 1053 struct sock *sk = sock->sk;
1056 1054
1055 lock_kernel();
1057 if (sk) { 1056 if (sk) {
1058 sock_orphan(sk); 1057 sock_orphan(sk);
1059 sock->sk = NULL; 1058 sock->sk = NULL;
1060 atalk_destroy_socket(sk); 1059 atalk_destroy_socket(sk);
1061 } 1060 }
1061 unlock_kernel();
1062 return 0; 1062 return 0;
1063} 1063}
1064 1064
@@ -1134,6 +1134,7 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1134 struct sockaddr_at *addr = (struct sockaddr_at *)uaddr; 1134 struct sockaddr_at *addr = (struct sockaddr_at *)uaddr;
1135 struct sock *sk = sock->sk; 1135 struct sock *sk = sock->sk;
1136 struct atalk_sock *at = at_sk(sk); 1136 struct atalk_sock *at = at_sk(sk);
1137 int err;
1137 1138
1138 if (!sock_flag(sk, SOCK_ZAPPED) || 1139 if (!sock_flag(sk, SOCK_ZAPPED) ||
1139 addr_len != sizeof(struct sockaddr_at)) 1140 addr_len != sizeof(struct sockaddr_at))
@@ -1142,37 +1143,44 @@ static int atalk_bind(struct socket *sock, struct sockaddr *uaddr, int addr_len)
1142 if (addr->sat_family != AF_APPLETALK) 1143 if (addr->sat_family != AF_APPLETALK)
1143 return -EAFNOSUPPORT; 1144 return -EAFNOSUPPORT;
1144 1145
1146 lock_kernel();
1145 if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) { 1147 if (addr->sat_addr.s_net == htons(ATADDR_ANYNET)) {
1146 struct atalk_addr *ap = atalk_find_primary(); 1148 struct atalk_addr *ap = atalk_find_primary();
1147 1149
1150 err = -EADDRNOTAVAIL;
1148 if (!ap) 1151 if (!ap)
1149 return -EADDRNOTAVAIL; 1152 goto out;
1150 1153
1151 at->src_net = addr->sat_addr.s_net = ap->s_net; 1154 at->src_net = addr->sat_addr.s_net = ap->s_net;
1152 at->src_node = addr->sat_addr.s_node= ap->s_node; 1155 at->src_node = addr->sat_addr.s_node= ap->s_node;
1153 } else { 1156 } else {
1157 err = -EADDRNOTAVAIL;
1154 if (!atalk_find_interface(addr->sat_addr.s_net, 1158 if (!atalk_find_interface(addr->sat_addr.s_net,
1155 addr->sat_addr.s_node)) 1159 addr->sat_addr.s_node))
1156 return -EADDRNOTAVAIL; 1160 goto out;
1157 1161
1158 at->src_net = addr->sat_addr.s_net; 1162 at->src_net = addr->sat_addr.s_net;
1159 at->src_node = addr->sat_addr.s_node; 1163 at->src_node = addr->sat_addr.s_node;
1160 } 1164 }
1161 1165
1162 if (addr->sat_port == ATADDR_ANYPORT) { 1166 if (addr->sat_port == ATADDR_ANYPORT) {
1163 int n = atalk_pick_and_bind_port(sk, addr); 1167 err = atalk_pick_and_bind_port(sk, addr);
1164 1168
1165 if (n < 0) 1169 if (err < 0)
1166 return n; 1170 goto out;
1167 } else { 1171 } else {
1168 at->src_port = addr->sat_port; 1172 at->src_port = addr->sat_port;
1169 1173
1174 err = -EADDRINUSE;
1170 if (atalk_find_or_insert_socket(sk, addr)) 1175 if (atalk_find_or_insert_socket(sk, addr))
1171 return -EADDRINUSE; 1176 goto out;
1172 } 1177 }
1173 1178
1174 sock_reset_flag(sk, SOCK_ZAPPED); 1179 sock_reset_flag(sk, SOCK_ZAPPED);
1175 return 0; 1180 err = 0;
1181out:
1182 unlock_kernel();
1183 return err;
1176} 1184}
1177 1185
1178/* Set the address we talk to */ 1186/* Set the address we talk to */
@@ -1182,6 +1190,7 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
1182 struct sock *sk = sock->sk; 1190 struct sock *sk = sock->sk;
1183 struct atalk_sock *at = at_sk(sk); 1191 struct atalk_sock *at = at_sk(sk);
1184 struct sockaddr_at *addr; 1192 struct sockaddr_at *addr;
1193 int err;
1185 1194
1186 sk->sk_state = TCP_CLOSE; 1195 sk->sk_state = TCP_CLOSE;
1187 sock->state = SS_UNCONNECTED; 1196 sock->state = SS_UNCONNECTED;
@@ -1206,12 +1215,15 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
1206#endif 1215#endif
1207 } 1216 }
1208 1217
1218 lock_kernel();
1219 err = -EBUSY;
1209 if (sock_flag(sk, SOCK_ZAPPED)) 1220 if (sock_flag(sk, SOCK_ZAPPED))
1210 if (atalk_autobind(sk) < 0) 1221 if (atalk_autobind(sk) < 0)
1211 return -EBUSY; 1222 goto out;
1212 1223
1224 err = -ENETUNREACH;
1213 if (!atrtr_get_dev(&addr->sat_addr)) 1225 if (!atrtr_get_dev(&addr->sat_addr))
1214 return -ENETUNREACH; 1226 goto out;
1215 1227
1216 at->dest_port = addr->sat_port; 1228 at->dest_port = addr->sat_port;
1217 at->dest_net = addr->sat_addr.s_net; 1229 at->dest_net = addr->sat_addr.s_net;
@@ -1219,7 +1231,10 @@ static int atalk_connect(struct socket *sock, struct sockaddr *uaddr,
1219 1231
1220 sock->state = SS_CONNECTED; 1232 sock->state = SS_CONNECTED;
1221 sk->sk_state = TCP_ESTABLISHED; 1233 sk->sk_state = TCP_ESTABLISHED;
1222 return 0; 1234 err = 0;
1235out:
1236 unlock_kernel();
1237 return err;
1223} 1238}
1224 1239
1225/* 1240/*
@@ -1232,17 +1247,21 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1232 struct sockaddr_at sat; 1247 struct sockaddr_at sat;
1233 struct sock *sk = sock->sk; 1248 struct sock *sk = sock->sk;
1234 struct atalk_sock *at = at_sk(sk); 1249 struct atalk_sock *at = at_sk(sk);
1250 int err;
1235 1251
1252 lock_kernel();
1253 err = -ENOBUFS;
1236 if (sock_flag(sk, SOCK_ZAPPED)) 1254 if (sock_flag(sk, SOCK_ZAPPED))
1237 if (atalk_autobind(sk) < 0) 1255 if (atalk_autobind(sk) < 0)
1238 return -ENOBUFS; 1256 goto out;
1239 1257
1240 *uaddr_len = sizeof(struct sockaddr_at); 1258 *uaddr_len = sizeof(struct sockaddr_at);
1241 memset(&sat.sat_zero, 0, sizeof(sat.sat_zero)); 1259 memset(&sat.sat_zero, 0, sizeof(sat.sat_zero));
1242 1260
1243 if (peer) { 1261 if (peer) {
1262 err = -ENOTCONN;
1244 if (sk->sk_state != TCP_ESTABLISHED) 1263 if (sk->sk_state != TCP_ESTABLISHED)
1245 return -ENOTCONN; 1264 goto out;
1246 1265
1247 sat.sat_addr.s_net = at->dest_net; 1266 sat.sat_addr.s_net = at->dest_net;
1248 sat.sat_addr.s_node = at->dest_node; 1267 sat.sat_addr.s_node = at->dest_node;
@@ -1253,9 +1272,23 @@ static int atalk_getname(struct socket *sock, struct sockaddr *uaddr,
1253 sat.sat_port = at->src_port; 1272 sat.sat_port = at->src_port;
1254 } 1273 }
1255 1274
1275 err = 0;
1256 sat.sat_family = AF_APPLETALK; 1276 sat.sat_family = AF_APPLETALK;
1257 memcpy(uaddr, &sat, sizeof(sat)); 1277 memcpy(uaddr, &sat, sizeof(sat));
1258 return 0; 1278
1279out:
1280 unlock_kernel();
1281 return err;
1282}
1283
1284static unsigned int atalk_poll(struct file *file, struct socket *sock,
1285 poll_table *wait)
1286{
1287 int err;
1288 lock_kernel();
1289 err = datagram_poll(file, sock, wait);
1290 unlock_kernel();
1291 return err;
1259} 1292}
1260 1293
1261#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE) 1294#if defined(CONFIG_IPDDP) || defined(CONFIG_IPDDP_MODULE)
@@ -1563,23 +1596,28 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1563 if (len > DDP_MAXSZ) 1596 if (len > DDP_MAXSZ)
1564 return -EMSGSIZE; 1597 return -EMSGSIZE;
1565 1598
1599 lock_kernel();
1566 if (usat) { 1600 if (usat) {
1601 err = -EBUSY;
1567 if (sock_flag(sk, SOCK_ZAPPED)) 1602 if (sock_flag(sk, SOCK_ZAPPED))
1568 if (atalk_autobind(sk) < 0) 1603 if (atalk_autobind(sk) < 0)
1569 return -EBUSY; 1604 goto out;
1570 1605
1606 err = -EINVAL;
1571 if (msg->msg_namelen < sizeof(*usat) || 1607 if (msg->msg_namelen < sizeof(*usat) ||
1572 usat->sat_family != AF_APPLETALK) 1608 usat->sat_family != AF_APPLETALK)
1573 return -EINVAL; 1609 goto out;
1574 1610
1611 err = -EPERM;
1575 /* netatalk didn't implement this check */ 1612 /* netatalk didn't implement this check */
1576 if (usat->sat_addr.s_node == ATADDR_BCAST && 1613 if (usat->sat_addr.s_node == ATADDR_BCAST &&
1577 !sock_flag(sk, SOCK_BROADCAST)) { 1614 !sock_flag(sk, SOCK_BROADCAST)) {
1578 return -EPERM; 1615 goto out;
1579 } 1616 }
1580 } else { 1617 } else {
1618 err = -ENOTCONN;
1581 if (sk->sk_state != TCP_ESTABLISHED) 1619 if (sk->sk_state != TCP_ESTABLISHED)
1582 return -ENOTCONN; 1620 goto out;
1583 usat = &local_satalk; 1621 usat = &local_satalk;
1584 usat->sat_family = AF_APPLETALK; 1622 usat->sat_family = AF_APPLETALK;
1585 usat->sat_port = at->dest_port; 1623 usat->sat_port = at->dest_port;
@@ -1603,8 +1641,9 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1603 1641
1604 rt = atrtr_find(&at_hint); 1642 rt = atrtr_find(&at_hint);
1605 } 1643 }
1644 err = ENETUNREACH;
1606 if (!rt) 1645 if (!rt)
1607 return -ENETUNREACH; 1646 goto out;
1608 1647
1609 dev = rt->dev; 1648 dev = rt->dev;
1610 1649
@@ -1614,7 +1653,7 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1614 size += dev->hard_header_len; 1653 size += dev->hard_header_len;
1615 skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err); 1654 skb = sock_alloc_send_skb(sk, size, (flags & MSG_DONTWAIT), &err);
1616 if (!skb) 1655 if (!skb)
1617 return err; 1656 goto out;
1618 1657
1619 skb->sk = sk; 1658 skb->sk = sk;
1620 skb_reserve(skb, ddp_dl->header_length); 1659 skb_reserve(skb, ddp_dl->header_length);
@@ -1637,7 +1676,8 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1637 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); 1676 err = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len);
1638 if (err) { 1677 if (err) {
1639 kfree_skb(skb); 1678 kfree_skb(skb);
1640 return -EFAULT; 1679 err = -EFAULT;
1680 goto out;
1641 } 1681 }
1642 1682
1643 if (sk->sk_no_check == 1) 1683 if (sk->sk_no_check == 1)
@@ -1676,7 +1716,8 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1676 rt = atrtr_find(&at_lo); 1716 rt = atrtr_find(&at_lo);
1677 if (!rt) { 1717 if (!rt) {
1678 kfree_skb(skb); 1718 kfree_skb(skb);
1679 return -ENETUNREACH; 1719 err = -ENETUNREACH;
1720 goto out;
1680 } 1721 }
1681 dev = rt->dev; 1722 dev = rt->dev;
1682 skb->dev = dev; 1723 skb->dev = dev;
@@ -1696,7 +1737,9 @@ static int atalk_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1696 } 1737 }
1697 SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len); 1738 SOCK_DEBUG(sk, "SK %p: Done write (%Zd).\n", sk, len);
1698 1739
1699 return len; 1740out:
1741 unlock_kernel();
1742 return err ? : len;
1700} 1743}
1701 1744
1702static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg, 1745static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
@@ -1708,10 +1751,13 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1708 int copied = 0; 1751 int copied = 0;
1709 int offset = 0; 1752 int offset = 0;
1710 int err = 0; 1753 int err = 0;
1711 struct sk_buff *skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT, 1754 struct sk_buff *skb;
1755
1756 lock_kernel();
1757 skb = skb_recv_datagram(sk, flags & ~MSG_DONTWAIT,
1712 flags & MSG_DONTWAIT, &err); 1758 flags & MSG_DONTWAIT, &err);
1713 if (!skb) 1759 if (!skb)
1714 return err; 1760 goto out;
1715 1761
1716 /* FIXME: use skb->cb to be able to use shared skbs */ 1762 /* FIXME: use skb->cb to be able to use shared skbs */
1717 ddp = ddp_hdr(skb); 1763 ddp = ddp_hdr(skb);
@@ -1739,6 +1785,9 @@ static int atalk_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr
1739 } 1785 }
1740 1786
1741 skb_free_datagram(sk, skb); /* Free the datagram. */ 1787 skb_free_datagram(sk, skb); /* Free the datagram. */
1788
1789out:
1790 unlock_kernel();
1742 return err ? : copied; 1791 return err ? : copied;
1743} 1792}
1744 1793
@@ -1810,24 +1859,26 @@ static int atalk_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1810static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) 1859static int atalk_compat_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
1811{ 1860{
1812 /* 1861 /*
1813 * All Appletalk ioctls except SIOCATALKDIFADDR are standard. And 1862 * SIOCATALKDIFADDR is a SIOCPROTOPRIVATE ioctl number, so we
1814 * SIOCATALKDIFADDR is handled by upper layer as well, so there is 1863 * cannot handle it in common code. The data we access if ifreq
1815 * nothing to do. Eventually SIOCATALKDIFADDR should be moved 1864 * here is compatible, so we can simply call the native
1816 * here so there is no generic SIOCPROTOPRIVATE translation in the 1865 * handler.
1817 * system.
1818 */ 1866 */
1867 if (cmd == SIOCATALKDIFADDR)
1868 return atalk_ioctl(sock, cmd, (unsigned long)compat_ptr(arg));
1869
1819 return -ENOIOCTLCMD; 1870 return -ENOIOCTLCMD;
1820} 1871}
1821#endif 1872#endif
1822 1873
1823 1874
1824static struct net_proto_family atalk_family_ops = { 1875static const struct net_proto_family atalk_family_ops = {
1825 .family = PF_APPLETALK, 1876 .family = PF_APPLETALK,
1826 .create = atalk_create, 1877 .create = atalk_create,
1827 .owner = THIS_MODULE, 1878 .owner = THIS_MODULE,
1828}; 1879};
1829 1880
1830static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = { 1881static const struct proto_ops atalk_dgram_ops = {
1831 .family = PF_APPLETALK, 1882 .family = PF_APPLETALK,
1832 .owner = THIS_MODULE, 1883 .owner = THIS_MODULE,
1833 .release = atalk_release, 1884 .release = atalk_release,
@@ -1836,7 +1887,7 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
1836 .socketpair = sock_no_socketpair, 1887 .socketpair = sock_no_socketpair,
1837 .accept = sock_no_accept, 1888 .accept = sock_no_accept,
1838 .getname = atalk_getname, 1889 .getname = atalk_getname,
1839 .poll = datagram_poll, 1890 .poll = atalk_poll,
1840 .ioctl = atalk_ioctl, 1891 .ioctl = atalk_ioctl,
1841#ifdef CONFIG_COMPAT 1892#ifdef CONFIG_COMPAT
1842 .compat_ioctl = atalk_compat_ioctl, 1893 .compat_ioctl = atalk_compat_ioctl,
@@ -1851,8 +1902,6 @@ static const struct proto_ops SOCKOPS_WRAPPED(atalk_dgram_ops) = {
1851 .sendpage = sock_no_sendpage, 1902 .sendpage = sock_no_sendpage,
1852}; 1903};
1853 1904
1854SOCKOPS_WRAP(atalk_dgram, PF_APPLETALK);
1855
1856static struct notifier_block ddp_notifier = { 1905static struct notifier_block ddp_notifier = {
1857 .notifier_call = ddp_device_event, 1906 .notifier_call = ddp_device_event,
1858}; 1907};