Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

3 Commits   0 Branches   0 Tags
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   2) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   3) #include <linux/if_arp.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   4) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   5) #include <net/6lowpan.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   6) #include <net/mac802154.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   7) #include <net/ieee802154_netdev.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   8) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   9) #include "6lowpan_i.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  11) #define LOWPAN_DISPATCH_FIRST		0xc0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  12) #define LOWPAN_DISPATCH_FRAG_MASK	0xf8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  13) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  14) #define LOWPAN_DISPATCH_NALP		0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  15) #define LOWPAN_DISPATCH_ESC		0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  16) #define LOWPAN_DISPATCH_HC1		0x42
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  17) #define LOWPAN_DISPATCH_DFF		0x43
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  18) #define LOWPAN_DISPATCH_BC0		0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  19) #define LOWPAN_DISPATCH_MESH		0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  20) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  21) static int lowpan_give_skb_to_device(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  22) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  23) 	skb->protocol = htons(ETH_P_IPV6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  24) 	skb->dev->stats.rx_packets++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  25) 	skb->dev->stats.rx_bytes += skb->len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  26) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  27) 	return netif_rx(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  28) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  29) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  30) static int lowpan_rx_handlers_result(struct sk_buff *skb, lowpan_rx_result res)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  31) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  32) 	switch (res) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  33) 	case RX_CONTINUE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  34) 		/* nobody cared about this packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  35) 		net_warn_ratelimited("%s: received unknown dispatch\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  36) 				     __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  37) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  38) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  39) 	case RX_DROP_UNUSABLE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  40) 		kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  41) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  42) 		fallthrough;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  43) 	case RX_DROP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  44) 		return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  45) 	case RX_QUEUED:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  46) 		return lowpan_give_skb_to_device(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  47) 	default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  48) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  49) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  50) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  51) 	return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  52) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  53) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  54) static inline bool lowpan_is_frag1(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  55) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  56) 	return (dispatch & LOWPAN_DISPATCH_FRAG_MASK) == LOWPAN_DISPATCH_FRAG1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  57) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  58) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  59) static inline bool lowpan_is_fragn(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  60) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  61) 	return (dispatch & LOWPAN_DISPATCH_FRAG_MASK) == LOWPAN_DISPATCH_FRAGN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  62) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  63) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  64) static lowpan_rx_result lowpan_rx_h_frag(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  66) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  67) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  68) 	if (!(lowpan_is_frag1(*skb_network_header(skb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  69) 	      lowpan_is_fragn(*skb_network_header(skb))))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  70) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  71) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  72) 	ret = lowpan_frag_rcv(skb, *skb_network_header(skb) &
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  73) 			      LOWPAN_DISPATCH_FRAG_MASK);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  74) 	if (ret == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  75) 		return RX_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  77) 	/* Packet is freed by lowpan_frag_rcv on error or put into the frag
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  78) 	 * bucket.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  79) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  80) 	return RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  81) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  82) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  83) int lowpan_iphc_decompress(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  84) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  85) 	struct ieee802154_hdr hdr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  86) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  87) 	if (ieee802154_hdr_peek_addrs(skb, &hdr) < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  88) 		return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  89) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  90) 	return lowpan_header_decompress(skb, skb->dev, &hdr.dest, &hdr.source);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  92) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  93) static lowpan_rx_result lowpan_rx_h_iphc(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  94) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  95) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  96) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  97) 	if (!lowpan_is_iphc(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  98) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  99) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) 	/* Setting datagram_offset to zero indicates non frag handling
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) 	 * while doing lowpan_header_decompress.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) 	lowpan_802154_cb(skb)->d_size = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) 	ret = lowpan_iphc_decompress(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) 	if (ret < 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) 		return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109) 	return RX_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) lowpan_rx_result lowpan_rx_h_ipv6(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) 	if (!lowpan_is_ipv6(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) 	/* Pull off the 1-byte of 6lowpan header. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) 	skb_pull(skb, 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) 	return RX_QUEUED;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) static inline bool lowpan_is_esc(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) 	return dispatch == LOWPAN_DISPATCH_ESC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) static lowpan_rx_result lowpan_rx_h_esc(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) 	if (!lowpan_is_esc(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) 	net_warn_ratelimited("%s: %s\n", skb->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) 			     "6LoWPAN ESC not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) 	return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) static inline bool lowpan_is_hc1(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) 	return dispatch == LOWPAN_DISPATCH_HC1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) static lowpan_rx_result lowpan_rx_h_hc1(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) 	if (!lowpan_is_hc1(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) 	net_warn_ratelimited("%s: %s\n", skb->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) 			     "6LoWPAN HC1 not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) 	return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) static inline bool lowpan_is_dff(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) 	return dispatch == LOWPAN_DISPATCH_DFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) static lowpan_rx_result lowpan_rx_h_dff(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) 	if (!lowpan_is_dff(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) 	net_warn_ratelimited("%s: %s\n", skb->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) 			     "6LoWPAN DFF not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) 	return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) static inline bool lowpan_is_bc0(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) 	return dispatch == LOWPAN_DISPATCH_BC0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) static lowpan_rx_result lowpan_rx_h_bc0(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) 	if (!lowpan_is_bc0(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) 	net_warn_ratelimited("%s: %s\n", skb->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) 			     "6LoWPAN BC0 not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) 	return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) static inline bool lowpan_is_mesh(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) 	return (dispatch & LOWPAN_DISPATCH_FIRST) == LOWPAN_DISPATCH_MESH;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) static lowpan_rx_result lowpan_rx_h_mesh(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) 	if (!lowpan_is_mesh(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) 		return RX_CONTINUE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) 	net_warn_ratelimited("%s: %s\n", skb->dev->name,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) 			     "6LoWPAN MESH not supported\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) 	return RX_DROP_UNUSABLE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) static int lowpan_invoke_rx_handlers(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204) 	lowpan_rx_result res;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) #define CALL_RXH(rxh)			\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) 	do {				\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) 		res = rxh(skb);	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209) 		if (res != RX_CONTINUE)	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) 			goto rxh_next;	\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) 	} while (0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) 	/* likely at first */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) 	CALL_RXH(lowpan_rx_h_iphc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) 	CALL_RXH(lowpan_rx_h_frag);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) 	CALL_RXH(lowpan_rx_h_ipv6);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) 	CALL_RXH(lowpan_rx_h_esc);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) 	CALL_RXH(lowpan_rx_h_hc1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) 	CALL_RXH(lowpan_rx_h_dff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) 	CALL_RXH(lowpan_rx_h_bc0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) 	CALL_RXH(lowpan_rx_h_mesh);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) rxh_next:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) 	return lowpan_rx_handlers_result(skb, res);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) #undef CALL_RXH
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) static inline bool lowpan_is_nalp(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) 	return (dispatch & LOWPAN_DISPATCH_FIRST) == LOWPAN_DISPATCH_NALP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) /* Lookup for reserved dispatch values at:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)  * https://www.iana.org/assignments/_6lowpan-parameters/_6lowpan-parameters.xhtml#_6lowpan-parameters-1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236)  * Last Updated: 2015-01-22
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) static inline bool lowpan_is_reserved(u8 dispatch)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) 	return ((dispatch >= 0x44 && dispatch <= 0x4F) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) 		(dispatch >= 0x51 && dispatch <= 0x5F) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) 		(dispatch >= 0xc8 && dispatch <= 0xdf) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) 		dispatch >= 0xe8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246) /* lowpan_rx_h_check checks on generic 6LoWPAN requirements
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247)  * in MAC and 6LoWPAN header.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)  * Don't manipulate the skb here, it could be shared buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) static inline bool lowpan_rx_h_check(struct sk_buff *skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) 	__le16 fc = ieee802154_get_fc_from_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) 	/* check on ieee802154 conform 6LoWPAN header */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) 	if (!ieee802154_is_data(fc) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) 	    !ieee802154_skb_is_intra_pan_addressing(fc, skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) 	/* check if we can dereference the dispatch */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) 	if (unlikely(!skb->len))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) 	if (lowpan_is_nalp(*skb_network_header(skb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) 	    lowpan_is_reserved(*skb_network_header(skb)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) 		return false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) 	return true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) static int lowpan_rcv(struct sk_buff *skb, struct net_device *wdev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) 		      struct packet_type *pt, struct net_device *orig_wdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) 	struct net_device *ldev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) 	if (wdev->type != ARPHRD_IEEE802154 ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) 	    skb->pkt_type == PACKET_OTHERHOST ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) 	    !lowpan_rx_h_check(skb))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) 	ldev = wdev->ieee802154_ptr->lowpan_dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) 	if (!ldev || !netif_running(ldev))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) 		goto drop;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) 	/* Replacing skb->dev and followed rx handlers will manipulate skb. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286) 	skb = skb_share_check(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) 	if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) 	skb->dev = ldev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) 	/* When receive frag1 it's likely that we manipulate the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) 	 * When recevie iphc we manipulate the data buffer. So we need
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) 	 * to unshare the buffer.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) 	 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) 	if (lowpan_is_frag1(*skb_network_header(skb)) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) 	    lowpan_is_iphc(*skb_network_header(skb))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) 		skb = skb_unshare(skb, GFP_ATOMIC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298) 		if (!skb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) 	return lowpan_invoke_rx_handlers(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) drop:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305) 	kfree_skb(skb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) 	return NET_RX_DROP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) static struct packet_type lowpan_packet_type = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) 	.type = htons(ETH_P_IEEE802154),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) 	.func = lowpan_rcv,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) void lowpan_rx_init(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317) 	dev_add_pack(&lowpan_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) void lowpan_rx_exit(void)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) 	dev_remove_pack(&lowpan_packet_type);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) }