X-Git-Url: http://ftp.safe.ca/?a=blobdiff_plain;f=net%2Fllc%2Faf_llc.c;h=56fd85ab358e3b9c93bf2ff811acd4a9499491ea;hb=eca217b36e5d7d4377493d5cedd89105e66a5a72;hp=7465170a36cabae04eca8f3f5d179924d0c33a58;hpb=624d1164730d58a494cc5aa4afa37d02c41e83a7;p=safe%2Fjmp%2Flinux-2.6 diff --git a/net/llc/af_llc.c b/net/llc/af_llc.c index 7465170..56fd85a 100644 --- a/net/llc/af_llc.c +++ b/net/llc/af_llc.c @@ -20,7 +20,6 @@ * * See the GNU General Public License for more details. */ -#include #include #include #include @@ -65,10 +64,10 @@ static inline u16 llc_ui_next_link_no(int sap) * * Given an ARP header type return the corresponding ethernet protocol. */ -static inline u16 llc_proto_type(u16 arphrd) +static inline __be16 llc_proto_type(u16 arphrd) { return arphrd == ARPHRD_IEEE802_TR ? - htons(ETH_P_TR_802_2) : htons(ETH_P_802_2); + htons(ETH_P_TR_802_2) : htons(ETH_P_802_2); } /** @@ -104,7 +103,6 @@ static inline u8 llc_ui_header_len(struct sock *sk, struct sockaddr_llc *addr) * llc_ui_send_data - send data via reliable llc2 connection * @sk: Connection the socket is using. * @skb: Data the user wishes to send. - * @addr: Source and destination fields provided by the user. * @noblock: can we block waiting for data? * * Send data via reliable llc2 connection. @@ -115,7 +113,7 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock) struct llc_sock* llc = llc_sk(sk); int rc = 0; - if (unlikely(llc_data_accept_state(llc->state) || + if (unlikely(llc_data_accept_state(llc->state) || llc->remote_busy_flag || llc->p_flag)) { long timeout = sock_sndtimeo(sk, noblock); @@ -129,10 +127,8 @@ static int llc_ui_send_data(struct sock* sk, struct sk_buff *skb, int noblock) static void llc_ui_sk_init(struct socket *sock, struct sock *sk) { + sock_graft(sk, sock); sk->sk_type = sock->type; - sk->sk_sleep = &sock->wait; - sk->sk_socket = sock; - sock->sk = sk; sock->ops = &llc_ui_ops; } @@ -151,14 +147,20 @@ static struct proto llc_proto = { * socket type we have available. * Returns 0 upon success, negative upon failure. */ -static int llc_ui_create(struct socket *sock, int protocol) +static int llc_ui_create(struct net *net, struct socket *sock, int protocol) { struct sock *sk; int rc = -ESOCKTNOSUPPORT; + if (!capable(CAP_NET_RAW)) + return -EPERM; + + if (net != &init_net) + return -EAFNOSUPPORT; + if (likely(sock->type == SOCK_DGRAM || sock->type == SOCK_STREAM)) { rc = -ENOMEM; - sk = llc_sk_alloc(PF_LLC, GFP_KERNEL, &llc_proto); + sk = llc_sk_alloc(net, PF_LLC, GFP_KERNEL, &llc_proto); if (sk) { rc = 0; llc_ui_sk_init(sock, sk); @@ -183,7 +185,7 @@ static int llc_ui_release(struct socket *sock) sock_hold(sk); lock_sock(sk); llc = llc_sk(sk); - dprintk("%s: closing local(%02X) remote(%02X)\n", __FUNCTION__, + dprintk("%s: closing local(%02X) remote(%02X)\n", __func__, llc->laddr.lsap, llc->daddr.lsap); if (!llc_send_disc(sk)) llc_ui_wait_for_disc(sk, sk->sk_rcvtimeo); @@ -250,7 +252,7 @@ static int llc_ui_autobind(struct socket *sock, struct sockaddr_llc *addr) if (!sock_flag(sk, SOCK_ZAPPED)) goto out; rc = -ENODEV; - llc->dev = dev_getfirstbyhwtype(addr->sllc_arphrd); + llc->dev = dev_getfirstbyhwtype(&init_net, addr->sllc_arphrd); if (!llc->dev) goto out; rc = -EUSERS; @@ -293,7 +295,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) struct llc_sap *sap; int rc = -EINVAL; - dprintk("%s: binding %02X\n", __FUNCTION__, addr->sllc_sap); + dprintk("%s: binding %02X\n", __func__, addr->sllc_sap); if (unlikely(!sock_flag(sk, SOCK_ZAPPED) || addrlen != sizeof(*addr))) goto out; rc = -EAFNOSUPPORT; @@ -301,7 +303,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) goto out; rc = -ENODEV; rtnl_lock(); - llc->dev = dev_getbyhwaddr(addr->sllc_arphrd, addr->sllc_mac); + llc->dev = dev_getbyhwaddr(&init_net, addr->sllc_arphrd, addr->sllc_mac); rtnl_unlock(); if (!llc->dev) goto out; @@ -325,7 +327,7 @@ static int llc_ui_bind(struct socket *sock, struct sockaddr *uaddr, int addrlen) memset(&laddr, 0, sizeof(laddr)); memset(&daddr, 0, sizeof(daddr)); /* - * FIXME: check if the the address is multicast, + * FIXME: check if the address is multicast, * only SOCK_DGRAM can do this. */ memcpy(laddr.mac, addr->sllc_mac, IFHWADDRLEN); @@ -430,7 +432,7 @@ static int llc_ui_connect(struct socket *sock, struct sockaddr *uaddr, rc = llc_establish_connection(sk, llc->dev->dev_addr, addr->sllc_mac, addr->sllc_sap); if (rc) { - dprintk("%s: llc_ui_send_conn failed :-(\n", __FUNCTION__); + dprintk("%s: llc_ui_send_conn failed :-(\n", __func__); sock->state = SS_UNCONNECTED; sk->sk_state = TCP_CLOSE; goto out; @@ -602,8 +604,8 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) struct sk_buff *skb; int rc = -EOPNOTSUPP; - dprintk("%s: accepting on %02X\n", __FUNCTION__, - llc_sk(sk)->laddr.lsap); + dprintk("%s: accepting on %02X\n", __func__, + llc_sk(sk)->laddr.lsap); lock_sock(sk); if (unlikely(sk->sk_type != SOCK_STREAM)) goto out; @@ -617,8 +619,8 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) if (rc) goto out; } - dprintk("%s: got a new connection on %02X\n", __FUNCTION__, - llc_sk(sk)->laddr.lsap); + dprintk("%s: got a new connection on %02X\n", __func__, + llc_sk(sk)->laddr.lsap); skb = skb_dequeue(&sk->sk_receive_queue); rc = -EINVAL; if (!skb->sk) @@ -638,7 +640,7 @@ static int llc_ui_accept(struct socket *sock, struct socket *newsock, int flags) /* put original socket back into a clean listen state. */ sk->sk_state = TCP_LISTEN; sk->sk_ack_backlog--; - dprintk("%s: ok success on %02X, client on %02X\n", __FUNCTION__, + dprintk("%s: ok success on %02X, client on %02X\n", __func__, llc_sk(sk)->addr.sllc_sap, newllc->daddr.lsap); frees: kfree_skb(skb); @@ -674,7 +676,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, lock_sock(sk); copied = -ENOTCONN; - if (sk->sk_state == TCP_LISTEN) + if (unlikely(sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_LISTEN)) goto out; timeo = sock_rcvtimeo(sk, nonblock); @@ -683,7 +685,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, if (flags & MSG_PEEK) { peek_seq = llc->copied_seq; seq = &peek_seq; - } + } target = sock_rcvlowat(sk, flags & MSG_WAITALL, len); copied = 0; @@ -733,7 +735,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, if (sk->sk_shutdown & RCV_SHUTDOWN) break; - if (sk->sk_state == TCP_CLOSE) { + if (sk->sk_type == SOCK_STREAM && sk->sk_state == TCP_CLOSE) { if (!sock_flag(sk, SOCK_DONE)) { /* * This occurs when user tries to read @@ -760,7 +762,7 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, if (net_ratelimit()) printk(KERN_DEBUG "LLC(%s:%d): Application " "bug, race in MSG_PEEK.\n", - current->comm, current->pid); + current->comm, task_pid_nr(current)); peek_seq = llc->copied_seq; } continue; @@ -785,24 +787,20 @@ static int llc_ui_recvmsg(struct kiocb *iocb, struct socket *sock, copied += used; len -= used; - if (used + offset < skb->len) - continue; - if (!(flags & MSG_PEEK)) { sk_eat_skb(sk, skb, 0); *seq = 0; } + + /* For non stream protcols we get one packet per recvmsg call */ + if (sk->sk_type != SOCK_STREAM) + goto copy_uaddr; + + /* Partial read */ + if (used + offset < skb->len) + continue; } while (len > 0); - /* - * According to UNIX98, msg_name/msg_namelen are ignored - * on connected socket. -ANK - * But... af_llc still doesn't have separate sets of methods for - * SOCK_DGRAM and SOCK_STREAM :-( So we have to do this test, will - * eventually fix this tho :-) -acme - */ - if (sk->sk_type == SOCK_DGRAM) - goto copy_uaddr; out: release_sock(sk); return copied; @@ -835,7 +833,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, size_t size = 0; int rc = -EINVAL, copied = 0, hdrlen; - dprintk("%s: sending from %02X to %02X\n", __FUNCTION__, + dprintk("%s: sending from %02X to %02X\n", __func__, llc->laddr.lsap, llc->daddr.lsap); lock_sock(sk); if (addr) { @@ -865,7 +863,7 @@ static int llc_ui_sendmsg(struct kiocb *iocb, struct socket *sock, goto release; skb->dev = llc->dev; skb->protocol = llc_proto_type(addr->sllc_arphrd); - skb_reserve(skb, hdrlen); + skb_reserve(skb, hdrlen); rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied); if (rc) goto out; @@ -893,7 +891,7 @@ out: kfree_skb(skb); release: dprintk("%s: failed sending from %02X to %02X: %d\n", - __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc); + __func__, llc->laddr.lsap, llc->daddr.lsap, rc); } release_sock(sk); return rc ? : copied; @@ -1121,11 +1119,11 @@ static const struct proto_ops llc_ui_ops = { }; static char llc_proc_err_msg[] __initdata = - KERN_CRIT "LLC: Unable to register the proc_fs entries\n"; + KERN_CRIT "LLC: Unable to register the proc_fs entries\n"; static char llc_sysctl_err_msg[] __initdata = - KERN_CRIT "LLC: Unable to register the sysctl entries\n"; + KERN_CRIT "LLC: Unable to register the sysctl entries\n"; static char llc_sock_err_msg[] __initdata = - KERN_CRIT "LLC: Unable to register the network family\n"; + KERN_CRIT "LLC: Unable to register the network family\n"; static int __init llc2_init(void) {