^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) /* Based on patches from Jon Smirl <jonsmirl@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Copyright (c) 2011 Jon Smirl <jonsmirl@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * This program is free software; you can redistribute it and/or modify
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * it under the terms of the GNU General Public License version 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * as published by the Free Software Foundation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) * This program is distributed in the hope that it will be useful,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) * but WITHOUT ANY WARRANTY; without even the implied warranty of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) * GNU General Public License for more details.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /* Jon's code is based on 6lowpan implementation for Contiki which is:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * Copyright (c) 2008, Swedish Institute of Computer Science.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * All rights reserved.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * Redistribution and use in source and binary forms, with or without
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * modification, are permitted provided that the following conditions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * are met:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) * 1. Redistributions of source code must retain the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * notice, this list of conditions and the following disclaimer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * 2. Redistributions in binary form must reproduce the above copyright
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * notice, this list of conditions and the following disclaimer in the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) * documentation and/or other materials provided with the distribution.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) * 3. Neither the name of the Institute nor the names of its contributors
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) * may be used to endorse or promote products derived from this software
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) * without specific prior written permission.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37) * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) * ARE DISCLAIMED. IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) * SUCH DAMAGE.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) #include <linux/bitops.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #include <linux/netdevice.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #include <net/6lowpan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) #include <net/ipv6.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #include "6lowpan_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #include "nhc.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) /* Values of fields within the IPHC encoding first byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define LOWPAN_IPHC_TF_MASK 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) #define LOWPAN_IPHC_TF_00 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define LOWPAN_IPHC_TF_01 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) #define LOWPAN_IPHC_TF_10 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) #define LOWPAN_IPHC_TF_11 0x18
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) #define LOWPAN_IPHC_NH 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) #define LOWPAN_IPHC_HLIM_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) #define LOWPAN_IPHC_HLIM_00 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) #define LOWPAN_IPHC_HLIM_01 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) #define LOWPAN_IPHC_HLIM_10 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) #define LOWPAN_IPHC_HLIM_11 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) /* Values of fields within the IPHC encoding second byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) #define LOWPAN_IPHC_CID 0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) #define LOWPAN_IPHC_SAC 0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) #define LOWPAN_IPHC_SAM_MASK 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) #define LOWPAN_IPHC_SAM_00 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81) #define LOWPAN_IPHC_SAM_01 0x10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) #define LOWPAN_IPHC_SAM_10 0x20
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) #define LOWPAN_IPHC_SAM_11 0x30
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) #define LOWPAN_IPHC_M 0x08
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) #define LOWPAN_IPHC_DAC 0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) #define LOWPAN_IPHC_DAM_MASK 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) #define LOWPAN_IPHC_DAM_00 0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) #define LOWPAN_IPHC_DAM_01 0x01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) #define LOWPAN_IPHC_DAM_10 0x02
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) #define LOWPAN_IPHC_DAM_11 0x03
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) /* ipv6 address based on mac
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) * second bit-flip (Universe/Local) is done according RFC2464
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) #define is_addr_mac_addr_based(a, m) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99) ((((a)->s6_addr[8]) == (((m)[0]) ^ 0x02)) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) (((a)->s6_addr[9]) == (m)[1]) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) (((a)->s6_addr[10]) == (m)[2]) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) (((a)->s6_addr[11]) == (m)[3]) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) (((a)->s6_addr[12]) == (m)[4]) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) (((a)->s6_addr[13]) == (m)[5]) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) (((a)->s6_addr[14]) == (m)[6]) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) (((a)->s6_addr[15]) == (m)[7]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) /* check whether we can compress the IID to 16 bits,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) * it's possible for unicast addresses with first 49 bits are zero only.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) #define lowpan_is_iid_16_bit_compressable(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) ((((a)->s6_addr16[4]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) (((a)->s6_addr[10]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) (((a)->s6_addr[11]) == 0xff) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) (((a)->s6_addr[12]) == 0xfe) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) (((a)->s6_addr[13]) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) /* check whether the 112-bit gid of the multicast address is mappable to: */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) /* 48 bits, FFXX::00XX:XXXX:XXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) #define lowpan_is_mcast_addr_compressable48(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) ((((a)->s6_addr16[1]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) (((a)->s6_addr16[2]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) (((a)->s6_addr16[3]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) (((a)->s6_addr16[4]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) (((a)->s6_addr[10]) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) /* 32 bits, FFXX::00XX:XXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) #define lowpan_is_mcast_addr_compressable32(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) ((((a)->s6_addr16[1]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) (((a)->s6_addr16[2]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) (((a)->s6_addr16[3]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) (((a)->s6_addr16[4]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) (((a)->s6_addr16[5]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) (((a)->s6_addr[12]) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) /* 8 bits, FF02::00XX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) #define lowpan_is_mcast_addr_compressable8(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) ((((a)->s6_addr[1]) == 2) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) (((a)->s6_addr16[1]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) (((a)->s6_addr16[2]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) (((a)->s6_addr16[3]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) (((a)->s6_addr16[4]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) (((a)->s6_addr16[5]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) (((a)->s6_addr16[6]) == 0) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) (((a)->s6_addr[14]) == 0))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) #define lowpan_is_linklocal_zero_padded(a) \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) (!(hdr->saddr.s6_addr[1] & 0x3f) && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) !hdr->saddr.s6_addr16[1] && \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) !hdr->saddr.s6_addr32[1])
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) #define LOWPAN_IPHC_CID_DCI(cid) (cid & 0x0f)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) #define LOWPAN_IPHC_CID_SCI(cid) ((cid & 0xf0) >> 4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) static inline void
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) lowpan_iphc_uncompress_802154_lladdr(struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) const struct ieee802154_addr *addr = lladdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) u8 eui64[EUI64_ADDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) switch (addr->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) case IEEE802154_ADDR_LONG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) ieee802154_le64_to_be64(eui64, &addr->extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) lowpan_iphc_uncompress_eui64_lladdr(ipaddr, eui64);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) case IEEE802154_ADDR_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) /* fe:80::ff:fe00:XXXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) * \__/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) * short_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) * Universe/Local bit is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) ipaddr->s6_addr[0] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) ipaddr->s6_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) ipaddr->s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) ipaddr->s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) ieee802154_le16_to_be16(&ipaddr->s6_addr16[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) &addr->short_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) /* should never handled and filtered by 802154 6lowpan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) static struct lowpan_iphc_ctx *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) lowpan_iphc_ctx_get_by_id(const struct net_device *dev, u8 id)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) struct lowpan_iphc_ctx *ret = &lowpan_dev(dev)->ctx.table[id];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) if (!lowpan_iphc_ctx_is_active(ret))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) return NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) static struct lowpan_iphc_ctx *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) lowpan_iphc_ctx_get_by_addr(const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) const struct in6_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) struct lowpan_iphc_ctx *table = lowpan_dev(dev)->ctx.table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) struct lowpan_iphc_ctx *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) struct in6_addr addr_pfx;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) u8 addr_plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) /* Check if context is valid. A context that is not valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) * MUST NOT be used for compression.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) if (!lowpan_iphc_ctx_is_active(&table[i]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) !lowpan_iphc_ctx_is_compression(&table[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) ipv6_addr_prefix(&addr_pfx, addr, table[i].plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) /* if prefix len < 64, the remaining bits until 64th bit is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) * zero. Otherwise we use table[i]->plen.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) if (table[i].plen < 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) addr_plen = 64;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) addr_plen = table[i].plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) if (ipv6_prefix_equal(&addr_pfx, &table[i].pfx, addr_plen)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) /* remember first match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) if (!ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) ret = &table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) /* get the context with longest prefix len */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) if (table[i].plen > ret->plen)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) ret = &table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) static struct lowpan_iphc_ctx *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) lowpan_iphc_ctx_get_by_mcast_addr(const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) const struct in6_addr *addr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) struct lowpan_iphc_ctx *table = lowpan_dev(dev)->ctx.table;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) struct lowpan_iphc_ctx *ret = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) struct in6_addr addr_mcast, network_pfx = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) /* init mcast address with */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) memcpy(&addr_mcast, addr, sizeof(*addr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) for (i = 0; i < LOWPAN_IPHC_CTX_TABLE_SIZE; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) /* Check if context is valid. A context that is not valid
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) * MUST NOT be used for compression.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) if (!lowpan_iphc_ctx_is_active(&table[i]) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) !lowpan_iphc_ctx_is_compression(&table[i]))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) /* setting plen */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) addr_mcast.s6_addr[3] = table[i].plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) /* get network prefix to copy into multicast address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) ipv6_addr_prefix(&network_pfx, &table[i].pfx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) table[i].plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) /* setting network prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) memcpy(&addr_mcast.s6_addr[4], &network_pfx, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) if (ipv6_addr_equal(addr, &addr_mcast)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) ret = &table[i];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) }
^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) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) static void lowpan_iphc_uncompress_lladdr(const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) switch (dev->addr_len) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) case ETH_ALEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) lowpan_iphc_uncompress_eui48_lladdr(ipaddr, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) case EUI64_ADDR_LEN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) lowpan_iphc_uncompress_eui64_lladdr(ipaddr, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) /* Uncompress address function for source and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) * destination address(non-multicast).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) * address_mode is the masked value for sam or dam value
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) static int lowpan_iphc_uncompress_addr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) u8 address_mode, const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) bool fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) switch (address_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* SAM and DAM are the same here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) case LOWPAN_IPHC_DAM_00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) /* for global link addresses */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) case LOWPAN_IPHC_SAM_01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) case LOWPAN_IPHC_DAM_01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) /* fe:80::XXXX:XXXX:XXXX:XXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) ipaddr->s6_addr[0] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) ipaddr->s6_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) case LOWPAN_IPHC_SAM_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) case LOWPAN_IPHC_DAM_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) /* fe:80::ff:fe00:XXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) ipaddr->s6_addr[0] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) ipaddr->s6_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) ipaddr->s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) ipaddr->s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) case LOWPAN_IPHC_SAM_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) case LOWPAN_IPHC_DAM_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) fail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) switch (lowpan_dev(dev)->lltype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) case LOWPAN_LLTYPE_IEEE802154:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) pr_debug("Invalid address mode value: 0x%x\n", address_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) if (fail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) pr_debug("Failed to fetch skb data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) raw_dump_inline(NULL, "Reconstructed ipv6 addr is",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) ipaddr->s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) /* Uncompress address function for source context
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) * based address(non-multicast).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) static int lowpan_iphc_uncompress_ctx_addr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) const struct lowpan_iphc_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) u8 address_mode, const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) bool fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) switch (address_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) /* SAM and DAM are the same here */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) case LOWPAN_IPHC_DAM_00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) fail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) /* SAM_00 -> unspec address ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) * Do nothing, address is already ::
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) * DAM 00 -> reserved should never occur.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) case LOWPAN_IPHC_SAM_01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) case LOWPAN_IPHC_DAM_01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[8], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) case LOWPAN_IPHC_SAM_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) case LOWPAN_IPHC_DAM_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) ipaddr->s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389) ipaddr->s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[14], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) case LOWPAN_IPHC_SAM_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394) case LOWPAN_IPHC_DAM_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) fail = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) switch (lowpan_dev(dev)->lltype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) case LOWPAN_LLTYPE_IEEE802154:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) lowpan_iphc_uncompress_802154_lladdr(ipaddr, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) lowpan_iphc_uncompress_lladdr(dev, ipaddr, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) ipv6_addr_prefix_copy(ipaddr, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) pr_debug("Invalid sam value: 0x%x\n", address_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) if (fail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) pr_debug("Failed to fetch skb data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) raw_dump_inline(NULL,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) "Reconstructed context based ipv6 src addr is",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) ipaddr->s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* Uncompress function for multicast destination address,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) * when M bit is set.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) static int lowpan_uncompress_multicast_daddr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427) struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) u8 address_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) bool fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) switch (address_mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) case LOWPAN_IPHC_DAM_00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) /* 00: 128 bits. The full address
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) * is carried in-line.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) fail = lowpan_fetch_skb(skb, ipaddr->s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) case LOWPAN_IPHC_DAM_01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) /* 01: 48 bits. The address takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) * the form ffXX::00XX:XXXX:XXXX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) ipaddr->s6_addr[0] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445) fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[11], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) case LOWPAN_IPHC_DAM_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) /* 10: 32 bits. The address takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449) * the form ffXX::00XX:XXXX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451) ipaddr->s6_addr[0] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[13], 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) case LOWPAN_IPHC_DAM_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) /* 11: 8 bits. The address takes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457) * the form ff02::00XX.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) ipaddr->s6_addr[0] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460) ipaddr->s6_addr[1] = 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[15], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) pr_debug("DAM value has a wrong value: 0x%x\n", address_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) if (fail) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) pr_debug("Failed to fetch skb data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473) raw_dump_inline(NULL, "Reconstructed ipv6 multicast addr is",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) ipaddr->s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479) static int lowpan_uncompress_multicast_ctx_daddr(struct sk_buff *skb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) struct lowpan_iphc_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) u8 address_mode)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) struct in6_addr network_pfx = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) bool fail;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) ipaddr->s6_addr[0] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) fail = lowpan_fetch_skb(skb, &ipaddr->s6_addr[1], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489) fail |= lowpan_fetch_skb(skb, &ipaddr->s6_addr[12], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) if (fail)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) return -EIO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) /* take prefix_len and network prefix from the context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494) ipaddr->s6_addr[3] = ctx->plen;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) /* get network prefix to copy into multicast address */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) ipv6_addr_prefix(&network_pfx, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) /* setting network prefix */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) memcpy(&ipaddr->s6_addr[4], &network_pfx, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) /* get the ecn values from iphc tf format and set it to ipv6hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) static inline void lowpan_iphc_tf_set_ecn(struct ipv6hdr *hdr, const u8 *tf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) /* get the two higher bits which is ecn */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507) u8 ecn = tf[0] & 0xc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) /* ECN takes 0x30 in hdr->flow_lbl[0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) hdr->flow_lbl[0] |= (ecn >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) /* get the dscp values from iphc tf format and set it to ipv6hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) static inline void lowpan_iphc_tf_set_dscp(struct ipv6hdr *hdr, const u8 *tf)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /* DSCP is at place after ECN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) u8 dscp = tf[0] & 0x3f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) /* The four highest bits need to be set at hdr->priority */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) hdr->priority |= ((dscp & 0x3c) >> 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) /* The two lower bits is part of hdr->flow_lbl[0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) hdr->flow_lbl[0] |= ((dscp & 0x03) << 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) /* get the flow label values from iphc tf format and set it to ipv6hdr */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) static inline void lowpan_iphc_tf_set_lbl(struct ipv6hdr *hdr, const u8 *lbl)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) /* flow label is always some array started with lower nibble of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529) * flow_lbl[0] and followed with two bytes afterwards. Inside inline
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) * data the flow_lbl position can be different, which will be handled
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) * by lbl pointer. E.g. case "01" vs "00" the traffic class is 8 bit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) * shifted, the different lbl pointer will handle that.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) * The flow label will started at lower nibble of flow_lbl[0], the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) * higher nibbles are part of DSCP + ECN.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) hdr->flow_lbl[0] |= lbl[0] & 0x0f;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) memcpy(&hdr->flow_lbl[1], &lbl[1], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) /* lowpan_iphc_tf_decompress - decompress the traffic class.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) * This function will return zero on success, a value lower than zero if
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) * failed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) static int lowpan_iphc_tf_decompress(struct sk_buff *skb, struct ipv6hdr *hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) u8 val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) u8 tf[4];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) /* Traffic Class and Flow Label */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) switch (val) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) case LOWPAN_IPHC_TF_00:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) /* ECN + DSCP + 4-bit Pad + Flow Label (4 bytes) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554) if (lowpan_fetch_skb(skb, tf, 4))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) /* 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) * |ECN| DSCP | rsv | Flow Label |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563) lowpan_iphc_tf_set_ecn(hdr, tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) lowpan_iphc_tf_set_dscp(hdr, tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565) lowpan_iphc_tf_set_lbl(hdr, &tf[1]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) case LOWPAN_IPHC_TF_01:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) if (lowpan_fetch_skb(skb, tf, 3))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* 1 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) * |ECN|rsv| Flow Label |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) lowpan_iphc_tf_set_ecn(hdr, tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) lowpan_iphc_tf_set_lbl(hdr, &tf[0]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) case LOWPAN_IPHC_TF_10:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) /* ECN + DSCP (1 byte), Flow Label is elided. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) if (lowpan_fetch_skb(skb, tf, 1))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586) /* 0 1 2 3 4 5 6 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) * +-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) * |ECN| DSCP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) * +-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) lowpan_iphc_tf_set_ecn(hdr, tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) lowpan_iphc_tf_set_dscp(hdr, tf);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) case LOWPAN_IPHC_TF_11:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) /* Traffic Class and Flow Label are elided */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) /* TTL uncompression values */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606) static const u8 lowpan_ttl_values[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) [LOWPAN_IPHC_HLIM_01] = 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) [LOWPAN_IPHC_HLIM_10] = 64,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) [LOWPAN_IPHC_HLIM_11] = 255,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) int lowpan_header_decompress(struct sk_buff *skb, const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) const void *daddr, const void *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) struct ipv6hdr hdr = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) struct lowpan_iphc_ctx *ci;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) u8 iphc0, iphc1, cid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 620) raw_dump_table(__func__, "raw skb data dump uncompressed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 621) skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 622)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 623) if (lowpan_fetch_skb(skb, &iphc0, sizeof(iphc0)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 624) lowpan_fetch_skb(skb, &iphc1, sizeof(iphc1)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 625) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 626)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 627) hdr.version = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 628)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 629) /* default CID = 0, another if the CID flag is set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 630) if (iphc1 & LOWPAN_IPHC_CID) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 631) if (lowpan_fetch_skb(skb, &cid, sizeof(cid)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 632) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 633) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 634)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 635) err = lowpan_iphc_tf_decompress(skb, &hdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 636) iphc0 & LOWPAN_IPHC_TF_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 637) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 638) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 639)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 640) /* Next Header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 641) if (!(iphc0 & LOWPAN_IPHC_NH)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 642) /* Next header is carried inline */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 643) if (lowpan_fetch_skb(skb, &hdr.nexthdr, sizeof(hdr.nexthdr)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 644) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 645)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 646) pr_debug("NH flag is set, next header carried inline: %02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 647) hdr.nexthdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 648) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 649)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 650) /* Hop Limit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 651) if ((iphc0 & LOWPAN_IPHC_HLIM_MASK) != LOWPAN_IPHC_HLIM_00) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 652) hdr.hop_limit = lowpan_ttl_values[iphc0 & LOWPAN_IPHC_HLIM_MASK];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 653) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 654) if (lowpan_fetch_skb(skb, &hdr.hop_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 655) sizeof(hdr.hop_limit)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 656) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 657) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 658)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 659) if (iphc1 & LOWPAN_IPHC_SAC) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 660) spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 661) ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_SCI(cid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 662) if (!ci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 663) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 664) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 665) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 666)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 667) pr_debug("SAC bit is set. Handle context based source address.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 668) err = lowpan_iphc_uncompress_ctx_addr(skb, dev, ci, &hdr.saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 669) iphc1 & LOWPAN_IPHC_SAM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 670) saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 671) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 672) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 673) /* Source address uncompression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 674) pr_debug("source address stateless compression\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 675) err = lowpan_iphc_uncompress_addr(skb, dev, &hdr.saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 676) iphc1 & LOWPAN_IPHC_SAM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 677) saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 678) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 679)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 680) /* Check on error of previous branch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 681) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 682) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 683)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 684) switch (iphc1 & (LOWPAN_IPHC_M | LOWPAN_IPHC_DAC)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 685) case LOWPAN_IPHC_M | LOWPAN_IPHC_DAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 686) skb->pkt_type = PACKET_BROADCAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 687)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 688) spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 689) ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_DCI(cid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 690) if (!ci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 691) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 692) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 693) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 694)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 695) /* multicast with context */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 696) pr_debug("dest: context-based mcast compression\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 697) err = lowpan_uncompress_multicast_ctx_daddr(skb, ci,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 698) &hdr.daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 699) iphc1 & LOWPAN_IPHC_DAM_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 700) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 701) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 702) case LOWPAN_IPHC_M:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 703) skb->pkt_type = PACKET_BROADCAST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 704)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 705) /* multicast */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 706) err = lowpan_uncompress_multicast_daddr(skb, &hdr.daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 707) iphc1 & LOWPAN_IPHC_DAM_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 708) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 709) case LOWPAN_IPHC_DAC:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 710) skb->pkt_type = PACKET_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 711)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 712) spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 713) ci = lowpan_iphc_ctx_get_by_id(dev, LOWPAN_IPHC_CID_DCI(cid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 714) if (!ci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 715) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 716) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 717) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 718)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 719) /* Destination address context based uncompression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 720) pr_debug("DAC bit is set. Handle context based destination address.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 721) err = lowpan_iphc_uncompress_ctx_addr(skb, dev, ci, &hdr.daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 722) iphc1 & LOWPAN_IPHC_DAM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 723) daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 724) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 725) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 726) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 727) skb->pkt_type = PACKET_HOST;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 728)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 729) err = lowpan_iphc_uncompress_addr(skb, dev, &hdr.daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 730) iphc1 & LOWPAN_IPHC_DAM_MASK,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 731) daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 732) pr_debug("dest: stateless compression mode %d dest %pI6c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 733) iphc1 & LOWPAN_IPHC_DAM_MASK, &hdr.daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 734) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 735) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 736)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 737) if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 738) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 739)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 740) /* Next header data uncompression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 741) if (iphc0 & LOWPAN_IPHC_NH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 742) err = lowpan_nhc_do_uncompression(skb, dev, &hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 743) if (err < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 744) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 745) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 746) err = skb_cow(skb, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 747) if (unlikely(err))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 748) return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 749) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 750)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 751) switch (lowpan_dev(dev)->lltype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 752) case LOWPAN_LLTYPE_IEEE802154:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 753) if (lowpan_802154_cb(skb)->d_size)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 754) hdr.payload_len = htons(lowpan_802154_cb(skb)->d_size -
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 755) sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 756) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 757) hdr.payload_len = htons(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 758) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 759) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 760) hdr.payload_len = htons(skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 761) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 762) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 763)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 764) pr_debug("skb headroom size = %d, data length = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 765) skb_headroom(skb), skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 766)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 767) pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n\t"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 768) "nexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 769) hdr.version, ntohs(hdr.payload_len), hdr.nexthdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 770) hdr.hop_limit, &hdr.daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 771)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 772) skb_push(skb, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 773) skb_reset_mac_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 774) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 775) skb_copy_to_linear_data(skb, &hdr, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 776)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 777) raw_dump_table(__func__, "raw header dump", (u8 *)&hdr, sizeof(hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 778)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 779) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 780) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 781) EXPORT_SYMBOL_GPL(lowpan_header_decompress);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 782)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 783) static const u8 lowpan_iphc_dam_to_sam_value[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 784) [LOWPAN_IPHC_DAM_00] = LOWPAN_IPHC_SAM_00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 785) [LOWPAN_IPHC_DAM_01] = LOWPAN_IPHC_SAM_01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 786) [LOWPAN_IPHC_DAM_10] = LOWPAN_IPHC_SAM_10,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 787) [LOWPAN_IPHC_DAM_11] = LOWPAN_IPHC_SAM_11,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 788) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 789)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 790) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 791) lowpan_iphc_compress_ctx_802154_lladdr(const struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 792) const struct lowpan_iphc_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 793) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 794) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 795) const struct ieee802154_addr *addr = lladdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 796) unsigned char extended_addr[EUI64_ADDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 797) bool lladdr_compress = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 798) struct in6_addr tmp = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 799)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 800) switch (addr->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 801) case IEEE802154_ADDR_LONG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 802) ieee802154_le64_to_be64(&extended_addr, &addr->extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 803) /* check for SAM/DAM = 11 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 804) memcpy(&tmp.s6_addr[8], &extended_addr, EUI64_ADDR_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 805) /* second bit-flip (Universe/Local) is done according RFC2464 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 806) tmp.s6_addr[8] ^= 0x02;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 807) /* context information are always used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 808) ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 809) if (ipv6_addr_equal(&tmp, ipaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 810) lladdr_compress = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 811) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 812) case IEEE802154_ADDR_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 813) tmp.s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 814) tmp.s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 815) ieee802154_le16_to_be16(&tmp.s6_addr16[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 816) &addr->short_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 817) /* context information are always used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 818) ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 819) if (ipv6_addr_equal(&tmp, ipaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 820) lladdr_compress = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 821) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 822) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 823) /* should never handled and filtered by 802154 6lowpan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 824) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 825) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 826) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 827)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 828) return lladdr_compress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 829) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 830)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 831) static bool lowpan_iphc_addr_equal(const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 832) const struct lowpan_iphc_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 833) const struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 834) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 835) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 836) struct in6_addr tmp = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 837)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 838) lowpan_iphc_uncompress_lladdr(dev, &tmp, lladdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 839)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 840) if (ctx)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 841) ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 842)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 843) return ipv6_addr_equal(&tmp, ipaddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 844) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 845)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 846) static u8 lowpan_compress_ctx_addr(u8 **hc_ptr, const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 847) const struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 848) const struct lowpan_iphc_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 849) const unsigned char *lladdr, bool sam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 850) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 851) struct in6_addr tmp = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 852) u8 dam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 853)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 854) switch (lowpan_dev(dev)->lltype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 855) case LOWPAN_LLTYPE_IEEE802154:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 856) if (lowpan_iphc_compress_ctx_802154_lladdr(ipaddr, ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 857) lladdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 858) dam = LOWPAN_IPHC_DAM_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 859) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 860) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 861) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 862) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 863) if (lowpan_iphc_addr_equal(dev, ctx, ipaddr, lladdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 864) dam = LOWPAN_IPHC_DAM_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 865) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 866) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 867) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 868) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 869)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 870) memset(&tmp, 0, sizeof(tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 871) /* check for SAM/DAM = 10 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 872) tmp.s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 873) tmp.s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 874) memcpy(&tmp.s6_addr[14], &ipaddr->s6_addr[14], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 875) /* context information are always used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 876) ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 877) if (ipv6_addr_equal(&tmp, ipaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 878) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[14], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 879) dam = LOWPAN_IPHC_DAM_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 880) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 881) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 882)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 883) memset(&tmp, 0, sizeof(tmp));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 884) /* check for SAM/DAM = 01, should always match */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 885) memcpy(&tmp.s6_addr[8], &ipaddr->s6_addr[8], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 886) /* context information are always used */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 887) ipv6_addr_prefix_copy(&tmp, &ctx->pfx, ctx->plen);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 888) if (ipv6_addr_equal(&tmp, ipaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 889) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[8], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 890) dam = LOWPAN_IPHC_DAM_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 891) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 892) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 893)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 894) WARN_ONCE(1, "context found but no address mode matched\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 895) return LOWPAN_IPHC_DAM_00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 896) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 897)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 898) if (sam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 899) return lowpan_iphc_dam_to_sam_value[dam];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 900) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 901) return dam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 902) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 903)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 904) static inline bool
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 905) lowpan_iphc_compress_802154_lladdr(const struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 906) const void *lladdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 908) const struct ieee802154_addr *addr = lladdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 909) unsigned char extended_addr[EUI64_ADDR_LEN];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 910) bool lladdr_compress = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 911) struct in6_addr tmp = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 912)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 913) switch (addr->mode) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 914) case IEEE802154_ADDR_LONG:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 915) ieee802154_le64_to_be64(&extended_addr, &addr->extended_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 916) if (is_addr_mac_addr_based(ipaddr, extended_addr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 917) lladdr_compress = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 918) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 919) case IEEE802154_ADDR_SHORT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 920) /* fe:80::ff:fe00:XXXX
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 921) * \__/
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 922) * short_addr
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 923) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 924) * Universe/Local bit is zero.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 925) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 926) tmp.s6_addr[0] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 927) tmp.s6_addr[1] = 0x80;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 928) tmp.s6_addr[11] = 0xFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 929) tmp.s6_addr[12] = 0xFE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 930) ieee802154_le16_to_be16(&tmp.s6_addr16[7],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 931) &addr->short_addr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 932) if (ipv6_addr_equal(&tmp, ipaddr))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 933) lladdr_compress = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 934) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 935) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 936) /* should never handled and filtered by 802154 6lowpan */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 937) WARN_ON_ONCE(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 938) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 939) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 940)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 941) return lladdr_compress;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 942) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 943)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 944) static u8 lowpan_compress_addr_64(u8 **hc_ptr, const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 945) const struct in6_addr *ipaddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 946) const unsigned char *lladdr, bool sam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 947) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 948) u8 dam = LOWPAN_IPHC_DAM_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 949)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 950) switch (lowpan_dev(dev)->lltype) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 951) case LOWPAN_LLTYPE_IEEE802154:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 952) if (lowpan_iphc_compress_802154_lladdr(ipaddr, lladdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 953) dam = LOWPAN_IPHC_DAM_11; /* 0-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 954) pr_debug("address compression 0 bits\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 955) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 956) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 957) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 958) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 959) if (lowpan_iphc_addr_equal(dev, NULL, ipaddr, lladdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 960) dam = LOWPAN_IPHC_DAM_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 961) pr_debug("address compression 0 bits\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 962) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 963) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 964)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 965) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 966) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 967)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 968) if (lowpan_is_iid_16_bit_compressable(ipaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 969) /* compress IID to 16 bits xxxx::XXXX */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 970) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr16[7], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 971) dam = LOWPAN_IPHC_DAM_10; /* 16-bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 972) raw_dump_inline(NULL, "Compressed ipv6 addr is (16 bits)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 973) *hc_ptr - 2, 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 974) goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 975) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 976)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 977) /* do not compress IID => xxxx::IID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 978) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr16[4], 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 979) raw_dump_inline(NULL, "Compressed ipv6 addr is (64 bits)",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 980) *hc_ptr - 8, 8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 981)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 982) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 983)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 984) if (sam)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 985) return lowpan_iphc_dam_to_sam_value[dam];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 986) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 987) return dam;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 988) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 989)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 990) /* lowpan_iphc_get_tc - get the ECN + DCSP fields in hc format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 991) static inline u8 lowpan_iphc_get_tc(const struct ipv6hdr *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 992) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 993) u8 dscp, ecn;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 994)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 995) /* hdr->priority contains the higher bits of dscp, lower are part of
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 996) * flow_lbl[0]. Note ECN, DCSP is swapped in ipv6 hdr.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 997) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 998) dscp = (hdr->priority << 2) | ((hdr->flow_lbl[0] & 0xc0) >> 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 999) /* ECN is at the two lower bits from first nibble of flow_lbl[0] */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) ecn = (hdr->flow_lbl[0] & 0x30);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) /* for pretty debug output, also shift ecn to get the ecn value */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) pr_debug("ecn 0x%02x dscp 0x%02x\n", ecn >> 4, dscp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) /* ECN is at 0x30 now, shift it to have ECN + DCSP */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1004) return (ecn << 2) | dscp;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1005) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1006)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) /* lowpan_iphc_is_flow_lbl_zero - check if flow label is zero */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) static inline bool lowpan_iphc_is_flow_lbl_zero(const struct ipv6hdr *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) return ((!(hdr->flow_lbl[0] & 0x0f)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) !hdr->flow_lbl[1] && !hdr->flow_lbl[2]);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) /* lowpan_iphc_tf_compress - compress the traffic class which is set by
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) * ipv6hdr. Return the corresponding format identifier which is used.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) static u8 lowpan_iphc_tf_compress(u8 **hc_ptr, const struct ipv6hdr *hdr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) /* get ecn dscp data in a byteformat as: ECN(hi) + DSCP(lo) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) u8 tc = lowpan_iphc_get_tc(hdr), tf[4], val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) /* printout the traffic class in hc format */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) pr_debug("tc 0x%02x\n", tc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) if (lowpan_iphc_is_flow_lbl_zero(hdr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) if (!tc) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) /* 11: Traffic Class and Flow Label are elided. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) val = LOWPAN_IPHC_TF_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) /* 10: ECN + DSCP (1 byte), Flow Label is elided.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) * 0 1 2 3 4 5 6 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) * +-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) * |ECN| DSCP |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) * +-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) lowpan_push_hc_data(hc_ptr, &tc, sizeof(tc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) val = LOWPAN_IPHC_TF_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) /* check if dscp is zero, it's after the first two bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) if (!(tc & 0x3f)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) /* 01: ECN + 2-bit Pad + Flow Label (3 bytes), DSCP is elided
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) * 1 2
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) * |ECN|rsv| Flow Label |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) memcpy(&tf[0], &hdr->flow_lbl[0], 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) /* zero the highest 4-bits, contains DCSP + ECN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) tf[0] &= ~0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) /* set ECN */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) tf[0] |= (tc & 0xc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) lowpan_push_hc_data(hc_ptr, tf, 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) val = LOWPAN_IPHC_TF_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) /* 00: ECN + DSCP + 4-bit Pad + Flow Label (4 bytes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) * 1 2 3
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) * |ECN| DSCP | rsv | Flow Label |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) memcpy(&tf[0], &tc, sizeof(tc));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) /* highest nibble of flow_lbl[0] is part of DSCP + ECN
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) * which will be the 4-bit pad and will be filled with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) * zeros afterwards.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) memcpy(&tf[1], &hdr->flow_lbl[0], 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) /* zero the 4-bit pad, which is reserved */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) tf[1] &= ~0xf0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) lowpan_push_hc_data(hc_ptr, tf, 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) val = LOWPAN_IPHC_TF_00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) static u8 lowpan_iphc_mcast_ctx_addr_compress(u8 **hc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) const struct lowpan_iphc_ctx *ctx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) const struct in6_addr *ipaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) u8 data[6];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) /* flags/scope, reserved (RIID) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) memcpy(data, &ipaddr->s6_addr[1], 2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) /* group ID */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) memcpy(&data[1], &ipaddr->s6_addr[11], 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) lowpan_push_hc_data(hc_ptr, data, 6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) return LOWPAN_IPHC_DAM_00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) static u8 lowpan_iphc_mcast_addr_compress(u8 **hc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) const struct in6_addr *ipaddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) u8 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) if (lowpan_is_mcast_addr_compressable8(ipaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) pr_debug("compressed to 1 octet\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) /* use last byte */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[15], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) val = LOWPAN_IPHC_DAM_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) } else if (lowpan_is_mcast_addr_compressable32(ipaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) pr_debug("compressed to 4 octets\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) /* second byte + the last three */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[13], 3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) val = LOWPAN_IPHC_DAM_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) } else if (lowpan_is_mcast_addr_compressable48(ipaddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) pr_debug("compressed to 6 octets\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) /* second byte + the last five */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[1], 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) lowpan_push_hc_data(hc_ptr, &ipaddr->s6_addr[11], 5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) val = LOWPAN_IPHC_DAM_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) pr_debug("using full address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) lowpan_push_hc_data(hc_ptr, ipaddr->s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) val = LOWPAN_IPHC_DAM_00;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) return val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) int lowpan_header_compress(struct sk_buff *skb, const struct net_device *dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) const void *daddr, const void *saddr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) u8 iphc0, iphc1, *hc_ptr, cid = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) struct ipv6hdr *hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) u8 head[LOWPAN_IPHC_MAX_HC_BUF_LEN] = {};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) struct lowpan_iphc_ctx *dci, *sci, dci_entry, sci_entry;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) int ret, ipv6_daddr_type, ipv6_saddr_type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) if (skb->protocol != htons(ETH_P_IPV6))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) hdr = ipv6_hdr(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) hc_ptr = head + 2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) pr_debug("IPv6 header dump:\n\tversion = %d\n\tlength = %d\n"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) "\tnexthdr = 0x%02x\n\thop_lim = %d\n\tdest = %pI6c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) hdr->version, ntohs(hdr->payload_len), hdr->nexthdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) hdr->hop_limit, &hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) raw_dump_table(__func__, "raw skb network header dump",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) skb_network_header(skb), sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) /* As we copy some bit-length fields, in the IPHC encoding bytes,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) * we sometimes use |=
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) * If the field is 0, and the current bit value in memory is 1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) * this does not work. We therefore reset the IPHC encoding here
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) iphc0 = LOWPAN_DISPATCH_IPHC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) iphc1 = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) raw_dump_table(__func__, "sending raw skb network uncompressed packet",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) ipv6_daddr_type = ipv6_addr_type(&hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) if (ipv6_daddr_type & IPV6_ADDR_MULTICAST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) dci = lowpan_iphc_ctx_get_by_mcast_addr(dev, &hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) dci = lowpan_iphc_ctx_get_by_addr(dev, &hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) if (dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) memcpy(&dci_entry, dci, sizeof(*dci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) cid |= dci->id;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) spin_lock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) sci = lowpan_iphc_ctx_get_by_addr(dev, &hdr->saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) if (sci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) memcpy(&sci_entry, sci, sizeof(*sci));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) cid |= (sci->id << 4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) spin_unlock_bh(&lowpan_dev(dev)->ctx.lock);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) /* if cid is zero it will be compressed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) if (cid) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) iphc1 |= LOWPAN_IPHC_CID;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) lowpan_push_hc_data(&hc_ptr, &cid, sizeof(cid));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) /* Traffic Class, Flow Label compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) iphc0 |= lowpan_iphc_tf_compress(&hc_ptr, hdr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) /* NOTE: payload length is always compressed */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) /* Check if we provide the nhc format for nexthdr and compression
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) * functionality. If not nexthdr is handled inline and not compressed.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) ret = lowpan_nhc_check_compression(skb, hdr, &hc_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) if (ret == -ENOENT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) lowpan_push_hc_data(&hc_ptr, &hdr->nexthdr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) sizeof(hdr->nexthdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) iphc0 |= LOWPAN_IPHC_NH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) /* Hop limit
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) * if 1: compress, encoding is 01
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) * if 64: compress, encoding is 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) * if 255: compress, encoding is 11
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) * else do not compress
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) switch (hdr->hop_limit) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) case 1:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) iphc0 |= LOWPAN_IPHC_HLIM_01;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) case 64:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) iphc0 |= LOWPAN_IPHC_HLIM_10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) case 255:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) iphc0 |= LOWPAN_IPHC_HLIM_11;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) lowpan_push_hc_data(&hc_ptr, &hdr->hop_limit,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) sizeof(hdr->hop_limit));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1226)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1227) ipv6_saddr_type = ipv6_addr_type(&hdr->saddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) /* source address compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) if (ipv6_saddr_type == IPV6_ADDR_ANY) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) pr_debug("source address is unspecified, setting SAC\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) iphc1 |= LOWPAN_IPHC_SAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) if (sci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) iphc1 |= lowpan_compress_ctx_addr(&hc_ptr, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) &hdr->saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) &sci_entry, saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) iphc1 |= LOWPAN_IPHC_SAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) if (ipv6_saddr_type & IPV6_ADDR_LINKLOCAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) lowpan_is_linklocal_zero_padded(hdr->saddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) iphc1 |= lowpan_compress_addr_64(&hc_ptr, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) &hdr->saddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) saddr, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) pr_debug("source address unicast link-local %pI6c iphc1 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) &hdr->saddr, iphc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) pr_debug("send the full source address\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) lowpan_push_hc_data(&hc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) hdr->saddr.s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) /* destination address compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) if (ipv6_daddr_type & IPV6_ADDR_MULTICAST) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) pr_debug("destination address is multicast: ");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) iphc1 |= LOWPAN_IPHC_M;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) if (dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) iphc1 |= lowpan_iphc_mcast_ctx_addr_compress(&hc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) &dci_entry,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) &hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) iphc1 |= LOWPAN_IPHC_DAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) iphc1 |= lowpan_iphc_mcast_addr_compress(&hc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) &hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) if (dci) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) iphc1 |= lowpan_compress_ctx_addr(&hc_ptr, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) &hdr->daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) &dci_entry, daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) iphc1 |= LOWPAN_IPHC_DAC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) if (ipv6_daddr_type & IPV6_ADDR_LINKLOCAL &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) lowpan_is_linklocal_zero_padded(hdr->daddr)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) iphc1 |= lowpan_compress_addr_64(&hc_ptr, dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) &hdr->daddr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) daddr, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) pr_debug("dest address unicast link-local %pI6c iphc1 0x%02x\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) &hdr->daddr, iphc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) pr_debug("dest address unicast %pI6c\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) &hdr->daddr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) lowpan_push_hc_data(&hc_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) hdr->daddr.s6_addr, 16);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) /* next header compression */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) if (iphc0 & LOWPAN_IPHC_NH) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) ret = lowpan_nhc_do_compression(skb, hdr, &hc_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) head[0] = iphc0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) head[1] = iphc1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) skb_pull(skb, sizeof(struct ipv6hdr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1303) skb_reset_transport_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1304) memcpy(skb_push(skb, hc_ptr - head), head, hc_ptr - head);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1305) skb_reset_network_header(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1306)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1307) pr_debug("header len %d skb %u\n", (int)(hc_ptr - head), skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1308)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1309) raw_dump_table(__func__, "raw skb data dump compressed",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1310) skb->data, skb->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1311) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1312) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1313) EXPORT_SYMBOL_GPL(lowpan_header_compress);