aboutsummaryrefslogtreecommitdiff
path: root/net
diff options
context:
space:
mode:
Diffstat (limited to 'net')
-rw-r--r--net/6lowpan/nhc.h2
-rw-r--r--net/ieee802154/6lowpan/core.c14
-rw-r--r--net/ieee802154/6lowpan/tx.c12
-rw-r--r--net/ieee802154/header_ops.c2
-rw-r--r--net/mac802154/iface.c17
-rw-r--r--net/mac802154/tx.c3
6 files changed, 36 insertions, 14 deletions
diff --git a/net/6lowpan/nhc.h b/net/6lowpan/nhc.h
index ed44938eb5de..c249f17fa37b 100644
--- a/net/6lowpan/nhc.h
+++ b/net/6lowpan/nhc.h
@@ -8,8 +8,6 @@
#include <net/6lowpan.h>
#include <net/ipv6.h>
-#define LOWPAN_NHC_MAX_ID_LEN 1
-
/**
* LOWPAN_NHC - helper macro to generate nh id fields and lowpan_nhc struct
*
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;
diff --git a/net/mac802154/iface.c b/net/mac802154/iface.c
index 8afe26d72971..b5a0936ce514 100644
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -537,8 +537,18 @@ static void ieee802154_if_setup(struct net_device *dev)
dev->addr_len = IEEE802154_EXTENDED_ADDR_LEN;
memset(dev->broadcast, 0xff, IEEE802154_EXTENDED_ADDR_LEN);
- dev->hard_header_len = MAC802154_FRAME_HARD_HEADER_LEN;
- dev->needed_tailroom = 2 + 16; /* FCS + MIC */
+ /* Let hard_header_len set to IEEE802154_MIN_HEADER_LEN. AF_PACKET
+ * will not send frames without any payload, but ack frames
+ * has no payload, so substract one that we can send a 3 bytes
+ * frame. The xmit callback assumes at least a hard header where two
+ * bytes fc and sequence field are set.
+ */
+ dev->hard_header_len = IEEE802154_MIN_HEADER_LEN - 1;
+ /* The auth_tag header is for security and places in private payload
+ * room of mac frame which stucks between payload and FCS field.
+ */
+ dev->needed_tailroom = IEEE802154_MAX_AUTH_TAG_LEN +
+ IEEE802154_FCS_LEN;
dev->mtu = IEEE802154_MTU;
dev->tx_queue_len = 300;
dev->flags = IFF_NOARP | IFF_BROADCAST;
@@ -617,7 +627,8 @@ ieee802154_if_add(struct ieee802154_local *local, const char *name,
if (!ndev)
return ERR_PTR(-ENOMEM);
- ndev->needed_headroom = local->hw.extra_tx_headroom;
+ ndev->needed_headroom = local->hw.extra_tx_headroom +
+ IEEE802154_MAX_HEADER_LEN;
ret = dev_alloc_name(ndev, ndev->name);
if (ret < 0)
diff --git a/net/mac802154/tx.c b/net/mac802154/tx.c
index 7ed439172f30..66d7ecb7c56b 100644
--- a/net/mac802154/tx.c
+++ b/net/mac802154/tx.c
@@ -77,9 +77,6 @@ ieee802154_tx(struct ieee802154_local *local, struct sk_buff *skb)
put_unaligned_le16(crc, skb_put(skb, 2));
}
- if (skb_cow_head(skb, local->hw.extra_tx_headroom))
- goto err_tx;
-
/* Stop the netif queue on each sub_if_data object. */
ieee802154_stop_queue(&local->hw);