summaryrefslogtreecommitdiff
path: root/net/ieee802154
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 09:38:14 -0700
committerLinus Torvalds <torvalds@linux-foundation.org>2014-08-06 09:38:14 -0700
commitae045e2455429c418a418a3376301a9e5753a0a8 (patch)
treeb445bdeecd3f38aa0d0a29c9585cee49e4ccb0f1 /net/ieee802154
parentf4f142ed4ef835709c7e6d12eaca10d190bcebed (diff)
parentd247b6ab3ce6dd43665780865ec5fa145d9ab6bd (diff)
Merge git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next
Pull networking updates from David Miller: "Highlights: 1) Steady transitioning of the BPF instructure to a generic spot so all kernel subsystems can make use of it, from Alexei Starovoitov. 2) SFC driver supports busy polling, from Alexandre Rames. 3) Take advantage of hash table in UDP multicast delivery, from David Held. 4) Lighten locking, in particular by getting rid of the LRU lists, in inet frag handling. From Florian Westphal. 5) Add support for various RFC6458 control messages in SCTP, from Geir Ola Vaagland. 6) Allow to filter bridge forwarding database dumps by device, from Jamal Hadi Salim. 7) virtio-net also now supports busy polling, from Jason Wang. 8) Some low level optimization tweaks in pktgen from Jesper Dangaard Brouer. 9) Add support for ipv6 address generation modes, so that userland can have some input into the process. From Jiri Pirko. 10) Consolidate common TCP connection request code in ipv4 and ipv6, from Octavian Purdila. 11) New ARP packet logger in netfilter, from Pablo Neira Ayuso. 12) Generic resizable RCU hash table, with intial users in netlink and nftables. From Thomas Graf. 13) Maintain a name assignment type so that userspace can see where a network device name came from (enumerated by kernel, assigned explicitly by userspace, etc.) From Tom Gundersen. 14) Automatic flow label generation on transmit in ipv6, from Tom Herbert. 15) New packet timestamping facilities from Willem de Bruijn, meant to assist in measuring latencies going into/out-of the packet scheduler, latency from TCP data transmission to ACK, etc" * git://git.kernel.org/pub/scm/linux/kernel/git/davem/net-next: (1536 commits) cxgb4 : Disable recursive mailbox commands when enabling vi net: reduce USB network driver config options. tg3: Modify tg3_tso_bug() to handle multiple TX rings amd-xgbe: Perform phy connect/disconnect at dev open/stop amd-xgbe: Use dma_set_mask_and_coherent to set DMA mask net: sun4i-emac: fix memory leak on bad packet sctp: fix possible seqlock seadlock in sctp_packet_transmit() Revert "net: phy: Set the driver when registering an MDIO bus device" cxgb4vf: Turn off SGE RX/TX Callback Timers and interrupts in PCI shutdown routine team: Simplify return path of team_newlink bridge: Update outdated comment on promiscuous mode net-timestamp: ACK timestamp for bytestreams net-timestamp: TCP timestamping net-timestamp: SCHED timestamp on entering packet scheduler net-timestamp: add key to disambiguate concurrent datagrams net-timestamp: move timestamp flags out of sk_flags net-timestamp: extend SCM_TIMESTAMPING ancillary data struct cxgb4i : Move stray CPL definitions to cxgb4 driver tcp: reduce spurious retransmits due to transient SACK reneging qlcnic: Initialize dcbnl_ops before register_netdev ...
Diffstat (limited to 'net/ieee802154')
-rw-r--r--net/ieee802154/6lowpan_iphc.c801
-rw-r--r--net/ieee802154/6lowpan_rtnl.c16
-rw-r--r--net/ieee802154/Kconfig9
-rw-r--r--net/ieee802154/Makefile5
-rw-r--r--net/ieee802154/af_ieee802154.c26
-rw-r--r--net/ieee802154/dgram.c28
-rw-r--r--net/ieee802154/ieee802154.h2
-rw-r--r--net/ieee802154/netlink.c4
-rw-r--r--net/ieee802154/nl-mac.c48
-rw-r--r--net/ieee802154/nl-phy.c23
-rw-r--r--net/ieee802154/raw.c14
-rw-r--r--net/ieee802154/reassembly.c69
-rw-r--r--net/ieee802154/wpan-class.c10
13 files changed, 132 insertions, 923 deletions
diff --git a/net/ieee802154/6lowpan_iphc.c b/net/ieee802154/6lowpan_iphc.c
deleted file mode 100644
index 211b5686d719..000000000000
--- a/net/ieee802154/6lowpan_iphc.c
+++ /dev/null
@@ -1,801 +0,0 @@
-/*
- * Copyright 2011, Siemens AG
- * written by Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
- */
-
-/*
- * Based on patches from Jon Smirl <jonsmirl@gmail.com>
- * Copyright (c) 2011 Jon Smirl <jonsmirl@gmail.com>
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2
- * as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
-
-/* Jon's code is based on 6lowpan implementation for Contiki which is:
- * Copyright (c) 2008, Swedish Institute of Computer Science.
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 3. Neither the name of the Institute nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- */
-
-#include <linux/bitops.h>
-#include <linux/if_arp.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <net/6lowpan.h>
-#include <net/ipv6.h>
-#include <net/af_ieee802154.h>
-
-/*
- * Uncompress address function for source and
- * destination address(non-multicast).
- *
- * address_mode is sam value or dam value.
- */
-static int uncompress_addr(struct sk_buff *skb,
- struct in6_addr *ipaddr, const u8 address_mode,
- const u8 *lladdr, const u8 addr_type,
- const u8 addr_len)
-{
- bool fail;
-
- switch (address_mode) {
- case LOWPAN_IPHC_ADDR_00:
- /* for global link addresses */
- fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16);
- break;
- case LOWPAN_IPHC_ADDR_01:
- /* fe:80::XXXX:XXXX:XXXX:XXXX */
- ipaddr->s6_addr[0] = 0xFE;
- ipaddr->s6_addr[1] = 0x80;
- fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8);
- break;
- case LOWPAN_IPHC_ADDR_02:
- /* fe:80::ff:fe00:XXXX */
- ipaddr->s6_addr[0] = 0xFE;
- ipaddr->s6_addr[1] = 0x80;
- ipaddr->s6_addr[11] = 0xFF;
- ipaddr->s6_addr[12] = 0xFE;
- fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2);
- break;
- case LOWPAN_IPHC_ADDR_03:
- fail = false;
- switch (addr_type) {
- case IEEE802154_ADDR_LONG:
- /* fe:80::XXXX:XXXX:XXXX:XXXX
- * \_________________/
- * hwaddr
- */
- ipaddr->s6_addr[0] = 0xFE;
- ipaddr->s6_addr[1] = 0x80;
- memcpy(&ipaddr->s6_addr[8], lladdr, addr_len);
- /* second bit-flip (Universe/Local)
- * is done according RFC2464
- */
- ipaddr->s6_addr[8] ^= 0x02;
- break;
- case IEEE802154_ADDR_SHORT:
- /* fe:80::ff:fe00:XXXX
- * \__/
- * short_addr
- *
- * Universe/Local bit is zero.
- */
- ipaddr->s6_addr[0] = 0xFE;
- ipaddr->s6_addr[1] = 0x80;
- ipaddr->s6_addr[11] = 0xFF;
- ipaddr->s6_addr[12] = 0xFE;
- ipaddr->s6_addr16[7] = htons(*((u16 *)lladdr));
- break;
- default:
- pr_debug("Invalid addr_type set\n");
- return -EINVAL;
- }
- break;
- default:
- pr_debug("Invalid address mode value: 0x%x\n", address_mode);
- return -EINVAL;
- }
-
- if (fail) {
- pr_debug("Failed to fetch skb data\n");
- return -EIO;
- }
-
- raw_dump_inline(NULL, "Reconstructed ipv6 addr is",
- ipaddr->s6_addr, 16);
-
- return 0;
-}
-
-/*
- * Uncompress address function for source context
- * based address(non-multicast).
- */
-static int uncompress_context_based_src_addr(struct sk_buff *skb,
- struct in6_addr *ipaddr,
- const u8 sam)
-{
- switch (sam) {
- case LOWPAN_IPHC_ADDR_00:
- /* unspec address ::
- * Do nothing, address is already ::
- */
- break;
- case LOWPAN_IPHC_ADDR_01:
- /* TODO */
- case LOWPAN_IPHC_ADDR_02:
- /* TODO */
- case LOWPAN_IPHC_ADDR_03:
- /* TODO */
- netdev_warn(skb->dev, "SAM value 0x%x not supported\n", sam);
- return -EINVAL;
- default:
- pr_debug("Invalid sam value: 0x%x\n", sam);
- return -EINVAL;
- }
-
- raw_dump_inline(NULL,
- "Reconstructed context based ipv6 src addr is",
- ipaddr->s6_addr, 16);
-
- return 0;
-}
-
-static int skb_deliver(struct sk_buff *skb, struct ipv6hdr *hdr,
- struct net_device *dev, skb_delivery_cb deliver_skb)
-{
- struct sk_buff *new;
- int stat;
-
- new = skb_copy_expand(skb, sizeof(struct ipv6hdr), skb_tailroom(skb),
- GFP_ATOMIC);
- kfree_skb(skb);
-
- if (!new)
- return -ENOMEM;
-
- skb_push(new, sizeof(struct ipv6hdr));
- skb_reset_network_header(new);
- skb_copy_to_linear_data(new, hdr, sizeof(struct ipv6hdr));
-
- new->protocol = htons(ETH_P_IPV6);
- new->pkt_type = PACKET_HOST;
- new->dev = dev;
-
- raw_dump_table(__func__, "raw skb data dump before receiving",
- new->data, new->len);
-
- stat = deliver_skb(new, dev);
-
- kfree_skb(new);
-
- return stat;
-}
-
-/* Uncompress function for multicast destination address,
- * when M bit is set.
- */
-static int
-lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
- struct in6_addr *ipaddr,
- const u8 dam)
-{
- bool fail;
-
- switch (dam) {
- case LOWPAN_IPHC_DAM_00:
- /* 00: 128 bits. The full address
- * is carried in-line.
- */
- fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16);
- break;
- case LOWPAN_IPHC_DAM_01:
- /* 01: 48 bits. The address takes
- * the form ffXX::00XX:XXXX:XXXX.
- */
- ipaddr->s6_addr[0] = 0xFF;
- fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1);
- fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5);
- break;
- case LOWPAN_IPHC_DAM_10:
- /* 10: 32 bits. The address takes
- * the form ffXX::00XX:XXXX.
- */
- ipaddr->s6_addr[0] = 0xFF;
- fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1);
- fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3);
- break;
- case LOWPAN_IPHC_DAM_11:
- /* 11: 8 bits. The address takes
- * the form ff02::00XX.
- */
- ipaddr->s6_addr[0] = 0xFF;
- ipaddr->s6_addr[1] = 0x02;
- fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1);
- break;
- default:
- pr_debug("DAM value has a wrong value: 0x%x\n", dam);
- return -EINVAL;
- }
-
- if (fail) {
- pr_debug("Failed to fetch skb data\n");
- return -EIO;
- }
-
- raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is",
- ipaddr->s6_addr, 16);
-
- return 0;
-}
-
-static int
-uncompress_udp_header(struct sk_buff *skb, struct udphdr *uh)
-{
- bool fail;
- u8 tmp = 0, val = 0;
-
- if (!uh)
- goto err;
-
- fail = lowpan_fetch_skb(skb, &tmp, 1);
-
- if ((tmp & LOWPAN_NHC_UDP_MASK) == LOWPAN_NHC_UDP_ID) {
- pr_debug("UDP header uncompression\n");
- switch (tmp & LOWPAN_NHC_UDP_CS_P_11) {
- case LOWPAN_NHC_UDP_CS_P_00:
- fail |= lowpan_fetch_skb(skb, &uh->source, 2);
- fail |= lowpan_fetch_skb(skb, &uh->dest, 2);
- break;
- case LOWPAN_NHC_UDP_CS_P_01:
- fail |= lowpan_fetch_skb(skb, &uh->source, 2);
- fail |= lowpan_fetch_skb(skb, &val, 1);
- uh->dest = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
- break;
- case LOWPAN_NHC_UDP_CS_P_10:
- fail |= lowpan_fetch_skb(skb, &val, 1);
- uh->source = htons(val + LOWPAN_NHC_UDP_8BIT_PORT);
- fail |= lowpan_fetch_skb(skb, &uh->dest, 2);
- break;
- case LOWPAN_NHC_UDP_CS_P_11:
- fail |= lowpan_fetch_skb(skb, &val, 1);
- uh->source = htons(LOWPAN_NHC_UDP_4BIT_PORT +
- (val >> 4));
- uh->dest = htons(LOWPAN_NHC_UDP_4BIT_PORT +
- (val & 0x0f));
- break;
- default:
- pr_debug("ERROR: unknown UDP format\n");
- goto err;
- break;
- }
-
- pr_debug("uncompressed UDP ports: src = %d, dst = %d\n",
- ntohs(uh->source), ntohs(uh->dest));
-
- /* checksum */
- if (tmp & LOWPAN_NHC_UDP_CS_C) {
- pr_debug_ratelimited("checksum elided currently not supported\n");
- goto err;
- } else {
- fail |= lowpan_fetch_skb(skb, &uh->check, 2);
- }
-
- /*
- * UDP lenght needs to be infered from the lower layers
- * here, we obtain the hint from the remaining size of the
- * frame
- */
- uh->len = htons(skb->len + sizeof(struct udphdr));
- pr_debug("uncompressed UDP length: src = %d", ntohs(uh->len));
- } else {
- pr_debug("ERROR: unsupported NH format\n");
- goto err;
- }
-
- if (fail)
- goto err;
-
- return 0;
-err:
- return -EINVAL;
-}
-
-/* TTL uncompression values */
-static const u8 lowpan_ttl_values[] = { 0, 1, 64, 255 };
-
-int lowpan_process_data(struct sk_buff *skb, struct net_device *dev,
- const u8 *saddr, const u8 saddr_type, const u8 saddr_len,
- const u8 *daddr, const u8 daddr_type, const u8 daddr_len,
- u8 iphc0, u8 iphc1, skb_delivery_cb deliver_skb)
-{
- struct ipv6hdr hdr = {};
- u8 tmp, num_context = 0;
- int err;
-
- raw_dump_table(__func__, "raw skb data dump uncompressed",
- skb->data, skb->len);
-
- /* another if the CID flag is set */
- if (iphc1 & LOWPAN_IPHC_CID) {
- pr_debug("CID flag is set, increase header with one\n");
- if (lowpan_fetch_skb_u8(skb, &num_context))
- goto drop;
- }
-
- hdr.version = 6;
-
- /* Traffic Class and Flow Label */
- switch ((iphc0 & LOWPAN_IPHC_TF) >> 3) {
- /*
- * Traffic Class and FLow Label carried in-line
- * ECN + DSCP + 4-bit Pad + Flow Label (4 bytes)
- */
- case 0: /* 00b */
- if (lowpan_fetch_skb_u8(skb, &tmp))
- goto drop;
-
- memcpy(&hdr.flow_lbl, &skb->data[0], 3);
- skb_pull(skb, 3);
- hdr.priority = ((tmp >> 2) & 0x0f);
- hdr.flow_lbl[0] = ((tmp >> 2) & 0x30) | (tmp << 6) |
- (hdr.flow_lbl[0] & 0x0f);
- break;
- /*
- * Traffic class carried in-line
- * ECN + DSCP (1 byte), Flow Label is elided
- */
- case 2: /* 10b */
- if (lowpan_fetch_skb_u8(skb, &tmp))
- goto drop;
-
- hdr.priority = ((tmp >> 2) & 0x0f);
- hdr.flow_lbl[0] = ((tmp << 6) & 0xC0) | ((tmp >> 2) & 0x30);
- break;
- /*
- * Flow Label carried in-line
- * ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided
- */
- case 1: /* 01b */
- if (lowpan_fetch_skb_u8(skb, &tmp))
- goto drop;
-
- hdr.flow_lbl[0] = (skb->data[0] & 0x0F) | ((tmp >> 2) & 0x30);
- memcpy(&hdr.flow_lbl[1], &skb->data[0], 2);
- skb_pull(skb, 2);
- break;
- /* Traffic Class and Flow Label are elided */
- case 3: /* 11b */
- break;
- default:
- break;
- }
-
- /* Next Header */
- if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) {
- /* Next header is carried inline */
- if (lowpan_fetch_skb_u8(skb, &(hdr.nexthdr)))
- goto drop;
-
- pr_debug("NH flag is set, next header carried inline: %02x\n",
- hdr.nexthdr);
- }
-
- /* Hop Limit */
- if ((iphc0 & 0x03) != LOWPAN_IPHC_TTL_I)
- hdr.hop_limit = lowpan_ttl_values[iphc0 & 0x03];
- else {
- if (lowpan_fetch_skb_u8(skb, &(hdr.hop_limit)))
- goto drop;
- }
-
- /* Extract SAM to the tmp variable */
- tmp = ((iphc1 & LOWPAN_IPHC_SAM) >> LOWPAN_IPHC_SAM_BIT) & 0x03;
-
- if (iphc1 & LOWPAN_IPHC_SAC) {
- /* Source address context based uncompression */
- pr_debug("SAC bit is set. Handle context based source address.\n");
- err = uncompress_context_based_src_addr(
- skb, &hdr.saddr, tmp);
- } else {
- /* Source address uncompression */
- pr_debug("source address stateless compression\n");
- err = uncompress_addr(skb, &hdr.saddr, tmp, saddr,
- saddr_type, saddr_len);
- }
-
- /* Check on error of previous branch */
- if (err)
- goto drop;
-
- /* Extract DAM to the tmp variable */
- tmp = ((iphc1 & LOWPAN_IPHC_DAM_11) >> LOWPAN_IPHC_DAM_BIT) & 0x03;
-
- /* check for Multicast Compression */
- if (iphc1 & LOWPAN_IPHC_M) {
- if (iphc1 & LOWPAN_IPHC_DAC) {
- pr_debug("dest: context-based mcast compression\n");
- /* TODO: implement this */
- } else {
- err = lowpan_uncompress_multicast_daddr(
- skb, &hdr.daddr, tmp);
- if (err)
- goto drop;
- }
- } else {
- err = uncompress_addr(skb, &hdr.daddr, tmp, daddr,
- daddr_type, daddr_len);
- pr_debug("dest: stateless compression mode %d dest %pI6c\n",
- tmp, &hdr.daddr);
- if (err)
- goto drop;
- }
-
- /* UDP data uncompression */
- if (iphc0 & LOWPAN_IPHC_NH_C) {
- struct udphdr uh;
- struct sk_buff *new;
- if (uncompress_udp_header(skb, &uh))
- goto drop;
-
- /*
- * replace the compressed UDP head by the uncompressed UDP
- * header
- */
- new = skb_copy_expand(skb, sizeof(struct udphdr),
- skb_tailroom(skb), GFP_ATOMIC);
- kfree_skb(skb);
-
- if (!new)
- return -ENOMEM;
-
- skb = new;
-
- skb_push(skb, sizeof(struct udphdr));
- skb_reset_transport_header(skb);
- skb_copy_to_linear_data(skb, &uh, sizeof(struct udphdr));
-
- raw_dump_table(__func__, "raw UDP header dump",
- (u8 *)&uh, sizeof(uh));
-
- hdr.nexthdr = UIP_PROTO_UDP;
- }
-
- hdr.payload_len = htons(skb->len);
-
- pr_debug("skb headroom size = %d, data length = %d\n",
- skb_headroom(skb), skb->len);
-
- pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t"
- "nexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n",
- hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
- hdr.hop_limit, &hdr.daddr);
-
- raw_dump_table(__func__, "raw header dump", (u8 *)&hdr,
- sizeof(hdr));
-
- return skb_deliver(skb, &hdr, dev, deliver_skb);
-
-drop:
- kfree_skb(skb);
- return -EINVAL;
-}
-EXPORT_SYMBOL_GPL(lowpan_process_data);
-
-static u8 lowpan_compress_addr_64(u8 **hc06_ptr, u8 shift,
- const struct in6_addr *ipaddr,
- const unsigned char *lladdr)
-{
- u8 val = 0;
-
- if (is_addr_mac_addr_based(ipaddr, lladdr)) {
- val = 3; /* 0-bits */
- pr_debug("address compression 0 bits\n");
- } else if (lowpan_is_iid_16_bit_compressable(ipaddr)) {
- /* compress IID to 16 bits xxxx::XXXX */
- memcpy(*hc06_ptr, &ipaddr->s6_addr16[7], 2);
- *hc06_ptr += 2;
- val = 2; /* 16-bits */
- raw_dump_inline(NULL, "Compressed ipv6 addr is (16 bits)",
- *hc06_ptr - 2, 2);
- } else {
- /* do not compress IID => xxxx::IID */
- memcpy(*hc06_ptr, &ipaddr->s6_addr16[4], 8);
- *hc06_ptr += 8;
- val = 1; /* 64-bits */
- raw_dump_inline(NULL, "Compressed ipv6 addr is (64 bits)",
- *hc06_ptr - 8, 8);
- }
-
- return rol8(val, shift);
-}
-
-static void compress_udp_header(u8 **hc06_ptr, struct sk_buff *skb)
-{
- struct udphdr *uh = udp_hdr(skb);
- u8 tmp;
-
- if (((ntohs(uh->source) & LOWPAN_NHC_UDP_4BIT_MASK) ==
- LOWPAN_NHC_UDP_4BIT_PORT) &&
- ((ntohs(uh->dest) & LOWPAN_NHC_UDP_4BIT_MASK) ==
- LOWPAN_NHC_UDP_4BIT_PORT)) {
- pr_debug("UDP header: both ports compression to 4 bits\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_11;
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- /* source and destination port */
- tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_4BIT_PORT +
- ((ntohs(uh->source) - LOWPAN_NHC_UDP_4BIT_PORT) << 4);
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- } else if ((ntohs(uh->dest) & LOWPAN_NHC_UDP_8BIT_MASK) ==
- LOWPAN_NHC_UDP_8BIT_PORT) {
- pr_debug("UDP header: remove 8 bits of dest\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_01;
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- /* source port */
- lowpan_push_hc_data(hc06_ptr, &uh->source, sizeof(uh->source));
- /* destination port */
- tmp = ntohs(uh->dest) - LOWPAN_NHC_UDP_8BIT_PORT;
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- } else if ((ntohs(uh->source) & LOWPAN_NHC_UDP_8BIT_MASK) ==
- LOWPAN_NHC_UDP_8BIT_PORT) {
- pr_debug("UDP header: remove 8 bits of source\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_10;
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- /* source port */
- tmp = ntohs(uh->source) - LOWPAN_NHC_UDP_8BIT_PORT;
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- /* destination port */
- lowpan_push_hc_data(hc06_ptr, &uh->dest, sizeof(uh->dest));
- } else {
- pr_debug("UDP header: can't compress\n");
- /* compression value */
- tmp = LOWPAN_NHC_UDP_CS_P_00;
- lowpan_push_hc_data(hc06_ptr, &tmp, sizeof(tmp));
- /* source port */
- lowpan_push_hc_data(hc06_ptr, &uh->source, sizeof(uh->source));
- /* destination port */
- lowpan_push_hc_data(hc06_ptr, &uh->dest, sizeof(uh->dest));
- }
-
- /* checksum is always inline */
- lowpan_push_hc_data(hc06_ptr, &uh->check, sizeof(uh->check));
-
- /* skip the UDP header */
- skb_pull(skb, sizeof(struct udphdr));
-}
-
-int lowpan_header_compress(struct sk_buff *skb, struct net_device *dev,
- unsigned short type, const void *_daddr,
- const void *_saddr, unsigned int len)
-{
- u8 tmp, iphc0, iphc1, *hc06_ptr;
- struct ipv6hdr *hdr;
- u8 head[100] = {};
-
- if (type != ETH_P_IPV6)
- return -EINVAL;
-
- hdr = ipv6_hdr(skb);
- hc06_ptr = head + 2;
-
- pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n"
- "\tnexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n",
- hdr->version, ntohs(hdr->payload_len), hdr->nexthdr,
- hdr->hop_limit, &hdr->daddr);
-
- raw_dump_table(__func__, "raw skb network header dump",
- skb_network_header(skb), sizeof(struct ipv6hdr));
-
- /*
- * As we copy some bit-length fields, in the IPHC encoding bytes,
- * we sometimes use |=
- * If the field is 0, and the current bit value in memory is 1,
- * this does not work. We therefore reset the IPHC encoding here
- */
- iphc0 = LOWPAN_DISPATCH_IPHC;
- iphc1 = 0;
-
- /* TODO: context lookup */
-
- raw_dump_inline(__func__, "saddr",
- (unsigned char *)_saddr, IEEE802154_ADDR_LEN);
- raw_dump_inline(__func__, "daddr",
- (unsigned char *)_daddr, IEEE802154_ADDR_LEN);
-
- raw_dump_table(__func__,
- "sending raw skb network uncompressed packet",
- skb->data, skb->len);
-
- /*
- * Traffic class, flow label
- * If flow label is 0, compress it. If traffic class is 0, compress it
- * We have to process both in the same time as the offset of traffic
- * class depends on the presence of version and flow label
- */
-
- /* hc06 format of TC is ECN | DSCP , original one is DSCP | ECN */
- tmp = (hdr->priority << 4) | (hdr->flow_lbl[0] >> 4);
- tmp = ((tmp & 0x03) << 6) | (tmp >> 2);
-
- if (((hdr->flow_lbl[0] & 0x0F) == 0) &&
- (hdr->flow_lbl[1] == 0) && (hdr->flow_lbl[2] == 0)) {
- /* flow label can be compressed */
- iphc0 |= LOWPAN_IPHC_FL_C;
- if ((hdr->priority == 0) &&
- ((hdr->flow_lbl[0] & 0xF0) == 0)) {
- /* compress (elide) all */
- iphc0 |= LOWPAN_IPHC_TC_C;
- } else {
- /* compress only the flow label */
- *hc06_ptr = tmp;
- hc06_ptr += 1;
- }
- } else {
- /* Flow label cannot be compressed */
- if ((hdr->priority == 0) &&
- ((hdr->flow_lbl[0] & 0xF0) == 0)) {
- /* compress only traffic class */
- iphc0 |= LOWPAN_IPHC_TC_C;
- *hc06_ptr = (tmp & 0xc0) | (hdr->flow_lbl[0] & 0x0F);
- memcpy(hc06_ptr + 1, &hdr->flow_lbl[1], 2);
- hc06_ptr += 3;
- } else {
- /* compress nothing */
- memcpy(hc06_ptr, hdr, 4);
- /* replace the top byte with new ECN | DSCP format */
- *hc06_ptr = tmp;
- hc06_ptr += 4;
- }
- }
-
- /* NOTE: payload length is always compressed */
-
- /* Next Header is compress if UDP */
- if (hdr->nexthdr == UIP_PROTO_UDP)
- iphc0 |= LOWPAN_IPHC_NH_C;
-
- if ((iphc0 & LOWPAN_IPHC_NH_C) == 0) {
- *hc06_ptr = hdr->nexthdr;
- hc06_ptr += 1;
- }
-
- /*
- * Hop limit
- * if 1: compress, encoding is 01
- * if 64: compress, encoding is 10
- * if 255: compress, encoding is 11
- * else do not compress
- */
- switch (hdr->hop_limit) {
- case 1:
- iphc0 |= LOWPAN_IPHC_TTL_1;
- break;
- case 64:
- iphc0 |= LOWPAN_IPHC_TTL_64;
- break;
- case 255:
- iphc0 |= LOWPAN_IPHC_TTL_255;
- break;
- default:
- *hc06_ptr = hdr->hop_limit;
- hc06_ptr += 1;
- break;
- }
-
- /* source address compression */
- if (is_addr_unspecified(&hdr->saddr)) {
- pr_debug("source address is unspecified, setting SAC\n");
- iphc1 |= LOWPAN_IPHC_SAC;
- /* TODO: context lookup */
- } else if (is_addr_link_local(&hdr->saddr)) {
- iphc1 |= lowpan_compress_addr_64(&hc06_ptr,
- LOWPAN_IPHC_SAM_BIT, &hdr->saddr, _saddr);
- pr_debug("source address unicast link-local %pI6c "
- "iphc1 0x%02x\n", &hdr->saddr, iphc1);
- } else {
- pr_debug("send the full source address\n");
- memcpy(hc06_ptr, &hdr->saddr.s6_addr16[0], 16);
- hc06_ptr += 16;
- }
-
- /* destination address compression */
- if (is_addr_mcast(&hdr->daddr)) {
- pr_debug("destination address is multicast: ");
- iphc1 |= LOWPAN_IPHC_M;
- if (lowpan_is_mcast_addr_compressable8(&hdr->daddr)) {
- pr_debug("compressed to 1 octet\n");
- iphc1 |= LOWPAN_IPHC_DAM_11;
- /* use last byte */
- *hc06_ptr = hdr->daddr.s6_addr[15];
- hc06_ptr += 1;
- } else if (lowpan_is_mcast_addr_compressable32(&hdr->daddr)) {
- pr_debug("compressed to 4 octets\n");
- iphc1 |= LOWPAN_IPHC_DAM_10;
- /* second byte + the last three */
- *hc06_ptr = hdr->daddr.s6_addr[1];
- memcpy(hc06_ptr + 1, &hdr->daddr.s6_addr[13], 3);
- hc06_ptr += 4;
- } else if (lowpan_is_mcast_addr_compressable48(&hdr->daddr)) {
- pr_debug("compressed to 6 octets\n");
- iphc1 |= LOWPAN_IPHC_DAM_01;
- /* second byte + the last five */
- *hc06_ptr = hdr->daddr.s6_addr[1];
- memcpy(hc06_ptr + 1, &hdr->daddr.s6_addr[11], 5);
- hc06_ptr += 6;
- } else {
- pr_debug("using full address\n");
- iphc1 |= LOWPAN_IPHC_DAM_00;
- memcpy(hc06_ptr, &hdr->daddr.s6_addr[0], 16);
- hc06_ptr += 16;
- }
- } else {
- /* TODO: context lookup */
- if (is_addr_link_local(&hdr->daddr)) {
- iphc1 |= lowpan_compress_addr_64(&hc06_ptr,
- LOWPAN_IPHC_DAM_BIT, &hdr->daddr, _daddr);
- pr_debug("dest address unicast link-local %pI6c "
- "iphc1 0x%02x\n", &hdr->daddr, iphc1);
- } else {
- pr_debug("dest address unicast %pI6c\n", &hdr->daddr);
- memcpy(hc06_ptr, &hdr->daddr.s6_addr16[0], 16);
- hc06_ptr += 16;
- }
- }
-
- /* UDP header compression */
- if (hdr->nexthdr == UIP_PROTO_UDP)
- compress_udp_header(&hc06_ptr, skb);
-
- head[0] = iphc0;
- head[1] = iphc1;
-
- skb_pull(skb, sizeof(struct ipv6hdr));
- skb_reset_transport_header(skb);
- memcpy(skb_push(skb, hc06_ptr - head), head, hc06_ptr - head);
- skb_reset_network_header(skb);
-
- pr_debug("header len %d skb %u\n", (int)(hc06_ptr - head), skb->len);
-
- raw_dump_table(__func__, "raw skb data dump compressed",
- skb->data, skb->len);
- return 0;
-}
-EXPORT_SYMBOL_GPL(lowpan_header_compress);
-
-MODULE_LICENSE("GPL");
diff --git a/net/ieee802154/6lowpan_rtnl.c b/net/ieee802154/6lowpan_rtnl.c
index fe6bd7a71081..016b77ee88f0 100644
--- a/net/ieee802154/6lowpan_rtnl.c
+++ b/net/ieee802154/6lowpan_rtnl.c
@@ -80,14 +80,14 @@ lowpan_dev_info *lowpan_dev_info(const struct net_device *dev)
static inline void lowpan_address_flip(u8 *src, u8 *dest)
{
int i;
+
for (i = 0; i < IEEE802154_ADDR_LEN; i++)
(dest)[IEEE802154_ADDR_LEN - i - 1] = (src)[i];
}
-static int lowpan_header_create(struct sk_buff *skb,
- struct net_device *dev,
- unsigned short type, const void *_daddr,
- const void *_saddr, unsigned int len)
+static int lowpan_header_create(struct sk_buff *skb, struct net_device *dev,
+ unsigned short type, const void *_daddr,
+ const void *_saddr, unsigned int len)
{
const u8 *saddr = _saddr;
const u8 *daddr = _daddr;
@@ -144,7 +144,7 @@ static int lowpan_header_create(struct sk_buff *skb,
}
static int lowpan_give_skb_to_devices(struct sk_buff *skb,
- struct net_device *dev)
+ struct net_device *dev)
{
struct lowpan_dev_record *entry;
struct sk_buff *skb_cp;
@@ -368,24 +368,28 @@ static netdev_tx_t lowpan_xmit(struct sk_buff *skb, struct net_device *dev)
static struct wpan_phy *lowpan_get_phy(const struct net_device *dev)
{
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+
return ieee802154_mlme_ops(real_dev)->get_phy(real_dev);
}
static __le16 lowpan_get_pan_id(const struct net_device *dev)
{
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+
return ieee802154_mlme_ops(real_dev)->get_pan_id(real_dev);
}
static __le16 lowpan_get_short_addr(const struct net_device *dev)
{
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+
return ieee802154_mlme_ops(real_dev)->get_short_addr(real_dev);
}
static u8 lowpan_get_dsn(const struct net_device *dev)
{
struct net_device *real_dev = lowpan_dev_info(dev)->real_dev;
+
return ieee802154_mlme_ops(real_dev)->get_dsn(real_dev);
}
@@ -454,7 +458,7 @@ static int lowpan_validate(struct nlattr *tb[], struct nlattr *data[])
}
static int lowpan_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt, struct net_device *orig_dev)
+ struct packet_type *pt, struct net_device *orig_dev)
{
struct ieee802154_hdr hdr;
int ret;
diff --git a/net/ieee802154/Kconfig b/net/ieee802154/Kconfig
index 8af1330b3137..c0d4154d144f 100644
--- a/net/ieee802154/Kconfig
+++ b/net/ieee802154/Kconfig
@@ -12,13 +12,6 @@ config IEEE802154
config IEEE802154_6LOWPAN
tristate "6lowpan support over IEEE 802.15.4"
- depends on IEEE802154 && IPV6
- select 6LOWPAN_IPHC
+ depends on IEEE802154 && 6LOWPAN
---help---
IPv6 compression over IEEE 802.15.4.
-
-config 6LOWPAN_IPHC
- tristate
- ---help---
- 6lowpan compression code which is shared between IEEE 802.15.4 and Bluetooth
- stacks.
diff --git a/net/ieee802154/Makefile b/net/ieee802154/Makefile
index bf1b51497a41..3914b1ed4274 100644
--- a/net/ieee802154/Makefile
+++ b/net/ieee802154/Makefile
@@ -1,8 +1,7 @@
obj-$(CONFIG_IEEE802154) += ieee802154.o af_802154.o
-obj-$(CONFIG_IEEE802154_6LOWPAN) += 6lowpan.o
-obj-$(CONFIG_6LOWPAN_IPHC) += 6lowpan_iphc.o
+obj-$(CONFIG_IEEE802154_6LOWPAN) += ieee802154_6lowpan.o
-6lowpan-y := 6lowpan_rtnl.o reassembly.o
+ieee802154_6lowpan-y := 6lowpan_rtnl.o reassembly.o
ieee802154-y := netlink.o nl-mac.o nl-phy.o nl_policy.o wpan-class.o \
header_ops.o
af_802154-y := af_ieee802154.o raw.o dgram.o
diff --git a/net/ieee802154/af_ieee802154.c b/net/ieee802154/af_ieee802154.c
index 351d9a94ec2f..29e0de63001b 100644
--- a/net/ieee802154/af_ieee802154.c
+++ b/net/ieee802154/af_ieee802154.c
@@ -40,9 +40,7 @@
#include "af802154.h"
-/*
- * Utility function for families
- */
+/* Utility function for families */
struct net_device*
ieee802154_get_dev(struct net *net, const struct ieee802154_addr *addr)
{
@@ -87,8 +85,8 @@ ieee802154_get_dev(struct net *net, const struct ieee802154_addr *addr)
rtnl_unlock();
break;
default:
- pr_warning("Unsupported ieee802154 address type: %d\n",
- addr->mode);
+ pr_warn("Unsupported ieee802154 address type: %d\n",
+ addr->mode);
break;
}
@@ -106,7 +104,7 @@ static int ieee802154_sock_release(struct socket *sock)
return 0;
}
static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
- struct msghdr *msg, size_t len)
+ struct msghdr *msg, size_t len)
{
struct sock *sk = sock->sk;
@@ -114,7 +112,7 @@ static int ieee802154_sock_sendmsg(struct kiocb *iocb, struct socket *sock,
}
static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr,
- int addr_len)
+ int addr_len)
{
struct sock *sk = sock->sk;
@@ -125,7 +123,7 @@ static int ieee802154_sock_bind(struct socket *sock, struct sockaddr *uaddr,
}
static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
- int addr_len, int flags)
+ int addr_len, int flags)
{
struct sock *sk = sock->sk;
@@ -139,7 +137,7 @@ static int ieee802154_sock_connect(struct socket *sock, struct sockaddr *uaddr,
}
static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
- unsigned int cmd)
+ unsigned int cmd)
{
struct ifreq ifr;
int ret = -ENOIOCTLCMD;
@@ -167,7 +165,7 @@ static int ieee802154_dev_ioctl(struct sock *sk, struct ifreq __user *arg,
}
static int ieee802154_sock_ioctl(struct socket *sock, unsigned int cmd,
- unsigned long arg)
+ unsigned long arg)
{
struct sock *sk = sock->sk;
@@ -238,8 +236,7 @@ static const struct proto_ops ieee802154_dgram_ops = {
};
-/*
- * Create a socket. Initialise the socket, blank the addresses
+/* Create a socket. Initialise the socket, blank the addresses
* set the state.
*/
static int ieee802154_create(struct net *net, struct socket *sock,
@@ -301,13 +298,14 @@ static const struct net_proto_family ieee802154_family_ops = {
};
static int ieee802154_rcv(struct sk_buff *skb, struct net_device *dev,
- struct packet_type *pt, struct net_device *orig_dev)
+ struct packet_type *pt, struct net_device *orig_dev)
{
if (!netif_running(dev))
goto drop;
pr_debug("got frame, type %d, dev %p\n", dev->type, dev);
#ifdef DEBUG
- print_hex_dump_bytes("ieee802154_rcv ", DUMP_PREFIX_NONE, skb->data, skb->len);
+ print_hex_dump_bytes("ieee802154_rcv ",
+ DUMP_PREFIX_NONE, skb->data, skb->len);
#endif
if (!net_eq(dev_net(dev), &init_net))
diff --git a/net/ieee802154/dgram.c b/net/ieee802154/dgram.c
index 4f0ed8780194..ef2ad8aaef13 100644
--- a/net/ieee802154/dgram.c
+++ b/net/ieee802154/dgram.c
@@ -149,8 +149,7 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
spin_lock_bh(&sk->sk_receive_queue.lock);
skb = skb_peek(&sk->sk_receive_queue);
if (skb != NULL) {
- /*
- * We will only return the amount
+ /* We will only return the amount
* of this packet since that is all
* that will be read.
*/
@@ -161,12 +160,13 @@ static int dgram_ioctl(struct sock *sk, int cmd, unsigned long arg)
}
}
+
return -ENOIOCTLCMD;
}
/* FIXME: autobind */
static int dgram_connect(struct sock *sk, struct sockaddr *uaddr,
- int len)
+ int len)
{
struct sockaddr_ieee802154 *addr = (struct sockaddr_ieee802154 *)uaddr;
struct dgram_sock *ro = dgram_sk(sk);
@@ -205,7 +205,7 @@ static int dgram_disconnect(struct sock *sk, int flags)
}
static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
- struct msghdr *msg, size_t size)
+ struct msghdr *msg, size_t size)
{
struct net_device *dev;
unsigned int mtu;
@@ -248,8 +248,8 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
hlen = LL_RESERVED_SPACE(dev);
tlen = dev->needed_tailroom;
skb = sock_alloc_send_skb(sk, hlen + tlen + size,
- msg->msg_flags & MSG_DONTWAIT,
- &err);
+ msg->msg_flags & MSG_DONTWAIT,
+ &err);
if (!skb)
goto out_dev;
@@ -262,7 +262,8 @@ static int dgram_sendmsg(struct kiocb *iocb, struct sock *sk,
cb->ackreq = ro->want_ack;
if (msg->msg_name) {
- DECLARE_SOCKADDR(struct sockaddr_ieee802154*, daddr, msg->msg_name);
+ DECLARE_SOCKADDR(struct sockaddr_ieee802154*,
+ daddr, msg->msg_name);
ieee802154_addr_from_sa(&dst_addr, &daddr->addr);
} else {
@@ -304,8 +305,8 @@ out:
}
static int dgram_recvmsg(struct kiocb *iocb, struct sock *sk,
- struct msghdr *msg, size_t len, int noblock, int flags,
- int *addr_len)
+ struct msghdr *msg, size_t len, int noblock,
+ int flags, int *addr_len)
{
size_t copied = 0;
int err = -EOPNOTSUPP;
@@ -398,6 +399,7 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
dgram_sk(sk))) {
if (prev) {
struct sk_buff *clone;
+
clone = skb_clone(skb, GFP_ATOMIC);
if (clone)
dgram_rcv_skb(prev, clone);
@@ -407,9 +409,9 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
}
}
- if (prev)
+ if (prev) {
dgram_rcv_skb(prev, skb);
- else {
+ } else {
kfree_skb(skb);
ret = NET_RX_DROP;
}
@@ -419,7 +421,7 @@ int ieee802154_dgram_deliver(struct net_device *dev, struct sk_buff *skb)
}
static int dgram_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
+ char __user *optval, int __user *optlen)
{
struct dgram_sock *ro = dgram_sk(sk);
@@ -463,7 +465,7 @@ static int dgram_getsockopt(struct sock *sk, int level, int optname,
}
static int dgram_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
+ char __user *optval, unsigned int optlen)
{
struct dgram_sock *ro = dgram_sk(sk);
struct net *net = sock_net(sk);
diff --git a/net/ieee802154/ieee802154.h b/net/ieee802154/ieee802154.h
index 8b83a231299e..5d352f86979e 100644
--- a/net/ieee802154/ieee802154.h
+++ b/net/ieee802154/ieee802154.h
@@ -43,7 +43,7 @@ struct genl_info;
struct sk_buff *ieee802154_nl_create(int flags, u8 req);
int ieee802154_nl_mcast(struct sk_buff *msg, unsigned int group);
struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
- int flags, u8 req);
+ int flags, u8 req);
int ieee802154_nl_reply(struct sk_buff *msg, struct genl_info *info);
extern struct genl_family nl802154_family;
diff --git a/net/ieee802154/netlink.c b/net/ieee802154/netlink.c
index 26efcf4fd2ff..9222966f5e6d 100644
--- a/net/ieee802154/netlink.c
+++ b/net/ieee802154/netlink.c
@@ -52,7 +52,7 @@ struct sk_buff *ieee802154_nl_create(int flags, u8 req)
spin_lock_irqsave(&ieee802154_seq_lock, f);
hdr = genlmsg_put(msg, 0, ieee802154_seq_num++,
- &nl802154_family, flags, req);
+ &nl802154_family, flags, req);
spin_unlock_irqrestore(&ieee802154_seq_lock, f);
if (!hdr) {
nlmsg_free(msg);
@@ -86,7 +86,7 @@ struct sk_buff *ieee802154_nl_new_reply(struct genl_info *info,
return NULL;
hdr = genlmsg_put_reply(msg, info,
- &nl802154_family, flags, req);
+ &nl802154_family, flags, req);
if (!hdr) {
nlmsg_free(msg);
return NULL;
diff --git a/net/ieee802154/nl-mac.c b/net/ieee802154/nl-mac.c
index a3281b8bfd5b..c6bfe22bfa5e 100644
--- a/net/ieee802154/nl-mac.c
+++ b/net/ieee802154/nl-mac.c
@@ -60,7 +60,8 @@ static __le16 nla_get_shortaddr(const struct nlattr *nla)
}
int ieee802154_nl_assoc_indic(struct net_device *dev,
- struct ieee802154_addr *addr, u8 cap)
+ struct ieee802154_addr *addr,
+ u8 cap)
{
struct sk_buff *msg;
@@ -93,7 +94,7 @@ nla_put_failure:
EXPORT_SYMBOL(ieee802154_nl_assoc_indic);
int ieee802154_nl_assoc_confirm(struct net_device *dev, __le16 short_addr,
- u8 status)
+ u8 status)
{
struct sk_buff *msg;
@@ -119,7 +120,8 @@ nla_put_failure:
EXPORT_SYMBOL(ieee802154_nl_assoc_confirm);
int ieee802154_nl_disassoc_indic(struct net_device *dev,
- struct ieee802154_addr *addr, u8 reason)
+ struct ieee802154_addr *addr,
+ u8 reason)
{
struct sk_buff *msg;
@@ -205,8 +207,9 @@ nla_put_failure:
EXPORT_SYMBOL(ieee802154_nl_beacon_indic);
int ieee802154_nl_scan_confirm(struct net_device *dev,
- u8 status, u8 scan_type, u32 unscanned, u8 page,
- u8 *edl/* , struct list_head *pan_desc_list */)
+ u8 status, u8 scan_type,
+ u32 unscanned, u8 page,
+ u8 *edl/* , struct list_head *pan_desc_list */)
{
struct sk_buff *msg;
@@ -260,7 +263,7 @@ nla_put_failure:
EXPORT_SYMBOL(ieee802154_nl_start_confirm);
static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
- u32 seq, int flags, struct net_device *dev)
+ u32 seq, int flags, struct net_device *dev)
{
void *hdr;
struct wpan_phy *phy;
@@ -270,7 +273,7 @@ static int ieee802154_nl_fill_iface(struct sk_buff *msg, u32 portid,
pr_debug("%s\n", __func__);
hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
- IEEE802154_LIST_IFACE);
+ IEEE802154_LIST_IFACE);
if (!hdr)
goto out;
@@ -330,14 +333,16 @@ static struct net_device *ieee802154_nl_get_dev(struct genl_info *info)
if (info->attrs[IEEE802154_ATTR_DEV_NAME]) {
char name[IFNAMSIZ + 1];
+
nla_strlcpy(name, info->attrs[IEEE802154_ATTR_DEV_NAME],
- sizeof(name));
+ sizeof(name));
dev = dev_get_by_name(&init_net, name);
- } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX])
+ } else if (info->attrs[IEEE802154_ATTR_DEV_INDEX]) {
dev = dev_get_by_index(&init_net,
nla_get_u32(info->attrs[IEEE802154_ATTR_DEV_INDEX]));
- else
+ } else {
return NULL;
+ }
if (!dev)
return NULL;
@@ -435,7 +440,7 @@ int ieee802154_disassociate_req(struct sk_buff *skb, struct genl_info *info)
int ret = -EOPNOTSUPP;
if ((!info->attrs[IEEE802154_ATTR_DEST_HW_ADDR] &&
- !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) ||
+ !info->attrs[IEEE802154_ATTR_DEST_SHORT_ADDR]) ||
!info->attrs[IEEE802154_ATTR_REASON])
return -EINVAL;
@@ -464,8 +469,7 @@ out:
return ret;
}
-/*
- * PANid, channel, beacon_order = 15, superframe_order = 15,
+/* PANid, channel, beacon_order = 15, superframe_order = 15,
* PAN_coordinator, battery_life_extension = 0,
* coord_realignment = 0, security_enable = 0
*/
@@ -559,8 +563,8 @@ int ieee802154_scan_req(struct sk_buff *skb, struct genl_info *info)
page = 0;
- ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels, page,
- duration);
+ ret = ieee802154_mlme_ops(dev)->scan_req(dev, type, channels,
+ page, duration);
out:
dev_put(dev);
@@ -570,7 +574,8 @@ out:
int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info)
{
/* Request for interface name, index, type, IEEE address,
- PAN Id, short address */
+ * PAN Id, short address
+ */
struct sk_buff *msg;
struct net_device *dev = NULL;
int rc = -ENOBUFS;
@@ -586,7 +591,7 @@ int ieee802154_list_iface(struct sk_buff *skb, struct genl_info *info)
goto out_dev;
rc = ieee802154_nl_fill_iface(msg, info->snd_portid, info->snd_seq,
- 0, dev);
+ 0, dev);
if (rc < 0)
goto out_free;
@@ -598,7 +603,6 @@ out_free:
out_dev:
dev_put(dev);
return rc;
-
}
int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
@@ -616,7 +620,8 @@ int ieee802154_dump_iface(struct sk_buff *skb, struct netlink_callback *cb)
goto cont;
if (ieee802154_nl_fill_iface(skb, NETLINK_CB(cb->skb).portid,
- cb->nlh->nlmsg_seq, NLM_F_MULTI, dev) < 0)
+ cb->nlh->nlmsg_seq,
+ NLM_F_MULTI, dev) < 0)
break;
cont:
idx++;
@@ -765,6 +770,7 @@ ieee802154_llsec_parse_key_id(struct genl_info *info,
case IEEE802154_SCF_KEY_SHORT_INDEX:
{
u32 source = nla_get_u32(info->attrs[IEEE802154_ATTR_LLSEC_KEY_SOURCE_SHORT]);
+
desc->short_source = cpu_to_le32(source);
break;
}
@@ -842,7 +848,7 @@ int ieee802154_llsec_getparams(struct sk_buff *skb, struct genl_info *info)
goto out_dev;
hdr = genlmsg_put(msg, 0, info->snd_seq, &nl802154_family, 0,
- IEEE802154_LLSEC_GETPARAMS);
+ IEEE802154_LLSEC_GETPARAMS);
if (!hdr)
goto out_free;
@@ -946,7 +952,7 @@ struct llsec_dump_data {
static int
ieee802154_llsec_dump_table(struct sk_buff *skb, struct netlink_callback *cb,
- int (*step)(struct llsec_dump_data*))
+ int (*step)(struct llsec_dump_data *))
{
struct net *net = sock_net(skb->sk);
struct net_device *dev;
diff --git a/net/ieee802154/nl-phy.c b/net/ieee802154/nl-phy.c
index 89b265aea151..972baf83411a 100644
--- a/net/ieee802154/nl-phy.c
+++ b/net/ieee802154/nl-phy.c
@@ -36,7 +36,7 @@
#include "ieee802154.h"
static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
- u32 seq, int flags, struct wpan_phy *phy)
+ u32 seq, int flags, struct wpan_phy *phy)
{
void *hdr;
int i, pages = 0;
@@ -48,7 +48,7 @@ static int ieee802154_nl_fill_phy(struct sk_buff *msg, u32 portid,
return -EMSGSIZE;
hdr = genlmsg_put(msg, 0, seq, &nl802154_family, flags,
- IEEE802154_LIST_PHY);
+ IEEE802154_LIST_PHY);
if (!hdr)
goto out;
@@ -80,7 +80,8 @@ out:
int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info)
{
/* Request for interface name, index, type, IEEE address,
- PAN Id, short address */
+ * PAN Id, short address
+ */
struct sk_buff *msg;
struct wpan_phy *phy;
const char *name;
@@ -105,7 +106,7 @@ int ieee802154_list_phy(struct sk_buff *skb, struct genl_info *info)
goto out_dev;
rc = ieee802154_nl_fill_phy(msg, info->snd_portid, info->snd_seq,
- 0, phy);
+ 0, phy);
if (rc < 0)
goto out_free;
@@ -117,7 +118,6 @@ out_free:
out_dev:
wpan_phy_put(phy);
return rc;
-
}
struct dump_phy_data {
@@ -137,10 +137,10 @@ static int ieee802154_dump_phy_iter(struct wpan_phy *phy, void *_data)
return 0;
rc = ieee802154_nl_fill_phy(data->skb,
- NETLINK_CB(data->cb->skb).portid,
- data->cb->nlh->nlmsg_seq,
- NLM_F_MULTI,
- phy);
+ NETLINK_CB(data->cb->skb).portid,
+ data->cb->nlh->nlmsg_seq,
+ NLM_F_MULTI,
+ phy);
if (rc < 0) {
data->idx--;
@@ -238,10 +238,9 @@ int ieee802154_add_iface(struct sk_buff *skb, struct genl_info *info)
addr.sa_family = ARPHRD_IEEE802154;
nla_memcpy(&addr.sa_data, info->attrs[IEEE802154_ATTR_HW_ADDR],
- IEEE802154_ADDR_LEN);
+ IEEE802154_ADDR_LEN);
- /*
- * strangely enough, some callbacks (inetdev_event) from
+ /* strangely enough, some callbacks (inetdev_event) from
* dev_set_mac_address require RTNL_LOCK
*/
rtnl_lock();
diff --git a/net/ieee802154/raw.c b/net/ieee802154/raw.c
index 74d54fae33d7..9d1f64806f02 100644
--- a/net/ieee802154/raw.c
+++ b/net/ieee802154/raw.c
@@ -96,7 +96,7 @@ out:
}
static int raw_connect(struct sock *sk, struct sockaddr *uaddr,
- int addr_len)
+ int addr_len)
{
return -ENOTSUPP;
}
@@ -106,8 +106,8 @@ static int raw_disconnect(struct sock *sk, int flags)
return 0;
}
-static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
- size_t size)
+static int raw_sendmsg(struct kiocb *iocb, struct sock *sk,
+ struct msghdr *msg, size_t size)
{
struct net_device *dev;
unsigned int mtu;
@@ -145,7 +145,7 @@ static int raw_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
hlen = LL_RESERVED_SPACE(dev);
tlen = dev->needed_tailroom;
skb = sock_alloc_send_skb(sk, hlen + tlen + size,
- msg->msg_flags & MSG_DONTWAIT, &err);
+ msg->msg_flags & MSG_DONTWAIT, &err);
if (!skb)
goto out_dev;
@@ -235,7 +235,6 @@ void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb)
bh_lock_sock(sk);
if (!sk->sk_bound_dev_if ||
sk->sk_bound_dev_if == dev->ifindex) {
-
struct sk_buff *clone;
clone = skb_clone(skb, GFP_ATOMIC);
@@ -248,13 +247,13 @@ void ieee802154_raw_deliver(struct net_device *dev, struct sk_buff *skb)
}
static int raw_getsockopt(struct sock *sk, int level, int optname,
- char __user *optval, int __user *optlen)
+ char __user *optval, int __user *optlen)
{
return -EOPNOTSUPP;
}
static int raw_setsockopt(struct sock *sk, int level, int optname,
- char __user *optval, unsigned int optlen)
+ char __user *optval, unsigned int optlen)
{
return -EOPNOTSUPP;
}
@@ -274,4 +273,3 @@ struct proto ieee802154_raw_prot = {
.getsockopt = raw_getsockopt,
.setsockopt = raw_setsockopt,
};
-
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index 6f1428c4870b..ffec6ce51005 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -30,6 +30,8 @@
#include "reassembly.h"
+static const char lowpan_frags_cache_name[] = "lowpan-frags";
+
struct lowpan_frag_info {
__be16 d_tag;
u16 d_size;
@@ -50,29 +52,25 @@ static unsigned int lowpan_hash_frag(__be16 tag, u16 d_size,
const struct ieee802154_addr *saddr,
const struct ieee802154_addr *daddr)
{
- u32 c;
-
net_get_random_once(&lowpan_frags.rnd, sizeof(lowpan_frags.rnd));
- c = jhash_3words(ieee802154_addr_hash(saddr),
- ieee802154_addr_hash(daddr),
- (__force u32)(tag + (d_size << 16)),
- lowpan_frags.rnd);
-
- return c & (INETFRAGS_HASHSZ - 1);
+ return jhash_3words(ieee802154_addr_hash(saddr),
+ ieee802154_addr_hash(daddr),
+ (__force u32)(tag + (d_size << 16)),
+ lowpan_frags.rnd);
}
-static unsigned int lowpan_hashfn(struct inet_frag_queue *q)
+static unsigned int lowpan_hashfn(const struct inet_frag_queue *q)
{
- struct lowpan_frag_queue *fq;
+ const struct lowpan_frag_queue *fq;
fq = container_of(q, struct lowpan_frag_queue, q);
return lowpan_hash_frag(fq->tag, fq->d_size, &fq->saddr, &fq->daddr);
}
-static bool lowpan_frag_match(struct inet_frag_queue *q, void *a)
+static bool lowpan_frag_match(const struct inet_frag_queue *q, const void *a)
{
- struct lowpan_frag_queue *fq;
- struct lowpan_create_arg *arg = a;
+ const struct lowpan_frag_queue *fq;
+ const struct lowpan_create_arg *arg = a;
fq = container_of(q, struct lowpan_frag_queue, q);
return fq->tag == arg->tag && fq->d_size == arg->d_size &&
@@ -80,10 +78,10 @@ static bool lowpan_frag_match(struct inet_frag_queue *q, void *a)
ieee802154_addr_equal(&fq->daddr, arg->dst);
}
-static void lowpan_frag_init(struct inet_frag_queue *q, void *a)
+static void lowpan_frag_init(struct inet_frag_queue *q, const void *a)
{
+ const struct lowpan_create_arg *arg = a;
struct lowpan_frag_queue *fq;
- struct lowpan_create_arg *arg = a;
fq = container_of(q, struct lowpan_frag_queue, q);
@@ -103,7 +101,7 @@ static void lowpan_frag_expire(unsigned long data)
spin_lock(&fq->q.lock);
- if (fq->q.last_in & INET_FRAG_COMPLETE)
+ if (fq->q.flags & INET_FRAG_COMPLETE)
goto out;
inet_frag_kill(&fq->q, &lowpan_frags);
@@ -128,7 +126,6 @@ fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
arg.src = src;
arg.dst = dst;
- read_lock(&lowpan_frags.lock);
hash = lowpan_hash_frag(frag_info->d_tag, frag_info->d_size, src, dst);
q = inet_frag_find(&ieee802154_lowpan->frags,
@@ -147,7 +144,7 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
struct net_device *dev;
int end, offset;
- if (fq->q.last_in & INET_FRAG_COMPLETE)
+ if (fq->q.flags & INET_FRAG_COMPLETE)
goto err;
offset = lowpan_cb(skb)->d_offset << 3;
@@ -159,14 +156,14 @@ static int lowpan_frag_queue(struct lowpan_frag_queue *fq,
* or have different end, the segment is corrupted.
*/
if (end < fq->q.len ||
- ((fq->q.last_in & INET_FRAG_LAST_IN) && end != fq->q.len))
+ ((fq->q.flags & INET_FRAG_LAST_IN) && end != fq->q.len))
goto err;
- fq->q.last_in |= INET_FRAG_LAST_IN;
+ fq->q.flags |= INET_FRAG_LAST_IN;
fq->q.len = end;
} else {
if (end > fq->q.len) {
/* Some bits beyond end -> corruption. */
- if (fq->q.last_in & INET_FRAG_LAST_IN)
+ if (fq->q.flags & INET_FRAG_LAST_IN)
goto err;
fq->q.len = end;
}
@@ -206,13 +203,13 @@ found:
if (frag_type == LOWPAN_DISPATCH_FRAG1) {
/* Calculate uncomp. 6lowpan header to estimate full size */
fq->q.meat += lowpan_uncompress_size(skb, NULL);
- fq->q.last_in |= INET_FRAG_FIRST_IN;
+ fq->q.flags |= INET_FRAG_FIRST_IN;
} else {
fq->q.meat += skb->len;
}
add_frag_mem_limit(&fq->q, skb->truesize);
- if (fq->q.last_in == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
+ if (fq->q.flags == (INET_FRAG_FIRST_IN | INET_FRAG_LAST_IN) &&
fq->q.meat == fq->q.len) {
int res;
unsigned long orefdst = skb->_skb_refdst;
@@ -223,7 +220,6 @@ found:
return res;
}
- inet_frag_lru_move(&fq->q);
return -1;
err:
kfree_skb(skb);
@@ -373,11 +369,10 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
if (frag_info->d_size > ieee802154_lowpan->max_dsize)
goto err;
- inet_frag_evictor(&ieee802154_lowpan->frags, &lowpan_frags, false);
-
fq = fq_find(net, frag_info, &source, &dest);
if (fq != NULL) {
int ret;
+
spin_lock(&fq->q.lock);
ret = lowpan_frag_queue(fq, skb, frag_type);
spin_unlock(&fq->q.lock);
@@ -393,20 +388,25 @@ err:
EXPORT_SYMBOL(lowpan_frag_rcv);
#ifdef CONFIG_SYSCTL
+static int zero;
+
static struct ctl_table lowpan_frags_ns_ctl_table[] = {
{
.procname = "6lowpanfrag_high_thresh",
.data = &init_net.ieee802154_lowpan.frags.high_thresh,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &init_net.ieee802154_lowpan.frags.low_thresh
},
{
.procname = "6lowpanfrag_low_thresh",
.data = &init_net.ieee802154_lowpan.frags.low_thresh,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec
+ .proc_handler = proc_dointvec_minmax,
+ .extra1 = &zero,
+ .extra2 = &init_net.ieee802154_lowpan.frags.high_thresh
},
{
.procname = "6lowpanfrag_time",
@@ -425,10 +425,12 @@ static struct ctl_table lowpan_frags_ns_ctl_table[] = {
{ }
};
+/* secret interval has been deprecated */
+static int lowpan_frags_secret_interval_unused;
static struct ctl_table lowpan_frags_ctl_table[] = {
{
.procname = "6lowpanfrag_secret_interval",
- .data = &lowpan_frags.secret_interval,
+ .data = &lowpan_frags_secret_interval_unused,
.maxlen = sizeof(int),
.mode = 0644,
.proc_handler = proc_dointvec_jiffies,
@@ -451,7 +453,10 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
goto err_alloc;
table[0].data = &ieee802154_lowpan->frags.high_thresh;
+ table[0].extra1 = &ieee802154_lowpan->frags.low_thresh;
+ table[0].extra2 = &init_net.ieee802154_lowpan.frags.high_thresh;
table[1].data = &ieee802154_lowpan->frags.low_thresh;
+ table[1].extra2 = &ieee802154_lowpan->frags.high_thresh;
table[2].data = &ieee802154_lowpan->frags.timeout;
table[3].data = &ieee802154_lowpan->max_dsize;
@@ -568,8 +573,10 @@ int __init lowpan_net_frag_init(void)
lowpan_frags.qsize = sizeof(struct frag_queue);
lowpan_frags.match = lowpan_frag_match;
lowpan_frags.frag_expire = lowpan_frag_expire;
- lowpan_frags.secret_interval = 10 * 60 * HZ;
- inet_frags_init(&lowpan_frags);
+ lowpan_frags.frags_cache_name = lowpan_frags_cache_name;
+ ret = inet_frags_init(&lowpan_frags);
+ if (ret)
+ goto err_pernet;
return ret;
err_pernet:
diff --git a/net/ieee802154/wpan-class.c b/net/ieee802154/wpan-class.c
index 8d6f6704da84..4955e0fe5883 100644
--- a/net/ieee802154/wpan-class.c
+++ b/net/ieee802154/wpan-class.c
@@ -48,7 +48,8 @@ MASTER_SHOW(transmit_power, "%d +- 1 dB");
MASTER_SHOW(cca_mode, "%d");
static ssize_t channels_supported_show(struct device *dev,
- struct device_attribute *attr, char *buf)
+ struct device_attribute *attr,
+ char *buf)
{
struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
int ret;
@@ -57,7 +58,7 @@ static ssize_t channels_supported_show(struct device *dev,
mutex_lock(&phy->pib_lock);
for (i = 0; i < 32; i++) {
ret = snprintf(buf + len, PAGE_SIZE - len,
- "%#09x\n", phy->channels_supported[i]);
+ "%#09x\n", phy->channels_supported[i]);
if (ret < 0)
break;
len += ret;
@@ -80,6 +81,7 @@ ATTRIBUTE_GROUPS(pmib);
static void wpan_phy_release(struct device *d)
{
struct wpan_phy *phy = container_of(d, struct wpan_phy, dev);
+
kfree(phy);
}
@@ -121,11 +123,12 @@ static int wpan_phy_iter(struct device *dev, void *_data)
{
struct wpan_phy_iter_data *wpid = _data;
struct wpan_phy *phy = container_of(dev, struct wpan_phy, dev);
+
return wpid->fn(phy, wpid->data);
}
int wpan_phy_for_each(int (*fn)(struct wpan_phy *phy, void *data),
- void *data)
+ void *data)
{
struct wpan_phy_iter_data wpid = {
.fn = fn,
@@ -197,6 +200,7 @@ EXPORT_SYMBOL(wpan_phy_free);
static int __init wpan_phy_class_init(void)
{
int rc;
+
rc = class_register(&wpan_phy_class);
if (rc)
goto err;