diff options
author | Alexander Aring <alex.aring@gmail.com> | 2014-02-28 01:32:50 -0500 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2014-02-28 17:05:22 -0500 |
commit | 7240cdec60b136f3e64a453c7fbded4ed1aa047e (patch) | |
tree | 1ef358c776a1493ba1d2e6786bf070b05e960c48 /net/ieee802154/reassembly.h | |
parent | 633fc86ff621bba79dcddfd4c67fb07ae5f8467c (diff) |
6lowpan: handling 6lowpan fragmentation via inet_frag api
This patch drops the current way of 6lowpan fragmentation on receiving
side and replace it with a implementation which use the inet_frag api.
The old fragmentation handling has some race conditions and isn't
rfc4944 compatible. Also adding support to match fragments on
destination address, source address, tag value and datagram_size
which is missing in the current implementation.
Signed-off-by: Alexander Aring <alex.aring@gmail.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/ieee802154/reassembly.h')
-rw-r--r-- | net/ieee802154/reassembly.h | 66 |
1 files changed, 66 insertions, 0 deletions
diff --git a/net/ieee802154/reassembly.h b/net/ieee802154/reassembly.h new file mode 100644 index 000000000000..055518b9da2d --- /dev/null +++ b/net/ieee802154/reassembly.h | |||
@@ -0,0 +1,66 @@ | |||
1 | #ifndef __IEEE802154_6LOWPAN_REASSEMBLY_H__ | ||
2 | #define __IEEE802154_6LOWPAN_REASSEMBLY_H__ | ||
3 | |||
4 | #include <net/inet_frag.h> | ||
5 | |||
6 | struct lowpan_create_arg { | ||
7 | __be16 tag; | ||
8 | u16 d_size; | ||
9 | const struct ieee802154_addr *src; | ||
10 | const struct ieee802154_addr *dst; | ||
11 | }; | ||
12 | |||
13 | /* Equivalent of ipv4 struct ip | ||
14 | */ | ||
15 | struct lowpan_frag_queue { | ||
16 | struct inet_frag_queue q; | ||
17 | |||
18 | __be16 tag; | ||
19 | u16 d_size; | ||
20 | struct ieee802154_addr saddr; | ||
21 | struct ieee802154_addr daddr; | ||
22 | }; | ||
23 | |||
24 | static inline u32 ieee802154_addr_hash(const struct ieee802154_addr *a) | ||
25 | { | ||
26 | switch (a->addr_type) { | ||
27 | case IEEE802154_ADDR_LONG: | ||
28 | return (__force u32)((((u32 *)a->hwaddr))[0] ^ | ||
29 | ((u32 *)(a->hwaddr))[1]); | ||
30 | case IEEE802154_ADDR_SHORT: | ||
31 | return (__force u32)(a->short_addr); | ||
32 | default: | ||
33 | return 0; | ||
34 | } | ||
35 | } | ||
36 | |||
37 | static inline bool ieee802154_addr_addr_equal(const struct ieee802154_addr *a1, | ||
38 | const struct ieee802154_addr *a2) | ||
39 | { | ||
40 | if (a1->pan_id != a2->pan_id) | ||
41 | return false; | ||
42 | |||
43 | if (a1->addr_type != a2->addr_type) | ||
44 | return false; | ||
45 | |||
46 | switch (a1->addr_type) { | ||
47 | case IEEE802154_ADDR_LONG: | ||
48 | if (memcmp(a1->hwaddr, a2->hwaddr, IEEE802154_ADDR_LEN)) | ||
49 | return false; | ||
50 | break; | ||
51 | case IEEE802154_ADDR_SHORT: | ||
52 | if (a1->short_addr != a2->short_addr) | ||
53 | return false; | ||
54 | break; | ||
55 | default: | ||
56 | return false; | ||
57 | } | ||
58 | |||
59 | return true; | ||
60 | } | ||
61 | |||
62 | int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type); | ||
63 | void lowpan_net_frag_exit(void); | ||
64 | int lowpan_net_frag_init(void); | ||
65 | |||
66 | #endif /* __IEEE802154_6LOWPAN_REASSEMBLY_H__ */ | ||