public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH 1/4] l2cap endianness annotations
@ 2006-10-15 21:29 Al Viro
  2006-10-15 23:39 ` Marcel Holtmann
  0 siblings, 1 reply; 4+ messages in thread
From: Al Viro @ 2006-10-15 21:29 UTC (permalink / raw)
  To: Linus Torvalds; +Cc: davem, linux-kernel

Signed-off-by: Al Viro <viro@zeniv.linux.org.uk>
---
 include/net/bluetooth/l2cap.h |   50 +++++++++++++++++++++--------------------
 net/bluetooth/l2cap.c         |   40 +++++++++++++++++----------------
 2 files changed, 46 insertions(+), 44 deletions(-)

diff --git a/include/net/bluetooth/l2cap.h b/include/net/bluetooth/l2cap.h
index 8242a0e..104e23b 100644
--- a/include/net/bluetooth/l2cap.h
+++ b/include/net/bluetooth/l2cap.h
@@ -34,7 +34,7 @@ #define L2CAP_CONN_TIMEOUT	(HZ * 40)
 /* L2CAP socket address */
 struct sockaddr_l2 {
 	sa_family_t	l2_family;
-	unsigned short	l2_psm;
+	__le16		l2_psm;
 	bdaddr_t	l2_bdaddr;
 };
 
@@ -76,32 +76,32 @@ #define L2CAP_INFO_RSP    0x0b
 
 /* L2CAP structures */
 struct l2cap_hdr {
-	__u16      len;
-	__u16      cid;
+	__le16      len;
+	__le16      cid;
 } __attribute__ ((packed));
 #define L2CAP_HDR_SIZE		4
 
 struct l2cap_cmd_hdr {
 	__u8       code;
 	__u8       ident;
-	__u16      len;
+	__le16     len;
 } __attribute__ ((packed));
 #define L2CAP_CMD_HDR_SIZE	4
 
 struct l2cap_cmd_rej {
-	__u16      reason;
+	__le16      reason;
 } __attribute__ ((packed));
 
 struct l2cap_conn_req {
-	__u16      psm;
-	__u16      scid;
+	__le16      psm;
+	__le16      scid;
 } __attribute__ ((packed));
 
 struct l2cap_conn_rsp {
-	__u16      dcid;
-	__u16      scid;
-	__u16      result;
-	__u16      status;
+	__le16      dcid;
+	__le16      scid;
+	__le16      result;
+	__le16      status;
 } __attribute__ ((packed));
 
 /* connect result */
@@ -117,15 +117,15 @@ #define L2CAP_CS_AUTHEN_PEND  0x0001
 #define L2CAP_CS_AUTHOR_PEND  0x0002
 
 struct l2cap_conf_req {
-	__u16      dcid;
-	__u16      flags;
+	__le16      dcid;
+	__le16      flags;
 	__u8       data[0];
 } __attribute__ ((packed));
 
 struct l2cap_conf_rsp {
-	__u16      scid;
-	__u16      flags;
-	__u16      result;
+	__le16      scid;
+	__le16      flags;
+	__le16      result;
 	__u8       data[0];
 } __attribute__ ((packed));
 
@@ -147,23 +147,23 @@ #define L2CAP_CONF_RFC		0x04
 #define L2CAP_CONF_MAX_SIZE	22
 
 struct l2cap_disconn_req {
-	__u16      dcid;
-	__u16      scid;
+	__le16      dcid;
+	__le16      scid;
 } __attribute__ ((packed));
 
 struct l2cap_disconn_rsp {
-	__u16      dcid;
-	__u16      scid;
+	__le16      dcid;
+	__le16      scid;
 } __attribute__ ((packed));
 
 struct l2cap_info_req {
-	__u16       type;
+	__le16       type;
 	__u8        data[0];
 } __attribute__ ((packed));
 
 struct l2cap_info_rsp {
-	__u16       type;
-	__u16       result;
+	__le16       type;
+	__le16       result;
 	__u8        data[0];
 } __attribute__ ((packed));
 
@@ -205,7 +205,7 @@ #define l2cap_pi(sk) ((struct l2cap_pinf
 
 struct l2cap_pinfo {
 	struct bt_sock	bt;
-	__u16		psm;
+	__le16		psm;
 	__u16		dcid;
 	__u16		scid;
 
@@ -221,7 +221,7 @@ struct l2cap_pinfo {
 
 	__u8		ident;
 
-	__u16		sport;
+	__le16		sport;
 
 	struct l2cap_conn	*conn;
 	struct sock		*next_c;
diff --git a/net/bluetooth/l2cap.c b/net/bluetooth/l2cap.c
index d56f60b..0995420 100644
--- a/net/bluetooth/l2cap.c
+++ b/net/bluetooth/l2cap.c
@@ -353,7 +353,7 @@ static inline int l2cap_send_cmd(struct 
 }
 
 /* ---- Socket interface ---- */
-static struct sock *__l2cap_get_sock_by_addr(u16 psm, bdaddr_t *src)
+static struct sock *__l2cap_get_sock_by_addr(__le16 psm, bdaddr_t *src)
 {
 	struct sock *sk;
 	struct hlist_node *node;
@@ -368,7 +368,7 @@ found:
 /* Find socket with psm and source bdaddr.
  * Returns closest match.
  */
-static struct sock *__l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src)
+static struct sock *__l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
 {
 	struct sock *sk = NULL, *sk1 = NULL;
 	struct hlist_node *node;
@@ -392,7 +392,7 @@ static struct sock *__l2cap_get_sock_by_
 
 /* Find socket with given address (psm, src).
  * Returns locked socket */
-static inline struct sock *l2cap_get_sock_by_psm(int state, u16 psm, bdaddr_t *src)
+static inline struct sock *l2cap_get_sock_by_psm(int state, __le16 psm, bdaddr_t *src)
 {
 	struct sock *s;
 	read_lock(&l2cap_sk_list.lock);
@@ -866,7 +866,7 @@ static inline int l2cap_do_send(struct s
 	lh->len = __cpu_to_le16(len + (hlen - L2CAP_HDR_SIZE));
 
 	if (sk->sk_type == SOCK_DGRAM)
-		put_unaligned(l2cap_pi(sk)->psm, (u16 *) skb_put(skb, 2));
+		put_unaligned(l2cap_pi(sk)->psm, (__le16 *) skb_put(skb, 2));
 
 	if (memcpy_fromiovec(skb_put(skb, count), msg->msg_iov, count)) {
 		err = -EFAULT;
@@ -1243,11 +1243,11 @@ static inline int l2cap_get_conf_opt(voi
 		break;
 
 	case 2:
-		*val = __le16_to_cpu(*((u16 *)opt->val));
+		*val = __le16_to_cpu(*((__le16 *)opt->val));
 		break;
 
 	case 4:
-		*val = __le32_to_cpu(*((u32 *)opt->val));
+		*val = __le32_to_cpu(*((__le32 *)opt->val));
 		break;
 
 	default:
@@ -1310,11 +1310,11 @@ static void l2cap_add_conf_opt(void **pt
 		break;
 
 	case 2:
-		*((u16 *) opt->val) = __cpu_to_le16(val);
+		*((__le16 *) opt->val) = __cpu_to_le16(val);
 		break;
 
 	case 4:
-		*((u32 *) opt->val) = __cpu_to_le32(val);
+		*((__le32 *) opt->val) = __cpu_to_le32(val);
 		break;
 
 	default:
@@ -1393,7 +1393,7 @@ static inline int l2cap_connect_req(stru
 	int result = 0, status = 0;
 
 	u16 dcid = 0, scid = __le16_to_cpu(req->scid);
-	u16 psm  = req->psm;
+	__le16 psm  = req->psm;
 
 	BT_DBG("psm 0x%2.2x scid 0x%4.4x", psm, scid);
 
@@ -1533,7 +1533,7 @@ static inline int l2cap_config_req(struc
 	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
 		return -ENOENT;
 
-	l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
+	l2cap_parse_conf_req(sk, req->data, __le16_to_cpu(cmd->len) - sizeof(*req));
 
 	if (flags & 0x0001) {
 		/* Incomplete config. Send empty response. */
@@ -1717,15 +1717,16 @@ static inline void l2cap_sig_channel(str
 	l2cap_raw_recv(conn, skb);
 
 	while (len >= L2CAP_CMD_HDR_SIZE) {
+		int this_len;
 		memcpy(&cmd, data, L2CAP_CMD_HDR_SIZE);
 		data += L2CAP_CMD_HDR_SIZE;
 		len  -= L2CAP_CMD_HDR_SIZE;
 
-		cmd.len = __le16_to_cpu(cmd.len);
+		this_len = __le16_to_cpu(cmd.len);
 
-		BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, cmd.len, cmd.ident);
+		BT_DBG("code 0x%2.2x len %d id 0x%2.2x", cmd.code, this_len, cmd.ident);
 
-		if (cmd.len > len || !cmd.ident) {
+		if (this_len > len || !cmd.ident) {
 			BT_DBG("corrupted command");
 			break;
 		}
@@ -1760,7 +1761,7 @@ static inline void l2cap_sig_channel(str
 			break;
 
 		case L2CAP_ECHO_REQ:
-			l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, cmd.len, data);
+			l2cap_send_cmd(conn, cmd.ident, L2CAP_ECHO_RSP, this_len, data);
 			break;
 
 		case L2CAP_ECHO_RSP:
@@ -1789,8 +1790,8 @@ static inline void l2cap_sig_channel(str
 			l2cap_send_cmd(conn, cmd.ident, L2CAP_COMMAND_REJ, sizeof(rej), &rej);
 		}
 
-		data += cmd.len;
-		len  -= cmd.len;
+		data += this_len;
+		len  -= this_len;
 	}
 
 	kfree_skb(skb);
@@ -1832,7 +1833,7 @@ done:
 	return 0;
 }
 
-static inline int l2cap_conless_channel(struct l2cap_conn *conn, u16 psm, struct sk_buff *skb)
+static inline int l2cap_conless_channel(struct l2cap_conn *conn, __le16 psm, struct sk_buff *skb)
 {
 	struct sock *sk;
 
@@ -1862,7 +1863,8 @@ done:
 static void l2cap_recv_frame(struct l2cap_conn *conn, struct sk_buff *skb)
 {
 	struct l2cap_hdr *lh = (void *) skb->data;
-	u16 cid, psm, len;
+	u16 cid, len;
+	__le16 psm;
 
 	skb_pull(skb, L2CAP_HDR_SIZE);
 	cid = __le16_to_cpu(lh->cid);
@@ -1876,7 +1878,7 @@ static void l2cap_recv_frame(struct l2ca
 		break;
 
 	case 0x0002:
-		psm = get_unaligned((u16 *) skb->data);
+		psm = get_unaligned((__le16 *) skb->data);
 		skb_pull(skb, 2);
 		l2cap_conless_channel(conn, psm, skb);
 		break;
-- 
1.4.2.GIT


^ permalink raw reply related	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/4] l2cap endianness annotations
  2006-10-15 21:29 [PATCH 1/4] l2cap endianness annotations Al Viro
@ 2006-10-15 23:39 ` Marcel Holtmann
  2006-10-15 23:49   ` Al Viro
  2006-10-16  0:12   ` Al Viro
  0 siblings, 2 replies; 4+ messages in thread
From: Marcel Holtmann @ 2006-10-15 23:39 UTC (permalink / raw)
  To: Al Viro; +Cc: Linus Torvalds, davem, linux-kernel

Hi Al,

> @@ -34,7 +34,7 @@ #define L2CAP_CONN_TIMEOUT	(HZ * 40)
>  /* L2CAP socket address */
>  struct sockaddr_l2 {
>  	sa_family_t	l2_family;
> -	unsigned short	l2_psm;
> +	__le16		l2_psm;
>  	bdaddr_t	l2_bdaddr;
>  };

this data structure is visible to the userspace (via the Bluetooth
library headers). Do we annotate them, too?

> @@ -205,7 +205,7 @@ #define l2cap_pi(sk) ((struct l2cap_pinf
>  
>  struct l2cap_pinfo {
>  	struct bt_sock	bt;
> -	__u16		psm;
> +	__le16		psm;
>  	__u16		dcid;
>  	__u16		scid;
>  
> @@ -221,7 +221,7 @@ struct l2cap_pinfo {
>  
>  	__u8		ident;
>  
> -	__u16		sport;
> +	__le16		sport;
>  
>  	struct l2cap_conn	*conn;
>  	struct sock		*next_c;

These are internal. We should have to annotate them. They should store
it in host order. If not, than that is the problem.

> @@ -1533,7 +1533,7 @@ static inline int l2cap_config_req(struc
>  	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
>  		return -ENOENT;
>  
> -	l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
> +	l2cap_parse_conf_req(sk, req->data, __le16_to_cpu(cmd->len) - sizeof(*req));

I have to look into this change. It basically means that this code never
worked on big endian systems, but it actually does.

Regards

Marcel



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/4] l2cap endianness annotations
  2006-10-15 23:39 ` Marcel Holtmann
@ 2006-10-15 23:49   ` Al Viro
  2006-10-16  0:12   ` Al Viro
  1 sibling, 0 replies; 4+ messages in thread
From: Al Viro @ 2006-10-15 23:49 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Linus Torvalds, davem, linux-kernel

On Mon, Oct 16, 2006 at 01:39:03AM +0200, Marcel Holtmann wrote:
> this data structure is visible to the userspace (via the Bluetooth
> library headers). Do we annotate them, too?

Yes. linux/types.h is exported header and it defines all endian types.
 
> > @@ -221,7 +221,7 @@ struct l2cap_pinfo {
> >  
> >  	__u8		ident;
> >  
> > -	__u16		sport;
> > +	__le16		sport;
> >  
> >  	struct l2cap_conn	*conn;
> >  	struct sock		*next_c;
> 
> These are internal. We should have to annotate them. They should store
> it in host order. If not, than that is the problem.

They do not.  Trivial search in vanilla tree shows
                for (psm = 0x1001; psm < 0x1100; psm += 2)
                        if (!__l2cap_get_sock_by_addr(psm, src)) {
                                l2cap_pi(sk)->psm   = htobs(psm);
                                l2cap_pi(sk)->sport = htobs(psm);
                                err = 0;
                                break;
                        }

which is very definitely not putting a host-endian there.  You can
switch it to host-endian, of course, but then you have to modify
at least that place.
 
> > @@ -1533,7 +1533,7 @@ static inline int l2cap_config_req(struc
> >  	if (!(sk = l2cap_get_chan_by_scid(&conn->chan_list, dcid)))
> >  		return -ENOENT;
> >  
> > -	l2cap_parse_conf_req(sk, req->data, cmd->len - sizeof(*req));
> > +	l2cap_parse_conf_req(sk, req->data, __le16_to_cpu(cmd->len) - sizeof(*req));
> 
> I have to look into this change. It basically means that this code never
> worked on big endian systems, but it actually does.

You are misreading it.  Old code flipped cmd->len in place in the caller.
New one doesn't.

^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: [PATCH 1/4] l2cap endianness annotations
  2006-10-15 23:39 ` Marcel Holtmann
  2006-10-15 23:49   ` Al Viro
@ 2006-10-16  0:12   ` Al Viro
  1 sibling, 0 replies; 4+ messages in thread
From: Al Viro @ 2006-10-16  0:12 UTC (permalink / raw)
  To: Marcel Holtmann; +Cc: Linus Torvalds, davem, linux-kernel

On Mon, Oct 16, 2006 at 01:39:03AM +0200, Marcel Holtmann wrote:
> > @@ -205,7 +205,7 @@ #define l2cap_pi(sk) ((struct l2cap_pinf
> >  
> >  struct l2cap_pinfo {
> >  	struct bt_sock	bt;
> > -	__u16		psm;
> > +	__le16		psm;
> >  	__u16		dcid;
> >  	__u16		scid;
> >  
> > @@ -221,7 +221,7 @@ struct l2cap_pinfo {
> >  
> >  	__u8		ident;
> >  
> > -	__u16		sport;
> > +	__le16		sport;
> >  
> >  	struct l2cap_conn	*conn;
> >  	struct sock		*next_c;
> 
> These are internal. We should have to annotate them. They should store
> it in host order. If not, than that is the problem.

BTW, I would leave ->psm is wire order; we compare it to ->l2_psm from
sockaddr_l2 a lot, so putting a conversion there looks odd.

Note that we do pass ->ls_psm to __l2cap_sock_by_addr(), so I'm not sure
if I like the idea of host-endian ->sport; we would need to slap a conversion
there as well.

See also
                bacpy(&bt_sk(sk)->src, &la->l2_bdaddr);
                l2cap_pi(sk)->psm   = la->l2_psm;
                l2cap_pi(sk)->sport = la->l2_psm;
                sk->sk_state = BT_BOUND;
for other place where net-endian gets there.

Are you sure that you want both to be switched to host-endian?

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2006-10-16  0:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-10-15 21:29 [PATCH 1/4] l2cap endianness annotations Al Viro
2006-10-15 23:39 ` Marcel Holtmann
2006-10-15 23:49   ` Al Viro
2006-10-16  0:12   ` Al Viro

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox