summaryrefslogtreecommitdiffstats
path: root/net/ieee802154
diff options
context:
space:
mode:
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/6lowpan/core.c14
-rw-r--r--net/ieee802154/6lowpan/tx.c12
-rw-r--r--net/ieee802154/header_ops.c2
3 files changed, 22 insertions, 6 deletions
diff --git a/net/ieee802154/6lowpan/core.c b/net/ieee802154/6lowpan/core.c
index 9f0cfa598e3a..44420ed95574 100644
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -104,9 +104,8 @@ static void lowpan_setup(struct net_device *ldev)
ldev->addr_len = IEEE802154_ADDR_LEN;
memset(ldev->broadcast, 0xff, IEEE802154_ADDR_LEN);
ldev->type = ARPHRD_6LOWPAN;
- /* Frame Control + Sequence Number + Address fields + Security Header */
- ldev->hard_header_len = 2 + 1 + 20 + 14;
- ldev->needed_tailroom = 2; /* FCS */
+ /* We need an ipv6hdr as minimum len when calling xmit */
+ ldev->hard_header_len = sizeof(struct ipv6hdr);
ldev->mtu = IPV6_MIN_MTU;
ldev->priv_flags |= IFF_NO_QUEUE;
ldev->flags = IFF_BROADCAST | IFF_MULTICAST;
@@ -156,6 +155,15 @@ static int lowpan_newlink(struct net *src_net, struct net_device *ldev,
lowpan_dev_info(ldev)->wdev = wdev;
/* Set the lowpan hardware address to the wpan hardware address. */
memcpy(ldev->dev_addr, wdev->dev_addr, IEEE802154_ADDR_LEN);
+ /* We need headroom for possible wpan_dev_hard_header call and tailroom
+ * for encryption/fcs handling. The lowpan interface will replace
+ * the IPv6 header with 6LoWPAN header. At worst case the 6LoWPAN
+ * header has LOWPAN_IPHC_MAX_HEADER_LEN more bytes than the IPv6
+ * header.
+ */
+ ldev->needed_headroom = LOWPAN_IPHC_MAX_HEADER_LEN +
+ wdev->needed_headroom;
+ ldev->needed_tailroom = wdev->needed_tailroom;
lowpan_netdev_setup(ldev, LOWPAN_LLTYPE_IEEE802154);
diff --git a/net/ieee802154/6lowpan/tx.c b/net/ieee802154/6lowpan/tx.c
index 6067e064a3fe..7e0563eaea98 100644
--- a/net/ieee802154/6lowpan/tx.c
+++ b/net/ieee802154/6lowpan/tx.c
@@ -10,6 +10,7 @@
#include <net/6lowpan.h>
#include <net/ieee802154_netdev.h>
+#include <net/mac802154.h>
#include "6lowpan_i.h"
@@ -36,6 +37,13 @@ lowpan_addr_info *lowpan_skb_priv(const struct sk_buff *skb)
sizeof(struct lowpan_addr_info));
}
+/* This callback will be called from AF_PACKET and IPv6 stack, the AF_PACKET
+ * sockets gives an 8 byte array for addresses only!
+ *
+ * TODO I think AF_PACKET DGRAM (sending/receiving) RAW (sending) makes no
+ * sense here. We should disable it, the right use-case would be AF_INET6
+ * RAW/DGRAM sockets.
+ */
int lowpan_header_create(struct sk_buff *skb, struct net_device *ldev,
unsigned short type, const void *_daddr,
const void *_saddr, unsigned int len)
@@ -77,13 +85,13 @@ lowpan_alloc_frag(struct sk_buff *skb, int size,
struct sk_buff *frag;
int rc;
- frag = alloc_skb(wdev->hard_header_len + wdev->needed_tailroom + size,
+ frag = alloc_skb(wdev->needed_headroom + wdev->needed_tailroom + size,
GFP_ATOMIC);
if (likely(frag)) {
frag->dev = wdev;
frag->priority = skb->priority;
- skb_reserve(frag, wdev->hard_header_len);
+ skb_reserve(frag, wdev->needed_headroom);
skb_reset_network_header(frag);
*mac_cb(frag) = *mac_cb(skb);
diff --git a/net/ieee802154/header_ops.c b/net/ieee802154/header_ops.c
index d8443b057022..c7439f0fbbdf 100644
--- a/net/ieee802154/header_ops.c
+++ b/net/ieee802154/header_ops.c
@@ -85,7 +85,7 @@ ieee802154_hdr_push_sechdr(u8 *buf, const struct ieee802154_sechdr *hdr)
int
ieee802154_hdr_push(struct sk_buff *skb, struct ieee802154_hdr *hdr)
{
- u8 buf[MAC802154_FRAME_HARD_HEADER_LEN];
+ u8 buf[IEEE802154_MAX_HEADER_LEN];
int pos = 2;
int rc;
struct ieee802154_hdr_fc *fc = &hdr->fc;