2015-07-31 12:38:06

by Alexander Aring

[permalink] [raw]
Subject: [RFCv2 bluetooth-next 0/2] 6lowpan: introduce generic 6lowpan private data

Hi,

I already thought many times to introduce something like that. Here is a draft
for introducing the generic 6lowpan private data into each lowpan interface.
For the beginning I introduced the enum "ll_type" which contains the LL type of
a lowpan interface.

Use cases for such feature (LL types):

- If we do in upper layers (6LoWPAN/IPv6) a evaluation of dev->type then
the value is on all lowpan interfaces "APRHRD_6LOWPAN". If we checked on
"dev->type" and it's ARPHRD_6LOWPAN we can safe use lowpan_priv to get
6LoWPAN generic private data. With this data we can check the LL type which
can be currently BTLE or IEEE802154. This could be useful to make different
handling in iphc compress/decompress and evaluating LL private data of skb
control block "skb->cb".

Example (802.15.4 has different address handling functionality):

switch (lowpan_priv(dev)->ll_type) {
case LOWPAN_LL_TYPE_BTLE:
/* do EUI64 btle handling */
break;
case LOWPAN_LL_TYPE_IEEE802154:
/* do complicated short/extended address handling */
/* we can surely call skb->cb to some other private data from LL
which was set before iphc compress/decompress function call */
break;
}

The handling is currently for 802.15.4 is in generic 6lowpan code currently
not quite. This should be handled by private data. At the moment btle use
the same handling like for 802.15.4 extended address. Nevertheless is we can
cleanup some handling then in generic iphc functionality.

This also possible in layers like IPv6, just doing a check on APRHRD_6LOWPAN
before calling lowpan_priv(dev)->ll_type, then we are sure that the private
data of the interface is a 6LoWPAN interface and we can cast it to lowpan_priv.
Then we can do 6LoWPAN generic stuff OR 6lowpan specific LL stuff.

- In Lukasz Duda RFC for introducing stateful address compression, I saw
some behaviour which such functionality is also useful. Currently we don't
have a allocated space for a 6LoWPAN generic space which is assigned to a
lowpan interface. When LL layers (BTLE, IEEE802154) calls iphc
compress/decompress Lukasz had no change to access some room which is needed
for storing the context information into a table. The workaround for this
feature was to add allocate a static data room for the table and doing a
lookup/match of netdev name. Which a generic 6lowpan private data room per each
lowpan interface we can put this table according to the netdev private room,
which means in short: no lookup is needed anymore, just dereferencing lowpan_priv.

In upper layer like IPv6 Lukasz could use that to get the stateful context
table information as an example for doing 6LoWPAN generic stuff in upper
layers.


Note about the implementation for LL 6LoWPAN private pointer:

I stole some mechanism from wireless for that. See [0], the vif struct is part
of sdata which is also part of private data of a wireless interface (mac80211).
I hope I can just adapt this behaviour.

- Alex

[0] http://lxr.free-electrons.com/source/include/net/mac80211.h#L1366

changes since v2:
- rename L2/l2 to LL/ll. I think the usually word in ietf for L2 is
LL which means "link layer". Also ipv6 stack use ll for variables like
lladdr -> link layer address.
- rebase to current bluetooth-next/master
- remove some brackets in function lowpan_priv.

Alexander Aring (2):
bluetooth: 6lowpan: change netdev_priv to lowpan_dev
6lowpan: add generic 6lowpan netdev private data

include/net/6lowpan.h | 18 ++++++++++++++++++
net/bluetooth/6lowpan.c | 9 ++++++---
net/ieee802154/6lowpan/6lowpan_i.h | 3 ++-
net/ieee802154/6lowpan/core.c | 5 ++++-
4 files changed, 30 insertions(+), 5 deletions(-)

--
2.5.0



2015-07-31 12:38:08

by Alexander Aring

[permalink] [raw]
Subject: [RFCv2 bluetooth-next 2/2] 6lowpan: add generic 6lowpan netdev private data

This patch introduced the 6lowpan netdev private data struct. We name it
lowpan_priv and it's placed at the beginning of netdev private data. All
lowpan interfaces should allocate this room at first of netdev private
data. 6LoWPAN LL private data can be allocate by additional netdev private
data, e.g. dev->priv_size should be "sizeof(struct lowpan_priv) +
sizeof(LL_LOWPAN_PRIVATE_DATA)".

Signed-off-by: Alexander Aring <[email protected]>
---
include/net/6lowpan.h | 18 ++++++++++++++++++
net/bluetooth/6lowpan.c | 7 +++++--
net/ieee802154/6lowpan/6lowpan_i.h | 3 ++-
net/ieee802154/6lowpan/core.c | 5 ++++-
4 files changed, 29 insertions(+), 4 deletions(-)

diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index dc03d77..a955be2 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -197,6 +197,24 @@
#define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */
#define LOWPAN_NHC_UDP_CS_C 0x04 /* checksum elided */

+enum lowpan_ll_types {
+ LOWPAN_LL_TYPE_BTLE,
+ LOWPAN_LL_TYPE_IEEE802154,
+};
+
+struct lowpan_priv {
+ enum lowpan_ll_types ll_type;
+
+ /* must be last */
+ u8 priv[0] __aligned(sizeof(void *));
+};
+
+static inline
+struct lowpan_priv *lowpan_priv(const struct net_device *dev)
+{
+ return netdev_priv(dev);
+}
+
#ifdef DEBUG
/* print data in line */
static inline void raw_dump_inline(const char *caller, char *msg,
diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 24ed5b0..eb61121 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -85,7 +85,7 @@ struct lowpan_dev {

static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev)
{
- return netdev_priv(netdev);
+ return (struct lowpan_dev *)lowpan_priv(netdev)->priv;
}

static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer)
@@ -848,7 +848,8 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
struct net_device *netdev;
int err = 0;

- netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
+ netdev = alloc_netdev(sizeof(struct lowpan_priv) +
+ sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
NET_NAME_UNKNOWN, netdev_setup);
if (!netdev)
return -ENOMEM;
@@ -869,6 +870,8 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
spin_unlock(&devices_lock);

+ lowpan_priv(netdev)->ll_type = LOWPAN_LL_TYPE_BTLE;
+
err = register_netdev(netdev);
if (err < 0) {
BT_INFO("register_netdev failed %d", err);
diff --git a/net/ieee802154/6lowpan/6lowpan_i.h b/net/ieee802154/6lowpan/6lowpan_i.h
index e50f69d..0dd4e46 100644
--- a/net/ieee802154/6lowpan/6lowpan_i.h
+++ b/net/ieee802154/6lowpan/6lowpan_i.h
@@ -5,6 +5,7 @@

#include <net/ieee802154_netdev.h>
#include <net/inet_frag.h>
+#include <net/6lowpan.h>

struct lowpan_create_arg {
u16 tag;
@@ -52,7 +53,7 @@ struct lowpan_dev_info {
static inline struct
lowpan_dev_info *lowpan_dev_info(const struct net_device *dev)
{
- return netdev_priv(dev);
+ return (struct lowpan_dev_info *)lowpan_priv(dev)->priv;
}

extern struct list_head lowpan_devices;
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index f20a387..ede602c 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -153,6 +153,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
list_add_tail(&entry->list, &lowpan_devices);
mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx);

+ lowpan_priv(dev)->ll_type = LOWPAN_LL_TYPE_IEEE802154;
+
ret = register_netdevice(dev);
if (ret >= 0) {
if (!lowpan_open_count)
@@ -193,7 +195,8 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head)

static struct rtnl_link_ops lowpan_link_ops __read_mostly = {
.kind = "lowpan",
- .priv_size = sizeof(struct lowpan_dev_info),
+ .priv_size = sizeof(struct lowpan_priv) +
+ sizeof(struct lowpan_dev_info),
.setup = lowpan_setup,
.newlink = lowpan_newlink,
.dellink = lowpan_dellink,
--
2.5.0


2015-07-31 12:38:07

by Alexander Aring

[permalink] [raw]
Subject: [RFCv2 bluetooth-next 1/2] bluetooth: 6lowpan: change netdev_priv to lowpan_dev

The usually way to get the btle lowpan private data is to use the
introduced lowpan_dev inline function. This patch will cleanup by using
lowpan_dev consequently.

Signed-off-by: Alexander Aring <[email protected]>
---
net/bluetooth/6lowpan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
index 0ffe2e2..24ed5b0 100644
--- a/net/bluetooth/6lowpan.c
+++ b/net/bluetooth/6lowpan.c
@@ -859,7 +859,7 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
SET_NETDEV_DEVTYPE(netdev, &bt_type);

- *dev = netdev_priv(netdev);
+ *dev = lowpan_dev(netdev);
(*dev)->netdev = netdev;
(*dev)->hdev = chan->conn->hcon->hdev;
INIT_LIST_HEAD(&(*dev)->peers);
--
2.5.0


2015-08-04 13:11:48

by Stefan Schmidt

[permalink] [raw]
Subject: Re: [RFCv2 bluetooth-next 2/2] 6lowpan: add generic 6lowpan netdev private data

Hello.

On 31/07/15 14:38, Alexander Aring wrote:
> This patch introduced the 6lowpan netdev private data struct. We name it
> lowpan_priv and it's placed at the beginning of netdev private data. All
> lowpan interfaces should allocate this room at first of netdev private
> data. 6LoWPAN LL private data can be allocate by additional netdev private
> data, e.g. dev->priv_size should be "sizeof(struct lowpan_priv) +
> sizeof(LL_LOWPAN_PRIVATE_DATA)".
>
> Signed-off-by: Alexander Aring<[email protected]>
> ---
> include/net/6lowpan.h | 18 ++++++++++++++++++
> net/bluetooth/6lowpan.c | 7 +++++--
> net/ieee802154/6lowpan/6lowpan_i.h | 3 ++-
> net/ieee802154/6lowpan/core.c | 5 ++++-
> 4 files changed, 29 insertions(+), 4 deletions(-)
>
> diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
> index dc03d77..a955be2 100644
> --- a/include/net/6lowpan.h
> +++ b/include/net/6lowpan.h
> @@ -197,6 +197,24 @@
> #define LOWPAN_NHC_UDP_CS_P_11 0xF3 /* source & dest = 0xF0B + 4bit inline */
> #define LOWPAN_NHC_UDP_CS_C 0x04 /* checksum elided */
>
> +enum lowpan_ll_types {
> + LOWPAN_LL_TYPE_BTLE,
> + LOWPAN_LL_TYPE_IEEE802154,
> +};
> +
> +struct lowpan_priv {
> + enum lowpan_ll_types ll_type;
> +
> + /* must be last */
> + u8 priv[0] __aligned(sizeof(void *));
> +};
> +
> +static inline
> +struct lowpan_priv *lowpan_priv(const struct net_device *dev)
> +{
> + return netdev_priv(dev);
> +}
> +
> #ifdef DEBUG
> /* print data in line */
> static inline void raw_dump_inline(const char *caller, char *msg,
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index 24ed5b0..eb61121 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -85,7 +85,7 @@ struct lowpan_dev {
>
> static inline struct lowpan_dev *lowpan_dev(const struct net_device *netdev)
> {
> - return netdev_priv(netdev);
> + return (struct lowpan_dev *)lowpan_priv(netdev)->priv;
> }
>
> static inline void peer_add(struct lowpan_dev *dev, struct lowpan_peer *peer)
> @@ -848,7 +848,8 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
> struct net_device *netdev;
> int err = 0;
>
> - netdev = alloc_netdev(sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
> + netdev = alloc_netdev(sizeof(struct lowpan_priv) +
> + sizeof(struct lowpan_dev), IFACE_NAME_TEMPLATE,
> NET_NAME_UNKNOWN, netdev_setup);
> if (!netdev)
> return -ENOMEM;
> @@ -869,6 +870,8 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
> list_add_rcu(&(*dev)->list, &bt_6lowpan_devices);
> spin_unlock(&devices_lock);
>
> + lowpan_priv(netdev)->ll_type = LOWPAN_LL_TYPE_BTLE;
> +
> err = register_netdev(netdev);
> if (err < 0) {
> BT_INFO("register_netdev failed %d", err);
> diff --git a/net/ieee802154/6lowpan/6lowpan_i.h b/net/ieee802154/6lowpan/6lowpan_i.h
> index e50f69d..0dd4e46 100644
> --- a/net/ieee802154/6lowpan/6lowpan_i.h
> +++ b/net/ieee802154/6lowpan/6lowpan_i.h
> @@ -5,6 +5,7 @@
>
> #include <net/ieee802154_netdev.h>
> #include <net/inet_frag.h>
> +#include <net/6lowpan.h>
>
> struct lowpan_create_arg {
> u16 tag;
> @@ -52,7 +53,7 @@ struct lowpan_dev_info {
> static inline struct
> lowpan_dev_info *lowpan_dev_info(const struct net_device *dev)
> {
> - return netdev_priv(dev);
> + return (struct lowpan_dev_info *)lowpan_priv(dev)->priv;
> }
>
> extern struct list_head lowpan_devices;
> diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
> index f20a387..ede602c 100644
> --- a/net/ieee802154/6lowpan/core.c
> +++ b/net/ieee802154/6lowpan/core.c
> @@ -153,6 +153,8 @@ static int lowpan_newlink(struct net *src_net, struct net_device *dev,
> list_add_tail(&entry->list, &lowpan_devices);
> mutex_unlock(&lowpan_dev_info(dev)->dev_list_mtx);
>
> + lowpan_priv(dev)->ll_type = LOWPAN_LL_TYPE_IEEE802154;
> +
> ret = register_netdevice(dev);
> if (ret >= 0) {
> if (!lowpan_open_count)
> @@ -193,7 +195,8 @@ static void lowpan_dellink(struct net_device *dev, struct list_head *head)
>
> static struct rtnl_link_ops lowpan_link_ops __read_mostly = {
> .kind = "lowpan",
> - .priv_size = sizeof(struct lowpan_dev_info),
> + .priv_size = sizeof(struct lowpan_priv) +
> + sizeof(struct lowpan_dev_info),
> .setup = lowpan_setup,
> .newlink = lowpan_newlink,
> .dellink = lowpan_dellink,

Reviewed-by: Stefan Schmidt <[email protected]>

regards
Stefan Schmidt

2015-08-04 13:11:39

by Stefan Schmidt

[permalink] [raw]
Subject: Re: [RFCv2 bluetooth-next 1/2] bluetooth: 6lowpan: change netdev_priv to lowpan_dev

Hello.

On 31/07/15 14:38, Alexander Aring wrote:
> The usually way to get the btle lowpan private data is to use the
> introduced lowpan_dev inline function. This patch will cleanup by using
> lowpan_dev consequently.
>
> Signed-off-by: Alexander Aring<[email protected]>
> ---
> net/bluetooth/6lowpan.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/bluetooth/6lowpan.c b/net/bluetooth/6lowpan.c
> index 0ffe2e2..24ed5b0 100644
> --- a/net/bluetooth/6lowpan.c
> +++ b/net/bluetooth/6lowpan.c
> @@ -859,7 +859,7 @@ static int setup_netdev(struct l2cap_chan *chan, struct lowpan_dev **dev)
> SET_NETDEV_DEV(netdev, &chan->conn->hcon->hdev->dev);
> SET_NETDEV_DEVTYPE(netdev, &bt_type);
>
> - *dev = netdev_priv(netdev);
> + *dev = lowpan_dev(netdev);
> (*dev)->netdev = netdev;
> (*dev)->hdev = chan->conn->hcon->hdev;
> INIT_LIST_HEAD(&(*dev)->peers);

Reviewed-by: Stefan Schmidt <[email protected]>

regards
Stefan Schmidt

2015-08-03 13:54:03

by Jukka Rissanen

[permalink] [raw]
Subject: Re: [RFCv2 bluetooth-next 0/2] 6lowpan: introduce generic 6lowpan private data

On ma, 2015-08-03 at 15:39 +0200, Alexander Aring wrote:
> On Mon, Aug 03, 2015 at 11:21:58AM +0300, Jukka Rissanen wrote:
> > Hi Alex,
> >
> > On pe, 2015-07-31 at 14:38 +0200, Alexander Aring wrote:
> > > Hi,
> > >
> > > I already thought many times to introduce something like that. Here is a draft
> > > for introducing the generic 6lowpan private data into each lowpan interface.
> > > For the beginning I introduced the enum "ll_type" which contains the LL type of
> > > a lowpan interface.
> >
> > Acked-by: Jukka Rissanen <[email protected]>
> >
> >
> > BTW, did you document the description below somewhere, it looks very
> > useful.
> >
>
> no, maybe we can create a "Documentation/networking/6lowpan.txt" for
> this?

You read my mind, I was thinking exactly that :)


Cheers,
Jukka



2015-08-03 13:39:17

by Alexander Aring

[permalink] [raw]
Subject: Re: [RFCv2 bluetooth-next 0/2] 6lowpan: introduce generic 6lowpan private data

On Mon, Aug 03, 2015 at 11:21:58AM +0300, Jukka Rissanen wrote:
> Hi Alex,
>
> On pe, 2015-07-31 at 14:38 +0200, Alexander Aring wrote:
> > Hi,
> >
> > I already thought many times to introduce something like that. Here is a draft
> > for introducing the generic 6lowpan private data into each lowpan interface.
> > For the beginning I introduced the enum "ll_type" which contains the LL type of
> > a lowpan interface.
>
> Acked-by: Jukka Rissanen <[email protected]>
>
>
> BTW, did you document the description below somewhere, it looks very
> useful.
>

no, maybe we can create a "Documentation/networking/6lowpan.txt" for
this?

- Alex

2015-08-03 08:21:58

by Jukka Rissanen

[permalink] [raw]
Subject: Re: [RFCv2 bluetooth-next 0/2] 6lowpan: introduce generic 6lowpan private data

Hi Alex,

On pe, 2015-07-31 at 14:38 +0200, Alexander Aring wrote:
> Hi,
>
> I already thought many times to introduce something like that. Here is a draft
> for introducing the generic 6lowpan private data into each lowpan interface.
> For the beginning I introduced the enum "ll_type" which contains the LL type of
> a lowpan interface.

Acked-by: Jukka Rissanen <[email protected]>


BTW, did you document the description below somewhere, it looks very
useful.


> Use cases for such feature (LL types):
>
> - If we do in upper layers (6LoWPAN/IPv6) a evaluation of dev->type then
> the value is on all lowpan interfaces "APRHRD_6LOWPAN". If we checked on
> "dev->type" and it's ARPHRD_6LOWPAN we can safe use lowpan_priv to get
> 6LoWPAN generic private data. With this data we can check the LL type which
> can be currently BTLE or IEEE802154. This could be useful to make different
> handling in iphc compress/decompress and evaluating LL private data of skb
> control block "skb->cb".
>
> Example (802.15.4 has different address handling functionality):
>
> switch (lowpan_priv(dev)->ll_type) {
> case LOWPAN_LL_TYPE_BTLE:
> /* do EUI64 btle handling */
> break;
> case LOWPAN_LL_TYPE_IEEE802154:
> /* do complicated short/extended address handling */
> /* we can surely call skb->cb to some other private data from LL
> which was set before iphc compress/decompress function call */
> break;
> }
>
> The handling is currently for 802.15.4 is in generic 6lowpan code currently
> not quite. This should be handled by private data. At the moment btle use
> the same handling like for 802.15.4 extended address. Nevertheless is we can
> cleanup some handling then in generic iphc functionality.
>
> This also possible in layers like IPv6, just doing a check on APRHRD_6LOWPAN
> before calling lowpan_priv(dev)->ll_type, then we are sure that the private
> data of the interface is a 6LoWPAN interface and we can cast it to lowpan_priv.
> Then we can do 6LoWPAN generic stuff OR 6lowpan specific LL stuff.
>
> - In Lukasz Duda RFC for introducing stateful address compression, I saw
> some behaviour which such functionality is also useful. Currently we don't
> have a allocated space for a 6LoWPAN generic space which is assigned to a
> lowpan interface. When LL layers (BTLE, IEEE802154) calls iphc
> compress/decompress Lukasz had no change to access some room which is needed
> for storing the context information into a table. The workaround for this
> feature was to add allocate a static data room for the table and doing a
> lookup/match of netdev name. Which a generic 6lowpan private data room per each
> lowpan interface we can put this table according to the netdev private room,
> which means in short: no lookup is needed anymore, just dereferencing lowpan_priv.
>
> In upper layer like IPv6 Lukasz could use that to get the stateful context
> table information as an example for doing 6LoWPAN generic stuff in upper
> layers.
>
>
> Note about the implementation for LL 6LoWPAN private pointer:
>
> I stole some mechanism from wireless for that. See [0], the vif struct is part
> of sdata which is also part of private data of a wireless interface (mac80211).
> I hope I can just adapt this behaviour.
>
> - Alex
>
> [0] http://lxr.free-electrons.com/source/include/net/mac80211.h#L1366
>
> changes since v2:
> - rename L2/l2 to LL/ll. I think the usually word in ietf for L2 is
> LL which means "link layer". Also ipv6 stack use ll for variables like
> lladdr -> link layer address.
> - rebase to current bluetooth-next/master
> - remove some brackets in function lowpan_priv.
>
> Alexander Aring (2):
> bluetooth: 6lowpan: change netdev_priv to lowpan_dev
> 6lowpan: add generic 6lowpan netdev private data
>
> include/net/6lowpan.h | 18 ++++++++++++++++++
> net/bluetooth/6lowpan.c | 9 ++++++---
> net/ieee802154/6lowpan/6lowpan_i.h | 3 ++-
> net/ieee802154/6lowpan/core.c | 5 ++++-
> 4 files changed, 30 insertions(+), 5 deletions(-)
>


Cheers,
Jukka