Skip to contentSkip to conversation

ieee802154: add rx LQI from userspace

PATCH In review Clément Péron 4 participants 9 messages Jun 7, 2018 – Aug 6, 2018

Subsystems (3)
lore
Share & tools
lore
#0 lore raw

PATCH 1/1 ieee802154: add rx LQI from userspace

From: Romuald CARI <[email protected]>

The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol.

This LQI data is available in the ancillary data buffer under the SOL_IEEE802154 level as the type WPAN_LQI. The value is an unsigned byte indicating the link quality with values ranging 0-255.

---
 include/net/af_ieee802154.h |  1 +
 net/ieee802154/socket.c     | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
include/net/af_ieee802154.h +1 -0
index a5563d27a3eb..8003a9f6eb43 100644
@@ -56,6 +56,7 @@ struct sockaddr_ieee802154 {
 #define WPAN_WANTACK		0
 #define WPAN_SECURITY		1
 #define WPAN_SECURITY_LEVEL	2
+#define WPAN_WANTLQI		3
 
 #define WPAN_SECURITY_DEFAULT	0
 #define WPAN_SECURITY_OFF	1
net/ieee802154/socket.c +17 -0
index a60658c85a9a..bc6b912603f1 100644
@@ -25,6 +25,7 @@
 #include <linux/termios.h>	/* For TIOCOUTQ/INQ */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/socket.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -452,6 +453,7 @@ struct dgram_sock {
 	unsigned int bound:1;
 	unsigned int connected:1;
 	unsigned int want_ack:1;
+	unsigned int want_lqi:1;
 	unsigned int secen:1;
 	unsigned int secen_override:1;
 	unsigned int seclevel:3;
@@ -486,6 +488,7 @@ static int dgram_init(struct sock *sk)
 	struct dgram_sock *ro = dgram_sk(sk);
 
 	ro->want_ack = 1;
+	ro->want_lqi = 0;
 	return 0;
 }
 
@@ -713,6 +716,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	size_t copied = 0;
 	int err = -EOPNOTSUPP;
 	struct sk_buff *skb;
+	struct dgram_sock *ro = dgram_sk(sk);
 	DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
 
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -744,6 +748,13 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		*addr_len = sizeof(*saddr);
 	}
 
+	if (ro->want_lqi) {
+		err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+			       sizeof(uint8_t), &(mac_cb(skb)->lqi));
+		if (err)
+			goto done;
+	}
+
 	if (flags & MSG_TRUNC)
 		copied = skb->len;
 done:
@@ -847,6 +858,9 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
 	case WPAN_WANTACK:
 		val = ro->want_ack;
 		break;
+	case WPAN_WANTLQI:
+		val = ro->want_lqi;
+		break;
 	case WPAN_SECURITY:
 		if (!ro->secen_override)
 			val = WPAN_SECURITY_DEFAULT;
@@ -892,6 +906,9 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
 	case WPAN_WANTACK:
 		ro->want_ack = !!val;
 		break;
+	case WPAN_WANTLQI:
+		ro->want_lqi = !!val;
+		break;
 	case WPAN_SECURITY:
 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
 		    !ns_capable(net->user_ns, CAP_NET_RAW)) {
Signature · 1 line
2.17.1
#1 lore raw

Could you review it please ?

Thanks,
Clement

Quoted 105 lines · Clément Péron

From: Romuald CARI <[email protected]>

The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol.

This LQI data is available in the ancillary data buffer under the SOL_IEEE802154 level as the type WPAN_LQI. The value is an unsigned byte indicating the link quality with values ranging 0-255.

---
 include/net/af_ieee802154.h |  1 +
 net/ieee802154/socket.c     | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
include/net/af_ieee802154.h +1 -0
index a5563d27a3eb..8003a9f6eb43 100644
@@ -56,6 +56,7 @@ struct sockaddr_ieee802154 {
 #define WPAN_WANTACK           0
 #define WPAN_SECURITY          1
 #define WPAN_SECURITY_LEVEL    2
+#define WPAN_WANTLQI           3
 
 #define WPAN_SECURITY_DEFAULT  0
 #define WPAN_SECURITY_OFF      1
net/ieee802154/socket.c +17 -1
index a60658c85a9a..bc6b912603f1 100644
@@ -25,6 +25,7 @@
 #include <linux/termios.h>     /* For TIOCOUTQ/INQ */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/socket.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -452,6 +453,7 @@ struct dgram_sock {
        unsigned int bound:1;
        unsigned int connected:1;
        unsigned int want_ack:1;
+       unsigned int want_lqi:1;
        unsigned int secen:1;
        unsigned int secen_override:1;
        unsigned int seclevel:3;
@@ -486,6 +488,7 @@ static int dgram_init(struct sock *sk)
        struct dgram_sock *ro = dgram_sk(sk);
 
        ro->want_ack = 1;
+       ro->want_lqi = 0;
        return 0;
 }
 
@@ -713,6 +716,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
        size_t copied = 0;
        int err = -EOPNOTSUPP;
        struct sk_buff *skb;
+       struct dgram_sock *ro = dgram_sk(sk);
        DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
 
        skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -744,6 +748,13 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
                *addr_len = sizeof(*saddr);
        }
 
+       if (ro->want_lqi) {
+               err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+                              sizeof(uint8_t), &(mac_cb(skb)->lqi));
+               if (err)
+                       goto done;
+       }
+
        if (flags & MSG_TRUNC)
                copied = skb->len;
 done:
@@ -847,6 +858,9 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
        case WPAN_WANTACK:
                val = ro->want_ack;
                break;
+       case WPAN_WANTLQI:
+               val = ro->want_lqi;
+               break;
        case WPAN_SECURITY:
                if (!ro->secen_override)
                        val = WPAN_SECURITY_DEFAULT;
@@ -892,6 +906,9 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
        case WPAN_WANTACK:
                ro->want_ack = !!val;
                break;
+       case WPAN_WANTLQI:
+               ro->want_lqi = !!val;
+               break;
        case WPAN_SECURITY:
                if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
                    !ns_capable(net->user_ns, CAP_NET_RAW)) {
--

2.17.1

#2 lore raw

Hello.

Quoted 2 lines · Clément Péron

Could you review it please ?

Yes, I will. Sorry for the delay, I am just back from 4 weeks parental leave. A few thousand mails top go through in total.

If you could bare with me for a few more days that would be appreciated. I have all the patches I need to review here marked in my local inbox already.

regards
Stefan Schmidt

#3 lore raw
In reply to Clément Péron

Hi,

Quoted 2 lines · Clément Péron

Could you review it please ?

sorry... I was thinking a lot what I can contribute to this patch, I want to make it short.

I see your use case and your use case has of course a valid point.

What I can say about the code? This socket layer was contributed a lot in a time where the subsystem was unmaintained. Stefan has some experience with this socket layer by doing some examples [0].

In my opinion I am confused that a lot of netlink handling is needed to do "something" with this socket layer. I already thought that we need some af802154ng for next generation.

Known bug is also RAW sockets on af802154 are totally messed up... but we don't need them, this can be done by AF_PACKET (just need to think about similar handling there).

---

Now to your patch, you use skb->cb there. The tc ingress part can _maybe_? use this control block information. I think this issue is out of scope because we have also other parts in the code how we pass data between driver and packet layer with skb->cb -> we simply do it wrong.

I have no problems to have this patch inside but for future we should tackle a af802154ng with a better UAPI handling.

If we fix skb->cb we just need to think about how to pass such data up to socket layer.

- Alex

[0] https://github.com/linux-wpan/wpan-tools/tree/master/examples

maintainer
#4 lore raw
In reply to Clément Péron

Hello Clement.

Finally coming to review the patch. Sorry for the delay.

Quoted 7 lines · Clément Péron

From: Romuald CARI <[email protected]>

The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol.

I can see that it makes the application life a lot easier to have data send out and LQI value synced up by using the socket approach instead of dealing with socket and ioctl's. I am good with this patch in general.

So you have some public code that uses this approach? I would be interesting in the userspace part of yours. A demo would be fine. If the network handling part of your application is public anyway that would be even better. :-)

As Alex mentioned we have some socket examples in the wpa-tools package to give people a head start when wanting to use the subsystem. Having such a simple example for the LQI feature would really give you bonus points. :-)

https://github.com/linux-wpan/wpan-tools/tree/master/examples

Quoted 61 lines

This LQI data is available in the ancillary data buffer under the SOL_IEEE802154 level as the type WPAN_LQI. The value is an unsigned byte indicating the link quality with values ranging 0-255.

---
 include/net/af_ieee802154.h |  1 +
 net/ieee802154/socket.c     | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
include/net/af_ieee802154.h +1 -0
index a5563d27a3eb..8003a9f6eb43 100644
@@ -56,6 +56,7 @@ struct sockaddr_ieee802154 {
 #define WPAN_WANTACK		0
 #define WPAN_SECURITY		1
 #define WPAN_SECURITY_LEVEL	2
+#define WPAN_WANTLQI		3
 
 #define WPAN_SECURITY_DEFAULT	0
 #define WPAN_SECURITY_OFF	1
net/ieee802154/socket.c +4 -0
index a60658c85a9a..bc6b912603f1 100644
@@ -25,6 +25,7 @@
 #include <linux/termios.h>	/* For TIOCOUTQ/INQ */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/socket.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -452,6 +453,7 @@ struct dgram_sock {
 	unsigned int bound:1;
 	unsigned int connected:1;
 	unsigned int want_ack:1;
+	unsigned int want_lqi:1;
 	unsigned int secen:1;
 	unsigned int secen_override:1;
 	unsigned int seclevel:3;
@@ -486,6 +488,7 @@ static int dgram_init(struct sock *sk)
 	struct dgram_sock *ro = dgram_sk(sk);
 
 	ro->want_ack = 1;
+	ro->want_lqi = 0;
 	return 0;
 }
 
@@ -713,6 +716,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	size_t copied = 0;
 	int err = -EOPNOTSUPP;
 	struct sk_buff *skb;
+	struct dgram_sock *ro = dgram_sk(sk);
 	DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
 
 	skb = skb_recv_datagram(sk, flags, noblock, &err);

net/ieee802154/socket.c static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, · line 757

Quoted 10 lines
net/ieee802154/socket.c +7 -0
@@ -744,6 +748,13 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		*addr_len = sizeof(*saddr);
 	}
 
+	if (ro->want_lqi) {
+		err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+			       sizeof(uint8_t), &(mac_cb(skb)->lqi));
+		if (err)
+			goto done;
+	}
+

I am wondering a bit about the LQI you get back here. Maybe Alex can also shed some lights on it. The LQI value stored here is always from the last frame send (to any peer)? Or is it the last frame send to this specific peer?

I have not put much thoughts into the LQI thing so far.Just thinking we need to be careful what we are providing to not let userspace make bad decisions (e.g. wrong routing changes due to link values given for a different peer connection).

Quoted 15 lines
net/ieee802154/socket.c +3 -0
 	if (flags & MSG_TRUNC)
 		copied = skb->len;
 done:
@@ -847,6 +858,9 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
 	case WPAN_WANTACK:
 		val = ro->want_ack;
 		break;
+	case WPAN_WANTLQI:
+		val = ro->want_lqi;
+		break;
 	case WPAN_SECURITY:
 		if (!ro->secen_override)
 			val = WPAN_SECURITY_DEFAULT;

net/ieee802154/socket.c static int dgram_setsockopt(struct sock *sk, int level, int optname, · line 914

Quoted 9 lines
net/ieee802154/socket.c +3 -0
@@ -892,6 +906,9 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
 	case WPAN_WANTACK:
 		ro->want_ack = !!val;
 		break;
+	case WPAN_WANTLQI:
+		ro->want_lqi = !!val;
+		break;
 	case WPAN_SECURITY:
 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
 		    !ns_capable(net->user_ns, CAP_NET_RAW)) {

Review wise I am happy with the patch. I will give it a test.

regards
Stefan Schmidt

#5 lore raw
Quoted 3 lines · Stefan Schmidt

Hello Clement.

Finally coming to review the patch. Sorry for the delay.

....

Quoted 14 lines

net/ieee802154/socket.c static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, · line 757

Quoted 8 lines
net/ieee802154/socket.c +7 -0
+	if (ro->want_lqi) {
+		err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+			       sizeof(uint8_t), &(mac_cb(skb)->lqi));
+		if (err)
+			goto done;
+	}
+

I am wondering a bit about the LQI you get back here. Maybe Alex can also shed some lights on it. The LQI value stored here is always from the last frame send (to any peer)? Or is it the last frame send to this specific peer?

LQI is available only for per received frame [0], it's important to store it always when address information are available for the received frame. The peer you get from the socket layer so far I understood.

Storing means: maybe with some intelligent logic behind to calculate the average... one LQI value alone don't say anything. With this patch you can do such logic in user space as a LQI to peer database[1].

Otherwise we already talked about a similar handling as wireless does with "iw ... station dump" to have such handling in kernel - out of scope of this discussion.

Side notes:

[0] Ack frames has no address information but it refers to a transmitted frame with address information... so not always true. But ack handling is offloaded anyhow in the most cases.

[1] Getting complicated how to map a short/pan _and_ extended to _ONE_

    peer entry. -> MLME assoc()/IPv6 ndisc information are needed here.

- Alex

#6 lore raw
In reply to Stefan Schmidt

Hi Alexander, Stefan,

Thanks for your feedbacks,

Quoted 14 lines · Stefan Schmidt

Hello Clement.

Finally coming to review the patch. Sorry for the delay.

Quoted 7 lines · Clément Péron

From: Romuald CARI <[email protected]>

The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol.

Quoted 8 lines

I can see that it makes the application life a lot easier to have data send out and LQI value synced up by using the socket approach instead of dealing with socket and ioctl's. I am good with this patch in general.

So you have some public code that uses this approach? I would be interesting in the userspace part of yours. A demo would be fine. If the network handling part of your application is public anyway that would be even better. :-)

I'm sorry but the userspace code that use this isn't open. I will check if I can share this part.
Just the idea is to compute an average LQI and when it reach a threshold we allow the remote to control the device.

Quoted 5 lines

As Alex mentiwe oned have some socket examples in the wpa-tools package to give people a head start when wanting to use the subsystem. Having such a simple example for the LQI feature would really give you bonus points. :-)

Indeed, add an example for this feature will be really interesting.

Quoted 103 lines

https://github.com/linux-wpan/wpan-tools/tree/master/examples

Quoted 61 lines

This LQI data is available in the ancillary data buffer under the SOL_IEEE802154 level as the type WPAN_LQI. The value is an unsigned byte indicating the link quality with values ranging 0-255.

---
 include/net/af_ieee802154.h |  1 +
 net/ieee802154/socket.c     | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
include/net/af_ieee802154.h +1 -0
index a5563d27a3eb..8003a9f6eb43 100644
@@ -56,6 +56,7 @@ struct sockaddr_ieee802154 {
 #define WPAN_WANTACK         0
 #define WPAN_SECURITY                1
 #define WPAN_SECURITY_LEVEL  2
+#define WPAN_WANTLQI         3
 
 #define WPAN_SECURITY_DEFAULT        0
 #define WPAN_SECURITY_OFF    1
net/ieee802154/socket.c +4 -0
index a60658c85a9a..bc6b912603f1 100644
@@ -25,6 +25,7 @@
 #include <linux/termios.h>   /* For TIOCOUTQ/INQ */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/socket.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -452,6 +453,7 @@ struct dgram_sock {
      unsigned int bound:1;
      unsigned int connected:1;
      unsigned int want_ack:1;
+     unsigned int want_lqi:1;
      unsigned int secen:1;
      unsigned int secen_override:1;
      unsigned int seclevel:3;
@@ -486,6 +488,7 @@ static int dgram_init(struct sock *sk)
      struct dgram_sock *ro = dgram_sk(sk);
 
      ro->want_ack = 1;
+     ro->want_lqi = 0;
      return 0;
 }
 
@@ -713,6 +716,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
      size_t copied = 0;
      int err = -EOPNOTSUPP;
      struct sk_buff *skb;
+     struct dgram_sock *ro = dgram_sk(sk);
      DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
 
      skb = skb_recv_datagram(sk, flags, noblock, &err);

net/ieee802154/socket.c static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len, · line 757

Quoted 10 lines
net/ieee802154/socket.c +7 -0
@@ -744,6 +748,13 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
              *addr_len = sizeof(*saddr);
      }
 
+     if (ro->want_lqi) {
+             err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+                            sizeof(uint8_t), &(mac_cb(skb)->lqi));
+             if (err)
+                     goto done;
+     }
+

I am wondering a bit about the LQI you get back here. Maybe Alex can also shed some lights on it. The LQI value stored here is always from the last frame send (to any peer)? Or is it the last frame send to this specific peer?

I have not put much thoughts into the LQI thing so far.Just thinking we need to be careful what we are providing to not let userspace make bad decisions (e.g. wrong routing changes due to link values given for a different peer connection).

Quoted 18 lines
net/ieee802154/socket.c +4 -0
      if (flags & MSG_TRUNC)
              copied = skb->len;
 done:
@@ -847,6 +858,9 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
      case WPAN_WANTACK:
              val = ro->want_ack;
              break;
+     case WPAN_WANTLQI:
+             val = ro->want_lqi;
+             break;
      case WPAN_SECURITY:
              if (!ro->secen_override)
                      val = WPAN_SECURITY_DEFAULT;
@@ -892,6 +906,9 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
      case WPAN_WANTACK:
              ro->want_ack = !!val;
              break;
+     case WPAN_WANTLQI:
Quoted 8 lines

net/ieee802154/socket.c static int dgram_setsockopt(struct sock *sk, int level, int optname, · line 914

Quoted 6 lines
net/ieee802154/socket.c +2 -0
+             ro->want_lqi = !!val;
+             break;
      case WPAN_SECURITY:
              if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
                  !ns_capable(net->user_ns, CAP_NET_RAW)) {

Review wise I am happy with the patch. I will give it a test.

Thanks, for the review,
Clement

Quoted 3 lines

regards
Stefan Schmidt

maintainer
#7 lore raw

Hello.

Quoted 23 lines · Clément Péron

Hi Alexander, Stefan,

Thanks for your feedbacks,

Quoted 18 lines · Stefan Schmidt

Hello Clement.

Finally coming to review the patch. Sorry for the delay.

Quoted 7 lines · Clément Péron

From: Romuald CARI <[email protected]>

The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol.

I can see that it makes the application life a lot easier to have data send out and LQI value synced up by using the socket approach instead of dealing with socket and ioctl's. I am good with this patch in general.

Quoted 6 lines
Quoted 4 lines

So you have some public code that uses this approach? I would be interesting in the userspace part of yours. A demo would be fine. If the network handling part of your application is public anyway that would be even better. :-)

I'm sorry but the userspace code that use this isn't open.

Fair enough.

Quoted 3 lines

I will check if I can share this part.
Just the idea is to compute an average LQI and when it reach a threshold we allow the remote to control the device.

Yes, I would be happy with a simple example just showing how to use the socket opt and a very basic algo on how this LQI would be used.

regards
Stefan Schmidt

maintainer
#8 lore raw
In reply to Clément Péron

Hello.

Quoted 93 lines · Clément Péron

From: Romuald CARI <[email protected]>

The Link Quality Indication data exposed by drivers could not be accessed from userspace. Since this data is per-datagram received, it makes sense to make it available to userspace application through the ancillary data mechanism in recvmsg rather than through ioctls. This can be activated using the socket option WPAN_WANTLQI under SOL_IEEE802154 protocol.

This LQI data is available in the ancillary data buffer under the SOL_IEEE802154 level as the type WPAN_LQI. The value is an unsigned byte indicating the link quality with values ranging 0-255.

---
 include/net/af_ieee802154.h |  1 +
 net/ieee802154/socket.c     | 17 +++++++++++++++++
 2 files changed, 18 insertions(+)
include/net/af_ieee802154.h +1 -0
index a5563d27a3eb..8003a9f6eb43 100644
@@ -56,6 +56,7 @@ struct sockaddr_ieee802154 {
 #define WPAN_WANTACK		0
 #define WPAN_SECURITY		1
 #define WPAN_SECURITY_LEVEL	2
+#define WPAN_WANTLQI		3
 
 #define WPAN_SECURITY_DEFAULT	0
 #define WPAN_SECURITY_OFF	1
net/ieee802154/socket.c +14 -0
index a60658c85a9a..bc6b912603f1 100644
@@ -25,6 +25,7 @@
 #include <linux/termios.h>	/* For TIOCOUTQ/INQ */
 #include <linux/list.h>
 #include <linux/slab.h>
+#include <linux/socket.h>
 #include <net/datalink.h>
 #include <net/psnap.h>
 #include <net/sock.h>
@@ -452,6 +453,7 @@ struct dgram_sock {
 	unsigned int bound:1;
 	unsigned int connected:1;
 	unsigned int want_ack:1;
+	unsigned int want_lqi:1;
 	unsigned int secen:1;
 	unsigned int secen_override:1;
 	unsigned int seclevel:3;
@@ -486,6 +488,7 @@ static int dgram_init(struct sock *sk)
 	struct dgram_sock *ro = dgram_sk(sk);
 
 	ro->want_ack = 1;
+	ro->want_lqi = 0;
 	return 0;
 }
 
@@ -713,6 +716,7 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 	size_t copied = 0;
 	int err = -EOPNOTSUPP;
 	struct sk_buff *skb;
+	struct dgram_sock *ro = dgram_sk(sk);
 	DECLARE_SOCKADDR(struct sockaddr_ieee802154 *, saddr, msg->msg_name);
 
 	skb = skb_recv_datagram(sk, flags, noblock, &err);
@@ -744,6 +748,13 @@ static int dgram_recvmsg(struct sock *sk, struct msghdr *msg, size_t len,
 		*addr_len = sizeof(*saddr);
 	}
 
+	if (ro->want_lqi) {
+		err = put_cmsg(msg, SOL_IEEE802154, WPAN_WANTLQI,
+			       sizeof(uint8_t), &(mac_cb(skb)->lqi));
+		if (err)
+			goto done;
+	}
+
 	if (flags & MSG_TRUNC)
 		copied = skb->len;
 done:
@@ -847,6 +858,9 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
 	case WPAN_WANTACK:
 		val = ro->want_ack;
 		break;
+	case WPAN_WANTLQI:
+		val = ro->want_lqi;
+		break;
 	case WPAN_SECURITY:
 		if (!ro->secen_override)
 			val = WPAN_SECURITY_DEFAULT;

net/ieee802154/socket.c static int dgram_setsockopt(struct sock *sk, int level, int optname, · line 914

Quoted 9 lines
net/ieee802154/socket.c +3 -0
@@ -892,6 +906,9 @@ static int dgram_setsockopt(struct sock *sk, int level, int optname,
 	case WPAN_WANTACK:
 		ro->want_ack = !!val;
 		break;
+	case WPAN_WANTLQI:
+		ro->want_lqi = !!val;
+		break;
 	case WPAN_SECURITY:
 		if (!ns_capable(net->user_ns, CAP_NET_ADMIN) &&
 		    !ns_capable(net->user_ns, CAP_NET_RAW)) {

This patch has been applied to the wpan-next tree and will be part of the next pull request to net-next. Thanks!

regards
Stefan Schmidt