summaryrefslogtreecommitdiffstats
path: root/net/ieee802154/reassembly.c
diff options
context:
space:
mode:
authorDavid S. Miller <davem@davemloft.net>2014-03-14 22:15:35 -0400
committerDavid S. Miller <davem@davemloft.net>2014-03-14 22:15:35 -0400
commit983f59617aabbbfadbc73b897b9a78e6ffd92841 (patch)
tree9e132ac257c7f520382d7082e34ab3f5f1cc9452 /net/ieee802154/reassembly.c
parent177943260a6088bec51fc6c04643d84e43bef423 (diff)
parentd1d7358e9f032a43bd48d56a623943b7bee7dce0 (diff)
downloadblackbird-op-linux-983f59617aabbbfadbc73b897b9a78e6ffd92841.tar.gz
blackbird-op-linux-983f59617aabbbfadbc73b897b9a78e6ffd92841.zip
Merge branch 'ieee802154-next'
Phoebe Buckheister says: ==================== ieee802154: fix endianness and header handling This patch set enforces network byte order on all internal operations and fields of the 802.15.4 stack and adds a general representation of 802.15.4 headers with operations to create and parse those headers. This reduces code duplication in the current stack and also allows for upper layers to read headers of packets they have just received; it is also necessary for 802.15.4 link layer security, which requires header mangling. Changes since v1: * fixed lowpan packet rx after reassembly. Control blocks were used to retrieve source/dest addresses, but the CB is clobbered by reassembly. Instead, parse the header anew in lowpan. ==================== Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154/reassembly.c')
-rw-r--r--net/ieee802154/reassembly.c40
1 files changed, 27 insertions, 13 deletions
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index 1dae1991883d..ef2d54372b13 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -30,6 +30,17 @@
#include "reassembly.h"
+struct lowpan_frag_info {
+ __be16 d_tag;
+ u16 d_size;
+ u8 d_offset;
+};
+
+struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb)
+{
+ return (struct lowpan_frag_info *)skb->cb;
+}
+
static struct inet_frags lowpan_frags;
static int lowpan_frag_reasm(struct lowpan_frag_queue *fq,
@@ -65,8 +76,8 @@ static bool lowpan_frag_match(struct inet_frag_queue *q, void *a)
fq = container_of(q, struct lowpan_frag_queue, q);
return fq->tag == arg->tag && fq->d_size == arg->d_size &&
- ieee802154_addr_addr_equal(&fq->saddr, arg->src) &&
- ieee802154_addr_addr_equal(&fq->daddr, arg->dst);
+ ieee802154_addr_equal(&fq->saddr, arg->src) &&
+ ieee802154_addr_equal(&fq->daddr, arg->dst);
}
static void lowpan_frag_init(struct inet_frag_queue *q, void *a)
@@ -102,8 +113,9 @@ out:
}
static inline struct lowpan_frag_queue *
-fq_find(struct net *net, const struct ieee802154_frag_info *frag_info,
- const struct ieee802154_addr *src, const struct ieee802154_addr *dst)
+fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
+ const struct ieee802154_addr *src,
+ const struct ieee802154_addr *dst)
{
struct inet_frag_queue *q;
struct lowpan_create_arg arg;
@@ -136,8 +148,8 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
if (fq->q.last_in & INET_FRAG_COMPLETE)
goto err;
- offset = mac_cb(skb)->frag_info.d_offset << 3;
- end = mac_cb(skb)->frag_info.d_size;
+ offset = lowpan_cb(skb)->d_offset << 3;
+ end = lowpan_cb(skb)->d_size;
/* Is this the final fragment? */
if (offset + skb->len == end) {
@@ -163,15 +175,13 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
* this fragment, right?
*/
prev = fq->q.fragments_tail;
- if (!prev || mac_cb(prev)->frag_info.d_offset <
- mac_cb(skb)->frag_info.d_offset) {
+ if (!prev || lowpan_cb(prev)->d_offset < lowpan_cb(skb)->d_offset) {
next = NULL;
goto found;
}
prev = NULL;
for (next = fq->q.fragments; next != NULL; next = next->next) {
- if (mac_cb(next)->frag_info.d_offset >=
- mac_cb(skb)->frag_info.d_offset)
+ if (lowpan_cb(next)->d_offset >= lowpan_cb(skb)->d_offset)
break; /* bingo! */
prev = next;
}
@@ -318,7 +328,7 @@ out_oom:
}
static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type,
- struct ieee802154_frag_info *frag_info)
+ struct lowpan_frag_info *frag_info)
{
bool fail;
u8 pattern = 0, low = 0;
@@ -345,9 +355,13 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
{
struct lowpan_frag_queue *fq;
struct net *net = dev_net(skb->dev);
- struct ieee802154_frag_info *frag_info = &mac_cb(skb)->frag_info;
+ struct lowpan_frag_info *frag_info = lowpan_cb(skb);
+ struct ieee802154_addr source, dest;
int err;
+ source = mac_cb(skb)->source;
+ dest = mac_cb(skb)->dest;
+
err = lowpan_get_frag_info(skb, frag_type, frag_info);
if (err < 0)
goto err;
@@ -357,7 +371,7 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
inet_frag_evictor(&net->ieee802154_lowpan.frags, &lowpan_frags, false);
- fq = fq_find(net, frag_info, &mac_cb(skb)->sa, &mac_cb(skb)->da);
+ fq = fq_find(net, frag_info, &source, &dest);
if (fq != NULL) {
int ret;
spin_lock(&fq->q.lock);
OpenPOWER on IntegriCloud