Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+842 -483
+13 -12
drivers/net/ieee802154/at86rf230.c
··· 745 745 struct at86rf230_local *lp = dev->priv; 746 746 747 747 if (changed & IEEE802515_AFILT_SADDR_CHANGED) { 748 + u16 addr = le16_to_cpu(filt->short_addr); 749 + 748 750 dev_vdbg(&lp->spi->dev, 749 751 "at86rf230_set_hw_addr_filt called for saddr\n"); 750 - __at86rf230_write(lp, RG_SHORT_ADDR_0, filt->short_addr); 751 - __at86rf230_write(lp, RG_SHORT_ADDR_1, filt->short_addr >> 8); 752 + __at86rf230_write(lp, RG_SHORT_ADDR_0, addr); 753 + __at86rf230_write(lp, RG_SHORT_ADDR_1, addr >> 8); 752 754 } 753 755 754 756 if (changed & IEEE802515_AFILT_PANID_CHANGED) { 757 + u16 pan = le16_to_cpu(filt->pan_id); 758 + 755 759 dev_vdbg(&lp->spi->dev, 756 760 "at86rf230_set_hw_addr_filt called for pan id\n"); 757 - __at86rf230_write(lp, RG_PAN_ID_0, filt->pan_id); 758 - __at86rf230_write(lp, RG_PAN_ID_1, filt->pan_id >> 8); 761 + __at86rf230_write(lp, RG_PAN_ID_0, pan); 762 + __at86rf230_write(lp, RG_PAN_ID_1, pan >> 8); 759 763 } 760 764 761 765 if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { 766 + u8 i, addr[8]; 767 + 768 + memcpy(addr, &filt->ieee_addr, 8); 762 769 dev_vdbg(&lp->spi->dev, 763 770 "at86rf230_set_hw_addr_filt called for IEEE addr\n"); 764 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_0, filt->ieee_addr[7]); 765 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_1, filt->ieee_addr[6]); 766 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_2, filt->ieee_addr[5]); 767 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_3, filt->ieee_addr[4]); 768 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_4, filt->ieee_addr[3]); 769 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_5, filt->ieee_addr[2]); 770 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_6, filt->ieee_addr[1]); 771 - at86rf230_write_subreg(lp, SR_IEEE_ADDR_7, filt->ieee_addr[0]); 771 + for (i = 0; i < 8; i++) 772 + __at86rf230_write(lp, RG_IEEE_ADDR_0 + i, addr[i]); 772 773 } 773 774 774 775 if (changed & IEEE802515_AFILT_PANC_CHANGED) {
+11 -11
drivers/net/ieee802154/fakehard.c
··· 63 63 * 64 64 * Return the ID of the PAN from the PIB. 65 65 */ 66 - static u16 fake_get_pan_id(const struct net_device *dev) 66 + static __le16 fake_get_pan_id(const struct net_device *dev) 67 67 { 68 68 BUG_ON(dev->type != ARPHRD_IEEE802154); 69 69 70 - return 0xeba1; 70 + return cpu_to_le16(0xeba1); 71 71 } 72 72 73 73 /** ··· 78 78 * device. If the device has not yet had a short address assigned 79 79 * then this should return 0xFFFF to indicate a lack of association. 80 80 */ 81 - static u16 fake_get_short_addr(const struct net_device *dev) 81 + static __le16 fake_get_short_addr(const struct net_device *dev) 82 82 { 83 83 BUG_ON(dev->type != ARPHRD_IEEE802154); 84 84 85 - return 0x1; 85 + return cpu_to_le16(0x1); 86 86 } 87 87 88 88 /** ··· 149 149 * 802.15.4-2006 document. 150 150 */ 151 151 static int fake_assoc_resp(struct net_device *dev, 152 - struct ieee802154_addr *addr, u16 short_addr, u8 status) 152 + struct ieee802154_addr *addr, __le16 short_addr, u8 status) 153 153 { 154 154 return 0; 155 155 } ··· 191 191 * Note: This is in section 7.5.2.3 of the IEEE 802.15.4-2006 192 192 * document, with 7.3.8 describing coordinator realignment. 193 193 */ 194 - static int fake_start_req(struct net_device *dev, struct ieee802154_addr *addr, 195 - u8 channel, u8 page, 196 - u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, 197 - u8 coord_realign) 194 + static int fake_start_req(struct net_device *dev, 195 + struct ieee802154_addr *addr, u8 channel, u8 page, 196 + u8 bcn_ord, u8 sf_ord, u8 pan_coord, u8 blx, 197 + u8 coord_realign) 198 198 { 199 199 struct wpan_phy *phy = fake_to_phy(dev); 200 200 ··· 281 281 switch (cmd) { 282 282 case SIOCGIFADDR: 283 283 /* FIXME: fixed here, get from device IRL */ 284 - pan_id = fake_get_pan_id(dev); 285 - short_addr = fake_get_short_addr(dev); 284 + pan_id = le16_to_cpu(fake_get_pan_id(dev)); 285 + short_addr = le16_to_cpu(fake_get_short_addr(dev)); 286 286 if (pan_id == IEEE802154_PANID_BROADCAST || 287 287 short_addr == IEEE802154_ADDR_BROADCAST) 288 288 return -EADDRNOTAVAIL;
+9 -8
drivers/net/ieee802154/mrf24j40.c
··· 465 465 if (changed & IEEE802515_AFILT_SADDR_CHANGED) { 466 466 /* Short Addr */ 467 467 u8 addrh, addrl; 468 - addrh = filt->short_addr >> 8 & 0xff; 469 - addrl = filt->short_addr & 0xff; 468 + addrh = le16_to_cpu(filt->short_addr) >> 8 & 0xff; 469 + addrl = le16_to_cpu(filt->short_addr) & 0xff; 470 470 471 471 write_short_reg(devrec, REG_SADRH, addrh); 472 472 write_short_reg(devrec, REG_SADRL, addrl); ··· 476 476 477 477 if (changed & IEEE802515_AFILT_IEEEADDR_CHANGED) { 478 478 /* Device Address */ 479 - int i; 479 + u8 i, addr[8]; 480 + 481 + memcpy(addr, &filt->ieee_addr, 8); 480 482 for (i = 0; i < 8; i++) 481 - write_short_reg(devrec, REG_EADR0+i, 482 - filt->ieee_addr[7-i]); 483 + write_short_reg(devrec, REG_EADR0 + i, addr[i]); 483 484 484 485 #ifdef DEBUG 485 486 printk(KERN_DEBUG "Set long addr to: "); 486 487 for (i = 0; i < 8; i++) 487 - printk("%02hhx ", filt->ieee_addr[i]); 488 + printk("%02hhx ", addr[7 - i]); 488 489 printk(KERN_DEBUG "\n"); 489 490 #endif 490 491 } ··· 493 492 if (changed & IEEE802515_AFILT_PANID_CHANGED) { 494 493 /* PAN ID */ 495 494 u8 panidl, panidh; 496 - panidh = filt->pan_id >> 8 & 0xff; 497 - panidl = filt->pan_id & 0xff; 495 + panidh = le16_to_cpu(filt->pan_id) >> 8 & 0xff; 496 + panidl = le16_to_cpu(filt->pan_id) & 0xff; 498 497 write_short_reg(devrec, REG_PANIDH, panidh); 499 498 write_short_reg(devrec, REG_PANIDL, panidl); 500 499
+2 -2
include/net/af_ieee802154.h
··· 36 36 /* address length, octets */ 37 37 #define IEEE802154_ADDR_LEN 8 38 38 39 - struct ieee802154_addr { 39 + struct ieee802154_addr_sa { 40 40 int addr_type; 41 41 u16 pan_id; 42 42 union { ··· 51 51 52 52 struct sockaddr_ieee802154 { 53 53 sa_family_t family; /* AF_IEEE802154 */ 54 - struct ieee802154_addr addr; 54 + struct ieee802154_addr_sa addr; 55 55 }; 56 56 57 57 /* get/setsockopt */
+24 -4
include/net/ieee802154.h
··· 42 42 (((x) << IEEE802154_FC_TYPE_SHIFT) & IEEE802154_FC_TYPE_MASK)); \ 43 43 } while (0) 44 44 45 - #define IEEE802154_FC_SECEN (1 << 3) 46 - #define IEEE802154_FC_FRPEND (1 << 4) 47 - #define IEEE802154_FC_ACK_REQ (1 << 5) 48 - #define IEEE802154_FC_INTRA_PAN (1 << 6) 45 + #define IEEE802154_FC_SECEN_SHIFT 3 46 + #define IEEE802154_FC_SECEN (1 << IEEE802154_FC_SECEN_SHIFT) 47 + #define IEEE802154_FC_FRPEND_SHIFT 4 48 + #define IEEE802154_FC_FRPEND (1 << IEEE802154_FC_FRPEND_SHIFT) 49 + #define IEEE802154_FC_ACK_REQ_SHIFT 5 50 + #define IEEE802154_FC_ACK_REQ (1 << IEEE802154_FC_ACK_REQ_SHIFT) 51 + #define IEEE802154_FC_INTRA_PAN_SHIFT 6 52 + #define IEEE802154_FC_INTRA_PAN (1 << IEEE802154_FC_INTRA_PAN_SHIFT) 49 53 50 54 #define IEEE802154_FC_SAMODE_SHIFT 14 51 55 #define IEEE802154_FC_SAMODE_MASK (3 << IEEE802154_FC_SAMODE_SHIFT) 52 56 #define IEEE802154_FC_DAMODE_SHIFT 10 53 57 #define IEEE802154_FC_DAMODE_MASK (3 << IEEE802154_FC_DAMODE_SHIFT) 58 + 59 + #define IEEE802154_FC_VERSION_SHIFT 12 60 + #define IEEE802154_FC_VERSION_MASK (3 << IEEE802154_FC_VERSION_SHIFT) 61 + #define IEEE802154_FC_VERSION(x) ((x & IEEE802154_FC_VERSION_MASK) >> IEEE802154_FC_VERSION_SHIFT) 54 62 55 63 #define IEEE802154_FC_SAMODE(x) \ 56 64 (((x) & IEEE802154_FC_SAMODE_MASK) >> IEEE802154_FC_SAMODE_SHIFT) ··· 66 58 #define IEEE802154_FC_DAMODE(x) \ 67 59 (((x) & IEEE802154_FC_DAMODE_MASK) >> IEEE802154_FC_DAMODE_SHIFT) 68 60 61 + #define IEEE802154_SCF_SECLEVEL_MASK 7 62 + #define IEEE802154_SCF_SECLEVEL_SHIFT 0 63 + #define IEEE802154_SCF_SECLEVEL(x) (x & IEEE802154_SCF_SECLEVEL_MASK) 64 + #define IEEE802154_SCF_KEY_ID_MODE_SHIFT 3 65 + #define IEEE802154_SCF_KEY_ID_MODE_MASK (3 << IEEE802154_SCF_KEY_ID_MODE_SHIFT) 66 + #define IEEE802154_SCF_KEY_ID_MODE(x) \ 67 + ((x & IEEE802154_SCF_KEY_ID_MODE_MASK) >> IEEE802154_SCF_KEY_ID_MODE_SHIFT) 68 + 69 + #define IEEE802154_SCF_KEY_IMPLICIT 0 70 + #define IEEE802154_SCF_KEY_INDEX 1 71 + #define IEEE802154_SCF_KEY_SHORT_INDEX 2 72 + #define IEEE802154_SCF_KEY_HW_INDEX 3 69 73 70 74 /* MAC footer size */ 71 75 #define IEEE802154_MFR_SIZE 2 /* 2 octets */
+163 -18
include/net/ieee802154_netdev.h
··· 28 28 #define IEEE802154_NETDEVICE_H 29 29 30 30 #include <net/af_ieee802154.h> 31 + #include <linux/netdevice.h> 32 + #include <linux/skbuff.h> 31 33 32 - struct ieee802154_frag_info { 33 - __be16 d_tag; 34 - u16 d_size; 35 - u8 d_offset; 34 + struct ieee802154_sechdr { 35 + #if defined(__LITTLE_ENDIAN_BITFIELD) 36 + u8 level:3, 37 + key_id_mode:2, 38 + reserved:3; 39 + #elif defined(__BIG_ENDIAN_BITFIELD) 40 + u8 reserved:3, 41 + key_id_mode:2, 42 + level:3; 43 + #else 44 + #error "Please fix <asm/byteorder.h>" 45 + #endif 46 + u8 key_id; 47 + __le32 frame_counter; 48 + union { 49 + __le32 short_src; 50 + __le64 extended_src; 51 + }; 36 52 }; 53 + 54 + struct ieee802154_addr { 55 + u8 mode; 56 + __le16 pan_id; 57 + union { 58 + __le16 short_addr; 59 + __le64 extended_addr; 60 + }; 61 + }; 62 + 63 + struct ieee802154_hdr_fc { 64 + #if defined(__LITTLE_ENDIAN_BITFIELD) 65 + u16 type:3, 66 + security_enabled:1, 67 + frame_pending:1, 68 + ack_request:1, 69 + intra_pan:1, 70 + reserved:3, 71 + dest_addr_mode:2, 72 + version:2, 73 + source_addr_mode:2; 74 + #elif defined(__BIG_ENDIAN_BITFIELD) 75 + u16 reserved:1, 76 + intra_pan:1, 77 + ack_request:1, 78 + frame_pending:1, 79 + security_enabled:1, 80 + type:3, 81 + source_addr_mode:2, 82 + version:2, 83 + dest_addr_mode:2, 84 + reserved2:2; 85 + #else 86 + #error "Please fix <asm/byteorder.h>" 87 + #endif 88 + }; 89 + 90 + struct ieee802154_hdr { 91 + struct ieee802154_hdr_fc fc; 92 + u8 seq; 93 + struct ieee802154_addr source; 94 + struct ieee802154_addr dest; 95 + struct ieee802154_sechdr sec; 96 + }; 97 + 98 + /* pushes hdr onto the skb. fields of hdr->fc that can be calculated from 99 + * the contents of hdr will be, and the actual value of those bits in 100 + * hdr->fc will be ignored. this includes the INTRA_PAN bit and the frame 101 + * version, if SECEN is set. 102 + */ 103 + int ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr); 104 + 105 + /* pulls the entire 802.15.4 header off of the skb, including the security 106 + * header, and performs pan id decompression 107 + */ 108 + int ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr); 109 + 110 + /* parses the frame control, sequence number of address fields in a given skb 111 + * and stores them into hdr, performing pan id decompression and length checks 112 + * to be suitable for use in header_ops.parse 113 + */ 114 + int ieee802154_hdr_peek_addrs(const struct sk_buff *skb, 115 + struct ieee802154_hdr *hdr); 116 + 117 + static inline int ieee802154_hdr_length(struct sk_buff *skb) 118 + { 119 + struct ieee802154_hdr hdr; 120 + int len = ieee802154_hdr_pull(skb, &hdr); 121 + 122 + if (len > 0) 123 + skb_push(skb, len); 124 + 125 + return len; 126 + } 127 + 128 + static inline bool ieee802154_addr_equal(const struct ieee802154_addr *a1, 129 + const struct ieee802154_addr *a2) 130 + { 131 + if (a1->pan_id != a2->pan_id || a1->mode != a2->mode) 132 + return false; 133 + 134 + if ((a1->mode == IEEE802154_ADDR_LONG && 135 + a1->extended_addr != a2->extended_addr) || 136 + (a1->mode == IEEE802154_ADDR_SHORT && 137 + a1->short_addr != a2->short_addr)) 138 + return false; 139 + 140 + return true; 141 + } 142 + 143 + static inline __le64 ieee802154_devaddr_from_raw(const void *raw) 144 + { 145 + u64 temp; 146 + 147 + memcpy(&temp, raw, IEEE802154_ADDR_LEN); 148 + return (__force __le64)swab64(temp); 149 + } 150 + 151 + static inline void ieee802154_devaddr_to_raw(void *raw, __le64 addr) 152 + { 153 + u64 temp = swab64((__force u64)addr); 154 + 155 + memcpy(raw, &temp, IEEE802154_ADDR_LEN); 156 + } 157 + 158 + static inline void ieee802154_addr_from_sa(struct ieee802154_addr *a, 159 + const struct ieee802154_addr_sa *sa) 160 + { 161 + a->mode = sa->addr_type; 162 + a->pan_id = cpu_to_le16(sa->pan_id); 163 + 164 + switch (a->mode) { 165 + case IEEE802154_ADDR_SHORT: 166 + a->short_addr = cpu_to_le16(sa->short_addr); 167 + break; 168 + case IEEE802154_ADDR_LONG: 169 + a->extended_addr = ieee802154_devaddr_from_raw(sa->hwaddr); 170 + break; 171 + } 172 + } 173 + 174 + static inline void ieee802154_addr_to_sa(struct ieee802154_addr_sa *sa, 175 + const struct ieee802154_addr *a) 176 + { 177 + sa->addr_type = a->mode; 178 + sa->pan_id = le16_to_cpu(a->pan_id); 179 + 180 + switch (a->mode) { 181 + case IEEE802154_ADDR_SHORT: 182 + sa->short_addr = le16_to_cpu(a->short_addr); 183 + break; 184 + case IEEE802154_ADDR_LONG: 185 + ieee802154_devaddr_to_raw(sa->hwaddr, a->extended_addr); 186 + break; 187 + } 188 + } 37 189 38 190 /* 39 191 * A control block of skb passed between the ARPHRD_IEEE802154 device ··· 193 41 */ 194 42 struct ieee802154_mac_cb { 195 43 u8 lqi; 196 - struct ieee802154_addr sa; 197 - struct ieee802154_addr da; 198 44 u8 flags; 199 45 u8 seq; 200 - struct ieee802154_frag_info frag_info; 46 + struct ieee802154_addr source; 47 + struct ieee802154_addr dest; 201 48 }; 202 49 203 50 static inline struct ieee802154_mac_cb *mac_cb(struct sk_buff *skb) ··· 208 57 209 58 #define MAC_CB_FLAG_ACKREQ (1 << 3) 210 59 #define MAC_CB_FLAG_SECEN (1 << 4) 211 - #define MAC_CB_FLAG_INTRAPAN (1 << 5) 212 60 213 - static inline int mac_cb_is_ackreq(struct sk_buff *skb) 61 + static inline bool mac_cb_is_ackreq(struct sk_buff *skb) 214 62 { 215 63 return mac_cb(skb)->flags & MAC_CB_FLAG_ACKREQ; 216 64 } 217 65 218 - static inline int mac_cb_is_secen(struct sk_buff *skb) 66 + static inline bool mac_cb_is_secen(struct sk_buff *skb) 219 67 { 220 68 return mac_cb(skb)->flags & MAC_CB_FLAG_SECEN; 221 - } 222 - 223 - static inline int mac_cb_is_intrapan(struct sk_buff *skb) 224 - { 225 - return mac_cb(skb)->flags & MAC_CB_FLAG_INTRAPAN; 226 69 } 227 70 228 71 static inline int mac_cb_type(struct sk_buff *skb) ··· 244 99 u8 channel, u8 page, u8 cap); 245 100 int (*assoc_resp)(struct net_device *dev, 246 101 struct ieee802154_addr *addr, 247 - u16 short_addr, u8 status); 102 + __le16 short_addr, u8 status); 248 103 int (*disassoc_req)(struct net_device *dev, 249 104 struct ieee802154_addr *addr, 250 105 u8 reason); ··· 263 118 * FIXME: these should become the part of PIB/MIB interface. 264 119 * However we still don't have IB interface of any kind 265 120 */ 266 - u16 (*get_pan_id)(const struct net_device *dev); 267 - u16 (*get_short_addr)(const struct net_device *dev); 121 + __le16 (*get_pan_id)(const struct net_device *dev); 122 + __le16 (*get_short_addr)(const struct net_device *dev); 268 123 u8 (*get_dsn)(const struct net_device *dev); 269 124 }; 270 125
+3 -3
include/net/mac802154.h
··· 20 20 #define NET_MAC802154_H 21 21 22 22 #include <net/af_ieee802154.h> 23 + #include <linux/skbuff.h> 23 24 24 25 /* General MAC frame format: 25 26 * 2 bytes: Frame Control ··· 51 50 * devices across independent networks. 52 51 */ 53 52 __le16 short_addr; 54 - u8 ieee_addr[IEEE802154_ADDR_LEN]; 53 + __le64 ieee_addr; 55 54 u8 pan_coord; 56 55 }; 57 56 ··· 154 153 int (*set_hw_addr_filt)(struct ieee802154_dev *dev, 155 154 struct ieee802154_hw_addr_filt *filt, 156 155 unsigned long changed); 157 - int (*ieee_addr)(struct ieee802154_dev *dev, 158 - u8 addr[IEEE802154_ADDR_LEN]); 156 + int (*ieee_addr)(struct ieee802154_dev *dev, __le64 addr); 159 157 int (*set_txpower)(struct ieee802154_dev *dev, int db); 160 158 int (*set_lbt)(struct ieee802154_dev *dev, bool on); 161 159 int (*set_cca_mode)(struct ieee802154_dev *dev, u8 mode);
+3 -3
include/net/nl802154.h
··· 52 52 * Note: This is in section 7.3.2 of the IEEE 802.15.4 document. 53 53 */ 54 54 int ieee802154_nl_assoc_confirm(struct net_device *dev, 55 - u16 short_addr, u8 status); 55 + __le16 short_addr, u8 status); 56 56 57 57 /** 58 58 * ieee802154_nl_disassoc_indic - Notify userland of disassociation. ··· 111 111 * Note: This API cannot indicate a beacon frame for a coordinator 112 112 * operating in long addressing mode. 113 113 */ 114 - int ieee802154_nl_beacon_indic(struct net_device *dev, u16 panid, 115 - u16 coord_addr); 114 + int ieee802154_nl_beacon_indic(struct net_device *dev, __le16 panid, 115 + __le16 coord_addr); 116 116 117 117 /** 118 118 * ieee802154_nl_start_confirm - Notify userland of completion of start.
+36 -22
net/ieee802154/6lowpan_rtnl.c
··· 119 119 mac_cb(skb)->seq = ieee802154_mlme_ops(dev)->get_dsn(dev); 120 120 121 121 /* prepare wpan address data */ 122 - sa.addr_type = IEEE802154_ADDR_LONG; 122 + sa.mode = IEEE802154_ADDR_LONG; 123 123 sa.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); 124 + sa.extended_addr = ieee802154_devaddr_from_raw(saddr); 124 125 125 - memcpy(&(sa.hwaddr), saddr, 8); 126 126 /* intra-PAN communications */ 127 - da.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); 127 + da.pan_id = sa.pan_id; 128 128 129 129 /* if the destination address is the broadcast address, use the 130 130 * corresponding short address 131 131 */ 132 132 if (lowpan_is_addr_broadcast(daddr)) { 133 - da.addr_type = IEEE802154_ADDR_SHORT; 134 - da.short_addr = IEEE802154_ADDR_BROADCAST; 133 + da.mode = IEEE802154_ADDR_SHORT; 134 + da.short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); 135 135 } else { 136 - da.addr_type = IEEE802154_ADDR_LONG; 137 - memcpy(&(da.hwaddr), daddr, IEEE802154_ADDR_LEN); 136 + da.mode = IEEE802154_ADDR_LONG; 137 + da.extended_addr = ieee802154_devaddr_from_raw(daddr); 138 138 139 139 /* request acknowledgment */ 140 140 mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ; 141 141 } 142 142 143 143 return dev_hard_header(skb, lowpan_dev_info(dev)->real_dev, 144 - type, (void *)&da, (void *)&sa, skb->len); 144 + type, (void *)&da, (void *)&sa, 0); 145 145 } 146 146 147 147 static int lowpan_give_skb_to_devices(struct sk_buff *skb, ··· 168 168 return stat; 169 169 } 170 170 171 - static int process_data(struct sk_buff *skb) 171 + static int process_data(struct sk_buff *skb, const struct ieee802154_hdr *hdr) 172 172 { 173 173 u8 iphc0, iphc1; 174 - const struct ieee802154_addr *_saddr, *_daddr; 174 + struct ieee802154_addr_sa sa, da; 175 + void *sap, *dap; 175 176 176 177 raw_dump_table(__func__, "raw skb data dump", skb->data, skb->len); 177 178 /* at least two bytes will be used for the encoding */ ··· 185 184 if (lowpan_fetch_skb_u8(skb, &iphc1)) 186 185 goto drop; 187 186 188 - _saddr = &mac_cb(skb)->sa; 189 - _daddr = &mac_cb(skb)->da; 187 + ieee802154_addr_to_sa(&sa, &hdr->source); 188 + ieee802154_addr_to_sa(&da, &hdr->dest); 190 189 191 - return lowpan_process_data(skb, skb->dev, (u8 *)_saddr->hwaddr, 192 - _saddr->addr_type, IEEE802154_ADDR_LEN, 193 - (u8 *)_daddr->hwaddr, _daddr->addr_type, 194 - IEEE802154_ADDR_LEN, iphc0, iphc1, 195 - lowpan_give_skb_to_devices); 190 + if (sa.addr_type == IEEE802154_ADDR_SHORT) 191 + sap = &sa.short_addr; 192 + else 193 + sap = &sa.hwaddr; 194 + 195 + if (da.addr_type == IEEE802154_ADDR_SHORT) 196 + dap = &da.short_addr; 197 + else 198 + dap = &da.hwaddr; 199 + 200 + return lowpan_process_data(skb, skb->dev, sap, sa.addr_type, 201 + IEEE802154_ADDR_LEN, dap, da.addr_type, 202 + IEEE802154_ADDR_LEN, iphc0, iphc1, 203 + lowpan_give_skb_to_devices); 196 204 197 205 drop: 198 206 kfree_skb(skb); ··· 362 352 return ieee802154_mlme_ops(real_dev)->get_phy(real_dev); 363 353 } 364 354 365 - static u16 lowpan_get_pan_id(const struct net_device *dev) 355 + static __le16 lowpan_get_pan_id(const struct net_device *dev) 366 356 { 367 357 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; 368 358 return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev); 369 359 } 370 360 371 - static u16 lowpan_get_short_addr(const struct net_device *dev) 361 + static __le16 lowpan_get_short_addr(const struct net_device *dev) 372 362 { 373 363 struct net_device *real_dev = lowpan_dev_info(dev)->real_dev; 374 364 return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev); ··· 448 438 struct packet_type *pt, struct net_device *orig_dev) 449 439 { 450 440 struct sk_buff *local_skb; 441 + struct ieee802154_hdr hdr; 451 442 int ret; 452 443 453 444 if (!netif_running(dev)) 454 445 goto drop_skb; 455 446 456 447 if (dev->type != ARPHRD_IEEE802154) 448 + goto drop_skb; 449 + 450 + if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) 457 451 goto drop_skb; 458 452 459 453 local_skb = skb_clone(skb, GFP_ATOMIC); ··· 480 466 } else { 481 467 switch (skb->data[0] & 0xe0) { 482 468 case LOWPAN_DISPATCH_IPHC: /* ipv6 datagram */ 483 - ret = process_data(local_skb); 469 + ret = process_data(local_skb, &hdr); 484 470 if (ret == NET_RX_DROP) 485 471 goto drop; 486 472 break; 487 473 case LOWPAN_DISPATCH_FRAG1: /* first fragment header */ 488 474 ret = lowpan_frag_rcv(local_skb, LOWPAN_DISPATCH_FRAG1); 489 475 if (ret == 1) { 490 - ret = process_data(local_skb); 476 + ret = process_data(local_skb, &hdr); 491 477 if (ret == NET_RX_DROP) 492 478 goto drop; 493 479 } ··· 495 481 case LOWPAN_DISPATCH_FRAGN: /* next fragments headers */ 496 482 ret = lowpan_frag_rcv(local_skb, LOWPAN_DISPATCH_FRAGN); 497 483 if (ret == 1) { 498 - ret = process_data(local_skb); 484 + ret = process_data(local_skb, &hdr); 499 485 if (ret == NET_RX_DROP) 500 486 goto drop; 501 487 }
+4 -1
net/ieee802154/Makefile
··· 3 3 obj-$(CONFIG_6LOWPAN_IPHC) += 6lowpan_iphc.o 4 4 5 5 6lowpan-y := 6lowpan_rtnl.o reassembly.o 6 - ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o 6 + ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o \ 7 + header_ops.o 7 8 af_802154-y := af_ieee802154.o raw.o dgram.o 9 + 10 + ccflags-y += -D__CHECK_ENDIAN__
+3 -2
net/ieee802154/af802154.h
··· 25 25 #define AF802154_H 26 26 27 27 struct sk_buff; 28 - struct net_devce; 28 + struct net_device; 29 + struct ieee802154_addr; 29 30 extern struct proto ieee802154_raw_prot; 30 31 extern struct proto ieee802154_dgram_prot; 31 32 void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb); 32 33 int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb); 33 34 struct net_device *ieee802154_get_dev(struct net *net, 34 - struct ieee802154_addr *addr); 35 + const struct ieee802154_addr *addr); 35 36 36 37 #endif
+11 -9
net/ieee802154/af_ieee802154.c
··· 43 43 /* 44 44 * Utility function for families 45 45 */ 46 - struct net_device *ieee802154_get_dev(struct net *net, 47 - struct ieee802154_addr *addr) 46 + struct net_device* 47 + ieee802154_get_dev(struct net *net, const struct ieee802154_addr *addr) 48 48 { 49 49 struct net_device *dev = NULL; 50 50 struct net_device *tmp; 51 - u16 pan_id, short_addr; 51 + __le16 pan_id, short_addr; 52 + u8 hwaddr[IEEE802154_ADDR_LEN]; 52 53 53 - switch (addr->addr_type) { 54 + switch (addr->mode) { 54 55 case IEEE802154_ADDR_LONG: 56 + ieee802154_devaddr_to_raw(hwaddr, addr->extended_addr); 55 57 rcu_read_lock(); 56 - dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, addr->hwaddr); 58 + dev = dev_getbyhwaddr_rcu(net, ARPHRD_IEEE802154, hwaddr); 57 59 if (dev) 58 60 dev_hold(dev); 59 61 rcu_read_unlock(); 60 62 break; 61 63 case IEEE802154_ADDR_SHORT: 62 - if (addr->pan_id == 0xffff || 63 - addr->short_addr == IEEE802154_ADDR_UNDEF || 64 - addr->short_addr == 0xffff) 64 + if (addr->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST) || 65 + addr->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || 66 + addr->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF)) 65 67 break; 66 68 67 69 rtnl_lock(); ··· 88 86 break; 89 87 default: 90 88 pr_warning("Unsupported ieee802154 address type: %d\n", 91 - addr->addr_type); 89 + addr->mode); 92 90 break; 93 91 } 94 92
+30 -26
net/ieee802154/dgram.c
··· 73 73 { 74 74 struct dgram_sock *ro = dgram_sk(sk); 75 75 76 - ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; 77 - ro->dst_addr.pan_id = 0xffff; 76 + ro->dst_addr.mode = IEEE802154_ADDR_LONG; 77 + ro->dst_addr.pan_id = cpu_to_le16(IEEE802154_ADDR_BROADCAST); 78 78 ro->want_ack = 1; 79 - memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); 79 + memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN); 80 80 return 0; 81 81 } 82 82 ··· 88 88 static int dgram_bind(struct sock *sk, struct sockaddr *uaddr, int len) 89 89 { 90 90 struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; 91 + struct ieee802154_addr haddr; 91 92 struct dgram_sock *ro = dgram_sk(sk); 92 93 int err = -EINVAL; 93 94 struct net_device *dev; ··· 103 102 if (addr->family != AF_IEEE802154) 104 103 goto out; 105 104 106 - dev = ieee802154_get_dev(sock_net(sk), &addr->addr); 105 + ieee802154_addr_from_sa(&haddr, &addr->addr); 106 + dev = ieee802154_get_dev(sock_net(sk), &haddr); 107 107 if (!dev) { 108 108 err = -ENODEV; 109 109 goto out; ··· 115 113 goto out_put; 116 114 } 117 115 118 - memcpy(&ro->src_addr, &addr->addr, sizeof(struct ieee802154_addr)); 116 + ro->src_addr = haddr; 119 117 120 118 ro->bound = 1; 121 119 err = 0; ··· 151 149 * of this packet since that is all 152 150 * that will be read. 153 151 */ 154 - /* FIXME: parse the header for more correct value */ 155 - amount = skb->len - (3+8+8); 152 + amount = skb->len - ieee802154_hdr_length(skb); 156 153 } 157 154 spin_unlock_bh(&sk->sk_receive_queue.lock); 158 155 return put_user(amount, (int __user *)arg); ··· 182 181 goto out; 183 182 } 184 183 185 - memcpy(&ro->dst_addr, &addr->addr, sizeof(struct ieee802154_addr)); 184 + ieee802154_addr_from_sa(&ro->dst_addr, &addr->addr); 186 185 187 186 out: 188 187 release_sock(sk); ··· 195 194 196 195 lock_sock(sk); 197 196 198 - ro->dst_addr.addr_type = IEEE802154_ADDR_LONG; 199 - memset(&ro->dst_addr.hwaddr, 0xff, sizeof(ro->dst_addr.hwaddr)); 197 + ro->dst_addr.mode = IEEE802154_ADDR_LONG; 198 + memset(&ro->dst_addr.extended_addr, 0xff, IEEE802154_ADDR_LEN); 200 199 201 200 release_sock(sk); 202 201 ··· 233 232 234 233 if (size > mtu) { 235 234 pr_debug("size = %Zu, mtu = %u\n", size, mtu); 236 - err = -EINVAL; 235 + err = -EMSGSIZE; 237 236 goto out_dev; 238 237 } 239 238 ··· 313 312 314 313 if (saddr) { 315 314 saddr->family = AF_IEEE802154; 316 - saddr->addr = mac_cb(skb)->sa; 315 + ieee802154_addr_to_sa(&saddr->addr, &mac_cb(skb)->source); 317 316 *addr_len = sizeof(*saddr); 318 317 } 319 318 ··· 337 336 return NET_RX_SUCCESS; 338 337 } 339 338 340 - static inline int ieee802154_match_sock(u8 *hw_addr, u16 pan_id, 341 - u16 short_addr, struct dgram_sock *ro) 339 + static inline bool 340 + ieee802154_match_sock(__le64 hw_addr, __le16 pan_id, __le16 short_addr, 341 + struct dgram_sock *ro) 342 342 { 343 343 if (!ro->bound) 344 - return 1; 344 + return true; 345 345 346 - if (ro->src_addr.addr_type == IEEE802154_ADDR_LONG && 347 - !memcmp(ro->src_addr.hwaddr, hw_addr, IEEE802154_ADDR_LEN)) 348 - return 1; 346 + if (ro->src_addr.mode == IEEE802154_ADDR_LONG && 347 + hw_addr == ro->src_addr.extended_addr) 348 + return true; 349 349 350 - if (ro->src_addr.addr_type == IEEE802154_ADDR_SHORT && 351 - pan_id == ro->src_addr.pan_id && 352 - short_addr == ro->src_addr.short_addr) 353 - return 1; 350 + if (ro->src_addr.mode == IEEE802154_ADDR_SHORT && 351 + pan_id == ro->src_addr.pan_id && 352 + short_addr == ro->src_addr.short_addr) 353 + return true; 354 354 355 - return 0; 355 + return false; 356 356 } 357 357 358 358 int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb) 359 359 { 360 360 struct sock *sk, *prev = NULL; 361 361 int ret = NET_RX_SUCCESS; 362 - u16 pan_id, short_addr; 362 + __le16 pan_id, short_addr; 363 + __le64 hw_addr; 363 364 364 365 /* Data frame processing */ 365 366 BUG_ON(dev->type != ARPHRD_IEEE802154); 366 367 367 368 pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); 368 369 short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); 370 + hw_addr = ieee802154_devaddr_from_raw(dev->dev_addr); 369 371 370 372 read_lock(&dgram_lock); 371 373 sk_for_each(sk, &dgram_head) { 372 - if (ieee802154_match_sock(dev->dev_addr, pan_id, short_addr, 373 - dgram_sk(sk))) { 374 + if (ieee802154_match_sock(hw_addr, pan_id, short_addr, 375 + dgram_sk(sk))) { 374 376 if (prev) { 375 377 struct sk_buff *clone; 376 378 clone = skb_clone(skb, GFP_ATOMIC);
+287
net/ieee802154/header_ops.c
··· 1 + /* 2 + * Copyright (C) 2014 Fraunhofer ITWM 3 + * 4 + * This program is free software; you can redistribute it and/or modify 5 + * it under the terms of the GNU General Public License version 2 6 + * as published by the Free Software Foundation. 7 + * 8 + * This program is distributed in the hope that it will be useful, 9 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 10 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 + * GNU General Public License for more details. 12 + * 13 + * Written by: 14 + * Phoebe Buckheister <phoebe.buckheister@itwm.fraunhofer.de> 15 + */ 16 + 17 + #include <net/mac802154.h> 18 + #include <net/ieee802154.h> 19 + #include <net/ieee802154_netdev.h> 20 + 21 + static int 22 + ieee802154_hdr_push_addr(u8 *buf, const struct ieee802154_addr *addr, 23 + bool omit_pan) 24 + { 25 + int pos = 0; 26 + 27 + if (addr->mode == IEEE802154_ADDR_NONE) 28 + return 0; 29 + 30 + if (!omit_pan) { 31 + memcpy(buf + pos, &addr->pan_id, 2); 32 + pos += 2; 33 + } 34 + 35 + switch (addr->mode) { 36 + case IEEE802154_ADDR_SHORT: 37 + memcpy(buf + pos, &addr->short_addr, 2); 38 + pos += 2; 39 + break; 40 + 41 + case IEEE802154_ADDR_LONG: 42 + memcpy(buf + pos, &addr->extended_addr, IEEE802154_ADDR_LEN); 43 + pos += IEEE802154_ADDR_LEN; 44 + break; 45 + 46 + default: 47 + return -EINVAL; 48 + } 49 + 50 + return pos; 51 + } 52 + 53 + static int 54 + ieee802154_hdr_push_sechdr(u8 *buf, const struct ieee802154_sechdr *hdr) 55 + { 56 + int pos = 5; 57 + 58 + memcpy(buf, hdr, 1); 59 + memcpy(buf + 1, &hdr->frame_counter, 4); 60 + 61 + switch (hdr->key_id_mode) { 62 + case IEEE802154_SCF_KEY_IMPLICIT: 63 + return pos; 64 + 65 + case IEEE802154_SCF_KEY_INDEX: 66 + break; 67 + 68 + case IEEE802154_SCF_KEY_SHORT_INDEX: 69 + memcpy(buf + pos, &hdr->short_src, 4); 70 + pos += 4; 71 + break; 72 + 73 + case IEEE802154_SCF_KEY_HW_INDEX: 74 + memcpy(buf + pos, &hdr->extended_src, IEEE802154_ADDR_LEN); 75 + pos += IEEE802154_ADDR_LEN; 76 + break; 77 + } 78 + 79 + buf[pos++] = hdr->key_id; 80 + 81 + return pos; 82 + } 83 + 84 + int 85 + ieee802154_hdr_push(struct sk_buff *skb, const struct ieee802154_hdr *hdr) 86 + { 87 + u8 buf[MAC802154_FRAME_HARD_HEADER_LEN]; 88 + int pos = 2; 89 + int rc; 90 + struct ieee802154_hdr_fc fc = hdr->fc; 91 + 92 + buf[pos++] = hdr->seq; 93 + 94 + fc.dest_addr_mode = hdr->dest.mode; 95 + 96 + rc = ieee802154_hdr_push_addr(buf + pos, &hdr->dest, false); 97 + if (rc < 0) 98 + return -EINVAL; 99 + pos += rc; 100 + 101 + fc.source_addr_mode = hdr->source.mode; 102 + 103 + if (hdr->source.pan_id == hdr->dest.pan_id && 104 + hdr->dest.mode != IEEE802154_ADDR_NONE) 105 + fc.intra_pan = true; 106 + 107 + rc = ieee802154_hdr_push_addr(buf + pos, &hdr->source, fc.intra_pan); 108 + if (rc < 0) 109 + return -EINVAL; 110 + pos += rc; 111 + 112 + if (fc.security_enabled) { 113 + fc.version = 1; 114 + 115 + rc = ieee802154_hdr_push_sechdr(buf + pos, &hdr->sec); 116 + if (rc < 0) 117 + return -EINVAL; 118 + 119 + pos += rc; 120 + } 121 + 122 + memcpy(buf, &fc, 2); 123 + 124 + memcpy(skb_push(skb, pos), buf, pos); 125 + 126 + return pos; 127 + } 128 + EXPORT_SYMBOL_GPL(ieee802154_hdr_push); 129 + 130 + static int 131 + ieee802154_hdr_get_addr(const u8 *buf, int mode, bool omit_pan, 132 + struct ieee802154_addr *addr) 133 + { 134 + int pos = 0; 135 + 136 + addr->mode = mode; 137 + 138 + if (mode == IEEE802154_ADDR_NONE) 139 + return 0; 140 + 141 + if (!omit_pan) { 142 + memcpy(&addr->pan_id, buf + pos, 2); 143 + pos += 2; 144 + } 145 + 146 + if (mode == IEEE802154_ADDR_SHORT) { 147 + memcpy(&addr->short_addr, buf + pos, 2); 148 + return pos + 2; 149 + } else { 150 + memcpy(&addr->extended_addr, buf + pos, IEEE802154_ADDR_LEN); 151 + return pos + IEEE802154_ADDR_LEN; 152 + } 153 + } 154 + 155 + static int ieee802154_hdr_addr_len(int mode, bool omit_pan) 156 + { 157 + int pan_len = omit_pan ? 0 : 2; 158 + 159 + switch (mode) { 160 + case IEEE802154_ADDR_NONE: return 0; 161 + case IEEE802154_ADDR_SHORT: return 2 + pan_len; 162 + case IEEE802154_ADDR_LONG: return IEEE802154_ADDR_LEN + pan_len; 163 + default: return -EINVAL; 164 + } 165 + } 166 + 167 + static int 168 + ieee802154_hdr_get_sechdr(const u8 *buf, struct ieee802154_sechdr *hdr) 169 + { 170 + int pos = 5; 171 + 172 + memcpy(hdr, buf, 1); 173 + memcpy(&hdr->frame_counter, buf + 1, 4); 174 + 175 + switch (hdr->key_id_mode) { 176 + case IEEE802154_SCF_KEY_IMPLICIT: 177 + return pos; 178 + 179 + case IEEE802154_SCF_KEY_INDEX: 180 + break; 181 + 182 + case IEEE802154_SCF_KEY_SHORT_INDEX: 183 + memcpy(&hdr->short_src, buf + pos, 4); 184 + pos += 4; 185 + break; 186 + 187 + case IEEE802154_SCF_KEY_HW_INDEX: 188 + memcpy(&hdr->extended_src, buf + pos, IEEE802154_ADDR_LEN); 189 + pos += IEEE802154_ADDR_LEN; 190 + break; 191 + } 192 + 193 + hdr->key_id = buf[pos++]; 194 + 195 + return pos; 196 + } 197 + 198 + static int ieee802154_hdr_sechdr_len(u8 sc) 199 + { 200 + switch (IEEE802154_SCF_KEY_ID_MODE(sc)) { 201 + case IEEE802154_SCF_KEY_IMPLICIT: return 5; 202 + case IEEE802154_SCF_KEY_INDEX: return 6; 203 + case IEEE802154_SCF_KEY_SHORT_INDEX: return 10; 204 + case IEEE802154_SCF_KEY_HW_INDEX: return 14; 205 + default: return -EINVAL; 206 + } 207 + } 208 + 209 + static int ieee802154_hdr_minlen(const struct ieee802154_hdr *hdr) 210 + { 211 + int dlen, slen; 212 + 213 + dlen = ieee802154_hdr_addr_len(hdr->fc.dest_addr_mode, false); 214 + slen = ieee802154_hdr_addr_len(hdr->fc.source_addr_mode, 215 + hdr->fc.intra_pan); 216 + 217 + if (slen < 0 || dlen < 0) 218 + return -EINVAL; 219 + 220 + return 3 + dlen + slen + hdr->fc.security_enabled; 221 + } 222 + 223 + static int 224 + ieee802154_hdr_get_addrs(const u8 *buf, struct ieee802154_hdr *hdr) 225 + { 226 + int pos = 0; 227 + 228 + pos += ieee802154_hdr_get_addr(buf + pos, hdr->fc.dest_addr_mode, 229 + false, &hdr->dest); 230 + pos += ieee802154_hdr_get_addr(buf + pos, hdr->fc.source_addr_mode, 231 + hdr->fc.intra_pan, &hdr->source); 232 + 233 + if (hdr->fc.intra_pan) 234 + hdr->source.pan_id = hdr->dest.pan_id; 235 + 236 + return pos; 237 + } 238 + 239 + int 240 + ieee802154_hdr_pull(struct sk_buff *skb, struct ieee802154_hdr *hdr) 241 + { 242 + int pos = 3, rc; 243 + 244 + if (!pskb_may_pull(skb, 3)) 245 + return -EINVAL; 246 + 247 + memcpy(hdr, skb->data, 3); 248 + 249 + rc = ieee802154_hdr_minlen(hdr); 250 + if (rc < 0 || !pskb_may_pull(skb, rc)) 251 + return -EINVAL; 252 + 253 + pos += ieee802154_hdr_get_addrs(skb->data + pos, hdr); 254 + 255 + if (hdr->fc.security_enabled) { 256 + int want = pos + ieee802154_hdr_sechdr_len(skb->data[pos]); 257 + 258 + if (!pskb_may_pull(skb, want)) 259 + return -EINVAL; 260 + 261 + pos += ieee802154_hdr_get_sechdr(skb->data + pos, &hdr->sec); 262 + } 263 + 264 + skb_pull(skb, pos); 265 + return pos; 266 + } 267 + EXPORT_SYMBOL_GPL(ieee802154_hdr_pull); 268 + 269 + int 270 + ieee802154_hdr_peek_addrs(const struct sk_buff *skb, struct ieee802154_hdr *hdr) 271 + { 272 + const u8 *buf = skb_mac_header(skb); 273 + int pos = 3, rc; 274 + 275 + if (buf + 3 > skb_tail_pointer(skb)) 276 + return -EINVAL; 277 + 278 + memcpy(hdr, buf, 3); 279 + 280 + rc = ieee802154_hdr_minlen(hdr); 281 + if (rc < 0 || buf + rc > skb_tail_pointer(skb)) 282 + return -EINVAL; 283 + 284 + pos += ieee802154_hdr_get_addrs(buf + pos, hdr); 285 + return pos; 286 + } 287 + EXPORT_SYMBOL_GPL(ieee802154_hdr_peek_addrs);
+62 -40
net/ieee802154/nl-mac.c
··· 39 39 40 40 #include "ieee802154.h" 41 41 42 + static int nla_put_hwaddr(struct sk_buff *msg, int type, __le64 hwaddr) 43 + { 44 + return nla_put_u64(msg, type, swab64((__force u64)hwaddr)); 45 + } 46 + 47 + static __le64 nla_get_hwaddr(const struct nlattr *nla) 48 + { 49 + return ieee802154_devaddr_from_raw(nla_data(nla)); 50 + } 51 + 52 + static int nla_put_shortaddr(struct sk_buff *msg, int type, __le16 addr) 53 + { 54 + return nla_put_u16(msg, type, le16_to_cpu(addr)); 55 + } 56 + 57 + static __le16 nla_get_shortaddr(const struct nlattr *nla) 58 + { 59 + return cpu_to_le16(nla_get_u16(nla)); 60 + } 61 + 42 62 int ieee802154_nl_assoc_indic(struct net_device *dev, 43 63 struct ieee802154_addr *addr, u8 cap) 44 64 { ··· 66 46 67 47 pr_debug("%s\n", __func__); 68 48 69 - if (addr->addr_type != IEEE802154_ADDR_LONG) { 49 + if (addr->mode != IEEE802154_ADDR_LONG) { 70 50 pr_err("%s: received non-long source address!\n", __func__); 71 51 return -EINVAL; 72 52 } ··· 79 59 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) || 80 60 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, 81 61 dev->dev_addr) || 82 - nla_put(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, 83 - addr->hwaddr) || 62 + nla_put_hwaddr(msg, IEEE802154_ATTR_SRC_HW_ADDR, 63 + addr->extended_addr) || 84 64 nla_put_u8(msg, IEEE802154_ATTR_CAPABILITY, cap)) 85 65 goto nla_put_failure; 86 66 ··· 92 72 } 93 73 EXPORT_SYMBOL(ieee802154_nl_assoc_indic); 94 74 95 - int ieee802154_nl_assoc_confirm(struct net_device *dev, u16 short_addr, 75 + int ieee802154_nl_assoc_confirm(struct net_device *dev, __le16 short_addr, 96 76 u8 status) 97 77 { 98 78 struct sk_buff *msg; ··· 107 87 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) || 108 88 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, 109 89 dev->dev_addr) || 110 - nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || 90 + nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || 111 91 nla_put_u8(msg, IEEE802154_ATTR_STATUS, status)) 112 92 goto nla_put_failure; 113 93 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); ··· 134 114 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, 135 115 dev->dev_addr)) 136 116 goto nla_put_failure; 137 - if (addr->addr_type == IEEE802154_ADDR_LONG) { 138 - if (nla_put(msg, IEEE802154_ATTR_SRC_HW_ADDR, IEEE802154_ADDR_LEN, 139 - addr->hwaddr)) 117 + if (addr->mode == IEEE802154_ADDR_LONG) { 118 + if (nla_put_hwaddr(msg, IEEE802154_ATTR_SRC_HW_ADDR, 119 + addr->extended_addr)) 140 120 goto nla_put_failure; 141 121 } else { 142 - if (nla_put_u16(msg, IEEE802154_ATTR_SRC_SHORT_ADDR, 143 - addr->short_addr)) 122 + if (nla_put_shortaddr(msg, IEEE802154_ATTR_SRC_SHORT_ADDR, 123 + addr->short_addr)) 144 124 goto nla_put_failure; 145 125 } 146 126 if (nla_put_u8(msg, IEEE802154_ATTR_REASON, reason)) ··· 177 157 } 178 158 EXPORT_SYMBOL(ieee802154_nl_disassoc_confirm); 179 159 180 - int ieee802154_nl_beacon_indic(struct net_device *dev, 181 - u16 panid, u16 coord_addr) 160 + int ieee802154_nl_beacon_indic(struct net_device *dev, __le16 panid, 161 + __le16 coord_addr) 182 162 { 183 163 struct sk_buff *msg; 184 164 ··· 192 172 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) || 193 173 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, 194 174 dev->dev_addr) || 195 - nla_put_u16(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, coord_addr) || 196 - nla_put_u16(msg, IEEE802154_ATTR_COORD_PAN_ID, panid)) 175 + nla_put_shortaddr(msg, IEEE802154_ATTR_COORD_SHORT_ADDR, 176 + coord_addr) || 177 + nla_put_shortaddr(msg, IEEE802154_ATTR_COORD_PAN_ID, panid)) 197 178 goto nla_put_failure; 198 179 return ieee802154_nl_mcast(msg, IEEE802154_COORD_MCGRP); 199 180 ··· 264 243 { 265 244 void *hdr; 266 245 struct wpan_phy *phy; 246 + __le16 short_addr, pan_id; 267 247 268 248 pr_debug("%s\n", __func__); 269 249 ··· 276 254 phy = ieee802154_mlme_ops(dev)->get_phy(dev); 277 255 BUG_ON(!phy); 278 256 257 + short_addr = ieee802154_mlme_ops(dev)->get_short_addr(dev); 258 + pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); 259 + 279 260 if (nla_put_string(msg, IEEE802154_ATTR_DEV_NAME, dev->name) || 280 261 nla_put_string(msg, IEEE802154_ATTR_PHY_NAME, wpan_phy_name(phy)) || 281 262 nla_put_u32(msg, IEEE802154_ATTR_DEV_INDEX, dev->ifindex) || 282 263 nla_put(msg, IEEE802154_ATTR_HW_ADDR, IEEE802154_ADDR_LEN, 283 264 dev->dev_addr) || 284 - nla_put_u16(msg, IEEE802154_ATTR_SHORT_ADDR, 285 - ieee802154_mlme_ops(dev)->get_short_addr(dev)) || 286 - nla_put_u16(msg, IEEE802154_ATTR_PAN_ID, 287 - ieee802154_mlme_ops(dev)->get_pan_id(dev))) 265 + nla_put_shortaddr(msg, IEEE802154_ATTR_SHORT_ADDR, short_addr) || 266 + nla_put_shortaddr(msg, IEEE802154_ATTR_PAN_ID, pan_id)) 288 267 goto nla_put_failure; 289 268 wpan_phy_put(phy); 290 269 return genlmsg_end(msg, hdr); ··· 345 322 goto out; 346 323 347 324 if (info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]) { 348 - addr.addr_type = IEEE802154_ADDR_LONG; 349 - nla_memcpy(addr.hwaddr, 350 - info->attrs[IEEE802154_ATTR_COORD_HW_ADDR], 351 - IEEE802154_ADDR_LEN); 325 + addr.mode = IEEE802154_ADDR_LONG; 326 + addr.extended_addr = nla_get_hwaddr( 327 + info->attrs[IEEE802154_ATTR_COORD_HW_ADDR]); 352 328 } else { 353 - addr.addr_type = IEEE802154_ADDR_SHORT; 354 - addr.short_addr = nla_get_u16( 329 + addr.mode = IEEE802154_ADDR_SHORT; 330 + addr.short_addr = nla_get_shortaddr( 355 331 info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); 356 332 } 357 - addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); 333 + addr.pan_id = nla_get_shortaddr( 334 + info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); 358 335 359 336 if (info->attrs[IEEE802154_ATTR_PAGE]) 360 337 page = nla_get_u8(info->attrs[IEEE802154_ATTR_PAGE]); ··· 388 365 if (!ieee802154_mlme_ops(dev)->assoc_resp) 389 366 goto out; 390 367 391 - addr.addr_type = IEEE802154_ADDR_LONG; 392 - nla_memcpy(addr.hwaddr, info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], 393 - IEEE802154_ADDR_LEN); 368 + addr.mode = IEEE802154_ADDR_LONG; 369 + addr.extended_addr = nla_get_hwaddr( 370 + info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]); 394 371 addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); 395 372 396 - 397 373 ret = ieee802154_mlme_ops(dev)->assoc_resp(dev, &addr, 398 - nla_get_u16(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]), 374 + nla_get_shortaddr(info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]), 399 375 nla_get_u8(info->attrs[IEEE802154_ATTR_STATUS])); 400 376 401 377 out: ··· 420 398 goto out; 421 399 422 400 if (info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]) { 423 - addr.addr_type = IEEE802154_ADDR_LONG; 424 - nla_memcpy(addr.hwaddr, 425 - info->attrs[IEEE802154_ATTR_DEST_HW_ADDR], 426 - IEEE802154_ADDR_LEN); 401 + addr.mode = IEEE802154_ADDR_LONG; 402 + addr.extended_addr = nla_get_hwaddr( 403 + info->attrs[IEEE802154_ATTR_DEST_HW_ADDR]); 427 404 } else { 428 - addr.addr_type = IEEE802154_ADDR_SHORT; 429 - addr.short_addr = nla_get_u16( 405 + addr.mode = IEEE802154_ADDR_SHORT; 406 + addr.short_addr = nla_get_shortaddr( 430 407 info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]); 431 408 } 432 409 addr.pan_id = ieee802154_mlme_ops(dev)->get_pan_id(dev); ··· 470 449 if (!ieee802154_mlme_ops(dev)->start_req) 471 450 goto out; 472 451 473 - addr.addr_type = IEEE802154_ADDR_SHORT; 474 - addr.short_addr = nla_get_u16( 452 + addr.mode = IEEE802154_ADDR_SHORT; 453 + addr.short_addr = nla_get_shortaddr( 475 454 info->attrs[IEEE802154_ATTR_COORD_SHORT_ADDR]); 476 - addr.pan_id = nla_get_u16(info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); 455 + addr.pan_id = nla_get_shortaddr( 456 + info->attrs[IEEE802154_ATTR_COORD_PAN_ID]); 477 457 478 458 channel = nla_get_u8(info->attrs[IEEE802154_ATTR_CHANNEL]); 479 459 bcn_ord = nla_get_u8(info->attrs[IEEE802154_ATTR_BCN_ORD]); ··· 489 467 page = 0; 490 468 491 469 492 - if (addr.short_addr == IEEE802154_ADDR_BROADCAST) { 470 + if (addr.short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST)) { 493 471 ieee802154_nl_start_confirm(dev, IEEE802154_NO_SHORT_ADDRESS); 494 472 dev_put(dev); 495 473 return -EINVAL;
+9 -5
net/ieee802154/raw.c
··· 28 28 #include <linux/slab.h> 29 29 #include <net/sock.h> 30 30 #include <net/af_ieee802154.h> 31 + #include <net/ieee802154_netdev.h> 31 32 32 33 #include "af802154.h" 33 34 ··· 56 55 sk_common_release(sk); 57 56 } 58 57 59 - static int raw_bind(struct sock *sk, struct sockaddr *uaddr, int len) 58 + static int raw_bind(struct sock *sk, struct sockaddr *_uaddr, int len) 60 59 { 61 - struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr; 60 + struct ieee802154_addr addr; 61 + struct sockaddr_ieee802154 *uaddr = (struct sockaddr_ieee802154 *)_uaddr; 62 62 int err = 0; 63 63 struct net_device *dev = NULL; 64 64 65 - if (len < sizeof(*addr)) 65 + if (len < sizeof(*uaddr)) 66 66 return -EINVAL; 67 67 68 - if (addr->family != AF_IEEE802154) 68 + uaddr = (struct sockaddr_ieee802154 *)_uaddr; 69 + if (uaddr->family != AF_IEEE802154) 69 70 return -EINVAL; 70 71 71 72 lock_sock(sk); 72 73 73 - dev = ieee802154_get_dev(sock_net(sk), &addr->addr); 74 + ieee802154_addr_from_sa(&addr, &uaddr->addr); 75 + dev = ieee802154_get_dev(sock_net(sk), &addr); 74 76 if (!dev) { 75 77 err = -ENODEV; 76 78 goto out;
+27 -13
net/ieee802154/reassembly.c
··· 30 30 31 31 #include "reassembly.h" 32 32 33 + struct lowpan_frag_info { 34 + __be16 d_tag; 35 + u16 d_size; 36 + u8 d_offset; 37 + }; 38 + 39 + struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb) 40 + { 41 + return (struct lowpan_frag_info *)skb->cb; 42 + } 43 + 33 44 static struct inet_frags lowpan_frags; 34 45 35 46 static int lowpan_frag_reasm(struct lowpan_frag_queue *fq, ··· 76 65 77 66 fq = container_of(q, struct lowpan_frag_queue, q); 78 67 return fq->tag == arg->tag && fq->d_size == arg->d_size && 79 - ieee802154_addr_addr_equal(&fq->saddr, arg->src) && 80 - ieee802154_addr_addr_equal(&fq->daddr, arg->dst); 68 + ieee802154_addr_equal(&fq->saddr, arg->src) && 69 + ieee802154_addr_equal(&fq->daddr, arg->dst); 81 70 } 82 71 83 72 static void lowpan_frag_init(struct inet_frag_queue *q, void *a) ··· 113 102 } 114 103 115 104 static inline struct lowpan_frag_queue * 116 - fq_find(struct net *net, const struct ieee802154_frag_info *frag_info, 117 - const struct ieee802154_addr *src, const struct ieee802154_addr *dst) 105 + fq_find(struct net *net, const struct lowpan_frag_info *frag_info, 106 + const struct ieee802154_addr *src, 107 + const struct ieee802154_addr *dst) 118 108 { 119 109 struct inet_frag_queue *q; 120 110 struct lowpan_create_arg arg; ··· 148 136 if (fq->q.last_in & INET_FRAG_COMPLETE) 149 137 goto err; 150 138 151 - offset = mac_cb(skb)->frag_info.d_offset << 3; 152 - end = mac_cb(skb)->frag_info.d_size; 139 + offset = lowpan_cb(skb)->d_offset << 3; 140 + end = lowpan_cb(skb)->d_size; 153 141 154 142 /* Is this the final fragment? */ 155 143 if (offset + skb->len == end) { ··· 175 163 * this fragment, right? 176 164 */ 177 165 prev = fq->q.fragments_tail; 178 - if (!prev || mac_cb(prev)->frag_info.d_offset < 179 - mac_cb(skb)->frag_info.d_offset) { 166 + if (!prev || lowpan_cb(prev)->d_offset < lowpan_cb(skb)->d_offset) { 180 167 next = NULL; 181 168 goto found; 182 169 } 183 170 prev = NULL; 184 171 for (next = fq->q.fragments; next != NULL; next = next->next) { 185 - if (mac_cb(next)->frag_info.d_offset >= 186 - mac_cb(skb)->frag_info.d_offset) 172 + if (lowpan_cb(next)->d_offset >= lowpan_cb(skb)->d_offset) 187 173 break; /* bingo! */ 188 174 prev = next; 189 175 } ··· 328 318 } 329 319 330 320 static int lowpan_get_frag_info(struct sk_buff *skb, const u8 frag_type, 331 - struct ieee802154_frag_info *frag_info) 321 + struct lowpan_frag_info *frag_info) 332 322 { 333 323 bool fail; 334 324 u8 pattern = 0, low = 0; ··· 355 345 { 356 346 struct lowpan_frag_queue *fq; 357 347 struct net *net = dev_net(skb->dev); 358 - struct ieee802154_frag_info *frag_info = &mac_cb(skb)->frag_info; 348 + struct lowpan_frag_info *frag_info = lowpan_cb(skb); 349 + struct ieee802154_addr source, dest; 359 350 int err; 351 + 352 + source = mac_cb(skb)->source; 353 + dest = mac_cb(skb)->dest; 360 354 361 355 err = lowpan_get_frag_info(skb, frag_type, frag_info); 362 356 if (err < 0) ··· 371 357 372 358 inet_frag_evictor(&net->ieee802154_lowpan.frags, &lowpan_frags, false); 373 359 374 - fq = fq_find(net, frag_info, &mac_cb(skb)->sa, &mac_cb(skb)->da); 360 + fq = fq_find(net, frag_info, &source, &dest); 375 361 if (fq != NULL) { 376 362 int ret; 377 363 spin_lock(&fq->q.lock);
+3 -28
net/ieee802154/reassembly.h
··· 23 23 24 24 static inline u32 ieee802154_addr_hash(const struct ieee802154_addr *a) 25 25 { 26 - switch (a->addr_type) { 26 + switch (a->mode) { 27 27 case IEEE802154_ADDR_LONG: 28 - return (__force u32)((((u32 *)a->hwaddr))[0] ^ 29 - ((u32 *)(a->hwaddr))[1]); 28 + return (((__force u64)a->extended_addr) >> 32) ^ 29 + (((__force u64)a->extended_addr) & 0xffffffff); 30 30 case IEEE802154_ADDR_SHORT: 31 31 return (__force u32)(a->short_addr); 32 32 default: 33 33 return 0; 34 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 35 } 61 36 62 37 int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type);
+2
net/mac802154/Makefile
··· 1 1 obj-$(CONFIG_MAC802154) += mac802154.o 2 2 mac802154-objs := ieee802154_dev.o rx.o tx.o mac_cmd.o mib.o monitor.o wpan.o 3 + 4 + ccflags-y += -D__CHECK_ENDIAN__
+4 -1
net/mac802154/ieee802154_dev.c
··· 27 27 #include <net/netlink.h> 28 28 #include <linux/nl802154.h> 29 29 #include <net/mac802154.h> 30 + #include <net/ieee802154_netdev.h> 30 31 #include <net/route.h> 31 32 #include <net/wpan-phy.h> 32 33 ··· 47 46 } 48 47 49 48 if (ipriv->ops->ieee_addr) { 50 - res = ipriv->ops->ieee_addr(&ipriv->hw, dev->dev_addr); 49 + __le64 addr = ieee802154_devaddr_from_raw(dev->dev_addr); 50 + 51 + res = ipriv->ops->ieee_addr(&ipriv->hw, addr); 51 52 WARN_ON(res); 52 53 if (res) 53 54 goto err;
+5 -4
net/mac802154/mac802154.h
··· 76 76 77 77 __le16 pan_id; 78 78 __le16 short_addr; 79 + __le64 extended_addr; 79 80 80 81 u8 chan; 81 82 u8 page; ··· 107 106 u8 page, u8 chan); 108 107 109 108 /* MIB callbacks */ 110 - void mac802154_dev_set_short_addr(struct net_device *dev, u16 val); 111 - u16 mac802154_dev_get_short_addr(const struct net_device *dev); 109 + void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val); 110 + __le16 mac802154_dev_get_short_addr(const struct net_device *dev); 112 111 void mac802154_dev_set_ieee_addr(struct net_device *dev); 113 - u16 mac802154_dev_get_pan_id(const struct net_device *dev); 114 - void mac802154_dev_set_pan_id(struct net_device *dev, u16 val); 112 + __le16 mac802154_dev_get_pan_id(const struct net_device *dev); 113 + void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val); 115 114 void mac802154_dev_set_page_channel(struct net_device *dev, u8 page, u8 chan); 116 115 u8 mac802154_dev_get_dsn(const struct net_device *dev); 117 116
+1 -1
net/mac802154/mac_cmd.c
··· 40 40 u8 pan_coord, u8 blx, 41 41 u8 coord_realign) 42 42 { 43 - BUG_ON(addr->addr_type != IEEE802154_ADDR_SHORT); 43 + BUG_ON(addr->mode != IEEE802154_ADDR_SHORT); 44 44 45 45 mac802154_dev_set_pan_id(dev, addr->pan_id); 46 46 mac802154_dev_set_short_addr(dev, addr->short_addr);
+12 -10
net/mac802154/mib.c
··· 24 24 #include <linux/if_arp.h> 25 25 26 26 #include <net/mac802154.h> 27 + #include <net/ieee802154_netdev.h> 27 28 #include <net/wpan-phy.h> 29 + #include <net/ieee802154_netdev.h> 28 30 29 31 #include "mac802154.h" 30 32 ··· 81 79 queue_work(priv->hw->dev_workqueue, &work->work); 82 80 } 83 81 84 - void mac802154_dev_set_short_addr(struct net_device *dev, u16 val) 82 + void mac802154_dev_set_short_addr(struct net_device *dev, __le16 val) 85 83 { 86 84 struct mac802154_sub_if_data *priv = netdev_priv(dev); 87 85 ··· 98 96 } 99 97 } 100 98 101 - u16 mac802154_dev_get_short_addr(const struct net_device *dev) 99 + __le16 mac802154_dev_get_short_addr(const struct net_device *dev) 102 100 { 103 101 struct mac802154_sub_if_data *priv = netdev_priv(dev); 104 - u16 ret; 102 + __le16 ret; 105 103 106 104 BUG_ON(dev->type != ARPHRD_IEEE802154); 107 105 ··· 117 115 struct mac802154_sub_if_data *priv = netdev_priv(dev); 118 116 struct mac802154_priv *mac = priv->hw; 119 117 118 + priv->extended_addr = ieee802154_devaddr_from_raw(dev->dev_addr); 119 + 120 120 if (mac->ops->set_hw_addr_filt && 121 - memcmp(mac->hw.hw_filt.ieee_addr, 122 - dev->dev_addr, IEEE802154_ADDR_LEN)) { 123 - memcpy(mac->hw.hw_filt.ieee_addr, 124 - dev->dev_addr, IEEE802154_ADDR_LEN); 121 + mac->hw.hw_filt.ieee_addr != priv->extended_addr) { 122 + mac->hw.hw_filt.ieee_addr = priv->extended_addr; 125 123 set_hw_addr_filt(dev, IEEE802515_AFILT_IEEEADDR_CHANGED); 126 124 } 127 125 } 128 126 129 - u16 mac802154_dev_get_pan_id(const struct net_device *dev) 127 + __le16 mac802154_dev_get_pan_id(const struct net_device *dev) 130 128 { 131 129 struct mac802154_sub_if_data *priv = netdev_priv(dev); 132 - u16 ret; 130 + __le16 ret; 133 131 134 132 BUG_ON(dev->type != ARPHRD_IEEE802154); 135 133 ··· 140 138 return ret; 141 139 } 142 140 143 - void mac802154_dev_set_pan_id(struct net_device *dev, u16 val) 141 + void mac802154_dev_set_pan_id(struct net_device *dev, __le16 val) 144 142 { 145 143 struct mac802154_sub_if_data *priv = netdev_priv(dev); 146 144
+118 -260
net/mac802154/wpan.c
··· 35 35 36 36 #include "mac802154.h" 37 37 38 - static inline int mac802154_fetch_skb_u8(struct sk_buff *skb, u8 *val) 39 - { 40 - if (unlikely(!pskb_may_pull(skb, 1))) 41 - return -EINVAL; 42 - 43 - *val = skb->data[0]; 44 - skb_pull(skb, 1); 45 - 46 - return 0; 47 - } 48 - 49 - static inline int mac802154_fetch_skb_u16(struct sk_buff *skb, u16 *val) 50 - { 51 - if (unlikely(!pskb_may_pull(skb, 2))) 52 - return -EINVAL; 53 - 54 - *val = skb->data[0] | (skb->data[1] << 8); 55 - skb_pull(skb, 2); 56 - 57 - return 0; 58 - } 59 - 60 - static inline void mac802154_haddr_copy_swap(u8 *dest, const u8 *src) 61 - { 62 - int i; 63 - for (i = 0; i < IEEE802154_ADDR_LEN; i++) 64 - dest[IEEE802154_ADDR_LEN - i - 1] = src[i]; 65 - } 66 - 67 38 static int 68 39 mac802154_wpan_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd) 69 40 { ··· 47 76 48 77 switch (cmd) { 49 78 case SIOCGIFADDR: 50 - if (priv->pan_id == IEEE802154_PANID_BROADCAST || 51 - priv->short_addr == IEEE802154_ADDR_BROADCAST) { 79 + { 80 + u16 pan_id, short_addr; 81 + 82 + pan_id = le16_to_cpu(priv->pan_id); 83 + short_addr = le16_to_cpu(priv->short_addr); 84 + if (pan_id == IEEE802154_PANID_BROADCAST || 85 + short_addr == IEEE802154_ADDR_BROADCAST) { 52 86 err = -EADDRNOTAVAIL; 53 87 break; 54 88 } 55 89 56 90 sa->family = AF_IEEE802154; 57 91 sa->addr.addr_type = IEEE802154_ADDR_SHORT; 58 - sa->addr.pan_id = priv->pan_id; 59 - sa->addr.short_addr = priv->short_addr; 92 + sa->addr.pan_id = pan_id; 93 + sa->addr.short_addr = short_addr; 60 94 61 95 err = 0; 62 96 break; 97 + } 63 98 case SIOCSIFADDR: 64 99 dev_warn(&dev->dev, 65 100 "Using DEBUGing ioctl SIOCSIFADDR isn't recommened!\n"); ··· 78 101 break; 79 102 } 80 103 81 - priv->pan_id = sa->addr.pan_id; 82 - priv->short_addr = sa->addr.short_addr; 104 + priv->pan_id = cpu_to_le16(sa->addr.pan_id); 105 + priv->short_addr = cpu_to_le16(sa->addr.short_addr); 83 106 84 107 err = 0; 85 108 break; ··· 105 128 static int mac802154_header_create(struct sk_buff *skb, 106 129 struct net_device *dev, 107 130 unsigned short type, 108 - const void *_daddr, 109 - const void *_saddr, 131 + const void *daddr, 132 + const void *saddr, 110 133 unsigned len) 111 134 { 112 - const struct ieee802154_addr *saddr = _saddr; 113 - const struct ieee802154_addr *daddr = _daddr; 114 - struct ieee802154_addr dev_addr; 135 + struct ieee802154_hdr hdr; 115 136 struct mac802154_sub_if_data *priv = netdev_priv(dev); 116 - int pos = 2; 117 - u8 head[MAC802154_FRAME_HARD_HEADER_LEN]; 118 - u16 fc; 137 + int hlen; 119 138 120 139 if (!daddr) 121 140 return -EINVAL; 122 141 123 - head[pos++] = mac_cb(skb)->seq; /* DSN/BSN */ 124 - fc = mac_cb_type(skb); 125 - if (mac_cb_is_ackreq(skb)) 126 - fc |= IEEE802154_FC_ACK_REQ; 142 + memset(&hdr.fc, 0, sizeof(hdr.fc)); 143 + hdr.fc.type = mac_cb_type(skb); 144 + hdr.fc.security_enabled = mac_cb_is_secen(skb); 145 + hdr.fc.ack_request = mac_cb_is_ackreq(skb); 127 146 128 147 if (!saddr) { 129 148 spin_lock_bh(&priv->mib_lock); 130 149 131 - if (priv->short_addr == IEEE802154_ADDR_BROADCAST || 132 - priv->short_addr == IEEE802154_ADDR_UNDEF || 133 - priv->pan_id == IEEE802154_PANID_BROADCAST) { 134 - dev_addr.addr_type = IEEE802154_ADDR_LONG; 135 - memcpy(dev_addr.hwaddr, dev->dev_addr, 136 - IEEE802154_ADDR_LEN); 150 + if (priv->short_addr == cpu_to_le16(IEEE802154_ADDR_BROADCAST) || 151 + priv->short_addr == cpu_to_le16(IEEE802154_ADDR_UNDEF) || 152 + priv->pan_id == cpu_to_le16(IEEE802154_PANID_BROADCAST)) { 153 + hdr.source.mode = IEEE802154_ADDR_LONG; 154 + hdr.source.extended_addr = priv->extended_addr; 137 155 } else { 138 - dev_addr.addr_type = IEEE802154_ADDR_SHORT; 139 - dev_addr.short_addr = priv->short_addr; 156 + hdr.source.mode = IEEE802154_ADDR_SHORT; 157 + hdr.source.short_addr = priv->short_addr; 140 158 } 141 159 142 - dev_addr.pan_id = priv->pan_id; 143 - saddr = &dev_addr; 160 + hdr.source.pan_id = priv->pan_id; 144 161 145 162 spin_unlock_bh(&priv->mib_lock); 163 + } else { 164 + hdr.source = *(const struct ieee802154_addr *)saddr; 146 165 } 147 166 148 - if (daddr->addr_type != IEEE802154_ADDR_NONE) { 149 - fc |= (daddr->addr_type << IEEE802154_FC_DAMODE_SHIFT); 167 + hdr.dest = *(const struct ieee802154_addr *)daddr; 150 168 151 - head[pos++] = daddr->pan_id & 0xff; 152 - head[pos++] = daddr->pan_id >> 8; 169 + hlen = ieee802154_hdr_push(skb, &hdr); 170 + if (hlen < 0) 171 + return -EINVAL; 153 172 154 - if (daddr->addr_type == IEEE802154_ADDR_SHORT) { 155 - head[pos++] = daddr->short_addr & 0xff; 156 - head[pos++] = daddr->short_addr >> 8; 157 - } else { 158 - mac802154_haddr_copy_swap(head + pos, daddr->hwaddr); 159 - pos += IEEE802154_ADDR_LEN; 160 - } 161 - } 162 - 163 - if (saddr->addr_type != IEEE802154_ADDR_NONE) { 164 - fc |= (saddr->addr_type << IEEE802154_FC_SAMODE_SHIFT); 165 - 166 - if ((saddr->pan_id == daddr->pan_id) && 167 - (saddr->pan_id != IEEE802154_PANID_BROADCAST)) { 168 - /* PANID compression/intra PAN */ 169 - fc |= IEEE802154_FC_INTRA_PAN; 170 - } else { 171 - head[pos++] = saddr->pan_id & 0xff; 172 - head[pos++] = saddr->pan_id >> 8; 173 - } 174 - 175 - if (saddr->addr_type == IEEE802154_ADDR_SHORT) { 176 - head[pos++] = saddr->short_addr & 0xff; 177 - head[pos++] = saddr->short_addr >> 8; 178 - } else { 179 - mac802154_haddr_copy_swap(head + pos, saddr->hwaddr); 180 - pos += IEEE802154_ADDR_LEN; 181 - } 182 - } 183 - 184 - head[0] = fc; 185 - head[1] = fc >> 8; 186 - 187 - memcpy(skb_push(skb, pos), head, pos); 188 173 skb_reset_mac_header(skb); 189 - skb->mac_len = pos; 174 + skb->mac_len = hlen; 190 175 191 - return pos; 176 + if (hlen + len + 2 > dev->mtu) 177 + return -EMSGSIZE; 178 + 179 + return hlen; 192 180 } 193 181 194 182 static int 195 183 mac802154_header_parse(const struct sk_buff *skb, unsigned char *haddr) 196 184 { 197 - const u8 *hdr = skb_mac_header(skb); 198 - const u8 *tail = skb_tail_pointer(skb); 185 + struct ieee802154_hdr hdr; 199 186 struct ieee802154_addr *addr = (struct ieee802154_addr *)haddr; 200 - u16 fc; 201 - int da_type; 202 187 203 - if (hdr + 3 > tail) 204 - goto malformed; 205 - 206 - fc = hdr[0] | (hdr[1] << 8); 207 - 208 - hdr += 3; 209 - 210 - da_type = IEEE802154_FC_DAMODE(fc); 211 - addr->addr_type = IEEE802154_FC_SAMODE(fc); 212 - 213 - switch (da_type) { 214 - case IEEE802154_ADDR_NONE: 215 - if (fc & IEEE802154_FC_INTRA_PAN) 216 - goto malformed; 217 - break; 218 - case IEEE802154_ADDR_LONG: 219 - if (fc & IEEE802154_FC_INTRA_PAN) { 220 - if (hdr + 2 > tail) 221 - goto malformed; 222 - addr->pan_id = hdr[0] | (hdr[1] << 8); 223 - hdr += 2; 224 - } 225 - 226 - if (hdr + IEEE802154_ADDR_LEN > tail) 227 - goto malformed; 228 - 229 - hdr += IEEE802154_ADDR_LEN; 230 - break; 231 - case IEEE802154_ADDR_SHORT: 232 - if (fc & IEEE802154_FC_INTRA_PAN) { 233 - if (hdr + 2 > tail) 234 - goto malformed; 235 - addr->pan_id = hdr[0] | (hdr[1] << 8); 236 - hdr += 2; 237 - } 238 - 239 - if (hdr + 2 > tail) 240 - goto malformed; 241 - 242 - hdr += 2; 243 - break; 244 - default: 245 - goto malformed; 246 - 188 + if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0) { 189 + pr_debug("malformed packet\n"); 190 + return 0; 247 191 } 248 192 249 - switch (addr->addr_type) { 250 - case IEEE802154_ADDR_NONE: 251 - break; 252 - case IEEE802154_ADDR_LONG: 253 - if (!(fc & IEEE802154_FC_INTRA_PAN)) { 254 - if (hdr + 2 > tail) 255 - goto malformed; 256 - addr->pan_id = hdr[0] | (hdr[1] << 8); 257 - hdr += 2; 258 - } 259 - 260 - if (hdr + IEEE802154_ADDR_LEN > tail) 261 - goto malformed; 262 - 263 - mac802154_haddr_copy_swap(addr->hwaddr, hdr); 264 - hdr += IEEE802154_ADDR_LEN; 265 - break; 266 - case IEEE802154_ADDR_SHORT: 267 - if (!(fc & IEEE802154_FC_INTRA_PAN)) { 268 - if (hdr + 2 > tail) 269 - goto malformed; 270 - addr->pan_id = hdr[0] | (hdr[1] << 8); 271 - hdr += 2; 272 - } 273 - 274 - if (hdr + 2 > tail) 275 - goto malformed; 276 - 277 - addr->short_addr = hdr[0] | (hdr[1] << 8); 278 - hdr += 2; 279 - break; 280 - default: 281 - goto malformed; 282 - } 283 - 284 - return sizeof(struct ieee802154_addr); 285 - 286 - malformed: 287 - pr_debug("malformed packet\n"); 288 - return 0; 193 + *addr = hdr.source; 194 + return sizeof(*addr); 289 195 } 290 196 291 197 static netdev_tx_t ··· 242 382 get_random_bytes(&priv->bsn, 1); 243 383 get_random_bytes(&priv->dsn, 1); 244 384 245 - priv->pan_id = IEEE802154_PANID_BROADCAST; 246 - priv->short_addr = IEEE802154_ADDR_BROADCAST; 385 + priv->pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST); 386 + priv->short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST); 247 387 } 248 388 249 389 static int mac802154_process_data(struct net_device *dev, struct sk_buff *skb) ··· 254 394 static int 255 395 mac802154_subif_frame(struct mac802154_sub_if_data *sdata, struct sk_buff *skb) 256 396 { 397 + __le16 span, sshort; 398 + 257 399 pr_debug("getting packet via slave interface %s\n", sdata->dev->name); 258 400 259 401 spin_lock_bh(&sdata->mib_lock); 260 402 261 - switch (mac_cb(skb)->da.addr_type) { 403 + span = sdata->pan_id; 404 + sshort = sdata->short_addr; 405 + 406 + switch (mac_cb(skb)->dest.mode) { 262 407 case IEEE802154_ADDR_NONE: 263 - if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_NONE) 408 + if (mac_cb(skb)->dest.mode != IEEE802154_ADDR_NONE) 264 409 /* FIXME: check if we are PAN coordinator */ 265 410 skb->pkt_type = PACKET_OTHERHOST; 266 411 else ··· 273 408 skb->pkt_type = PACKET_HOST; 274 409 break; 275 410 case IEEE802154_ADDR_LONG: 276 - if (mac_cb(skb)->da.pan_id != sdata->pan_id && 277 - mac_cb(skb)->da.pan_id != IEEE802154_PANID_BROADCAST) 411 + if (mac_cb(skb)->dest.pan_id != span && 412 + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) 278 413 skb->pkt_type = PACKET_OTHERHOST; 279 - else if (!memcmp(mac_cb(skb)->da.hwaddr, sdata->dev->dev_addr, 280 - IEEE802154_ADDR_LEN)) 414 + else if (mac_cb(skb)->dest.extended_addr == sdata->extended_addr) 281 415 skb->pkt_type = PACKET_HOST; 282 416 else 283 417 skb->pkt_type = PACKET_OTHERHOST; 284 418 break; 285 419 case IEEE802154_ADDR_SHORT: 286 - if (mac_cb(skb)->da.pan_id != sdata->pan_id && 287 - mac_cb(skb)->da.pan_id != IEEE802154_PANID_BROADCAST) 420 + if (mac_cb(skb)->dest.pan_id != span && 421 + mac_cb(skb)->dest.pan_id != cpu_to_le16(IEEE802154_PANID_BROADCAST)) 288 422 skb->pkt_type = PACKET_OTHERHOST; 289 - else if (mac_cb(skb)->da.short_addr == sdata->short_addr) 423 + else if (mac_cb(skb)->dest.short_addr == sshort) 290 424 skb->pkt_type = PACKET_HOST; 291 - else if (mac_cb(skb)->da.short_addr == 292 - IEEE802154_ADDR_BROADCAST) 425 + else if (mac_cb(skb)->dest.short_addr == 426 + cpu_to_le16(IEEE802154_ADDR_BROADCAST)) 293 427 skb->pkt_type = PACKET_BROADCAST; 294 428 else 295 429 skb->pkt_type = PACKET_OTHERHOST; ··· 315 451 } 316 452 } 317 453 454 + static void mac802154_print_addr(const char *name, 455 + const struct ieee802154_addr *addr) 456 + { 457 + if (addr->mode == IEEE802154_ADDR_NONE) 458 + pr_debug("%s not present\n", name); 459 + 460 + pr_debug("%s PAN ID: %04x\n", name, le16_to_cpu(addr->pan_id)); 461 + if (addr->mode == IEEE802154_ADDR_SHORT) { 462 + pr_debug("%s is short: %04x\n", name, 463 + le16_to_cpu(addr->short_addr)); 464 + } else { 465 + u64 hw = swab64((__force u64) addr->extended_addr); 466 + 467 + pr_debug("%s is hardware: %8phC\n", name, &hw); 468 + } 469 + } 470 + 318 471 static int mac802154_parse_frame_start(struct sk_buff *skb) 319 472 { 320 - u8 *head = skb->data; 321 - u16 fc; 473 + int hlen; 474 + struct ieee802154_hdr hdr; 322 475 323 - if (mac802154_fetch_skb_u16(skb, &fc) || 324 - mac802154_fetch_skb_u8(skb, &(mac_cb(skb)->seq))) 325 - goto err; 476 + hlen = ieee802154_hdr_pull(skb, &hdr); 477 + if (hlen < 0) 478 + return -EINVAL; 326 479 327 - pr_debug("fc: %04x dsn: %02x\n", fc, head[2]); 480 + skb->mac_len = hlen; 328 481 329 - mac_cb(skb)->flags = IEEE802154_FC_TYPE(fc); 330 - mac_cb(skb)->sa.addr_type = IEEE802154_FC_SAMODE(fc); 331 - mac_cb(skb)->da.addr_type = IEEE802154_FC_DAMODE(fc); 482 + pr_debug("fc: %04x dsn: %02x\n", le16_to_cpup((__le16 *)&hdr.fc), 483 + hdr.seq); 332 484 333 - if (fc & IEEE802154_FC_INTRA_PAN) 334 - mac_cb(skb)->flags |= MAC_CB_FLAG_INTRAPAN; 485 + mac_cb(skb)->flags = hdr.fc.type; 335 486 336 - if (mac_cb(skb)->da.addr_type != IEEE802154_ADDR_NONE) { 337 - if (mac802154_fetch_skb_u16(skb, &(mac_cb(skb)->da.pan_id))) 338 - goto err; 487 + if (hdr.fc.ack_request) 488 + mac_cb(skb)->flags |= MAC_CB_FLAG_ACKREQ; 489 + if (hdr.fc.security_enabled) 490 + mac_cb(skb)->flags |= MAC_CB_FLAG_SECEN; 339 491 340 - /* source PAN id compression */ 341 - if (mac_cb_is_intrapan(skb)) 342 - mac_cb(skb)->sa.pan_id = mac_cb(skb)->da.pan_id; 492 + mac802154_print_addr("destination", &hdr.dest); 493 + mac802154_print_addr("source", &hdr.source); 343 494 344 - pr_debug("dest PAN addr: %04x\n", mac_cb(skb)->da.pan_id); 495 + mac_cb(skb)->source = hdr.source; 496 + mac_cb(skb)->dest = hdr.dest; 345 497 346 - if (mac_cb(skb)->da.addr_type == IEEE802154_ADDR_SHORT) { 347 - u16 *da = &(mac_cb(skb)->da.short_addr); 498 + if (hdr.fc.security_enabled) { 499 + u64 key; 348 500 349 - if (mac802154_fetch_skb_u16(skb, da)) 350 - goto err; 501 + pr_debug("seclevel %i\n", hdr.sec.level); 351 502 352 - pr_debug("destination address is short: %04x\n", 353 - mac_cb(skb)->da.short_addr); 354 - } else { 355 - if (!pskb_may_pull(skb, IEEE802154_ADDR_LEN)) 356 - goto err; 503 + switch (hdr.sec.key_id_mode) { 504 + case IEEE802154_SCF_KEY_IMPLICIT: 505 + pr_debug("implicit key\n"); 506 + break; 357 507 358 - mac802154_haddr_copy_swap(mac_cb(skb)->da.hwaddr, 359 - skb->data); 360 - skb_pull(skb, IEEE802154_ADDR_LEN); 508 + case IEEE802154_SCF_KEY_INDEX: 509 + pr_debug("key %02x\n", hdr.sec.key_id); 510 + break; 361 511 362 - pr_debug("destination address is hardware\n"); 363 - } 364 - } 512 + case IEEE802154_SCF_KEY_SHORT_INDEX: 513 + pr_debug("key %04x:%04x %02x\n", 514 + le32_to_cpu(hdr.sec.short_src) >> 16, 515 + le32_to_cpu(hdr.sec.short_src) & 0xffff, 516 + hdr.sec.key_id); 517 + break; 365 518 366 - if (mac_cb(skb)->sa.addr_type != IEEE802154_ADDR_NONE) { 367 - /* non PAN-compression, fetch source address id */ 368 - if (!(mac_cb_is_intrapan(skb))) { 369 - u16 *sa_pan = &(mac_cb(skb)->sa.pan_id); 370 - 371 - if (mac802154_fetch_skb_u16(skb, sa_pan)) 372 - goto err; 519 + case IEEE802154_SCF_KEY_HW_INDEX: 520 + key = swab64((__force u64) hdr.sec.extended_src); 521 + pr_debug("key source %8phC %02x\n", &key, 522 + hdr.sec.key_id); 523 + break; 373 524 } 374 525 375 - pr_debug("source PAN addr: %04x\n", mac_cb(skb)->da.pan_id); 376 - 377 - if (mac_cb(skb)->sa.addr_type == IEEE802154_ADDR_SHORT) { 378 - u16 *sa = &(mac_cb(skb)->sa.short_addr); 379 - 380 - if (mac802154_fetch_skb_u16(skb, sa)) 381 - goto err; 382 - 383 - pr_debug("source address is short: %04x\n", 384 - mac_cb(skb)->sa.short_addr); 385 - } else { 386 - if (!pskb_may_pull(skb, IEEE802154_ADDR_LEN)) 387 - goto err; 388 - 389 - mac802154_haddr_copy_swap(mac_cb(skb)->sa.hwaddr, 390 - skb->data); 391 - skb_pull(skb, IEEE802154_ADDR_LEN); 392 - 393 - pr_debug("source address is hardware\n"); 394 - } 526 + return -EINVAL; 395 527 } 396 528 397 529 return 0; 398 - err: 399 - return -EINVAL; 400 530 } 401 531 402 532 void mac802154_wpans_rx(struct mac802154_priv *priv, struct sk_buff *skb)