Commit 50fc5ecd authored by David S. Miller's avatar David S. Miller

Merge master.kernel.org:/home/acme/BK/llc-2.5

into nuts.ninka.net:/home/davem/src/BK/net-2.5
parents 496ad0ad ae55ac2b
...@@ -878,18 +878,22 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, int size, ...@@ -878,18 +878,22 @@ static int llc_ui_recvmsg(struct socket *sock, struct msghdr *msg, int size,
if (!skb) /* shutdown */ if (!skb) /* shutdown */
goto out; goto out;
copied = skb->len; copied = skb->len;
if (copied > size) { if (copied > size)
copied = size; copied = size;
msg->msg_flags |= MSG_TRUNC;
}
rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied); rc = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
if (rc) if (rc)
goto dgram_free; goto dgram_free;
if (skb->len > copied) {
skb_pull(skb, copied);
skb_queue_head(&sk->receive_queue, skb);
}
if (uaddr) if (uaddr)
memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr)); memcpy(uaddr, llc_ui_skb_cb(skb), sizeof(*uaddr));
msg->msg_namelen = sizeof(*uaddr); msg->msg_namelen = sizeof(*uaddr);
if (!skb->list) {
dgram_free: dgram_free:
kfree_skb(skb); kfree_skb(skb);
}
out: out:
release_sock(sk); release_sock(sk);
return rc ? : copied; return rc ? : copied;
...@@ -915,7 +919,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, ...@@ -915,7 +919,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
int noblock = flags & MSG_DONTWAIT; int noblock = flags & MSG_DONTWAIT;
struct net_device *dev; struct net_device *dev;
struct sk_buff *skb; struct sk_buff *skb;
int rc = -EINVAL, size = 0; int rc = -EINVAL, size = 0, copied = 0, hdrlen;
dprintk("%s: sending from %02X to %02X\n", __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap); dprintk("%s: sending from %02X to %02X\n", __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap);
lock_sock(sk); lock_sock(sk);
...@@ -943,20 +947,26 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, ...@@ -943,20 +947,26 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
goto release; goto release;
} else } else
dev = llc->dev; dev = llc->dev;
size = dev->hard_header_len + len + llc_ui_header_len(sk, addr); hdrlen = dev->hard_header_len + llc_ui_header_len(sk, addr);
rc = -EMSGSIZE; size = hdrlen + len;
if (size > dev->mtu) if (size > dev->mtu)
goto release; size = dev->mtu;
copied = size - hdrlen;
skb = sock_alloc_send_skb(sk, size, noblock, &rc); skb = sock_alloc_send_skb(sk, size, noblock, &rc);
if (!skb) if (!skb)
goto release; goto release;
skb->sk = sk; skb->sk = sk;
skb->dev = dev; skb->dev = dev;
skb->protocol = llc_proto_type(addr->sllc_arphrd); skb->protocol = llc_proto_type(addr->sllc_arphrd);
skb_reserve(skb, dev->hard_header_len + llc_ui_header_len(sk, addr)); skb_reserve(skb, hdrlen);
rc = memcpy_fromiovec(skb_put(skb, len), msg->msg_iov, len); rc = memcpy_fromiovec(skb_put(skb, copied), msg->msg_iov, copied);
if (rc) if (rc)
goto out; goto out;
if (sk->type == SOCK_DGRAM || addr->sllc_ua) {
llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_dmac,
addr->sllc_dsap);
goto out;
}
if (addr->sllc_test) { if (addr->sllc_test) {
llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_dmac, llc_build_and_send_test_pkt(llc->sap, skb, addr->sllc_dmac,
addr->sllc_dsap); addr->sllc_dsap);
...@@ -967,11 +977,6 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, ...@@ -967,11 +977,6 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
addr->sllc_dsap); addr->sllc_dsap);
goto out; goto out;
} }
if (sk->type == SOCK_DGRAM || addr->sllc_ua) {
llc_build_and_send_ui_pkt(llc->sap, skb, addr->sllc_dmac,
addr->sllc_dsap);
goto out;
}
rc = -ENOPROTOOPT; rc = -ENOPROTOOPT;
if (!(sk->type == SOCK_STREAM && !addr->sllc_ua)) if (!(sk->type == SOCK_STREAM && !addr->sllc_ua))
goto out; goto out;
...@@ -986,7 +991,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len, ...@@ -986,7 +991,7 @@ static int llc_ui_sendmsg(struct socket *sock, struct msghdr *msg, int len,
dprintk("%s: failed sending from %02X to %02X: %d\n", dprintk("%s: failed sending from %02X to %02X: %d\n",
__FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc); __FUNCTION__, llc->laddr.lsap, llc->daddr.lsap, rc);
release_sock(sk); release_sock(sk);
return rc ? : len; return rc ? : copied;
} }
/** /**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment