^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) * Copyright 2011, Siemens AG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * written by Alexander Smirnov <alex.bluesman.smirnov@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Based on patches from Jon Smirl <jonsmirl@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) 2011 Jon Smirl <jonsmirl@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * it under the terms of the GNU General Public License version 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) * as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) * You should have received a copy of the GNU General Public License along
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) * with this program; if not, write to the Free Software Foundation, Inc.,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) /* Jon's code is based on 6lowpan implementation for Contiki which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * Copyright (c) 2008, Swedish Institute of Computer Science.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * 3. Neither the name of the Institute nor the names of its contributors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * may be used to endorse or promote products derived from this software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) * SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #ifndef __6LOWPAN_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #define __6LOWPAN_H__
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include <linux/debugfs.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #include <net/net_namespace.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) /* special link-layer handling */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #include <net/mac802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define EUI64_ADDR_LEN 8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define LOWPAN_NHC_MAX_ID_LEN 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) /* Maximum next header compression length which we currently support inclusive
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) * possible inline data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define LOWPAN_NHC_MAX_HDR_LEN (sizeof(struct udphdr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) /* Max IPHC Header len without IPv6 hdr specific inline data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) * Useful for getting the "extra" bytes we need at worst case compression.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) * LOWPAN_IPHC + CID + LOWPAN_NHC_MAX_ID_LEN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) #define LOWPAN_IPHC_MAX_HEADER_LEN (2 + 1 + LOWPAN_NHC_MAX_ID_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) /* Maximum worst case IPHC header buffer size */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) #define LOWPAN_IPHC_MAX_HC_BUF_LEN (sizeof(struct ipv6hdr) + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) LOWPAN_IPHC_MAX_HEADER_LEN + \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) LOWPAN_NHC_MAX_HDR_LEN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) /* SCI/DCI is 4 bit width, so we have maximum 16 entries */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define LOWPAN_IPHC_CTX_TABLE_SIZE (1 << 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) #define LOWPAN_DISPATCH_IPV6 0x41 /* 01000001 = 65 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define LOWPAN_DISPATCH_IPHC 0x60 /* 011xxxxx = ... */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) #define LOWPAN_DISPATCH_IPHC_MASK 0xe0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) static inline bool lowpan_is_ipv6(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) return dispatch == LOWPAN_DISPATCH_IPV6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) static inline bool lowpan_is_iphc(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) return (dispatch & LOWPAN_DISPATCH_IPHC_MASK) == LOWPAN_DISPATCH_IPHC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define LOWPAN_PRIV_SIZE(llpriv_size) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) (sizeof(struct lowpan_dev) + llpriv_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) enum lowpan_lltypes {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) LOWPAN_LLTYPE_BTLE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) LOWPAN_LLTYPE_IEEE802154,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) enum lowpan_iphc_ctx_flags {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) LOWPAN_IPHC_CTX_FLAG_ACTIVE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) LOWPAN_IPHC_CTX_FLAG_COMPRESSION,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) struct lowpan_iphc_ctx {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) u8 id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) struct in6_addr pfx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) u8 plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) unsigned long flags;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct lowpan_iphc_ctx_table {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) spinlock_t lock;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) const struct lowpan_iphc_ctx_ops *ops;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) struct lowpan_iphc_ctx table[LOWPAN_IPHC_CTX_TABLE_SIZE];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) static inline bool lowpan_iphc_ctx_is_active(const struct lowpan_iphc_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) return test_bit(LOWPAN_IPHC_CTX_FLAG_ACTIVE, &ctx->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) lowpan_iphc_ctx_is_compression(const struct lowpan_iphc_ctx *ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) return test_bit(LOWPAN_IPHC_CTX_FLAG_COMPRESSION, &ctx->flags);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) struct lowpan_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) enum lowpan_lltypes lltype;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) struct dentry *iface_debugfs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) struct lowpan_iphc_ctx_table ctx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /* must be last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) u8 priv[] __aligned(sizeof(void *));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) struct lowpan_802154_neigh {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) __le16 short_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) struct lowpan_802154_neigh *lowpan_802154_neigh(void *neigh_priv)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return neigh_priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) struct lowpan_dev *lowpan_dev(const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) return netdev_priv(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) /* private device info */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) struct lowpan_802154_dev {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) struct net_device *wdev; /* wpan device ptr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) u16 fragment_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) static inline struct
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) lowpan_802154_dev *lowpan_802154_dev(const struct net_device *dev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) return (struct lowpan_802154_dev *)lowpan_dev(dev)->priv;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) struct lowpan_802154_cb {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) u16 d_tag;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) unsigned int d_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) u8 d_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) static inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) struct lowpan_802154_cb *lowpan_802154_cb(const struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) BUILD_BUG_ON(sizeof(struct lowpan_802154_cb) > sizeof(skb->cb));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) return (struct lowpan_802154_cb *)skb->cb;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) static inline void lowpan_iphc_uncompress_eui64_lladdr(struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) /* fe:80::XXXX:XXXX:XXXX:XXXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) * \_________________/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) * hwaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) ipaddr->s6_addr[0] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) ipaddr->s6_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) memcpy(&ipaddr->s6_addr[8], lladdr, EUI64_ADDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) /* second bit-flip (Universe/Local)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) * is done according RFC2464
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) ipaddr->s6_addr[8] ^= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) static inline void lowpan_iphc_uncompress_eui48_lladdr(struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) /* fe:80::XXXX:XXff:feXX:XXXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) * \_________________/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) * hwaddr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ipaddr->s6_addr[0] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) ipaddr->s6_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) memcpy(&ipaddr->s6_addr[8], lladdr, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) ipaddr->s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) ipaddr->s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) memcpy(&ipaddr->s6_addr[13], lladdr + 3, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) #ifdef DEBUG
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) /* print data in line */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) static inline void raw_dump_inline(const char *caller, char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) const unsigned char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) if (msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) pr_debug("%s():%s: ", caller, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) print_hex_dump_debug("", DUMP_PREFIX_NONE, 16, 1, buf, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) /* print data in a table format:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) * addr: xx xx xx xx xx xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) * addr: xx xx xx xx xx xx
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) * ...
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) static inline void raw_dump_table(const char *caller, char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) const unsigned char *buf, int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (msg)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) pr_debug("%s():%s:\n", caller, msg);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) print_hex_dump_debug("\t", DUMP_PREFIX_OFFSET, 16, 1, buf, len, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) #else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) static inline void raw_dump_table(const char *caller, char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) const unsigned char *buf, int len) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static inline void raw_dump_inline(const char *caller, char *msg,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) const unsigned char *buf, int len) { }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) * lowpan_fetch_skb - getting inline data from 6LoWPAN header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) * This function will pull data from sk buffer and put it into data to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) * remove the 6LoWPAN inline data. This function returns true if the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) * sk buffer is too small to pull the amount of data which is specified
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) * by len.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) * @skb: the buffer where the inline data should be pulled from.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) * @data: destination buffer for the inline data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * @len: amount of data which should be pulled in bytes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) static inline bool lowpan_fetch_skb(struct sk_buff *skb, void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) unsigned int len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) if (unlikely(!pskb_may_pull(skb, len)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) skb_copy_from_linear_data(skb, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) skb_pull(skb, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) static inline bool lowpan_802154_is_valid_src_short_addr(__le16 addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) /* First bit of addr is multicast, reserved or 802.15.4 specific */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) return !(addr & cpu_to_le16(0x8000));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) static inline void lowpan_push_hc_data(u8 **hc_ptr, const void *data,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) const size_t len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) memcpy(*hc_ptr, data, len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) *hc_ptr += len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) int lowpan_register_netdevice(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) enum lowpan_lltypes lltype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) int lowpan_register_netdev(struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) enum lowpan_lltypes lltype);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) void lowpan_unregister_netdevice(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) void lowpan_unregister_netdev(struct net_device *dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) * lowpan_header_decompress - replace 6LoWPAN header with IPv6 header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) * This function replaces the IPHC 6LoWPAN header which should be pointed at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) * skb->data and skb_network_header, with the IPv6 header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) * It would be nice that the caller have the necessary headroom of IPv6 header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) * and greatest Transport layer header, this would reduce the overhead for
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * reallocate headroom.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * @skb: the buffer which should be manipulate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) * @dev: the lowpan net device pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) * @daddr: destination lladdr of mac header which is used for compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) * methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) * @saddr: source lladdr of mac header which is used for compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) * methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) const void *daddr, const void *saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) * lowpan_header_compress - replace IPv6 header with 6LoWPAN header
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) * This function replaces the IPv6 header which should be pointed at
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) * skb->data and skb_network_header, with the IPHC 6LoWPAN header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) * The caller need to be sure that the sk buffer is not shared and at have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) * at least a headroom which is smaller or equal LOWPAN_IPHC_MAX_HEADER_LEN,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) * which is the IPHC "more bytes than IPv6 header" at worst case.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) * @skb: the buffer which should be manipulate.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) * @dev: the lowpan net device pointer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) * @daddr: destination lladdr of mac header which is used for compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) * methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) * @saddr: source lladdr of mac header which is used for compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) * methods.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) const void *daddr, const void *saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) #endif /* __6LOWPAN_H__ */